01Role model: the MCP server as resource server
Since revision 2025-06-18, a protected MCP server acts as an OAuth 2.1 resource server: it accepts and validates access tokens but does not issue them itself; the MCP client acts as an OAuth client on the user's behalf. The authorization server is a separate role – it may be hosted alongside the resource server, but its implementation is out of scope for the specification. It was not always this way: revision 2025-03-26 effectively treated the MCP server as authorization server and resource server in one, with default endpoints /authorize, /token and /register directly on the MCP server. The formal separation relieves server operators and allows established identity providers instead of home-built token issuance.
02Discovery chain: RFC 9728 and RFC 8414
The client locates the responsible authorization server at runtime instead of through configuration: to a request without a valid token, the MCP server responds with 401 Unauthorized and points via the WWW-Authenticate header to its Protected Resource Metadata (RFC 9728) – a mandatory document whose authorization_servers field names at least one authorization server. From there, the client fetches the Authorization Server Metadata per RFC 8414 (/.well-known/oauth-authorization-server) with authorize, token and registration endpoints; only then does the actual OAuth 2.1 flow begin. This runtime discovery replaces hard-coded configuration – crucial for agents that are assigned tools only at runtime. Revision 2025-11-25 adds OpenID Connect Discovery and a .well-known fallback without the header; revision 2026-07-28 adds issuer validation per RFC 9207 against mix-up attacks.
03Client registration: RFC 7591 and CIMD
Because arbitrary MCP clients encounter arbitrary servers, manual client registration does not scale. Revision 2025-06-18 therefore recommends (SHOULD) Dynamic Client Registration per RFC 7591: the client registers itself at the registration endpoint and receives its own client_id – in practice usually as a public client without a client secret; alternatives are a pre-provisioned client ID or manual entry. Revision 2026-07-28, however, declares DCR deprecated and relies on the Client ID Metadata Documents (CIMD) introduced with revision 2025-11-25: URL-based client identities. At the same time, it clarifies that stored client credentials are bound to the issuing authorization server and must not be reused across server boundaries. DCR continues to work transitionally for compatibility reasons – new implementations should know both paths.
04OAuth 2.1 ground rules: PKCE, headers, short lifetimes
OAuth 2.1 clears out insecure legacy features of OAuth 2.0: the implicit grant and password grant are removed, redirect URIs are matched only exactly, and PKCE is mandatory – MCP clients MUST implement PKCE, in practice with the S256 challenge method instead of “plain”. Access tokens belong in the Authorization header of every single request as bearer tokens and must never appear in the URI query string; all authorization server endpoints run over HTTPS, and redirect URIs are restricted to localhost or HTTPS. Refresh tokens for public clients must, under OAuth 2.1, be sender-constrained or one-time tokens with rotation. Common practical recommendations add short-lived access tokens of a few minutes plus reuse detection that revokes the entire token family when an old refresh token is reused.
05Audience binding (RFC 8707) and the token passthrough ban
A token must be issued for exactly one MCP server: clients MUST send the resource parameter per RFC 8707 in the authorization and token request, specifying the canonical URI of the target server; the server MUST verify that it is the intended audience and reject foreign or expired tokens with 401. The passthrough ban is equally strict: an MCP server MUST NOT pass the token received from the client on to downstream APIs, but acts there as its own OAuth client with its own token. Otherwise the confused deputy problem looms – the server acts as a confused deputy with someone else's privileges, and the downstream API's rate limiting, monitoring and audit trail come to nothing. Proxy servers with a static client ID MUST additionally obtain separate user consent for every dynamically registered client, because reused consent cookies otherwise route authorization codes to attackers.
06MCP07 in practice: findings and controls
The OWASP MCP Top 10 (version v0.1, beta – not a finalized standard) list this area as MCP07 “Insufficient Authentication & Authorization”. The real-world findings are sobering: Trend Micro found a total of 492 MCP servers exposed on the internet in 2025 without authentication or transport encryption, the Astrix audit counted 53 percent static API keys against only 8.5 percent OAuth, and CVE-2025-6514 in the npm package mcp-remote (CVSS 9.6) showed that manipulated OAuth discovery fields alone can trigger code execution. Effective controls start from the specification: OAuth 2.1 with PKCE and a separate authorization server, short-lived, audience-bound tokens instead of passthrough – with token exchange per RFC 8693 for upstream calls –, per-client consent in proxies and the MCP server as its own non-human identity in IAM. Two audit questions for internal audit and the board: is there a token passthrough anywhere in the chain – and how long does an agent token live?