| title | Authorization |
|---|---|
| sidebarTitle | Overview |
The Model Context Protocol provides authorization capabilities at the transport level, enabling MCP clients to make requests to restricted MCP servers on behalf of resource owners. This specification defines the authorization flow for HTTP-based transports.
Authorization is OPTIONAL for MCP implementations. When supported:
- Implementations using an HTTP-based transport SHOULD conform to this specification.
- Implementations using an STDIO transport SHOULD NOT follow this specification, and instead retrieve credentials from the environment.
- Implementations using alternative transports MUST follow established security best practices for their protocol.
This authorization mechanism is based on established specifications listed below, but implements a selected subset of their features to ensure security and interoperability while maintaining simplicity:
- OAuth 2.1 IETF DRAFT (draft-ietf-oauth-v2-1-13)
- OAuth 2.0 Bearer Token Usage (RFC6750)
- OAuth 2.0 Authorization Server Metadata (RFC8414)
- OAuth 2.0 Dynamic Client Registration Protocol (RFC7591)
- Resource Indicators for OAuth 2.0 (RFC8707)
- OAuth 2.0 Protected Resource Metadata (RFC9728)
- OAuth 2.0 Authorization Server Issuer Identification (RFC9207)
- OAuth Client ID Metadata Documents (draft-ietf-oauth-client-id-metadata-document-00)
- OpenID Connect Discovery 1.0
- OpenID Connect Dynamic Client Registration 1.0 (OpenID Connect Registration)
A protected MCP server acts as an OAuth 2.1 resource server, capable of accepting and responding to protected resource requests using access tokens.
An MCP client acts as an OAuth 2.1 client, making protected resource requests on behalf of a resource owner.
The authorization server is responsible for interacting with the user (if necessary) and issuing access tokens for use at the MCP server. The implementation details of the authorization server are beyond the scope of this specification. It may be hosted with the resource server or a separate entity. Authorization Server Discovery specifies how an MCP server indicates the location of its corresponding authorization server to a client.
-
Authorization servers MUST implement OAuth 2.1 with appropriate security measures for both confidential and public clients.
-
Authorization servers and MCP clients SHOULD support OAuth Client ID Metadata Documents (draft-ietf-oauth-client-id-metadata-document-00).
-
Authorization servers and MCP clients MAY support the OAuth 2.0 Dynamic Client Registration Protocol (RFC7591). Note that Dynamic Client Registration is deprecated and retained for backwards compatibility with authorization servers that do not support Client ID Metadata Documents.
-
MCP servers MUST implement OAuth 2.0 Protected Resource Metadata (RFC9728). MCP clients MUST use OAuth 2.0 Protected Resource Metadata for authorization server discovery.
-
MCP authorization servers MUST provide at least one of the following discovery mechanisms:
- OAuth 2.0 Authorization Server Metadata (RFC8414)
- OpenID Connect Discovery 1.0
MCP clients MUST support both discovery mechanisms to obtain the information required to interact with the authorization server.
MCP servers advertise their associated authorization servers through OAuth 2.0 Protected Resource Metadata, and MCP clients determine authorization server endpoints and supported capabilities through authorization server metadata discovery. Implementations MUST follow the normative discovery requirements defined in Authorization Server Discovery.
Before initiating the authorization flow, MCP clients MUST obtain a client ID through one of three registration mechanisms: Client ID Metadata Documents, pre-registration, or Dynamic Client Registration, following the requirements and selection priority defined in Client Registration.
MCP servers SHOULD include a scope parameter in the WWW-Authenticate header as defined in
RFC 6750 Section 3
to indicate the scopes required for accessing the resource. This provides clients with immediate
guidance on the appropriate scopes to request during authorization,
following the principle of least privilege and preventing clients from requesting excessive permissions.
The scopes included in the WWW-Authenticate challenge MAY match scopes_supported, be a subset
or superset of it, or an alternative collection that is neither a strict subset nor
superset. Clients MUST NOT assume any particular set relationship between the challenged
scope set and scopes_supported. Clients MUST treat the scopes provided in the
challenge as authoritative for the current operation. These scopes are required to
satisfy the current request. When re-authorizing, clients SHOULD include these scopes
alongside any previously granted scopes to avoid losing permissions needed for other operations
(see Step-Up Authorization Flow). Servers SHOULD strive for
consistency in how they construct scope sets but they are not required to surface every dynamically
issued scope through scopes_supported.
Example 401 response with scope guidance:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
scope="files:read"When implementing authorization flows, MCP clients SHOULD follow the principle of least privilege by requesting only the scopes necessary for their intended operations. During the initial authorization handshake, MCP clients SHOULD follow this priority order for scope selection:
- Use
scopeparameter from the initialWWW-Authenticateheader in the 401 response, if provided - If
scopeis not available, use all scopes defined inscopes_supportedfrom the Protected Resource Metadata document, omitting thescopeparameter ifscopes_supportedis undefined.
This approach accommodates the general-purpose nature of MCP clients, which typically lack domain-specific knowledge to make informed decisions about individual scope selection. Requesting all available scopes allows the authorization server and end-user to determine appropriate permissions during the consent process.
This approach minimizes user friction while following the principle of least privilege.
The scopes_supported field is intended to represent the minimal set of scopes necessary
for basic functionality (see Scope Minimization),
with additional scopes requested incrementally through the step-up authorization flow steps
described in the Scope Challenge Handling section.
The registration step shown in the flow uses one of the mechanisms defined in Client Registration.
The complete Authorization flow proceeds as follows:
sequenceDiagram
participant B as User-Agent (Browser)
participant C as Client
participant M as MCP Server (Resource Server)
participant A as Authorization Server
C->>M: MCP request without token
M->>C: HTTP 401 Unauthorized with WWW-Authenticate header
Note over C: Extract resource_metadata URL from WWW-Authenticate
C->>M: Request Protected Resource Metadata
M->>C: Return metadata
Note over C: Parse metadata and extract authorization server(s)<br/>Client determines AS to use
C->>A: GET Authorization server metadata endpoint
Note over C,A: Try OAuth 2.0 and OpenID Connect<br/>discovery endpoints in priority order
A-->>C: Authorization server metadata
alt Client ID Metadata Documents
Note over C: Client uses HTTPS URL as client_id
Note over A: Server detects URL-formatted client_id
A->>C: Fetch metadata from client_id URL
C-->>A: JSON metadata document
Note over A: Validate metadata and redirect_uris
else Dynamic client registration
C->>A: POST /register
A->>C: Client Credentials
else Pre-registered client
Note over C: Use existing client_id
end
Note over C: Generate PKCE parameters<br/>Include resource parameter<br/>Apply scope selection strategy<br/>Record expected issuer
C->>B: Open browser with authorization URL + code_challenge + resource
B->>A: Authorization request with resource parameter
Note over A: User authorizes
A->>B: Redirect to callback with authorization code + iss
B->>C: Authorization code callback
Note over C: Validate iss against recorded issuer (RFC 9207)
C->>A: Token request + code_verifier + resource
A->>C: Access token (+ refresh token)
C->>M: MCP request with access token
M-->>C: MCP response
Note over C,M: MCP communication continues with valid token
Before redirecting the user-agent, the client MUST record the issuer value from the selected authorization server's validated metadata document (see Authorization Server Metadata Discovery) and associate it with the same per-request record used to store the PKCE code verifier (and the state value, if used). The validation in this section depends on that recorded value being authentic; it provides no protection if the expected issuer was obtained from an unvalidated source.
MCP authorization servers SHOULD include the iss parameter in authorization responses, including error responses, as defined in RFC9207 Section 2. Authorization servers that include the iss parameter MUST advertise this by setting authorization_response_iss_parameter_supported to true in their metadata (RFC9207 Section 2.3).
On receiving the authorization response, MCP clients MUST apply the validation in RFC9207 Section 2.4 before transmitting the authorization code to any token endpoint:
authorization_response_iss_parameter_supported |
iss in response |
Client action |
|---|---|---|
true |
present | Compare to the recorded issuer using simple string comparison (RFC3986 Section 6.2.1) |
true |
absent | Reject the response |
false or absent |
present | Compare to the recorded issuer using simple string comparison (RFC3986 Section 6.2.1) |
false or absent |
absent | Proceed |
The third row applies the local-policy provision in RFC9207 Section 2.4: this specification compares a present iss against the recorded issuer regardless of metadata advertisement, to accommodate authorization servers that emit iss before updating their metadata.
A future revision of this specification is expected to upgrade authorization server inclusion of iss from SHOULD to MUST. Implementers are encouraged to emit and validate iss now to ease that transition; client rejection behavior on iss absence will continue to be keyed on authorization_response_iss_parameter_supported until that revision defines the upgrade path.
After decoding the iss value from the application/x-www-form-urlencoded response per RFC 9207 Section 2.4, clients MUST NOT apply scheme or host case folding, default-port elision, trailing-slash, or percent-encoding normalization (RFC 3986 Sections 6.2.2-6.2.3) before comparison.
This validation applies equally to error responses - on mismatch the client MUST NOT act on or display error, error_description, or error_uri.
MCP clients MUST implement Resource Indicators for OAuth 2.0 as defined in RFC 8707
to explicitly specify the target resource for which the token is being requested. The resource parameter:
- MUST be included in both authorization requests and token requests.
- MUST identify the MCP server that the client intends to use the token with.
- MUST use the canonical URI of the MCP server as defined in RFC 8707 Section 2.
For the purposes of this specification, the canonical URI of an MCP server is defined as the resource identifier as specified in
RFC 8707 Section 2 and aligns with the resource parameter in
RFC 9728.
MCP clients SHOULD provide the most specific URI that they can for the MCP server they intend to access, following the guidance in RFC 8707. While the canonical form uses lowercase scheme and host components, implementations SHOULD accept uppercase scheme and host components for robustness and interoperability.
Examples of valid canonical URIs:
https://mcp.example.com/mcphttps://mcp.example.comhttps://mcp.example.com:8443https://mcp.example.com/server/mcp(when path component is necessary to identify individual MCP server)
Examples of invalid canonical URIs:
mcp.example.com(missing scheme)https://mcp.example.com#fragment(contains fragment)
Note: While both
https://mcp.example.com/(with trailing slash) andhttps://mcp.example.com(without trailing slash) are technically valid absolute URIs according to RFC 3986, implementations SHOULD consistently use the form without the trailing slash for better interoperability unless the trailing slash is semantically significant for the specific resource.
For example, if accessing an MCP server at https://mcp.example.com, the authorization request would include:
&resource=https%3A%2F%2Fmcp.example.com
MCP clients MUST send this parameter regardless of whether authorization servers support it.
Access token handling when making requests to MCP servers MUST conform to the requirements defined in OAuth 2.1 Section 5 "Resource Requests". Specifically:
- MCP client MUST use the Authorization request header field defined in OAuth 2.1 Section 5.1.1:
Authorization: Bearer <access-token>
Note that authorization MUST be included in every HTTP request from client to server.
- Access tokens MUST NOT be included in the URI query string
Example request:
GET /mcp HTTP/1.1
Host: mcp.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...MCP servers, acting in their role as an OAuth 2.1 resource server, MUST validate access tokens as described in OAuth 2.1 Section 5.2. MCP servers MUST validate that access tokens were issued specifically for them as the intended audience, according to RFC 8707 Section 2. If validation fails, servers MUST respond according to OAuth 2.1 Section 5.3 error handling requirements. Invalid or expired tokens MUST receive a HTTP 401 response.
MCP clients MUST NOT send tokens to the MCP server other than ones issued by the MCP server's authorization server.
MCP servers MUST only accept tokens that are valid for use with their own resources.
MCP servers MUST NOT accept or transit any other tokens.
This section provides guidance for MCP Clients and MCP Servers when handling or issuing refresh tokens for both OAuth and OpenID Connect.
MCP Clients that desire refresh tokens:
- MUST keep refresh tokens confidential in transit and storage as specified in OAuth 2.1 Section 4.3
- SHOULD include
refresh_tokenin theirgrant_typesclient metadata - MAY add
offline_accessto thescopeparameter of the authorization and token requests when the Authorization Server metadata contains it inscopes_supported - MUST NOT assume refresh tokens will be issued; the AS retains discretion
MCP Servers (Protected Resources) SHOULD NOT include offline_access in
WWW-Authenticate scope or Protected Resource Metadata scopes_supported, as refresh
tokens are not a resource requirement.
Servers MUST return appropriate HTTP status codes for authorization errors:
| Status Code | Description | Usage |
|---|---|---|
| 401 | Unauthorized | Authorization required or token invalid |
| 403 | Forbidden | Invalid scopes or insufficient permissions |
| 400 | Bad Request | Malformed authorization request |
This section covers handling insufficient scope errors during runtime operations when a client already has a token but needs additional permissions. This follows the error handling patterns defined in OAuth 2.1 Section 5 and leverages the metadata fields from RFC 9728 (OAuth 2.0 Protected Resource Metadata).
When a client makes a request with an access token with insufficient scope during runtime operations, the server SHOULD respond with:
HTTP 403 Forbiddenstatus code (per RFC 6750 Section 3.1)WWW-Authenticateheader with theBearerscheme and additional parameters:error="insufficient_scope"- indicating the specific type of authorization failurescope="required_scope1 required_scope2"- specifying the minimum scopes needed for the operationresource_metadata- the URI of the Protected Resource Metadata document (for consistency with 401 responses)error_description(optional) - human-readable description of the error
Server Scope Management: When responding with insufficient scope errors, servers
SHOULD include the scopes needed to satisfy the current operation in the scope
parameter, consistent with
RFC 6750 Section 3.1.
The scope attribute describes the scopes necessary to access
the requested resource — servers are not required to include
the client's previously granted scopes.
Servers have flexibility in determining which scopes to include:
- Minimum approach: Include only the scopes required for the specific operation that triggered the error.
- Recommended approach: Include the scopes required for the current operation along with related scopes that commonly work together, to reduce the number of step-up authorization rounds.
- Extended approach: Include the scopes required for the current operation, related scopes, and any other scopes the server anticipates the client may need in the near future.
The choice depends on the server's assessment of user experience impact and authorization friction.
Regardless of the approach chosen, servers SHOULD include all scopes required for the current operation in a single challenge. Challenging incrementally (returning one missing scope, then another on the subsequent retry) forces multiple authorization round-trips for a single operation and degrades user experience. The required scopes may be determined dynamically based on the specific request arguments and context, but once determined, they should be emitted together.
Servers SHOULD be consistent in their scope inclusion strategy to provide predictable behavior for clients.
Servers SHOULD consider the user experience impact when determining which scopes to include in the response, as misconfigured scopes may require frequent user interaction.
Scope accumulation across operations is a client-side responsibility. Clients **SHOULD** compute the union of previously requested scopes and newly challenged scopes when initiating re-authorization, as described in [Step-Up Authorization Flow](#step-up-authorization-flow). This allows servers to remain stateless with respect to client scope sets while ensuring clients do not lose previously granted permissions.Example insufficient scope response:
HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope",
scope="files:write",
resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
error_description="File write permission required for this operation"Clients will receive scope-related errors during initial authorization or at runtime (insufficient_scope).
Clients SHOULD respond to these errors by requesting a new access token with an increased set of scopes via a step-up authorization flow or handle the errors in other, appropriate ways.
Clients acting on behalf of a user SHOULD attempt the step-up authorization flow. Clients acting on their own behalf (client_credentials clients)
MAY attempt the step-up authorization flow or abort the request immediately.
The flow is as follows:
- Parse error information from the authorization server response or
WWW-Authenticateheader - Determine required scopes by computing the union of the client's previously requested scope set and the scopes from the current challenge. This ensures previously granted permissions are preserved when servers emit per-operation scope challenges per RFC 6750 Section 3.1. Clients MAY also consult the Scope Selection Strategy for initial scope selection guidance.
- Initiate (re-)authorization with the determined scope set
- Retry the original request with the new authorization no more than a few times and treat this as a permanent authorization failure
Clients SHOULD implement retry limits and SHOULD track scope upgrade attempts to avoid repeated failures for the same resource and operation combination.
**Hierarchical scopes**: Some authorization servers define scope hierarchies where a broader scope implies narrower ones (for example, an `admin` scope that subsumes `read`). When accumulating scopes, the client's union may contain semantically redundant entries — for example, a token previously granted a broad scope may be challenged with a narrower one it already implies. Clients need not deduplicate hierarchically; authorization servers typically normalize such redundancy during token issuance. Servers, for their part, must account for hierarchy when deciding whether a token is sufficient for an operation, but this does not affect the scopes they emit in a challenge.Implementations of this specification MUST follow the normative security requirements in Security Considerations, covering token audience binding and validation, token theft, communication security, authorization code protection, mix-up and confused deputy attacks, open redirection, and Client ID Metadata Document security.
There are several authorization extensions to the core protocol that define additional authorization mechanisms. These extensions are:
- Optional - Implementations can choose to adopt these extensions
- Additive - Extensions do not modify or break core protocol functionality; they add new capabilities while preserving core protocol behavior
- Composable - Extensions are modular and designed to work together without conflicts, allowing implementations to adopt multiple extensions simultaneously
- Versioned independently - Extensions follow the core MCP versioning cycle but may adopt independent versioning as needed
A list of supported extensions can be found in the MCP Authorization Extensions repository.