Last updated: October 15, 2026
What is MCP authentication? It is how an MCP client proves it may call an MCP server. For HTTP transports the current spec builds it on OAuth 2.1: the server acts as an OAuth resource server and a separate authorization server issues tokens. Local stdio servers skip OAuth and read credentials from the environment.
TL;DR: Key Takeaways
- The 2026-07-28 MCP spec requires protected servers to publish RFC 9728 metadata and clients to send the RFC 8707
resourceparameter in 2 requests: authorization and token (MCP specification). - Token passthrough is forbidden: the spec names 2 failure modes, audience validation failures and passthrough (MCP security best practices).
- A flaw in the MCP Python SDK OAuth client hit versions 1.9.1 through 2.1.1 and was fixed in 1.30.0 and 2.2.0, according to Cycode (2026).
- It is rated 7.5 (high) for the 2 machine-to-machine providers and 6.5 for the interactive one, per The Hacker News (2026).
MCP authentication at a glance
| Element | Standard | Spec requirement |
|---|---|---|
| Protected resource metadata | RFC 9728 | Servers MUST implement |
| Authorization server metadata | RFC 8414 or OpenID Connect Discovery | Authorization server MUST offer one |
| PKCE with S256 | OAuth 2.1 | Clients MUST implement |
| Resource indicators | RFC 8707 | Clients MUST send resource |
| Issuer check on the response | RFC 9207 | Clients MUST validate a present iss |
| Audience validation | RFC 8707 | Servers MUST validate |
How MCP authentication works
MCP authentication follows one pattern. The client calls the server without a token and gets a 401 challenge. It then discovers the authorization server, obtains a token through an authorization code flow with PKCE, and sends it on every request. According to the MCP specification (2026-07-28), the server is an OAuth 2.1 resource server. OAuth 2.1 is still an IETF draft.
| Step | What happens |
|---|---|
| 1 | Client sends a request without a token and gets 401 with a WWW-Authenticate header |
| 2 | Client fetches protected resource metadata and reads authorization_servers |
| 3 | Client discovers authorization server metadata and records the issuer |
| 4 | Client gets a client ID and opens the authorization URL with a PKCE challenge, resource and scopes |
| 5 | Client validates iss on the response, then exchanges the code with its verifier |
| 6 | Client sends Authorization: Bearer <token> on every request, never in the query string |
| 7 | Server validates the token and its audience, returning 401 if invalid or expired |
This guide covers authentication only. For wider threats read MCP Security 101, and for basics see What Is the Model Context Protocol.
How we built this guide
We read the 2026-07-28 MCP authorization pages, the security best practices, Cycode's write-up, The Hacker News report and the SDK release notes. We did not run the SDK, and we could not open the GitHub advisory page, so advisory details come from the two reports.
MCP authorization server discovery
A client finds the authorization server in two hops. The MCP server advertises it through protected resource metadata, then the client reads the authorization server's own metadata. Both are untrusted until validated.
Under the discovery rules, servers advertise resource metadata through a resource_metadata URL in the 401 WWW-Authenticate header, or at a well-known URI such as /.well-known/oauth-protected-resource. The document must list authorization_servers. Clients must support both routes.
For authorization server metadata, clients try the RFC 8414 URI first and then OpenID Connect Discovery endpoints. The issuer in the document must be identical to the issuer used to build the URL, or the client must not use it. The spec's own example is a document fetched from attacker.example that claims https://honest.example, which must be rejected.
Client registration, PKCE and resource indicators
The client registration rules prefer pre-registered credentials, then Client ID Metadata Documents, then Dynamic Client Registration. PKCE with S256 and the resource parameter are mandatory.
| Mechanism | Use when | Status |
|---|---|---|
| Pre-registration | Client and server already have a relationship | First choice if available |
| Client ID Metadata Documents | No prior relationship | Preferred |
| Dynamic Client Registration | Authorization server lacks metadata document support | Deprecated, kept for compatibility |
Clients must key stored credentials by the authorization server's issuer and not reuse them elsewhere. On PKCE, if code_challenge_methods_supported is absent from the metadata, the client must refuse to proceed. The resource value is the server's canonical URI, such as https://mcp.example.com/mcp.
PKCE alone does not stop a mix-up attack, the security best practices note, because the client sends the code_verifier to the attacker's token endpoint. Hence the exact-match issuer check on the authorization response.
Token audience binding, token passthrough and the confused deputy
An MCP server must accept only tokens issued for it and must never forward the token it received to an upstream API. If it calls a third-party service, it needs a separate token from that service's authorization server.
The best practices define token passthrough as accepting a client's token without checking it was issued to the server, then passing it downstream. They list control circumvention and audit gaps among the risks. Servers must reject tokens that do not list them in the audience claim, per the authorization security considerations.
The confused deputy problem
This applies to MCP proxy servers that front a third-party API with one static client ID. According to the best practices, it becomes possible when dynamic client registration, a consent cookie and missing per-client consent at the proxy combine. The mitigation is per-client consent.
Scopes, step-up authorization and 401 versus 403
Scopes decide what a valid token may do. Servers challenge with the scopes the current operation needs, clients start with the minimum, and a 403 with insufficient_scope triggers step-up authorization.
| Situation | Status | Header content |
|---|---|---|
| No token, or invalid or expired token | 401 | resource_metadata, optionally scope |
| Valid token, scope too narrow | 403 | error="insufficient_scope", required scope |
In step-up, the client requests the union of its earlier and newly challenged scopes. The best practices warn against publishing every scope in scopes_supported and against wildcard scopes such as * or full-access.
stdio servers: environment credentials instead of OAuth
The spec says implementations using the stdio transport should not follow the authorization specification and should instead retrieve credentials from the environment. There is no audience, discovery or consent screen, so the environment credential is exactly what the server can use. Give each local server its own narrowly scoped credential, not a personal admin key. The best practices warn that local servers run with the client's privileges, so sandbox the process.
The September 2026 MCP Python SDK OAuth flaw
In September 2026, the official MCP Python SDK's maintainers published advisory GHSA-qx49-fqc8-xw99 for a client-side OAuth flaw. According to Cycode (2026), a malicious MCP server could steer the SDK's OAuth flow so the app's client secret, authorization code and PKCE verifier reached the attacker.
What was affected
Cycode reports that SDK versions 1.9.1 through 2.1.1 were affected, in three providers. The Hacker News adds the deprecated 1.x RFC7523OAuthClientProvider. SDK-built servers, stdio clients and clients that attach their own tokens are not affected. No CVE ID had been assigned by September 29, according to The Hacker News (2026).
| Provider | Reported severity | Action |
|---|---|---|
OAuthClientProvider (interactive) | 6.5 | Upgrade, clear stored registrations |
ClientCredentialsOAuthProvider | 7.5 | Upgrade and pass issuer= |
PrivateKeyJWTOAuthProvider | 7.5 | Upgrade and pass issuer= |
RFC7523OAuthClientProvider (deprecated) | Not scored in our sources | Switch provider, no issuer= option |
How the attack worked
Cycode describes this chain. The malicious server answers the modern discovery request with HTTP 404, sending the SDK down a fallback path where the issuer check did not run. The metadata then pointed the login page at the real provider and the token endpoint at the attacker. The user saw a genuine login, and the SDK sent the code, client secret and verifier to the attacker.
Cycode calls this full account takeover and argues the 6.5 score understates the interactive provider's risk. Those are the researcher's views. According to The Hacker News, neither the advisory nor Cycode reports attacks in the wild.
The fix and what to do
The fixed versions are 1.30.0 and 2.2.0. The release notes state that "Authorization server metadata whose issuer doesn't match the server it was fetched for is now rejected." They add that client registrations are now remembered per issuer (SDK release notes). The Hacker News reports these shipped on September 7 as behavior changes, and the advisory followed on September 28. Reported remediation:
- Upgrade to 1.30.0 or 2.2.0.
- Pass
issuer=for the 2 machine-to-machine providers, because upgrading alone changes nothing for them. - Clear stored client registrations once so they are recreated with an issuer binding.
- If a client may have contacted an untrusted server, rotate its secret and revoke its tokens.
What it implies
This is a client-side validation gap that the current spec forbids: the 2026-07-28 text tells clients to reject metadata with a mismatched issuer. A spec rule only helps when your library enforces it. Treat discovery URLs as untrusted, connect OAuth workflows only to vetted servers, and inventory the apps that embed the SDK.
Common MCP authentication mistakes
The table lists mistakes the spec itself warns against.
| Mistake | Why it hurts | Fix |
|---|---|---|
| Accepting any valid token without an audience check | Tokens meant for other services work on your server | Require your canonical URI in the audience |
| Forwarding the inbound token upstream | Confused deputy, broken audit trail | Obtain a separate upstream token |
| Trusting server-supplied metadata | Credentials can reach the wrong token endpoint | Validate issuer, pass issuer= |
Production checklist: secure an MCP server with OAuth in 7 steps
This procedure suits a remote server over Streamable HTTP and follows the 2026-07-28 spec.
How to secure an MCP server with OAuth
- Choose the transport. Use OAuth for HTTP. For local stdio servers, use narrowly scoped environment credentials.
- Select a compliant authorization server. It should publish RFC 8414 or OpenID Connect metadata with
code_challenge_methods_supported. - Publish protected resource metadata. Serve an RFC 9728 document with
authorization_servers, and return 401 withresource_metadatainWWW-Authenticate. - Validate every token. Check signature, expiry and that your canonical URI is in the audience.
- Define minimal scopes. Start with read scopes, and return 403 with
insufficient_scopewhen a tool needs more. - Never pass tokens through. Use a separate credential for upstream APIs.
- Monitor, rotate and test. Issue short-lived tokens, log scope elevation with correlation IDs, and test clients against mismatched issuer metadata.
Security and governance: what OAuth does not cover
OAuth answers who is calling and which scopes the token holds, not whether an agent should make a particular call. Four risks surround a correct setup: token theft, over-broad scopes, prompt injection and shadow servers, all named in the OWASP MCP Top 10 (beta) as MCP01, MCP02, MCP06 and MCP09.
Token theft
According to the authorization security considerations, attackers who obtain tokens stored by the client, or logged on the server, can make requests that look legitimate. The spec says authorization servers should issue short-lived tokens.
Over-broad scopes
A token issued with files:* or admin:* lets anyone holding it chain tools, and the best practices cite a wider blast radius. Our guide to excessive agency explains why least privilege must cover tools as well as tokens.
Prompt injection driving authenticated tool calls
A valid token authorizes whatever the agent decides to do, so injected text can steer a call that arrives with correct credentials. OWASP describes MCP06 as classic injection where "the 'interpreter' is the model and the 'payload' is text." Our guide to MCP prompt injection covers patterns and defenses.
Shadow MCP servers
OWASP describes shadow servers as unapproved deployments outside formal governance. You cannot apply OAuth rules to a server you do not know exists.
How NeuralTrust addresses these risks
These controls sit alongside your OAuth setup. Agent Gateway (TrustGate) sits between agents, workflows, models and MCP tools and enforces per-agent permissions and limits, so a valid token does not mean unlimited tool use. It offers 200+ pre-built MCP servers. Agent Runtime Security (TrustGuard) detects prompt injection and data leakage at runtime. Agent Posture Management (TrustLens) inventories agents and their connections, a baseline for spotting unapproved servers. AI Red Teaming (TrustTest) tests agents before launch. Together they form the Runtime Security Mesh.
Which MCP authentication approach should you choose?
Match the approach to who calls the server. Local single-user tools can use environment credentials, while remote and multi-user servers need OAuth with audience validation and narrow scopes.
| Your situation | Use | Why |
|---|---|---|
| Local tool for one user | stdio with narrow environment credentials | The spec says not to use OAuth here |
| Remote server for many users | Streamable HTTP with OAuth 2.1 and an external authorization server | Standard discovery and audience binding |
| Unattended agent with no user | Client credentials with a pinned issuer= | The SDK fix changes nothing until issuer= is set |
Conclusion
MCP authentication comes down to following the spec exactly: publish protected resource metadata, bind tokens to one audience, send the resource parameter, require PKCE and never pass a token through. The September SDK flaw shows clients must enforce issuer checks too. Keep scopes minimal, rotate secrets, and control what an authenticated agent may do, because a valid token says who is calling, not whether the call is wise.
Secure MCP Servers in Production with NeuralTrust
Apply per-agent permissions, runtime detection and an inventory of connections across every MCP server your teams run.
Related Comparisons
FAQs about MCP Authentication
1. What is MCP authentication?
MCP authentication is how an MCP client proves it may access an MCP server. For HTTP transports it builds on OAuth 2.1: the server is a resource server, an authorization server issues tokens, and the client sends the token on every request. Stdio servers use environment credentials.
2. Does MCP use OAuth 2.1?
Yes, for HTTP transports. The 2026-07-28 spec builds on the OAuth 2.1 IETF draft plus RFC 9728, RFC 8414, RFC 8707 and RFC 9207. Authorization is optional overall, but HTTP implementations should conform.
3. Do stdio MCP servers use OAuth?
No. The spec says stdio implementations should not follow the authorization specification and should retrieve credentials from the environment. Give each server a narrowly scoped credential.
4. What is token passthrough and why is it forbidden?
Token passthrough means an MCP server accepts a client's token without checking it was issued to that server, then forwards it downstream. The spec forbids it because it bypasses controls and muddies audit trails.
5. Do I still need Dynamic Client Registration?
Not for new work. The 2026-07-28 spec deprecates it and keeps it only for authorization servers without Client ID Metadata Document support.
6. Was the MCP Python SDK vulnerable in September 2026?
Its OAuth client was. Cycode reports that versions 1.9.1 through 2.1.1 could send a client secret, authorization code and PKCE verifier to an attacker-chosen token endpoint. The fixes are 1.30.0 and 2.2.0. The Hacker News reports no attacks.
About the Author
Roger Howroyd is Head of Global SEO and AI at NeuralTrust, where he leads the company's search strategy across SEO, AEO, GEO, and LLM optimization. He specializes in AI-powered search, content strategy, and SEM. Connect on LinkedIn.
NeuralTrust is the leading platform for securing and scaling AI agents. Named a Pioneer in the Gartner Emerging Market Quadrant for AI Application Security 2026, recognized across four Gartner Hype Cycle reports in 2026, and featured in the Gartner Market Guide for Guardian Agents 2026, the Gartner Market Guide for AI Gateways 2025 and the KuppingerCole Leadership Compass for Generative AI Defense 2025. Headquartered in Barcelona with offices in London and New York. ISO 27001 certified.
Sources
- Model Context Protocol, "Authorization," revision 2026-07-28: https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization
- Model Context Protocol, "Authorization Server Discovery," revision 2026-07-28: https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization/authorization-server-discovery
- Model Context Protocol, "Client Registration," revision 2026-07-28: https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization/client-registration
- Model Context Protocol, "Authorization Security Considerations," revision 2026-07-28: https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization/security-considerations
- Model Context Protocol, "Security Best Practices": https://modelcontextprotocol.io/specification/latest/basic/security_best_practices
- Cycode, "Cycode Uncovers Account Takeover in Anthropic's MCP Python SDK," Sep 28, 2026 (updated Sep 29): https://cycode.com/blog/mcp-python-sdk-oauth-account-takeover/
- The Hacker News, report on the MCP Python SDK OAuth flaw (GHSA-qx49-fqc8-xw99), Sep 29, 2026: https://thehackernews.com/2026/09/official-mcp-python-sdk-flaw-can-let.html
- MCP Python SDK v1.30.0 release notes, mirrored by newreleases.io: https://newreleases.io/project/github/modelcontextprotocol/python-sdk/release/v1.30.0
- OWASP, "MCP Top 10" (beta): https://owasp.org/www-project-mcp-top-10/
)
)
)
)
)
)
)