GPTMap

MCP Authorization Explained: How OAuth 2.1 Lands in MCP (2026-07-28 Spec)

The MCP authorization spec clause by clause: role mapping, RFC9728 discovery, three registration mechanisms, the iss validation table, resource parameters, token red lines, and the step-up authorization flow.

TL;DR
The MCP authorization spec (2026-07-28): the server is an OAuth 2.1 resource server, the client an OAuth client; optional -- HTTP SHOULD conform, stdio SHOULD NOT. Discovery via RFC9728; registration via Client ID Metadata Documents, pre-registration, or deprecated RFC7591. Red lines: Bearer header only, never query strings, always the resource parameter; audience validated; no token transit.
MCP authorization is the transport-level authorization flow defined by the 2026-07-28 spec version: a selective subset of OAuth 2.1 (draft-ietf-oauth-v2-1-13) plus RFC6750 / 8414 / 7591 / 8707 / 9728 / 9207, mapping the protected MCP server to a resource server and the MCP client to an OAuth client, and specifying discovery (RFC9728), registration (three mechanisms), authorization-code response validation (including RFC9207 iss checks), token usage, and scope step-up rules.

How to

  1. Fetch protected resource metadata

    Request the RFC9728 Protected Resource Metadata from the protected MCP server to locate its authorization server, then obtain endpoints and capabilities via RFC8414 or OIDC Discovery (clients must support both).

  2. Obtain a client ID

    Use one of the three registration mechanisms by priority: Client ID Metadata Documents, pre-registration, or Dynamic Client Registration (RFC7591 -- deprecated, compatibility only).

  3. Send resource-scoped authorization requests

    Include the RFC8707 resource parameter in both authorization and token requests, set to the MCP server's canonical URI (lowercase scheme/host, no trailing slash); record the PKCE verifier and issuer in the same request context.

  4. Validate the authorization response

    Validate iss per RFC9207: reject when advertised but absent; when present, string-compare against the recorded issuer with no case folding or normalization; the validation applies to error responses too.

  5. Use tokens correctly

    Send Authorization: Bearer on every request, never in the query string; only send tokens issued by the target server's authorization server, always with the resource parameter.

  6. Handle scope challenges

    Pick initial scope from the 401 challenge first, scopes_supported as fallback; on runtime 403 + insufficient_scope, run step-up with the challenged scopes while keeping previously granted ones.

Remote MCP servers face real users and real data, which makes authorization unavoidable. The Authorization chapter of the 2026-07-28 spec version (verified 2026-09-03) standardizes it: MCP invents no new protocol -- it stands on the OAuth 2.1 draft and a row of RFCs, specifying a selective subset: what role the MCP server plays, how clients discover and register with authorization servers, how tokens travel, and how scopes stay minimal. This article unpacks the spec from an implementer's perspective; every MUST and SHOULD here is quoted from the specification.

1. First: Who Plays Which Role, and Who Needs OAuth

The role mapping is clean:

MCP worldOAuth world
Protected MCP serverOAuth 2.1 resource server
MCP clientOAuth 2.1 client
Authorization serverInteracts with the user and issues access tokens; implementation details out of scope

Authorization is optional, treated differently by transport:

2. The Standards Base: Which OAuth Pieces MCP Uses

The spec declares itself a selective subset of these standards (list quoted from the spec):

StandardRole in MCP authorization
OAuth 2.1 (draft-ietf-oauth-v2-1-13)Base: authorization servers MUST implement it
RFC 6750Bearer token usage + WWW-Authenticate scope challenges
RFC 8414 / OIDC DiscoveryAuthorization server metadata discovery (server provides at least one; clients must support both)
RFC 7591Dynamic Client Registration (deprecated, MAY, compatibility only)
RFC 8707The resource parameter: naming the token's target resource
RFC 9728Protected Resource Metadata: servers MUST implement, clients MUST use
RFC 9207The iss parameter: authorization response validation
Client ID Metadata Documents (draft)Preferred registration mechanism (SHOULD support)

3. Discovery and Registration: Two MUSTs and Three Routes

Discovery: the protected MCP server MUST implement RFC 9728, advertising its authorization server through Protected Resource Metadata; the client MUST use that metadata for discovery, then perform authorization server metadata discovery for endpoints and capabilities.

Registration: before initiating the flow, the client MUST obtain a client ID through one of three mechanisms -- Client ID Metadata Documents, pre-registration, or Dynamic Client Registration (RFC 7591). Note the spec's verdict on dynamic registration: deprecated, retained for backwards compatibility with authorization servers that do not support Client ID Metadata Documents; new implementations SHOULD use Client ID Metadata Documents.

4. Validating the Authorization Response: The iss Table

Before redirecting the user-agent, the client MUST record the issuer from the validated metadata document alongside the PKCE verifier in the same per-request record -- the validation relies on that record being authentic. Authorization servers SHOULD include iss in responses (RFC 9207), advertising it via authorization_response_iss_parameter_supported. The client's decision table (quoted from the spec):

iss advertisediss in responseClient action
truepresentCompare with the recorded issuer (simple string comparison, RFC 3986 §6.2.1)
trueabsentReject the response
false / absentpresentCompare with the recorded issuer
false / absentabsentProceed

Three details: the comparison must not apply case folding, default-port elision, trailing-slash, or percent-encoding normalization; a future revision is expected to upgrade iss from SHOULD to MUST (implementers are encouraged to emit and validate now); and the validation applies equally to error responses -- on mismatch, the client MUST NOT act on or display error, error_description, or error_uri.

5. The Resource Parameter: Tokens Issued for One Server

