Short answer. MCP authentication for remote MCP servers uses OAuth 2.1. The MCP server acts as an OAuth resource server: it points the client to an authorization server, the user signs in there, and the client sends the resulting access token, issued for that one server, on every request. Local MCP servers that run over stdio skip OAuth and take their credentials from the environment.
MCP authentication for remote servers is OAuth 2.1
The MCP authorization specification defines how an MCP client gets access to a protected MCP server over HTTP. This article follows version 2026-07-28, the latest version on modelcontextprotocol.io when we read it on October 31, 2026. Authorization is optional in MCP, but a server that supports it over HTTP should follow the spec. It assigns three OAuth roles:
- MCP server: the resource server. It accepts access tokens and answers protected requests.
- MCP client: the OAuth client. Claude, Cursor or a custom agent makes requests on behalf of the user.
- Authorization server: the token issuer. It signs the user in and issues tokens. It can be part of the MCP server or a separate service, such as your identity provider.
The spec builds on existing standards rather than inventing new ones: the OAuth 2.1 draft, Protected Resource Metadata (RFC 9728), Authorization Server Metadata (RFC 8414), Resource Indicators (RFC 8707), Authorization Server Issuer Identification (RFC 9207), OAuth Client ID Metadata Documents and, for backwards compatibility, Dynamic Client Registration (RFC 7591).
The MCP OAuth flow, step by step
The flow starts with the server's challenge, so a client needs no prior setup to find out where to sign in:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
scope="files:read"- The server challenges. The client calls the MCP server without a token. The server answers
401 Unauthorizedwith aWWW-Authenticateheader that points to its Protected Resource Metadata. - The client finds the authorization server. The Protected Resource Metadata document (RFC 9728) lists the server's
authorization_servers. If the header has no metadata URL, the client tries the well-known URIs in order: first the one for the server's MCP path (forhttps://example.com/public/mcp, that'shttps://example.com/.well-known/oauth-protected-resource/public/mcp), then the roothttps://example.com/.well-known/oauth-protected-resource. - The client reads the authorization server's metadata. It fetches OAuth Authorization Server Metadata (RFC 8414) or OpenID Connect Discovery, checks that the
issuermatches, and confirms PKCE support. Ifcode_challenge_methods_supportedis missing, the client must stop. - The client gets a client ID. It uses a pre-registered client ID if it has one, then a Client ID Metadata Document (an HTTPS URL that serves as the client ID), then Dynamic Client Registration (RFC 7591), which the 2026-07-28 spec marks as deprecated.
- The user signs in. The client sends the user to the authorization server with a PKCE
S256code challenge and aresourceparameter (RFC 8707) naming the MCP server. The user signs in and approves, and the client exchanges the code for an access token. - Every request carries the token. The client sends
Authorization: Bearer <token>on every HTTP request, never in the query string. The server checks that the token was issued for it and rejects anything else. - More scope is requested only when needed. If a call needs more access, the server answers
403witherror="insufficient_scope"and the scopes it needs, and the client re-authorizes for the larger set.
Two more client checks matter. Before redirecting, the client records the authorization server's issuer and compares it with the iss value in the response (RFC 9207), which stops mix-up attacks between authorization servers. And all authorization server endpoints must use HTTPS, with redirect URIs on HTTPS or localhost. Details: authorization server discovery, client registration, security considerations.
Local stdio MCP servers take credentials from the environment
The spec says stdio implementations should not follow the OAuth flow and should instead retrieve credentials from the environment. A local server launched by the client usually reads an API key or token from an environment variable or a config file. The OAuth section doesn't apply, which also means the credential is often long-lived and shared by everything that runs on that machine.
MCP's security guidance treats local servers as code running with the user's privileges. Clients that offer one-click setup must show the exact command and get consent before running it, and servers meant to run locally should prefer stdio or restrict access if they listen over HTTP. Source: local MCP server compromise.
MCP authentication vs authorization
The MCP spec is called "authorization", but most of it is about getting the right token to the right server. Deciding whether a specific tool call should run is a separate step:
| Authentication | Authorization | |
|---|---|---|
| Question it answers | Who is calling, and for which user? | May this call run, with these arguments, right now? |
| When it happens | When the client gets a token, and again when the token is checked | On every tool call |
| What the MCP spec defines | OAuth 2.1 discovery, sign-in, token audience and scopes | Scopes and 403 step-up only; per-tool rules are left to the server |
| Typical failure | A token issued for another service is accepted | A valid user's agent calls a destructive tool it should never use |
Per-user tokens beat shared API keys. A token from the OAuth flow names the user who signed in, carries scopes and expires. A shared API key names only the key, so the server can't apply per-user rules, the logs can't show who asked, and revoking it stops everyone who uses it. For how agents prove who they are more generally, see how AI agent authentication works.
The confused deputy risk. An MCP server often calls other APIs for the user. If it simply forwards the token it received, those APIs may trust a token that was never meant for them, and the MCP server's own checks and logs are bypassed. That's why the spec requires servers to accept only tokens issued for themselves and to get separate tokens for anything upstream.
Common MCP authentication mistakes
Each of these comes from the MCP spec or its security best practices:
- Passing the client's token through to upstream APIs. The spec calls token passthrough an anti-pattern and forbids it: an MCP server that calls another API must get its own token for that API. MCP security best practices
- Skipping audience validation. A server that doesn't check that the token was issued for it can be handed a token meant for a different service. Authorization security considerations
- Leaving out the resource parameter. Clients must send
resourcein both the authorization and token requests, even if the authorization server ignores it, so tokens can be bound to one server. MCP authorization spec - Asking for every scope up front. Publishing all scopes in
scopes_supported, or using wildcard scopes such as*orfull-access, widens the damage if a token leaks. The spec suggests a small starting set and step-up for privileged tools. Scope minimization - Treating a scope as the whole authorization decision. The spec's own list of common mistakes includes trusting the scopes in a token without server-side authorization logic. A scope says what kind of access was granted, not whether this call is safe.
- Treating a state handle as a login. MCP has no protocol-level sessions. Servers must verify every request and must not treat possession of a cart or workflow ID as authentication. State handle hijacking
- Running an OAuth proxy without per-client consent. An MCP server that fronts a third-party API with one static client ID can be used as a confused deputy unless it asks each user to approve each MCP client before forwarding. Confused deputy problem
Enterprises can let their identity provider decide MCP access
In the core flow, each user approves each client for each server. The optional Enterprise-Managed Authorization extension puts the company's IdP in charge instead: the client exchanges the user's corporate sign-in for an Identity Assertion JWT Authorization Grant (ID-JAG), the IdP applies its access policy, and the MCP server's authorization server trades the ID-JAG for an access token. Support varies by client and IdP, so check before you plan around it.
For a deeper look at connecting MCP to an IdP, including OIDC, token exchange and service-to-service flows, read Wiring MCP to Your IdP.
Where an MCP gateway fits in MCP authentication
Implementing the spec on every MCP server means every server needs discovery, token validation and its own access rules. An MCP gateway moves that work to one place. Clients connect to a single URL, the gateway signs users in through your enterprise IdP, and it gets its own credentials for each upstream server instead of passing the client's token through.
{
"mcpServers": {
"company-gateway": { "url": "https://<your-gateway-url>/gateway/mcp" }
}
}Signing in at the gateway covers authentication. The bigger difference between gateways is whether they also authorize each tool call for the agent and the user it acts for. How to compare MCP gateways lists tests you can run during a trial.
SecureAuth MCP Authority is an MCP gateway that works downstream of the identity provider you already have. Agents connect to one gateway URL, and each agent run gets its own identity tied to the delegating user. Short-lived OAuth tokens replace API keys, and each tool call is checked against policy down to its arguments. A tool a user is denied is left out of that user's tool list, denied calls are recorded, and revoking an agent instance means its next token is rejected.
Explore MCP Authority by SecureAuthFrequently Asked Questions
How does MCP authentication work?
For remote MCP servers over HTTP, the MCP authorization spec uses OAuth 2.1. The client calls the server, gets a 401 response that points to the server's Protected Resource Metadata (RFC 9728), and reads which authorization server to use. It then signs the user in with the authorization code flow, PKCE and a resource parameter naming the MCP server, and sends the access token as a Bearer token on every request. The server checks that each token was issued for it.
Does MCP use OAuth?
Yes, for remote servers. The MCP authorization specification (version 2026-07-28) is based on the OAuth 2.1 draft along with RFC 9728, RFC 8414, RFC 8707 and RFC 9207. Authorization is optional in MCP, but HTTP-based servers that support it should follow the spec. Local servers that run over stdio don't use OAuth.
What is the difference between MCP authentication and authorization?
Authentication establishes who is calling: the OAuth flow signs the user in and gives the client a token for one MCP server. Authorization decides whether a specific tool call should run, for that user and agent, with those arguments. The MCP spec covers tokens, audience and scopes, and leaves per-tool rules to the server or a gateway in front of it.
Do stdio MCP servers need OAuth?
No. The MCP spec says implementations using the stdio transport should not follow the OAuth flow and should retrieve credentials from the environment instead, such as an API key in an environment variable. Those credentials are often long-lived, so treat local servers as code running with the user's privileges.
Should MCP servers accept API keys?
They can, since authorization is optional in MCP, but a shared API key identifies the key, not the person. The server can't apply per-user rules, logs can't show who asked, and revoking the key stops everyone using it. For remote servers, per-user OAuth tokens that are short-lived and issued for that server are the safer default.
How does an MCP gateway handle authentication?
Clients connect to the gateway's single URL and sign in through the company's identity provider. The gateway validates their tokens and gets its own credentials for each upstream MCP server, rather than passing the client's token through. Some gateways, such as SecureAuth MCP Authority, also check each tool call against policy for the agent and the user it acts for.