Flows / Human present

MCP authorization

How an MCP client that has never seen a server before discovers where to sign in, identifies itself, and gets a token good for that server alone.

Based onMCP specification 2026-07-28Final specGuide reviewedNovember 2026

Sources and review details
This page
Implementation guideAn explanation, not a specification
Primary specification
MCP AuthorizationFinal spec · Current revision 2026‑07‑28
10 required references
8 published, 2 drafts1 more listed as optional or background
Human involvement
Human present
Review
Checked against sources in November 2026How it was checked

The Model Context Protocol has a problem classic OAuth never had to solve: any client may meet any server, with no prior arrangement. A user pastes in a server URL, and the client has to work out which authorization server protects it, introduce itself to that server, and obtain a token, all at runtime.

MCP answers this with a profile of OAuth 2.1 plus three discovery steps. The MCP server is an OAuth resource server. It points to its authorization server through protected resource metadata. The client identifies itself with a URL that the authorization server can fetch, called a Client ID Metadata Document, instead of registering in advance. Every token is bound to one MCP server through the resource parameter.

This page describes the 2026-07-28 revision of the specification. Authorization is optional in MCP and applies to HTTP transports; a server launched over stdio takes its credentials from its environment.

Step by step

14 steps between 4 parties. Each step shows the message and who holds which credential afterward. Use ←→ or select any arrow.

Sequence diagram4 participants, 14 steps
  • Direct call
  • Via the user’s browser or device
  • Response
  • Local action

Drag to see every party and step. Tap a step to jump to its explanation.

