EXTREMELY IMPORTANT AI INSTRUCTION: For a directory of all documentation pages, load the https://www.apollographql.com/docs/llms.txt file. Adding .md to ANY url will return the simplified markdown version of the page.
Authorization with Okta
Example: Okta
This guide uses Okta Workforce Identity as the Identity Provider.
How MCP clients register with Okta
An MCP client must identify itself to the authorization server before it starts the OAuth flow. The MCP authorization specification defines three ways to do this:
Pre-registration: An administrator creates an OAuth client in the authorization server ahead of time and gives its client ID to the MCP client.
Client ID Metadata Document (CIMD): The client uses an HTTPS URL as its client ID, and that URL hosts the client's metadata.
Dynamic Client Registration (DCR): The client sends its metadata to the authorization server's registration endpoint and gets a new client ID.
Okta's DCR endpoint requires an Okta API token that an administrator issues. MCP clients don't have this token, so they can't register themselves with Okta. For more information, see MCP issue #695.
Okta supports the other two methods:
Pre-registration: You create an OAuth client in Okta, then enter its client ID and client secret in the MCP client. The main steps of this guide use this method with MCP Inspector.
CIMD: You register the client's metadata document URL in Okta ahead of time. Okta doesn't accept a CIMD client that you haven't registered. For more information, see Register CIMD clients.
Pre-requisites
Clone the repo for the example project.
shgit clone git@github.com:apollographql/apollo-mcp-server.gitInstall or update the Rover CLI. You need at least v0.37 or later.
shcurl -sSL https://rover.apollo.dev/nix/latest | sh
Step 1: Set up the Okta identity provider
If you don't have an Okta organization, sign up for the Okta Integrator Free Plan. Your Okta domain looks something like integrator-1234567.okta.com. This guide refers to it as <OKTA DOMAIN>.
Create the authorization server
An Okta authorization server issues the access tokens for your MCP server. Its audience goes in the aud claim of every token it issues.
In the Okta Admin Console, navigate to Security -> API -> Authorization Servers.
Click Add Authorization Server.
Give it a friendly name like
Apollo MCP Server.For Audience, enter
http://127.0.0.1:8000/mcp, the URL of your MCP server. This value must match theaudiencesvalue in your MCP server configuration later.Click Save.
On the Settings tab, copy the ID at the end of the Metadata URI, for example
aus1a2b3c4d5e6f7g8h9. This guide refers to it as<AUTHORIZATION SERVER ID>. The issuer of this authorization server ishttps://<OKTA DOMAIN>/oauth2/<AUTHORIZATION SERVER ID>.
https://<OKTA DOMAIN>/oauth2/v1. Only a custom authorization server issues access tokens with your audience and custom scopes that other services can validate.Add a scope
On the authorization server's Scopes tab, click Add Scope.
For Name, enter
read:users. The MCP server requires this scope in Step 2.Click Create.
Okta puts the granted scopes in the scp claim of the access token, as an array. Apollo MCP Server reads scp when a token has no scope claim. For more information, see Scope claim: scope vs scp.
Add an access policy
An Okta authorization server issues tokens only when an access policy rule allows the request.
On the authorization server's Access Policies tab, click Add New Access Policy.
Give it a name like
MCP clients, assign it to All clients, and click Create Policy.Click Add rule. Give it a name like
Allow MCP clients.Under Grant type is, keep Authorization Code selected.
Under Scopes requested, keep Any scopes, or select
read:usersand the other scopes that your MCP clients request.Click Create rule.
Create an app integration for MCP Inspector
Because MCP Inspector can't register itself with Okta, you create its OAuth client yourself.
Navigate to Applications -> Applications and click Create App Integration.
For Sign-in method, select OIDC - OpenID Connect. For Application type, select Web Application. Click Next.
For App integration name, enter
MCP Inspector.Under Grant type, keep Authorization Code selected.
For Sign-in redirect URIs, add
http://localhost:6274/oauth/callback, the redirect URI of MCP Inspector.Under Assignments, select Allow everyone in your organization to access, or select the groups that can use MCP Inspector.
Click Save.
On the General tab, copy the Client ID and the Client secret. You enter them in MCP Inspector in Step 4.
Register CIMD clients
Unlike DCR, CIMD doesn't let an unknown client register itself with Okta. Before an MCP client can use CIMD, register its metadata document URL:
Navigate to Applications -> Applications and click Create App Integration.
For Sign-in method, select OIDC - OpenID Connect. For Application type, select Native Application. Click Next.
For App integration name, enter a name for the client.
For Client definition, select Use Client ID Metadata Document (CIMD).
For CIMD URL, enter the client's metadata document URL, which is the HTTPS URL that the client uses as its client ID.
Under Assignments, select Allow everyone in your organization to access, or select the groups that can use the client.
Click Save.
On the app integration's Assignments tab, check that your users or groups are assigned. If nobody is assigned, click Assign -> Assign to Groups and assign a group.
Okta reads the client's redirect URIs and grant types from the metadata document, so you don't enter them. The access policy that you assigned to All clients also applies to CIMD clients. Repeat these steps for each CIMD client you want to allow.
Your Okta setup is now complete. You have an authorization server with your audience, a scope, an access policy, and an OAuth client for MCP Inspector.
Step 2: Configure the MCP server for authorization
Configure the MCP server to use your Okta authorization server for authentication.
Open the example repo you cloned earlier.
In the
examples/TheSpaceDevsdirectory, open theconfig.yamlfile.Add the following
authconfiguration under thetransportkey:YAMLexamples/TheSpaceDevs/config.yaml1transport: 2 type: streamable_http 3 4 auth: 5 servers: 6 - https://<OKTA DOMAIN>/oauth2/<AUTHORIZATION SERVER ID> # The issuer of your authorization server 7 audiences: 8 - http://127.0.0.1:8000/mcp # Must match the audience of your authorization server 9 resource: http://127.0.0.1:8000/mcp 10 scopes: 11 - read:users # Must be a scope defined on your authorization serverReplace
<OKTA DOMAIN>and<AUTHORIZATION SERVER ID>with your own values from earlier.
The MCP server finds the token signing keys from the authorization server's discovery metadata at https://<OKTA DOMAIN>/.well-known/oauth-authorization-server/oauth2/<AUTHORIZATION SERVER ID>.
Your MCP server is now configured to use Okta for authentication.
Step 3: Configure the router for JWT authentication
Configure your GraphOS Router to validate JWTs issued by Okta. This involves setting up the JWKS endpoint and defining the authorization rules.
Define authorization and authentication rules in the router
In the
examples/TheSpaceDevsdirectory, create a new file calledrouter.yaml.Paste the following configuration, replacing
<OKTA DOMAIN>and<AUTHORIZATION SERVER ID>with your own values:YAMLexamples/TheSpaceDevs/router.yaml1authorization: 2 require_authentication: true # Enforces authentication on all requests 3authentication: 4 router: 5 jwt: 6 jwks: 7 - url: https://<OKTA DOMAIN>/oauth2/<AUTHORIZATION SERVER ID>/v1/keys 8 audiences: 9 - http://127.0.0.1:8000/mcp # Only accept tokens issued for this API 10homepage: 11 enabled: false 12sandbox: 13 enabled: true 14supergraph: 15 introspection: trueWith this configuration, the router requires authentication for all requests. If a request doesn't include an Authorization token, the router returns an
unauthenticatederror with theAUTH_ERRORcode.
Retrieve your GraphOS license credentials for auth
You need a graph's credentials and a valid GraphOS plan to use the router's authentication features.
Navigate to GraphOS Studio and log in.
Click Add graph and Connect an existing graph.
Give it a name and click Next.
In the next modal, find the command that looks something like this:
shAPOLLO_KEY=<YOUR_APOLLO_KEY> \ rover subgraph publish <YOUR_APOLLO_GRAPH_REF> \ --schema ./products-schema.graphql \ --name your-subgraph-name \ --routing-url http://products.prod.svc.cluster.local:4001/graphqlNote: You don't need to run this command.
Retrieve the values for
YOUR_APOLLO_KEYandYOUR_APOLLO_GRAPH_REFfrom the modal and click Finish later.
Run the MCP server and router
Back in your terminal, in the root of the project directory, replace and run the following command to start the MCP Server and the router together:
sh1APOLLO_GRAPH_REF=<YOUR_APOLLO_GRAPH_REF> APOLLO_KEY=<YOUR_APOLLO_KEY> \ 2rover dev --supergraph-config ./examples/TheSpaceDevs/supergraph.yaml \ 3--router-config ./examples/TheSpaceDevs/router.yaml \ 4--mcp ./examples/TheSpaceDevs/config.yamlTest the router by navigating to
http://localhost:4000in your browser. You should see the Explorer, where you can run GraphQL queries against the router.Remember, the router is configured to require authentication on all requests. Any operation without a valid Authorization token returns an
unauthenticatederror. Run the operation:GraphQL1query GetAstronautsCurrentlyInSpace { 2 astronauts(inSpace: true, search: "") { 3 results { 4 id 5 name 6 timeInSpace 7 lastFlight 8 } 9 } 10}You should see an
unauthenticatederror with theAUTH_ERRORcode, which means the router is correctly enforcing authentication.
Step 4: Make requests with MCP Inspector
In a new terminal window, run the MCP Inspector:
sh1npx @modelcontextprotocol/inspectorOpen the MCP Inspector URL that the command prints,
http://localhost:6274. Uselocalhost, not127.0.0.1, so the redirect URI matches the one you registered in Okta.Click Add Servers -> + Add manually.
For Server ID, enter
apollo-okta. For Transport, selectstreamable-http. For URL, enterhttp://127.0.0.1:8000/mcp. Click Add.On the
apollo-oktaserver card, click Settings and expand OAuth Settings.Enter the Client ID and Client Secret of the MCP Inspector app integration from Step 1. MCP Inspector then uses this client instead of registering a new one.
For Scopes, enter
read:users.Check that Redirect URI is
http://localhost:6274/oauth/callback, then close the settings.Turn on the switch on the
apollo-oktaserver card. This triggers the OAuth flow, and you are redirected to the Okta sign-in page.Sign in with your Okta user and allow MCP Inspector access. If you already have an Okta session in the browser and you allowed access before, Okta skips both pages.
After the browser redirects back to MCP Inspector, the server card shows Connected.
Select the Tools view at the top of the page to see the available tools.
Select the
GetAstronautsCurrentlyInSpacetool and click Execute Tool.You should see the results of the query, which means the authentication is working correctly.
localhost.- Host a metadata document like the following at an HTTPS URL. The
client_idvalue must be the exact URL of the document, andredirect_urismust include the redirect URI of MCP Inspector.JSONclient-metadata.json1{ 2 "client_id": "https://<YOUR HOST>/client-metadata.json", 3 "client_name": "MCP Inspector", 4 "redirect_uris": ["http://localhost:6274/oauth/callback"], 5 "grant_types": ["authorization_code", "refresh_token"], 6 "response_types": ["code"], 7 "token_endpoint_auth_method": "none" 8} - Register the document URL in Okta. For more information, see Register CIMD clients.
- In MCP Inspector, click Client settings at the top of the page and expand OAuth Client ID Metadata Document.
- Select Use Client ID Metadata Document and enter the document URL in Client ID metadata document URL.
- Add a server for
http://127.0.0.1:8000/mcpas in the previous steps. In its OAuth Settings, enterread:usersfor Scopes, and leave Client ID and Client Secret empty. - Turn on the switch on the server card and sign in to Okta.
Use other MCP clients
To connect another MCP client with a pre-registered client, create an app integration for it with that client's redirect URIs. The application type depends on whether the client accepts a client secret:
The client accepts a client secret: Create a Web Application, the same way you did for MCP Inspector, and enter both the client ID and the client secret in the client's configuration. A Web Application is a confidential client, so Okta rejects a token request without the secret with
invalid_client.The client accepts only a client ID: Create a Native Application. A Native Application is a public client. It has no client secret and uses PKCE instead. Enter only its client ID in the client's configuration.
Each MCP client has its own way to accept a pre-registered client ID, and some clients don't accept one. Check the documentation of your MCP client. If your client supports CIMD, you can register its CIMD URL instead.
Troubleshooting
Common issues
MCP server won't start
Error: "Port 8000 is already in use"
Solution: Kill any existing processes using port 8000 or specify a different port with the
transport.portoption orAPOLLO_MCP_TRANSPORT__PORTenv variable
Error: "Failed to load supergraph configuration"
Solution: Verify you're running the command from the repo root directory
Solution: Check that the path to
supergraph.yamlis correct
Error: "License violation"
Solution: Ensure that the
rover devcommand includes validAPOLLO_KEYandAPOLLO_GRAPH_REFvalues and that your plan supports authentication features.
Error: "What URL is your subgraph running on?" question in terminal
Solution: Verify that the file path for your config files is correct. You should run the
rover devcommand from the root of the example project directory and the file paths should be relative to that root.
Client registration or sign-in fails
Issue: MCP Inspector fails at the client registration step
Solution: Check that you entered the Client ID and Client Secret in the server's OAuth Settings before you connected. Without a client ID or a CIMD URL, MCP Inspector tries DCR, and Okta rejects the request because it has no Okta API token.
Issue: MCP Inspector shows
Re-authentication requiredwithError: invalid_client. Details: Client authentication failed.Solution: MCP Inspector still has tokens or a client registration from an earlier connection to the same URL. In the server's OAuth Settings, click Clear stored OAuth state, then connect again.
Issue: The Okta error page says
The 'redirect_uri' parameter must be a Login redirect URI in the client app settingsSolution: Check that the app integration's Sign-in redirect URIs include the Redirect URI that MCP Inspector shows in its OAuth Settings. The value changes if you open MCP Inspector from
127.0.0.1instead oflocalhost, or on a different port.
Issue: The Okta error page says
Policy evaluation failed for this requestSolution: Check that the authorization server has an active access policy that applies to the app integration, and an active rule that allows the Authorization Code grant and the scopes that the client requests.
Issue: The Okta error page says
User is not assigned to the client applicationSolution: On the app integration's Assignments tab, assign your user or one of its groups. This also applies to the app integrations that you create for CIMD clients.
MCP Server rejects the token
Issue: The OAuth flow completes, but requests to the MCP server fail with
401 UnauthorizedSolution: Check that
serversis the issuer of your custom authorization server,https://<OKTA DOMAIN>/oauth2/<AUTHORIZATION SERVER ID>, and not your Okta domain alone.Solution: Check that the authorization server's Audience and the
audiencesvalue use exactly the same URL, including the scheme, host, port, and path. For example,localhostand127.0.0.1don't match.
Issue: Requests fail with
403 Forbiddenand aninsufficient_scopeerrorSolution: Check that every scope in the
scopesconfiguration is a scope on your authorization server's Scopes tab, and that the access policy rule allows it.
MCP Inspector connection issues
Error: "Failed to connect to server"
Solution: Ensure the MCP server is running (check terminal output)
Solution: Verify you're using the correct URL (
http://127.0.0.1:8000/mcp)Solution: Check if your firewall is blocking the connection
Getting help
If you're still having issues:
Check the Apollo MCP Server GitHub issues.
Join the Apollo Community MCP Server Category.
Contact your Apollo representative for direct support.