API Key Authentication for MCP Servers
A static key in a request header is the most common way to authenticate service-to-service calls to a remote MCP server.
- Method
- API key
- Platform
- Any platform
- MCP Specification
- 2026-07-28
How it works
The agent sends Authorization: Bearer <key> on every request to the MCP server. The server checks the key and resolves it to a caller before running a tool. Agent SDKs take the header when the client is constructed, so the first request on the wire is an authenticated initialize — there is no unauthenticated probe, no 401, no .well-known lookup and no browser step.
- Best for
- Service-to-service calls where you control both the agent and the MCP server
- MCP spec
- Outside the spec's OAuth flow, which the spec makes optional
- Works with
- Supported by every agent SDK; hosted connectors are more limited
- Effort
- An afternoon
The exchange
Each step in the exchange, in order.
- Your agent Cloud Run, Lambda, CI
- MCP server validates the key
-
The key is configured when the client is constructed, so the first message on the wire is already authenticated: no 401, no .well-known lookup, no browser step.
Your agent to MCP server
POST /mcp Authorization: Bearer sk_live_… -
Inside MCP server
Look the key up and resolve it to a caller -
MCP server to Your agent
200 OK initialize result — tools listed -
There is no session credential to establish. Every subsequent request carries the same static key.
Your agent to MCP server
POST /mcp tools/call, same Authorization header -
MCP server to Your agent
200 OK tool result
Connect your agent
Pick your language and SDK.
When to use something else
Use this when
- Both ends belong to you: an agent calling your own MCP server, a scheduled job, a CI step.
- One credential can represent the whole integration, because no end user's identity needs to reach the API behind the server.
- You need something that works across every agent SDK without a browser step.
Use something else when
- The agent and the MCP server run in the same cloud, where workload identity removes the secret entirely.
- The server will be listed in the ChatGPT or Claude connector directories, both of which require the spec OAuth flow.
- Calls are made on behalf of a named person, or the audit trail has to identify a user rather than a caller.
The specification makes authorization OPTIONAL and says HTTP transports SHOULD, rather than MUST, conform to its OAuth flow. A static key therefore sits outside the spec rather than in conflict with it. The spec provides no way to advertise that a server expects a key, which is why each caller has to be configured directly.
What lands on you next
A static key answers exactly one question: is this caller allowed in. Every question asked of you after it ships is a different question.
-
Which tools can this key call?
-
mcp-capability-filter-inboundAn exact allow-list of tools, prompts and resources per route. A call to a hidden tool is refused with
MethodNotFoundbefore it reaches your server. -
Who ran
refund_orderat 3am? -
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.
-
That key is in five agents' env vars. How do we rotate it?
-
set-upstream-api-key-inboundAgents authenticate to the gateway, which strips that credential and injects the upstream key — so the secret your agents hold and the one your server accepts stop being the same secret.
-
Sales wants this in Claude with our Okta login. Do we rewrite the server?
-
mcp-okta-oauth-inboundNo — the inbound method is a policy, and there is a first-class one for eleven named identity providers plus any OIDC provider. Exactly one per project, and the provider's token never reaches the MCP client.
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
Does MCP require OAuth, or can I use an API key?
An API key is permitted. The specification makes authorization optional and says HTTP transports SHOULD, rather than MUST, conform to its OAuth flow. The real limits are hosted-connector support and directory listing, not spec compliance.
Do agent SDKs run the OAuth discovery flow automatically?
Not when a header is configured. Supplying headers means no auth provider is wired up, so the credential goes out on the first request and no 401 is ever exchanged. Discovery applies to clients that connect without a credential.
Why do so many MCP servers accept a fixed token instead of implementing OAuth?
The server usually sits in front of an API that already authenticates with a token. Running an authorization server to reach the same result adds work without adding security when both ends belong to the same team.
Can one endpoint accept both static keys and OAuth?
Yes, and it has to if both audiences matter. Validate the static credential first and dispatch when it succeeds; fall through to a 401 with WWW-Authenticate only when nothing usable was presented. Reversing that order pushes callers holding a valid key into a discovery flow.
Why would a client ignore the header it was given and attempt OAuth?
Some clients read /.well-known/oauth-protected-resource on connect and treat its presence as proof that OAuth is required. A server that accepts static keys should either omit that document or ensure a valid key dispatches before any 401 is written.
Is a header name other than Authorization acceptable?
In your own agents, yes: every SDK shown here sets arbitrary headers. The Anthropic Messages API connector exposes only authorization_token, so a server that insists on X-API-Key cannot be reached through it. Authorization: Bearer is the portable choice.
Should an API key be used when the agent and MCP server share a cloud?
Usually not. On Cloud Run, Lambda or a shared Kubernetes cluster the platform can issue a short-lived identity token instead, which removes the stored secret and makes the caller's identity verifiable rather than looked up.
How does a server move from API keys to OAuth?
Accept both during the transition by validating the bearer token as either a key or a JWT, then withdraw key acceptance one caller at a time. Handling this at a gateway makes it a single change rather than one per server.
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.