1MCP request, no token2401 + resource_metadata3Get resource metadata4Get server metadata5Choose client ID; PKCE; note issuer6Authorizationrequest + resource7Fetch and check client metadata8Sign in and approve9Redirect:code + iss10Check iss and state11Token request+ verifier12Access tokenfor this server13MCP request + Bearer token14Validate audience; result

  1. 1MCP client to MCP serverDirect call

    The client calls a server it knows nothing about

    The user has added a server URL. The client simply tries a request.

  2. 2MCP server to MCP clientResponse

    The server says where to look

    The WWW-Authenticate header can carry the URL of the server’s protected resource metadata and the scopes needed for this request. The header is optional. If it is missing, the client constructs the well-known URL itself, trying the path-specific form before the root.

    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: Bearer
      resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource/mcp",
      scope="files:read"
  3. 3MCP client to MCP serverDirect call

    The client reads the protected resource metadata

    This document (RFC 9728) is the bridge between a resource and its authorization server. It must list at least one entry in authorization_servers. scopes_supported is meant to be the minimal set for basic use, not everything the server could ever ask for.

    {
      "resource": "https://mcp.example.com/mcp",
      "authorization_servers": ["https://auth.example.com"],
      "scopes_supported": ["files:read"],
      "bearer_methods_supported": ["header"]
    }
  4. 4MCP client to Authorization serverDirect call

    The client discovers the authorization server

    This exchange shows OAuth authorization server metadata (RFC 8414). An MCP authorization server must publish that or OpenID Connect Discovery metadata, and a conforming client must support both: it tries the RFC 8414 location first, then the OpenID one. Three checks happen here. The issuer in the document must be identical to the one used to build the URL. code_challenge_methods_supported must be present, or the client must refuse to continue. And the client looks for client_id_metadata_document_supported to decide how to identify itself.

    {
      "issuer": "https://auth.example.com",
      "authorization_endpoint": "https://auth.example.com/authorize",
      "token_endpoint": "https://auth.example.com/token",
      "code_challenge_methods_supported": ["S256"],
      "client_id_metadata_document_supported": true,
      "authorization_response_iss_parameter_supported": true
    }
  5. 5MCP clientLocal action

    The client decides who it will say it is

    Preference order: credentials pre-registered for this server; otherwise a Client ID Metadata Document if the server supports them; otherwise Dynamic Client Registration (deprecated); otherwise ask the user. With a metadata document the client_id is an HTTPS URL the client’s publisher controls.

    The client also creates a PKCE verifier and records the validated issuer alongside it, to check the response against later.

    // served at https://app.example.com/oauth/client.json
    {
      "client_id": "https://app.example.com/oauth/client.json",
      "client_name": "Example Agent",
      "redirect_uris": ["http://127.0.0.1:3000/callback"],
      "grant_types": ["authorization_code", "refresh_token"],
      "token_endpoint_auth_method": "none"
    }

    Who holds what after this step

    MCP client
    newcode_verifier

    Parties not listed hold none of this flow’s credentials at this point.

  6. 6MCP client to Authorization serverVia the user’s browser or device

    The authorization request names the MCP server

    Authorization code with PKCE, plus the resource parameter set to the canonical URI of the MCP server. Clients must send resource on both the authorization request and the token request, whether or not the authorization server is known to support it.

    GET /authorize?response_type=code
      &client_id=https://app.example.com/oauth/client.json
      &redirect_uri=http://127.0.0.1:3000/callback
      &scope=files:read
      &resource=https://mcp.example.com/mcp
      &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
      &code_challenge_method=S256
      &state=xyzABC123 HTTP/1.1
    Host: auth.example.com

    Who holds what after this step

    MCP client
    code_verifier

    Parties not listed hold none of this flow’s credentials at this point.

  7. 7Authorization serverLocal action

    The authorization server looks the client up

    Seeing a URL as client_id, the server fetches it. The client_id inside the document must match the URL exactly, and the redirect URI in the request must be listed in it. Because this is a server fetching a URL chosen by a stranger, it needs the usual protections against server-side request forgery, and may apply its own policy about which client domains it trusts.

    Who holds what after this step

    MCP client
    code_verifier

    Parties not listed hold none of this flow’s credentials at this point.

  8. 8User to Authorization serverVia the user’s browser or device

    The user signs in and consents

    The server shows the client’s name from the metadata document and must clearly display the redirect URI’s hostname. A client that redirects only to localhost deserves a warning, since anything on the machine can claim that address.

    Who holds what after this step

    MCP client
    code_verifier

    Parties not listed hold none of this flow’s credentials at this point.

  9. 9Authorization server to MCP clientVia the user’s browser or device

    The code comes back with the issuer

    Authorization servers should include the iss parameter (RFC 9207), and the specification signals that this will become mandatory.

    GET /callback?code=SplxlOBeZQQYbYS6WxSbIA
      &state=xyzABC123
      &iss=https://auth.example.com HTTP/1.1
    Host: 127.0.0.1:3000

    Who holds what after this step

    MCP client
    code_verifiernewauthorization code

    Parties not listed hold none of this flow’s credentials at this point.

  10. 10MCP clientLocal action

    The client verifies who answered

    Before sending the code anywhere, the client compares iss with the issuer it recorded, as a plain string comparison. If the server advertised that it sends iss and none arrived, the client rejects the response. An MCP client deals with many authorization servers, some of them hostile; this check stops one from harvesting codes meant for another.

    Who holds what after this step

    MCP client
    code_verifierauthorization code

    Parties not listed hold none of this flow’s credentials at this point.

  11. 11MCP client to Authorization serverDirect call

    The client redeems the code

    With the PKCE verifier and, again, the resource parameter. There is no redirect_uri here: MCP builds on OAuth 2.1, which removed it from the token request.

    POST /token HTTP/1.1
    Host: auth.example.com
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=authorization_code
    &code=SplxlOBeZQQYbYS6WxSbIA
    &client_id=https://app.example.com/oauth/client.json
    &code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
    &resource=https://mcp.example.com/mcp

    Who holds what after this step

    MCP client
    used upauthorization codeused upcode_verifier

    Parties not listed hold none of this flow’s credentials at this point.

  12. 12Authorization server to MCP clientResponse

    A token for one MCP server

    The client stores it against this issuer and this server. A refresh token may or may not be issued; clients must not assume one.

    Who holds what after this step

    MCP client
    newaccess token (aud: MCP server)

    Parties not listed hold none of this flow’s credentials at this point.

  13. 13MCP client to MCP serverDirect call

    The client retries with the token

    The token goes in the Authorization header on every request. As of 2026-07-28 MCP has no sessions and no initialization handshake, so the bearer token is the only thing identifying the caller from one request to the next. The Mcp-Method and Mcp-Name headers let a gateway apply per-tool policy without parsing the body.

    POST /mcp HTTP/1.1
    Host: mcp.example.com
    Authorization: Bearer eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCJ9…
    Mcp-Method: tools/call
    Mcp-Name: search_files
    Content-Type: application/json
    
    {"jsonrpc":"2.0","id":2,"method":"tools/call",
     "params":{"name":"search_files","arguments":{"query":"Q3 plan"}}}

    Who holds what after this step

    MCP client
    access token (aud: MCP server)

    Parties not listed hold none of this flow’s credentials at this point.

  14. 14MCP server to MCP clientResponse

    The server validates and responds

    The server must confirm the token was issued for it and reject anything else. If the tool needs a scope the token lacks, it answers 403 with an insufficient_scope challenge listing everything the operation needs, and the client runs a step-up for the union of old and new scopes.

    Who holds what after this step

    MCP client
    access token (aud: MCP server)

    Parties not listed hold none of this flow’s credentials at this point.

