How an Anthropic-managed agent authenticates to your MCP server
Four Anthropic surfaces can call your MCP server, and each one presents its credential through a different field with different limits.
- Method
- Anthropic-hosted agents
- Platform
- Claude Managed Agents
- MCP Specification
- 2026-07-28
How it works
Each surface takes the credential in a different field. A Managed Agent declares the server URL at agent creation and receives its credential at session creation from a vault — mcp_oauth or static_bearer, matched on the normalised mcp_server_url. The Messages API connector exposes only authorization_token. Neither has a header field. claude.ai custom connectors add static_headers, in beta, entered by an administrator and restricted to a reviewed allowlist that does include x-api-key. Claude Code runs on the user's own machine and takes any headers you like, or a headersHelper command. Anthropic's hosted traffic reaches your server from 160.79.104.0/21.
- Best for
- Reaching your MCP server from an agent that runs on Anthropic's infrastructure
- MCP spec
- Mixed — claude.ai and Claude Code run the spec's OAuth flow; a vault token or a static header sits outside it, not against it
- Works with
- Four surfaces, four credential fields; only Claude Code, which runs locally, sends a header name of your choosing
- Effort
- An afternoon per surface
The exchange
Each step in the exchange, in order.
- Your backend Anthropic API client
- Managed agent Anthropic control plane
- Your MCP server validates the token
-
Three calls, on purpose. The agent definition holds the URL, the vault holds the secret, and the session joins them — so one agent definition is reusable and carries no credential.
Your backend to Managed agent
POST /v1/agents mcp_servers[].url — no token here -
Your backend to Managed agent
POST /v1/vaults/{id}/credentials static_bearer, mcp_server_url, token -
Your backend to Managed agent
POST /v1/sessions vault_ids: [vlt_01ABC…] -
The match is on the normalised mcp_server_url: scheme and host are lowercased and default ports and trailing slashes stripped, but a different path, subdomain or non-default port does not match. When nothing matches, the connection is attempted unauthenticated.
Inside Managed agent
Normalise both URLs and match the credential -
Managed agent to Your MCP server
POST /mcp token from the matched credential -
Your MCP server to Managed agent
200 OK initialize result — tools listed
Connect your agent
Pick your language and SDK.
When to use something else
Use this when
- The agent runs on Anthropic's infrastructure and your MCP server is reachable from
160.79.104.0/21— the only outbound range Anthropic publishes, and it is IPv4. - Each end user gets their own credential: a vault is the credential collection for one user, and the session that references it is where the credential is chosen.
- Your server accepts a bearer token — the two MCP vault credential types are
mcp_oauthandstatic_bearer, and there is no third.
Use something else when
- Your server needs a header you name. A Managed Agents or Messages API
mcp_serversentry has no header field at all, and claude.ai's names come from a reviewed allowlist, four at most. - You run on Amazon Bedrock or Google Cloud, where Anthropic states the MCP connector "is not currently available".
- You need Zero Data Retention or HIPAA BAA coverage: Managed Agents is stateful by design, and Anthropic states it is not currently eligible for either.
Authorization is OPTIONAL in the specification, and HTTP transports SHOULD rather than MUST conform to its OAuth flow — so a vault credential or a static header sits outside the spec rather than in conflict with it. Only the interactive surfaces run the flow itself: claude.ai reads RFC 9728 protected resource metadata from a 401 and always sends PKCE S256, and Claude Code does the same discovery locally. Managed Agents and the Messages API never run it — you obtain the token and hand it over.
What lands on you next
Anthropic's half of this connection is now settled and will not change per user. Everything asked of you next is about your half.
-
It ran unattended overnight and hit us 4,000 times. Can we cap it?
-
rate-limit-inboundWith
rateLimitBy: "user"every call is counted against the authenticated identity rather than a shared egress IP — which matters here, because every Anthropic-hosted surface arrives from one CIDR. -
Which of our tools can that vault token actually call?
-
mcp-capability-filter-inboundTool gating in
mcp_toolsetlives in the agent definition. This is an allow-list on the route: a hidden tool is refused withMethodNotFoundbefore your server sees it. Static per route, with no per-user axis. -
Who ran
refund_orderat 3am — the agent, or a person? -
capability_invocationEvery tool call emits an event carrying the caller, the capability, the upstream, the outcome and the latency. Tokens and request bodies are never logged.
-
The vault holds the same key our own backend uses. Can we split them?
-
set-upstream-api-key-inboundThe gateway strips the inbound credential and injects the upstream key, so the token in the vault and the token your server accepts stop being the same secret. It is also how you obey the spec's MUST NOT on token passthrough.
All of these attach to one MCP route's policies.inbound — the same policy engine on the way in and on the way out.
Common questions
Can a Managed Agent send a custom header like X-API-Key to my MCP server?
No. A Managed Agents mcp_servers entry takes type, name and url and nothing else, and the two MCP vault credential types are mcp_oauth and static_bearer — both bearer tokens. Make the key work as a bearer token, or terminate the credential at a gateway that injects your own header upstream. claude.ai custom connectors are the one hosted exception: x-api-key is on the allowlist there.
Why is my Managed Agent connecting to the MCP server unauthenticated?
Credentials are matched by URL. Both URLs are normalized first — scheme and host lowercased, default ports and trailing slashes stripped — but a different path, subdomain or non-default port does not match, and Anthropic states that if none matches "the connection is attempted unauthenticated." Session creation does not validate this, so the failure arrives later as a session.error carrying mcp_authentication_failed_error.
Which IP addresses does Anthropic call my MCP server from?
Outbound requests, including MCP tool calls, originate from 160.79.104.0/21 over IPv4; inbound is 160.79.104.0/23 and 2607:6bc0::/48. Five older addresses in 34.162.0.0/16 are documented as no longer in use and should be removed from firewall rules. On Claude Platform on AWS, outbound tool calls come from the same Anthropic ranges.
Is the Messages API MCP connector available on Bedrock or Google Cloud?
No. Anthropic states it is available on the Claude API, Claude Platform on AWS, and Microsoft Foundry — on Foundry only with a Hosted on Anthropic deployment — and that "it is not currently available on Amazon Bedrock or Google Cloud."
How does an Anthropic agent reach an MCP server on a private network?
Through an MCP tunnel or a self-hosted sandbox. The tunnel is a research preview with no uptime commitment; per Anthropic you run cloudflared and an Anthropic proxy inside your network, and cloudflared reaches the tunnel edge outbound-only on 7844 TCP and UDP. Anthropic is explicit that "the tunnel carries encrypted traffic to your MCP server but does not authenticate to it" — you still layer your own OAuth or bearer token. Tunneled servers are reachable from Managed Agents and the Messages API; tunnels created through the Console are not available as connectors in claude.ai. A self-hosted sandbox is the other route: tool execution moves to your infrastructure, so network reach becomes your network policy.
Can a claude.ai custom connector use an API key instead of OAuth?
Yes, through static_headers, which is in beta and being rolled out slowly. An organization administrator enters the value once, Claude never shows it again, and the credential is shared across the organization rather than per user. Header names come from a reviewed allowlist such as authorization, x-api-key and x-auth-token, you may add up to four, and no scheme is added for you. Headers can ride alongside OAuth, with one exception: OAuth owns Authorization, so it cannot be configured as a request header on an OAuth connection.
Does Claude Code fall back to OAuth if my configured header is rejected?
No. Anthropic's wording is that if you configured headers.Authorization and the server rejects that header, "Claude Code reports the connection as failed instead of falling back to OAuth." Remove the header to use the OAuth flow. For a rotating credential use headersHelper, a command that writes a JSON object of string key-value pairs to stdout and runs in a shell with a 10-second timeout.
What changes for this page in the 2026-07-28 MCP spec revision?
Nothing about Anthropic's credential fields, which are product surfaces rather than spec surfaces. The revision keeps authorization OPTIONAL and keeps the MUST NOT on a server accepting or transiting tokens issued for anything else. What does move is registration, which matters only on the OAuth surfaces: clients MUST now obtain a client ID through one of three mechanisms, and Dynamic Client Registration is deprecated and retained for backwards compatibility. Beta identifiers move far more often than the spec does: mcp-client-2025-11-20 already replaced a deprecated predecessor.
One policy engine for APIs, AI, and MCP
Put your MCP servers behind a gateway that speaks every identity provider, filters tools per role, and logs every call.