Point your AS at it
Configuring the authorization server comes first. It is the box to the left of your MCP server in Deployment. One step decides whether any of this works.
-
Settle the public URL.
resourceServerUrlhas to be the URL clients dial, path and all. The library publishes RFC 9728 metadata at/.well-known/oauth-protected-resource/mcpfor an/mcppath, and names that same URL asresource. A client that reads a different host there declines to attach its token. -
Register that URL at your AS as a resource identifier, with RFC 8707 resource indicators enabled. The client sends
resource=https://mcp.acme.com/mcp, and your AS has to mint a token whoseaudequals it. Without it you get a perfectly signed token that this library refuses with 401.Create an API whose Identifier is exactly
https://mcp.acme.com/mcp(that value becomesaud). Enable Authorize using Resource Indicator / RFC 8707 for the application that will connect to MCP. Grant the scopes you will advertise (mcp, plus any step-up scopes such aswrite).In AuthKit / MCP resource server settings, register
https://mcp.acme.com/mcpas the resource. Tokens minted for that connector must carryaudequal to that URL. Map Google Workspace (or your IdP) soemail,email_verified, andhdreach the access token when your policy uses them.Under Connected Apps / MCP resource server, set the resource identifier to
https://mcp.acme.com/mcp. Enable resource indicators so the client’sresource=parameter is honoured asaud. Pass through verified email and Workspacehdif your rules match on them. -
Define the scopes. The baseline is whatever you pass to
requiredScopes(defaultmcp), plus one scope for each entry intoolScopesorcapabilityScopes, such aswrite. Grant them to the client. The library advertises the full set asscopes_supportedin the resource metadata. -
Decide how clients register. Prefer an AS that supports CIMD. If yours only offers DCR, publish
registration_endpointinoauthMetadataand treat it as a stopgap: DCR is deprecated in this protocol revision. -
Check the claims your rules need.
iss,sub,audandexpare always required. Anyemailordomainrule also needsemailandemail_verified: true. A Workspacedomainrule readshd, so the AS has to pass it through from Google.
Then hand the library the issuer
Section titled “Then hand the library the issuer”const fetch = createMcpFetch({ resourceServerUrl: new URL(process.env.MCP_PUBLIC_URL!), oauthMetadata: await discoverOAuth(process.env.OAUTH_ISSUER!), policy, createServer,});discoverOAuth reads the endpoints and jwks_uri off the AS, so the verifier
block stays optional.
token_verifier = JwtVerifier( issuer=os.environ["OAUTH_ISSUER"], jwks_uri=os.environ["OAUTH_JWKS_URI"], resource=os.environ["MCP_PUBLIC_URL"],)Nothing in the Python package discovers AS metadata for you. Give JwtVerifier
the issuer and jwks_uri directly. Step 3 collapses to the baseline scope,
because per-capability step-up is npm-only.
Add https://mcp.acme.com/mcp in Claude as a custom connector and sign in.
If something misbehaves, the symptom-to-cause table is in Troubleshooting.