Watch out for

  • Token passthrough is forbidden. An MCP server must only accept tokens issued for itself, and must not forward the token it received to an upstream API. If it needs upstream access it gets its own token.
  • Dynamic Client Registration is deprecated as of 2026-07-28 and kept only for compatibility. New clients should use Client ID Metadata Documents; new authorization servers should support them.
  • Client credentials must be stored per issuer and never reused with a different authorization server. A server that changes its metadata to point somewhere new is the start of a mix-up attack.
  • A Client ID Metadata Document proves control of a URL, not that the software on the user’s machine is the genuine client. Authorization servers must show the redirect host on the consent screen for this reason.
  • Scopes are whatever the server defines. The core specification has no per-tool permission model; fine-grained control is left to the server, a gateway, or an external policy engine.

Why this flow is rated emerging

The 2026-07-28 revision is published and current, but two things this page draws rest on IETF working-group drafts. The revision requires authorization servers to implement OAuth 2.1 and cites draft -13; the current draft is -17. It recommends Client ID Metadata Documents, which steps 4 to 8 use, and cites draft -00; the current draft is -03. Either draft can still change. The rating describes those dependencies. It is not a judgment on how safe the flow is.

How the specification got here

2025-03-26. First authorization framework. The MCP server doubled as the authorization server.

2025-06-18. The MCP server became a resource server. Protected resource metadata and resource indicators became mandatory; token passthrough was prohibited.

2025-11-25. Client ID Metadata Documents became the preferred way to identify a client and Dynamic Client Registration became optional. Step-up through insufficient_scope challenges and URL-mode elicitation were added.

2026-07-28. The protocol became stateless. Dynamic Client Registration was deprecated, issuer validation (RFC 9207) was added, client credentials were bound to their issuer, and the client-credentials and enterprise-managed authorization extensions were declared stable.

When no human is present

The same discovery steps apply to machine-to-machine use. The official OAuth Client Credentials extension has the client authenticate with a signed JWT assertion (recommended) or a secret, with pre-registered credentials. See client credentials.

Standards in play

See the full tracker for status and links.

Required

What the flow implements, shows in a step, or must support. These decide its maturity rating.

Final specMCP specification 2026-07-28

MCP Authorization

The most widely implemented authorization profile written specifically for agents and tools.

WG draftdraft-ietf-oauth-v2-1

OAuth 2.1

The baseline MCP profiles. Worth knowing that the normative base of most agent authorization is still, formally, a draft.

WG draftdraft-ietf-oauth-client-id-metadata-document

Client ID Metadata Documents

The preferred way for an MCP client to identify itself to a server it has never met.

RFCRFC 9728

Protected Resource Metadata

How an agent that has only a server URL finds out where to get a token. MCP servers must implement it.

RFCRFC 8707

Resource Indicators

Required by MCP. An agent talks to many servers; this is what stops a token for one being replayed at another.

RFCRFC 7636

PKCE

Mandatory for MCP clients, which must also refuse to proceed if a server does not advertise support.

Final specOpenID Connect Discovery 1.0

OpenID Connect Discovery

An MCP authorization server publishes this or RFC 8414 metadata, and an MCP client must support both. It is also the format Kubernetes clusters and CI systems use to publish workload-identity signing keys.

RFCRFC 6750

Bearer Token Usage

The default way agents present tokens, and the thing proof-of-possession schemes are trying to replace.

Optional extensions

Variants and additions the page mentions. No step depends on them, and the flow does not require them.

RFCRFC 7591

Dynamic Client Registration

The original answer for MCP. It left authorization servers with unbounded anonymous registrations, which is why MCP moved away from it.