Authentication for connectors changedconnectors/building/authentication
Nearest release: v2.1.309, published 3 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 23 Oct 2026 00:06 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 23 Oct 2026 18:07 UTC.
Upstream edited
Recorded here
Lines+18added
Lines−18removed
From line
21
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits11to this page, all time
The whole hunk
from line 21, old and new numbered
/
from line 21
2121
2222> [!NOTE]
2323>
24> * If some of your tools work without the user's account, see [Lazy authentication](/docs/connectors/building/lazy-authentication.md) to let people use those right away and sign in only when Claude reaches a tool that needs their account
25> * If you want enterprise users to connect through their organization's SSO without a consent screen, see [Enterprise Managed Auth](/docs/connectors/building/enterprise-managed-auth.md)
24> * If some of your tools work without the user's account, see [Lazy authentication](https://claude.com/docs/connectors/building/lazy-authentication.md) to let people use those right away and sign in only when Claude reaches a tool that needs their account
25> * If you want enterprise users to connect through their organization's SSO without a consent screen, see [Enterprise Managed Auth](https://claude.com/docs/connectors/building/enterprise-managed-auth.md)
2626
2727Use this page to [pick an authentication type](#supported-authentication-types), [register Claude as an OAuth client](#register-claude-as-an-oauth-client), [make discovery and redirects work](#oauth-discovery-and-redirect-uris), and [meet the token endpoint requirements](#token-endpoint-requirements).
2828
from line 37
3737| `oauth_anthropic_creds` | OAuth 2.0 with [Anthropic-held client credentials](#anthropic-held-client-credentials) | Supported. [Enter the client in the developer portal](#enter-your-oauth-client-in-the-developer-portal) |
3838| `custom_connection` | Custom URL or OAuth client credentials [entered at connection time](#credentials-entered-at-connection-time) | Contact `[email protected]` |
3939| `static_headers` | Fixed credential (API key or bearer token) entered by an organization Owner as a request header when adding the connector | Beta, for a limited set of organizations |
40| `none` | No authentication (authless server) | Supported by default. To leave some tools open and require sign-in for others, see [Lazy authentication](/docs/connectors/building/lazy-authentication.md) |
40| `none` | No authentication (authless server) | Supported by default. To leave some tools open and require sign-in for others, see [Lazy authentication](https://claude.com/docs/connectors/building/lazy-authentication.md) |
4141
4242If your server URL varies per customer, read [Servers with per-customer URLs](#servers-with-per-customer-urls) before you pick a type.
4343
from line 48
4848* **Read the credential from a request header**: standard authentication header names such as `authorization`, `x-api-key`, and `x-auth-token` work for every connector. If you need a different header name, Anthropic has to approve it before Owners can save the connector, so ask `[email protected]` first
4949* **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](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#token-requirements)
5050* **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
51* **Tell Owners what to enter**: document the header name and where they get the key. [Authenticate with request headers](/docs/connectors/custom/add-unlisted.md#authenticate-with-request-headers) shows what the Owner sees when adding the connector
51* **Tell Owners what to enter**: document the header name and where they get the key. [Authenticate with request headers](https://claude.com/docs/connectors/custom/add-unlisted.md#authenticate-with-request-headers) shows what the Owner sees when adding the connector
5252
5353### Servers with per-customer URLs
5454
from line 85
8585If your authorization server doesn't support DCR, meaning it exposes no `registration_endpoint`, you have these options:
8686
8787* Expose a `registration_endpoint`
88* Support CIMD instead. Claude selects CIMD only when your authorization server metadata advertises both `"client_id_metadata_document_supported": true` and `"none"` in `token_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](/docs/connectors/building/lazy-authentication.md#identify-claude-with-a-client-id-metadata-document) for a worked CIMD example
88* Support CIMD instead. Claude selects CIMD only when your authorization server metadata advertises both `"client_id_metadata_document_supported": true` and `"none"` in `token_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](https://claude.com/docs/connectors/building/lazy-authentication.md#identify-claude-with-a-client-id-metadata-document) for a worked CIMD example
8989* Switch to `oauth_anthropic_creds`, if your listing doesn't use a URL pattern
9090
9191If your server URL varies per customer and DCR isn't available, CIMD is the recommended path. Every customer's authorization server must advertise both CIMD values. Otherwise Claude falls back to DCR for that customer, which needs a `registration_endpoint`.
from line 105
105105
106106### Enter your OAuth client in the developer portal
107107
108If your listing uses Anthropic-held client credentials, enter your OAuth client in the **How users authenticate** section when you [submit your connector](/docs/connectors/building/submission.md):
108If your listing uses Anthropic-held client credentials, enter your OAuth client in the **How users authenticate** section when you [submit your connector](https://claude.com/docs/connectors/building/submission.md):
109109
1101101. Under **Authentication requirement**, select **Always required** or **Required when the server asks**.
1111112. Under **Authentication methods**, find the **OAuth sign-in** card. If there's none, click **Add OAuth sign-in**.
from line 160
160160
161161Claude includes a [PKCE](https://datatracker.ietf.org/doc/html/rfc7636) `code_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](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#authorization-code-protection) also requires it to advertise `"code_challenge_methods_supported": ["S256"]` in its metadata so spec-compliant clients can verify support before starting the flow.
162162
163To 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](/docs/connectors/building/lazy-authentication.md#answer-a-protected-call-with-401-before-the-mcp-sdk-runs) for the canonical `401` shape.
163To 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](https://claude.com/docs/connectors/building/lazy-authentication.md#answer-a-protected-call-with-401-before-the-mcp-sdk-runs) for the canonical `401` shape.
164164
165165## OAuth discovery and redirect URIs
166166
from line 175
175175* **List your primary issuer first**: the document's `authorization_servers` field 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
176176* **Serve authorization server metadata Claude can reach**: your authorization server must serve its own discovery metadata, either [RFC 8414](https://www.rfc-editor.org/rfc/rfc8414) authorization server metadata or [OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html), at its `/.well-known/` paths. That host must also be reachable from Anthropic's [published egress range](https://platform.claude.com/docs/en/api/ip-addresses). 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
177177
178The `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](/docs/connectors/building/lazy-authentication.md#answer-a-protected-call-with-401-before-the-mcp-sdk-runs):
178The `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](https://claude.com/docs/connectors/building/lazy-authentication.md#answer-a-protected-call-with-401-before-the-mcp-sdk-runs):
179179
180180```http theme={null}
181181HTTP/1.1 401 Unauthorized
from line 188
188188
189189> [!NOTE]
190190>
191> 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](https://learn.microsoft.com/en-us/entra/identity-platform/identifier-uri-restrictions), so an MCP server on a platform hostname such as `*.azurewebsites.net` needs a custom domain first. See [the troubleshooting entry](/docs/connectors/building/troubleshooting.md#microsoft-entra-id-rejects-the-resource-value) for the fix.
191> 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](https://learn.microsoft.com/en-us/entra/identity-platform/identifier-uri-restrictions), so an MCP server on a platform hostname such as `*.azurewebsites.net` needs a custom domain first. See [the troubleshooting entry](https://claude.com/docs/connectors/building/troubleshooting.md#microsoft-entra-id-rejects-the-resource-value) for the fix.
192192
193193If you control both hosts, an alternative is to serve the MCP endpoint and the authorization server behind a single custom domain that can route both `/.well-known/*` and your MCP path.
194194
195195> [!TIP]
196196>
197> A common symptom of a discovery failure is that your MCP server receives the initial request but your authorization server sees no traffic at all. That happens when neither path works: there's no `WWW-Authenticate: Bearer resource_metadata=…` header on your `401`, and the well-known paths on your MCP server's origin return `404`. With no metadata to read, Claude never learns where your authorization server is, and the connection fails with "Couldn't reach the MCP server." See [troubleshooting](/docs/connectors/building/troubleshooting.md) for the full diagnostic flow.
197> A common symptom of a discovery failure is that your MCP server receives the initial request but your authorization server sees no traffic at all. That happens when neither path works: there's no `WWW-Authenticate: Bearer resource_metadata=…` header on your `401`, and the well-known paths on your MCP server's origin return `404`. With no metadata to read, Claude never learns where your authorization server is, and the connection fails with "Couldn't reach the MCP server." See [troubleshooting](https://claude.com/docs/connectors/building/troubleshooting.md) for the full diagnostic flow.
198198
199199### Callback URLs
200200
from line 212
212212http://localhost:3118/callback
213213```
214214
215Claude Code declares `http://localhost/callback` and `http://127.0.0.1/callback` in its [Client ID Metadata Document](https://claude.ai/oauth/claude-code-client-metadata), so match both with the port component ignored. [RFC 8252 section 7.3](https://datatracker.ietf.org/doc/html/rfc8252#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](/docs/connectors/building/lazy-authentication.md#match-loopback-redirect-uris-without-the-port) for implementation details.
215Claude Code declares `http://localhost/callback` and `http://127.0.0.1/callback` in its [Client ID Metadata Document](https://claude.ai/oauth/claude-code-client-metadata), so match both with the port component ignored. [RFC 8252 section 7.3](https://datatracker.ietf.org/doc/html/rfc8252#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](https://claude.com/docs/connectors/building/lazy-authentication.md#match-loopback-redirect-uris-without-the-port) for implementation details.
216216
217217On your consent screen, display the redirect URI's hostname clearly. The [MCP authorization spec](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#localhost-redirect-uri-risks) 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.
218218
from line 243
243243
244244Unless 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:
245245
246* **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](/docs/connectors/building/enterprise-managed-auth.md) for what your authorization server needs to support
246* **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](https://claude.com/docs/connectors/building/enterprise-managed-auth.md) for what your authorization server needs to support
247247* **Customer-supplied OAuth client**: a listing that asks for [credentials entered at connection time](#credentials-entered-at-connection-time) has each customer supply its own OAuth client, and an administrator who adds your server as a [custom connector](#custom-connectors) can enter one too
248248
249249### Custom connectors
250250
251When 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](/docs/connectors/custom/add-unlisted.md#choose-authentication-settings) shows the dialog the customer sees. On your side:
251When 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](https://claude.com/docs/connectors/custom/add-unlisted.md#choose-authentication-settings) shows the dialog the customer sees. On your side:
252252
253253* **Support CIMD or DCR**: customers can then connect without registering a client with you first. See [DCR and CIMD details](#dcr-and-cimd-details) for what each needs from your authorization server
254254* **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
255* **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](#supported-authentication-types) and [Authenticate with request headers](/docs/connectors/custom/add-unlisted.md#authenticate-with-request-headers) for what Owners see
255* **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](#supported-authentication-types) and [Authenticate with request headers](https://claude.com/docs/connectors/custom/add-unlisted.md#authenticate-with-request-headers) for what Owners see
256256
257257## Network reference
258258
from line 260
260260
261261## Next steps
262262
263* [Lazy authentication](/docs/connectors/building/lazy-authentication.md): 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
264* [Enterprise Managed Auth](/docs/connectors/building/enterprise-managed-auth.md): accept identity assertions from enterprise SSO instead of an interactive consent step
265* [Test your connector](/docs/connectors/building/testing.md): add your server as a custom connector and exercise the auth flow
266* [Troubleshoot your connector](/docs/connectors/building/troubleshooting.md): diagnose "Couldn't reach the MCP server" and "Authorization with the MCP server failed"
263* [Lazy authentication](https://claude.com/docs/connectors/building/lazy-authentication.md): 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
264* [Enterprise Managed Auth](https://claude.com/docs/connectors/building/enterprise-managed-auth.md): accept identity assertions from enterprise SSO instead of an interactive consent step
265* [Test your connector](https://claude.com/docs/connectors/building/testing.md): add your server as a custom connector and exercise the auth flow
266* [Troubleshoot your connector](https://claude.com/docs/connectors/building/troubleshooting.md): diagnose "Couldn't reach the MCP server" and "Authorization with the MCP server failed"
267267
No line in this hunk matches that.