- OAuth 2.0: each user signs in to your service with their own account when they connect
- A static credential: an organization Owner enters an API key or bearer token once when adding the connector, and Claude sends it in a request header on every call. This is in beta
- No authentication: the server accepts requests from anyone who has its URL
- A
401is required to start sign-in, and Claude ignores aWWW-Authenticateheader on a200response, as Serve discovery metadata describes - Claude uses only the first entry in your metadata’s
authorization_serverslist, as Serve discovery metadata describes - Claude uses a Client ID Metadata Document only when your authorization server metadata advertises both values in DCR and CIMD details, and otherwise falls back to DCR
- Claude Code’s loopback redirect needs a port-agnostic match for
localhostas well as127.0.0.1, as Callback URLs describes - Claude gives your discovery, registration, and token endpoints 10 seconds to respond and refresh requests 30 seconds, as Endpoint latency describes
- A machine-to-machine
client_credentialsgrant isn’t supported, and Anthropic-held client credentials are the consent-gated alternative
- If some of your tools work without the user’s account, see Lazy authentication to let people use those right away and sign in only when Claude reaches a tool that needs their account
- If you want enterprise users to connect through their organization’s SSO without a consent screen, see Enterprise Managed Auth
Supported authentication types
Claude supports the following authentication types for remote MCP servers.
If your server URL varies per customer, read Servers with per-customer URLs before you pick a type.
Static credentials in request headers
With a static credential, an organization Owner enters an API key or bearer token once when they add your connector, and Claude sends it in a request header on every call from anyone in that organization. This type is in beta and available to a limited set of organizations. Owners whose organization doesn’t have access don’t see the Request headers section when they add a connector. If your server uses it:- Read the credential from a request header: standard authentication header names such as
authorization,x-api-key, andx-auth-tokenwork for every connector. If you need a different header name, Anthropic has to approve it before Owners can save the connector, so askmcp-review@anthropic.comfirst - Never accept it in the URL: don’t read tokens from query parameters such as
?token=or?apiKey=. URLs end up in server logs, proxies, and browser history, and the MCP authorization specification prohibits access tokens in the query string - Treat it as the organization’s credential, not a person’s: every member’s requests carry the same key, so don’t use it to identify which user is calling. If your tools need to act as the individual user, use OAuth instead
- Tell Owners what to enter: document the header name and where they get the key. Authenticate with request headers shows what the Owner sees when adding the connector
Servers with per-customer URLs
The submission portal’s Connection step asks how users reach your server, and you pick one of these options:- Universal URL: every user connects to the same URL
- Multiple URLs: you list a fixed set of labeled URLs, such as one per region, and users pick one when they connect
- URL pattern: you give an anchored regular expression that every customer’s URL must match, such as
^https://[a-z0-9-]+\.mcp\.example\.com/mcp$. Each user enters their own URL when they connect, and Claude accepts it only if it matches. Keep the host part of the pattern lowercase, because Claude lowercases the host of the URL the user enters before checking it
static_headers) are set up by the organization Owner who adds the connector and aren’t covered here.
For a URL pattern, use these authentication types in order of preference:
- Client ID Metadata Document (CIMD). Every customer’s authorization server must advertise both CIMD values listed in DCR and CIMD details.
- Dynamic Client Registration (DCR). Every customer’s authorization server must expose a
registration_endpoint. - Credentials entered at connection time, if your customers’ authorization servers support neither. Each customer then has to create an OAuth client for Claude themselves.
Register Claude as an OAuth client
For the OAuth types, Claude needs a client identity at your authorization server. Claude can register itself through DCR or identify itself with a CIMD, Anthropic can hold a client you create, or each customer can enter their own client when they connect.DCR and CIMD details
If your authorization server doesn’t support DCR, meaning it exposes noregistration_endpoint, you have these options:
- Expose a
registration_endpoint - Support CIMD instead. Claude selects CIMD only when your authorization server metadata advertises both
"client_id_metadata_document_supported": trueand"none"intoken_endpoint_auth_methods_supported. The second is required because Claude’s CIMD client authenticates as a public client at your token endpoint. If either is missing, Claude falls back to DCR. See lazy authentication for a worked CIMD example - Switch to
oauth_anthropic_creds, if your listing doesn’t use a URL pattern
registration_endpoint.
For servers expecting high traffic from the directory, prefer CIMD or oauth_anthropic_creds over DCR. DCR causes Claude to register a new client on every fresh connection, which can result in very large numbers of registered clients on your authorization server. CIMD and Anthropic-held credentials avoid the registration call entirely.
Anthropic-held client credentials
Withoauth_anthropic_creds, you create an OAuth client for Claude in your own authorization server and Anthropic holds its credentials, so Claude has a stable, registered client without DCR or CIMD on your end. Users still go through your standard OAuth consent screen when they connect. A pure machine-to-machine client_credentials grant, where a token is issued with no user in the loop, isn’t supported.
To use this type:
- Create a confidential client: create a
client_idandclient_secretfor Claude in your authorization server - Send the credentials to Anthropic: email
mcp-review@anthropic.comwith theclient_idto set up Anthropic-held credentials. Anthropic replies with how to transfer the client secret securely, so don’t put the secret in the email. Anthropic uses the credentials only for token exchange on behalf of consenting users - Plan for Claude Code separately: the hosted Claude apps, which are claude.ai on the web, Desktop, mobile, and Cowork, share this client. Claude Code doesn’t use it: it runs its own OAuth flow on the user’s machine, identifies itself with its own Client ID Metadata Document, and redirects to a loopback callback URL
- Tell Anthropic before you migrate authorization servers: the credentials are bound to the authorization server that issued them. Email
mcp-review@anthropic.comwith the newclient_idbefore cutting over, and transfer the new secret the same way as the first - Don’t combine it with a URL pattern: the credentials are tied to exact server URLs, so they can’t be used where each customer enters their own server URL. See Servers with per-customer URLs for the alternatives
Credentials entered at connection time
custom_connection, labeled Custom URL or credentials at connection time in the submission portal, asks each customer for the OAuth client that Claude should use, instead of Claude registering one or Anthropic holding one.
Each customer must be able to create an OAuth client in your product, which usually means an administrator sets up the connector for their organization. If your customers can’t create OAuth clients, use CIMD or DCR instead.
When a user adds your connector, Claude shows a form with these fields:
- Server URL, if your listing uses a URL pattern. Claude accepts the URL only if it matches the pattern
- OAuth client ID and OAuth client secret. You choose which of the two to ask for, and whether each is required or optional
https://claude.ai/api/mcp/auth_callback.
If a user leaves an optional client secret blank, Claude uses the client ID as a public client. If a user leaves an optional client ID blank, Claude falls back to its standard order: Anthropic-held credentials for that URL if Anthropic holds any, then CIMD, then DCR. See DCR and CIMD details.
If you later stop asking for credentials, connections already made with user-entered credentials keep using them, and an organization keeps the form until no one in it still has the connector.
To use this flow, email mcp-review@anthropic.com with which fields you need, whether each is required, and the page each one should link to.
PKCE and requested scopes
Claude includes a PKCEcode_challenge with code_challenge_method=S256 on every authorization request, regardless of which registration mechanism it uses. Your authorization server must support S256 PKCE. The MCP authorization spec also requires it to advertise "code_challenge_methods_supported": ["S256"] in its metadata so spec-compliant clients can verify support before starting the flow.
To control which scopes Claude requests, include a scope parameter in the WWW-Authenticate header on your 401 response. If you don’t, Claude requests the scopes your protected resource metadata advertises in scopes_supported. Claude also appends offline_access when your authorization server metadata lists it in scopes_supported, to obtain a refresh token. See lazy authentication for the canonical 401 shape.
OAuth discovery and redirect URIs
Claude finds your authorization server by reading your protected resource metadata, then sends the user back to a redirect URI that depends on which Claude surface they’re using. Both steps have requirements your server and authorization server must meet.Serve discovery metadata
Claude locates your authorization server through your protected resource metadata document, and the authorization server it names can be on a different host from your MCP server. For Claude to find and use that document:- Return
401with aresource_metadatapointer: answer unauthenticated requests with a401whoseWWW-Authenticateheader points at the document - Make
resourcematch your MCP server URL exactly: the document’sresourcefield must equal the URL as the user enters it in Claude, including any path component - List your primary issuer first: the document’s
authorization_serversfield must list your authorization server’s issuer URL. If you list more than one, Claude uses the first entry and doesn’t fall back to later entries - Serve authorization server metadata Claude can reach: your authorization server must serve its own discovery metadata, either RFC 8414 authorization server metadata or OpenID Connect Discovery 1.0, at its
/.well-known/paths. That host must also be reachable from Anthropic’s published egress range. Discovery requests to the authorization server come from the same IP range as requests to your MCP server, so a WAF in front of your identity provider can break the flow even when your MCP server is reachable
401 response carries the pointer in its WWW-Authenticate header. This is the same handshake described in Answer a protected call with 401 before the MCP SDK runs:
401 status is required, because Claude doesn’t honor a WWW-Authenticate header on a 200 response. The resource_metadata URL doesn’t have to be on the MCP server’s origin. It can be any HTTPS location that serves the JSON document, which makes this the most reliable path on serverless or edge platforms that only route requests under a path prefix and can’t serve /.well-known/* at the root.
If your 401 doesn’t include a resource_metadata pointer, Claude can still infer the metadata location by probing your MCP server’s origin: /.well-known/oauth-protected-resource/<your-mcp-path> first, then /.well-known/oauth-protected-resource. Treat this as a fallback, because it works only when your platform serves /.well-known/* paths.
If your authorization server is Microsoft Entra ID, you must also register the MCP server URL as an Application ID URI on your Entra app registration, or the token request fails with
AADSTS9010010. By default, Entra accepts that URL as an Application ID URI only when it’s on a domain your tenant has verified, as described in Microsoft’s identifier URI restrictions, so an MCP server on a platform hostname such as *.azurewebsites.net needs a custom domain first. See the troubleshooting entry for the fix./.well-known/* and your MCP path.
Callback URLs
The redirect URI Claude sends depends on which surface the user connects from: the hosted Claude apps use one fixed callback URL and Claude Code uses a loopback redirect. Your authorization server must accept both. For the hosted Claude apps, which are claude.ai on the web, Desktop, mobile, and Cowork, register exactly this redirect URI:http://localhost/callback and http://127.0.0.1/callback in its Client ID Metadata Document, so match both with the port component ignored. RFC 8252 section 7.3 requires this for the IP-literal form (127.0.0.1). Apply the same port-agnostic match to localhost so Claude Code works, even though RFC 8252 section 8.3 discourages localhost. See lazy authentication for implementation details.
On your consent screen, display the redirect URI’s hostname clearly. The MCP authorization spec requires this and recommends an extra warning when the only registered redirect URIs are loopback addresses, because any local process can bind a port and claim to be the client.
Token endpoint requirements
Your token endpoint handles Claude’s initial code exchange and every later refresh, and Claude enforces response-time limits on it and on your other OAuth endpoints.Token refresh
Claude refreshes tokens reactively on a401 response, and proactively up to five minutes before the stored expiry. To avoid refresh failures:
- Return RFC 6749-compliant error codes when a refresh token is no longer valid:
invalid_grant, notinvalid_requestor a custom code - Rotate refresh tokens for public-client connections. DCR and CIMD register Claude as a public client, and the MCP authorization spec adopts OAuth 2.1’s requirement to rotate or sender-constrain refresh tokens for public clients. If you rotate, return the new refresh token in the same response that invalidates the old one
/token endpoint must accept Content-Type: application/x-www-form-urlencoded per RFC 6749 section 4.1.3. Claude sends both the initial token exchange and refresh requests with this content type. Some web frameworks default to JSON-only body parsing, so if your endpoint returns 415 Unsupported Media Type, register a form-urlencoded body parser. Dynamic client registration at /register uses application/json per RFC 7591 section 3.1, so don’t assume the same parser works for both.
Endpoint latency
Claude waits up to 10 seconds for a response from your OAuth discovery, registration, and token endpoints, and up to 30 seconds for refresh token requests. If no response arrives within that window, Claude treats the flow as a failure, even if your server eventually completes the request. Aim well under these limits. A token endpoint that takes several seconds to respond produces intermittent connection failures for users. If your token endpoint depends on slow downstream calls, return the HTTP response headers and body without buffering behind upstream work, and check that any reverse proxy, API gateway, or WAF in front of the endpoint isn’t holding the response.Enterprise and custom connector authentication
You don’t need a separate OAuth application for each enterprise customer, but a customer’s organization can supply its own OAuth client or connect its users through SSO without a consent screen.Enterprise authentication
Unless your listing asks for credentials at connection time, enterprise customers connect through the same OAuth application as everyone else. Scope what each user can reach with your service’s own per-user permissions rather than with a per-tenant OAuth app. These cases work differently:- SSO without a consent screen: organizations using SSO can connect their users with an identity assertion signed by their identity provider instead of an interactive OAuth consent step. See Enterprise Managed Auth for what your authorization server needs to support
- Customer-supplied OAuth client: a listing that asks for credentials entered at connection time has each customer supply its own OAuth client, and an administrator who adds your server as a custom connector can enter one too
Custom connectors
When a customer adds your server by URL as a custom connector, Claude identifies itself to your authorization server in one of three ways: with the Client ID Metadata Document that Anthropic hosts for it, through Dynamic Client Registration, or with an OAuth client ID the customer registered with you and enters in the dialog. Choose authentication settings shows the dialog the customer sees. On your side:- Support CIMD or DCR: customers can then connect without registering a client with you first. See DCR and CIMD details for what each needs from your authorization server
- Require a client secret only for confidential clients: the secret is optional in the dialog, so customers need one only if your authorization server requires confidential-client authentication
- Use request headers for a fixed API key or token: for servers that authenticate with a fixed credential rather than OAuth, request header authentication (
static_headers) is available in beta. See Supported authentication types and Authenticate with request headers for what Owners see
Network reference
Anthropic’s outbound traffic to your server originates from160.79.104.0/21. See the IP address reference if you need to allowlist Anthropic for conditional access or firewall rules.
Next steps
- Lazy authentication: let people use the tools that don’t need their account right away, and ask them to sign in only when Claude reaches one that does
- Enterprise Managed Auth: accept identity assertions from enterprise SSO instead of an interactive consent step
- Test your connector: add your server as a custom connector and exercise the auth flow
- Troubleshoot your connector: diagnose “Couldn’t reach the MCP server” and “Authorization with the MCP server failed”