Clients MUST implement RFC 8707's resource parameter: include it in both authorization and token requests, with the target MCP server's canonical URI (lowercase scheme and host; implementations SHOULD accept uppercase for robustness), regardless of authorization server support.

Valid canonical URI examples (quoted from the spec):
https://mcp.example.com/mcp
https://mcp.example.com
https://mcp.example.com:8443
https://mcp.example.com/server/mcp (when a path is needed to distinguish servers)

Invalid examples:
mcp.example.com                (missing scheme)
https://mcp.example.com#fragment  (contains a fragment)

The spec also recommends: trailing-slash and non-trailing-slash forms are both valid absolute URIs, but consistently use the form without the trailing slash for better interoperability unless it is semantically significant. In an authorization request: &resource=https%3A%2F%2Fmcp.example.com.

6. Token Red Lines

Client side:

GET /mcp HTTP/1.1
Host: mcp.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
  • The token must ride in the Authorization: Bearer header, on every request from client to server;
  • The token MUST NOT be placed in the URI query string.

Server side (the MCP server as resource server):

  • Validate tokens per OAuth 2.1, and MUST validate the audience (RFC 8707 §2 -- was this token issued for this server?);
  • Invalid or expired tokens get HTTP 401;
  • Clients MUST NOT send tokens not issued by that server's authorization server;
  • Servers MUST NOT accept or transit any other tokens -- the formal clause against the Token Passthrough anti-pattern (see MCP Security Guide: The 8 Official Attack Vectors and Their Mitigations).

7. Scopes: Minimization and Step-Up

Initial scope selection priority (clients SHOULD follow least privilege):

  1. Prefer the scope in the 401 WWW-Authenticate challenge (RFC 6750 §3);
  2. Otherwise use scopes_supported from the Protected Resource Metadata (omitting the parameter if undefined).

Two MUST-level constraints: clients MUST NOT assume any set relationship between the challenged scopes and scopes_supported (either may be a subset, superset, or neither) -- the challenged scopes are authoritative for the current operation; and scopes_supported represents the minimal baseline, with extra permissions obtained incrementally via the step-up authorization flow. The standard 401 shape:

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

8. Runtime Shortfalls and Error Codes

StatusMeaningUsage
401UnauthorizedAuthorization required, or token invalid
403ForbiddenInvalid scopes or insufficient permissions
400Bad RequestMalformed authorization request

At runtime with an insufficient-scope token: the server returns 403 plus WWW-Authenticate with error="insufficient_scope", the minimum required scope set, and resource_metadata (consistent with 401 responses). The client then runs step-up: requests the additional scopes, SHOULD keeping previously granted ones so other operations keep working.

Refresh token rules worth remembering: clients MUST keep refresh tokens confidential in transit and storage, SHOULD declare refresh_token in their grant_types metadata, MAY add offline_access when it appears in the server's scopes_supported, and MUST NOT assume refresh tokens will be issued; servers SHOULD NOT include offline_access in WWW-Authenticate or scopes_supported (it is not a resource requirement).

9. Common Mistakes and Troubleshooting

  • Putting OAuth on a stdio server: the spec says stdio SHOULD NOT -- credentials from the environment; do not force the HTTP flow onto local processes.
  • Tokens in the query string: explicitly forbidden; Authorization header only.
  • Omitting the resource parameter: "the server doesn't support it" is not an exemption -- MUST send, with the canonical URI.
  • Skipping audience validation: accepting tokens minted for other resources is the entry point for Token-Passthrough-class risks.
  • Normalizing before the iss comparison: case folding, trailing slashes, and port elision all break the comparison semantics -- simple string comparison only.
  • Treating scopes_supported as a full catalog: it is the minimal baseline; extra permissions go through step-up.

10. Next Steps

Key points

  • Role mapping: the protected MCP server is an OAuth 2.1 resource server; the MCP client is an OAuth 2.1 client; the authorization server's implementation details are out of scope (it may be hosted with the resource server or separately)
  • Authorization is OPTIONAL: HTTP transports SHOULD conform; stdio transports SHOULD NOT (credentials come from the environment); alternative transports MUST follow their protocol's security best practices
  • Discovery and registration: MCP servers MUST implement RFC9728 Protected Resource Metadata and clients MUST use it for authorization server discovery; registration is one of three -- Client ID Metadata Documents (SHOULD support), pre-registration, or Dynamic Client Registration RFC7591 (MAY, deprecated, kept for compatibility)
  • Authorization response validation: clients MUST record the issuer and validate iss per RFC9207; a four-row decision table (including rejecting when advertised but absent); no case folding, default-port elision, or other normalization before comparison
  • Token red lines: only in the Authorization: Bearer header on every request; MUST NOT go in the URI query string; the RFC8707 resource parameter (canonical URI, no trailing slash preferred) MUST be sent; servers MUST validate audience and MUST NOT accept or transit other tokens
  • Scope minimization plus step-up: the 401 challenge scope is authoritative for the current request (clients MUST NOT assume any set relationship with scopes_supported); runtime shortfalls return 403 with error=insufficient_scope and the required scopes

Frequently asked questions

No. The spec is explicit: authorization is OPTIONAL for MCP implementations. When supported: implementations using an HTTP-based transport SHOULD conform to the specification; implementations using stdio SHOULD NOT follow it -- credentials are retrieved from the environment; and alternative transports MUST follow their own protocol's security best practices. Local stdio servers need no OAuth; remote HTTP servers fall under this flow.

Official references

Related articles

Subscribe to GPTMap Weekly

One email every Monday: curated OpenAI updates, deep dives, and best practices. No ads, unsubscribe anytime.

GPTMap EditorialPublished 2026-09-03 7 min read
Test environment (EEAT)
Last tested: 2026-09-03
Model used: gpt-5.6