You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Holding on creating a PR until there is community interest in this enhancement.
Abstract
This SEP proposes moving OAuth authorization flow management from MCP Clients to MCP Servers, eliminating the need for dynamic client registration and server discovery by clients. The proposal introduces two key mechanisms: (1) a proof-of-possession system for MCP Clients to prove session continuity over extended periods, and (2) a server-directed browser redirect capability that allows MCP Servers to handle authorization flows. This provides a more secure, authenticated connection between the client and the server, enables MCP servers to manage multiple authorization contexts and chain authorization requests across server hierarchies, and allows existing resource servers to use existing authorization mechanisms.
Motivation
MCP has enabled AI agents to discover and invoke arbitrary APIs, driving a dramatic shift in IT architecture. The MCP authorization specification defines how an MCP Client can obtain authorization to access protected resources at an MCP Server using OAuth. This represents a novel usage of OAuth that differs significantly from traditional patterns.
In traditional OAuth deployments, developers pre-register their applications with authorization servers that protect specific resources. Developers know in advance which scopes their applications need and which authorization servers to use. Access to sensitive resources typically requires developers to provide additional verification during a manual registration process.
MCP's dynamic discovery model inverts this pattern. MCP clients dynamically discover authorization requirements by examining WWW-Authenticate headers and fetching .well-known metadata from arbitrary servers - operations that are uncommon in traditional OAuth flows.
I created this SEP based on my past experience in security architectures, my experience with OAuth (I led the design of what became OAuth 2.0 and am working on OAuth 2.1), and personal implementation experience writing an MCP Server for the Hellō Admin APIs to enable developers to register and manage their Hellō application from their IDE or CLI. I updated our OAuth infrastructure to support the MCP requirements, and while doing that, I ended up circumventing the spirit of the MCP Authorization Specification:
Our registration endpoint always returns the same client_id
Only the mcp scope can be requested with that client_id
We allow any redirect_uri to be used with that client_id
The mcp scope only allows read, create, and additive updates to resources - no destructive operations
To minimize the risk of token exfiltration, we do not support refresh tokens
After discussions at the recent IETF 123 meeting in Madrid, and reviewing the auth issues in this repository, I concluded that for a number of use cases, OAuth is not a good fit between the MCP Client and MCP Server.
Problems
I've included links to related issues / PRs I came across in the repo.
OAuth is a Web Based Protocol
Not all user interfaces are web based.
OAuth Scopes are Coarse Grained Access
Many applications require fine grained access control and use a policy engine to determine what access the principal has.
PR 646 proposes how to enable enterprise use cases.
Dynamic Client Registration (DCR) DCR (RFC 7591) is not a commonly deployed OAuth pattern, and the DCR trust model of open, unauthenticated registration does not map well to widely deployed OAuth infrastructure. An OAuth client is typically registered, and the authorization server knows the identity of the client application, and the developer that registered it. Additional verification can be required for access to more sensitive scopes.
Issue 1032 wants add software_statement and jwks_uri
Issue 991 proposes using a URL-based client identifier instead of DCR.
Issue 582 proposes Client ID Metadata Documents as an alternative to DCR
Untrusted Redirect URIs
The use of localhost and custom schemes removes one of the protocol mechanisms of identifying the client. An HTTPS redirect URI provides some assurance to the authorization server that the authorization request came from the registered client. Security research has demonstrated practical attacks including "OAuth Account Takeover by hijacking custom schemes" where malicious applications can claim the same custom URI schemes to intercept authorization responses
Single Authorization Mechanism
The only mechanism for the MCP Server to interact directly with the user is to return a 401 response and have the MCP Client request a scope from the configured authorization server. This prevents the MCP Server from getting access tokens from more than one authorization server and requires all authorization to be represented in a single access token. There is no mechanism for downstream servers to obtain their own access tokens.
Issue 1036 and PR 887 propose an out of band mechanism for authorization.
Implementation Complexity
Every MCP Client and Server developer needs to implement discovery, registration, and token management. Any potential enhancement to resolve issues needs to be implemented by all clients for interoperability to servers that may require the functionality.
PR 971 proposes fallback to WWW-Authenticate as deploying Protected Resource Metadata is challenging.
Bearer Token Access
Besides the Mcp-Session-Id, the access token from the authorization server is the only mechanism to bind requests across a session and maintain context, and both of these are bearer tokens. There is no trusted source of the client identity, and the user identity is abstracted by the single access token. This is a barrier to adoption in high value deployment environments.
Issue 544 describes this and a number of other security issues with the current design.
Proposed Solution
To move authorization management to the MCP Server, the server needs both a binding between the instance of the MCP Client and the server, and a mechanism to request the client to have an interaction with the server.
Cryptographic Binding Between MCP Client and MCP Server
When a client instance starts a relation with a server, it generates a key pair, proves possession of the private key, shares the public key with the server on first use. The client proves possession of the private on all subsequent requests. The server can now track user and session context with the public key vs an OAuth access token. HTTP Message Signatures (RFC 9421) is the proposed cryptographic binding mechanism. See Rationale for a comparison to other mechanisms
Interaction Request
At any time, the server can request the client to present a prompt for user to interact directly with the MCP Server. This interaction request can be the response to an MCP request, or sent as an event over SSE. If the interaction request is a web interaction (other interaction channels may be defined), it will contain a description and a URL. The prompt and URL are opaque to the client. The URL should contain context to bind the user interaction to the client instance. The URL may be at the MCP Server, or could be a delegate for the MCP Server. The redirect could be used for any of the following:
The user loads a page at the MCP Server that starts an OAuth flow to obtain an access token. The MCP Server is the OAuth client in this flow, and binds the resulting access token to the client instance.
Present the user a contextual description of an operation to be performed and obtain confirmation. Examples include confirmation of wiring $1M or deleting a database.
Log the user in with their enterprise credentials at the MCP Server so that the MCP Server or downstream resources can make policy decisions using existing access control mechanisms when future requests are made by the MCP Client to the MCP Server.
Note the MCP Server can initiate an interaction with the user directly if it has a channel such as pushing a message to the user's mobile phone for a confirmation.
Benefits of Client Authentication and Server-Side Authorization
Having the client authenticate to the server, and moving authorization management to the MCP Server provides several advantages:
Non-breaking Change
The existing OAuth flows can be used by clients with existing servers that have deployed the current specification.
Improved Client Security Posture
Access and refresh tokens are now managed in a server and not by the client. Exfiltration of bearer tokens on a user's device is no longer a security risk. The client instance identity is verified with proof of possession. The Initialize can be extended to include client posture assertions common in enterprise scenarios.
Preregistered OAuth Clients
the MCP Server is now the OAuth client and can be preregistered with an HTTPS redirect URI and is able to manage client secrets, building on existing, deployed OAuth infrastructure.
Simplified Client Implementation
Clients no longer need to implement OAuth flows, dynamic client registration, server discovery, or manage sensitive bearer tokens.
Simplified Server Implementation
Servers can now use the access management systems that are currently in use for the resources and functionality to be made available over MCP. No requirement to deploy DCR or OAuth discovery endpoints.
Enterprise-Friendly
Enterprises can build a MCP Server on top of their existing authorization mechanisms for their resources including fine grained access control.
Dynamic Authorization
Servers can request authorization at any time, supporting step-up authentication and progressive consent bringing humans in the loop with the server for critical operations.
Policy Enforcement Flexibility
Servers making authorization decisions based on operation sensitivity, client posture, IP changes, and other contextual factors. They can now request additional authorization or authentication without losing context, rather than just returning an opaque to the user
Multi-Resource Support
Servers can manage multiple access tokens for different backend resources and chain authorization requests through server hierarchies
Protocol Comparison
Current OAuth Flow
sequenceDiagram
participant Client as MCP Client
participant Server as MCP Server
participant AS as Authorization Server
participant Browser as User Browser
participant RS as Resource Server
Note over Client, Server: Initial MCP Request Without Authorization
Client->>Server: MCP request without token
Server-->>Client: HTTP 401 Unauthorized with WWW-Authenticate header
Note over Client, Server: Extract resource_metadata<br/>from WWW-Authenticate
Client->>Server: GET /.well-known/oauth-protected-resource
Server-->>Client: Resource metadata with authorization server URL
Note over Client, AS: Validate RS metadata,<br/>build AS metadata URL
Client->>AS: GET /.well-known/oauth-authorization-server
AS-->>Client: Authorization server metadata
Note over Client, AS: Register Instance of Client
Client->>AS: POST /register (Dynamic Client Registration)
AS-->>Client: Client Credentials
Note over Client, Browser: OAuth 2.1 Authorization Flow
Client->>Browser: Open Authorization URL
Browser->>AS: Authorization Request
AS-->>Browser: Authorization Code
Browser-->>Client: Authorization Code
Client->>AS: Exchange Code for Token
AS-->>Client: Access Token
Note over Client, Server: Authorized MCP Communication
Client->>Server: MCP Request with Bearer Token
Server->>RS: Resource Request
RS-->>Server: Resource Response
Server-->>Client: MCP Response
Loading
Proposed Server-Side OAuth Flow With SSE Interaction Request
sequenceDiagram
participant Client as MCP Client
participant Server as MCP Server
participant AS as Authorization Server
participant Browser as User Browser
participant RS as Resource Server
Client->>Server: MCP Request w/ HTTP Signature
Server-->>Client: Interaction Request SSE
Client->>Server: Interaction URL
Note over Client, Browser: OAuth 2.1 Authorization Flow
Server-->>Browser: Open Authorization URL
Browser->>AS: Authorization Request
AS-->>Browser: Authorization Code
Browser-->>Server: Authorization Code
Server->>AS: Exchange Code for Token
AS-->>Server: Access Token
Note over Server: MCP Request can now be completed
Server->>RS: Request with access token
RS-->>Server: Resource Response
Server-->>Client: MCP Response SSE
Loading
Proposed Server-Side OAuth Flow With Interaction Request Response
sequenceDiagram
participant Client as MCP Client
participant Server as MCP Server
participant AS as Authorization Server
participant Browser as User Browser
participant RS as Resource Server
Client->>Server: MCP Request w/ HTTP Signature
Server-->>Client: Interaction Request Response
Note over Client, Browser: Client presents interaction to user
Client->>Browser: Open Interaction URL
Browser->>Server: Load interaction page
Note over Server, Browser: OAuth 2.1 Authorization Flow
Server-->>Browser: Redirect to Authorization Server
Browser->>AS: Authorization Request
AS-->>Browser: Authorization Code
Browser-->>Server: Authorization Code with session binding
Server->>AS: Exchange Code for Token
AS-->>Server: Access Token
Note over Server: Authorization complete, notify client
Server->>Client: POST to completion endpoint (id=request_id)
Note over Client: Client remakes original request
Client->>Server: MCP Request w/ HTTP Signature (retry)
Note over Server: Now authorized, can complete request
Server->>RS: Request with access token
RS-->>Server: Resource Response
Server-->>Client: MCP Response
Loading
Specification
HTTP Message Signing Profile
For security and interoperability, we profile HTTP Message Signing specifying how the public key is exchanged, what the keyid is, and which fields are included in the signature.
Key Management
Clients generate a public/private key pair per MCP server using Ed25519:
This approach provides backward compatibility and strong cryptographic guarantees while maintaining the simplicity and flexibility that makes MCP accessible to developers.
Interaction Request
An interaction can be requested by providing a SSE event if Content-Type is text/event-stream or an error response if Content-Type is application/json. A text/event-stream response is recommended as it allows the an interaction to be performed while a request is outstanding and a more seamless user experience.
The interaction request has the following data:
type type of interaction. Only web is currently defined
url URL to load on user gesture
explanation message to be presented to user
timeout how long the URL is valid for
text/event-stream response
event: interaction_required
data: {
"type": "web",
"url": "https://mcp.example.com/oauth/authorize",
"explanation": "Example requires authorization to complete this request",
"timeout": 300
}
If a interaction_completion_uri was provided in the initialize message, the server will load it with the query parameter id set to the value of the RequestID. The MCP Client can then retry its request.
Rationale
Several cryptographic mechanisms could provide proof of possession for MCP client session binding. This section analyzes the trade-offs of each approach.
Mutual TLS (mTLS)
Description: Client presents a self signed certificate during TLS handshake.
Pros:
Transport-level security, automatic with TLS
Strong cryptographic guarantees
Well-established in enterprise environments
No application-layer signature computation required
Cons:
In cloud deployments, TLS terminates at the CDN or the load balancer, not at web application.
TLS is required, adding significant complexity to local development environments
Not all TLS implementations expose client certificates to applications
Verdict: Wrong layer for an application
Signed JSON-RPC
Description: Client signs JSON-RPC message content using JWS or similar mechanisms.
Pros:
Protocol-native approach
Message-level integrity
Can work over any transport
Cons:
No protection for HTTP headers
Sending JWS instead of JSON breaks backward compatibility
Easily replayed
Verdict: Too narrow in scope for complete session security.
HTTP Signatures (RFC 9421)
Description: Client signs HTTP requests using cryptographic signatures in HTTP headers.
Pros:
Application-layer security independent of transport
Works across all HTTP implementations
Request integrity and authenticity in single mechanism
Replay protection when combined with RequestId cache
Backwards compatible as older servers can ignore headers
Cons:
Signature computation overhead per request
RequestId cache to protect against all replay attacks
Verdict: Optimal balance of security and implementability for MCP.
Based on the analysis above, we propose using HTTP Message Signatures (RFC 9421) as the proof of possession mechanism for MCP.
Backward Compatibility
This SEP introduces optional changes that do not break existing implementations:
New client authentication method: HTTP Message Signatures are additive - existing OAuth flows continue to work
New interaction request mechanism: Servers can support both old and new authorization patterns
Extended initialization message: The clientInfo extensions are optional fields
Reference Implementation
None at this time.
Security Implications
Security Improvements
This SEP addresses several critical security concerns:
1. Dynamic Client Registration Vulnerabilities
Current Risk: DCR allows unauthenticated client registration, enabling potential phishing attacks. Mitigation: Eliminates DCR requirement by moving OAuth to server-side.
2. Bearer Token Exposure
Current Risk: Access tokens stored on client devices can be exfiltrated. Mitigation: Tokens managed server-side, only cryptographic proof of possession on client.
3. Untrusted Redirect URIs
Current Risk: localhost and custom URI schemes reduce client identification assurance. Mitigation: Server manages redirects with HTTPS endpoints and proper validation.
4. Session Binding Weaknesses
Current Risk: Only bearer tokens provide session continuity. Mitigation: Cryptographic session binding with replay protection.
New Security Considerations
1. HTTP Signature Security
Risks:
Private key compromise allows impersonation
Signature timing attacks if implementation is vulnerable
Replay attacks if timestamp validation is insufficient
Mitigations:
Ed25519 provides strong cryptographic guarantees
Short signature validity windows (1-3 minutes)
Request ID caching prevents replay attacks
Key rotation policies recommended
2. Interaction Request Security
Risks:
Malicious servers could request excessive user interactions
URL tampering in interaction requests
Session fixation through interaction flows
Interaction URL binding attacks where malicious actors attempt to complete authorization flows for other client sessions
Interaction URLs MUST contain cryptographically secure, unguessable session binding tokens that tie the web interaction to the specific MCP client instance. These tokens should be:
Cryptographically random with sufficient entropy (minimum 128 bits)
Unique per client session and interaction request
Validated by the server to ensure the web interaction corresponds to the correct MCP client binding
Preamble
Title: Server-Side Authorization Management with Client Session Binding
Author: @dickhardt
Status: Draft
Type: Feature
Created: 2025-08-04
Holding on creating a PR until there is community interest in this enhancement.
Abstract
This SEP proposes moving OAuth authorization flow management from MCP Clients to MCP Servers, eliminating the need for dynamic client registration and server discovery by clients. The proposal introduces two key mechanisms: (1) a proof-of-possession system for MCP Clients to prove session continuity over extended periods, and (2) a server-directed browser redirect capability that allows MCP Servers to handle authorization flows. This provides a more secure, authenticated connection between the client and the server, enables MCP servers to manage multiple authorization contexts and chain authorization requests across server hierarchies, and allows existing resource servers to use existing authorization mechanisms.
Motivation
MCP has enabled AI agents to discover and invoke arbitrary APIs, driving a dramatic shift in IT architecture. The MCP authorization specification defines how an MCP Client can obtain authorization to access protected resources at an MCP Server using OAuth. This represents a novel usage of OAuth that differs significantly from traditional patterns.
In traditional OAuth deployments, developers pre-register their applications with authorization servers that protect specific resources. Developers know in advance which scopes their applications need and which authorization servers to use. Access to sensitive resources typically requires developers to provide additional verification during a manual registration process.
MCP's dynamic discovery model inverts this pattern. MCP clients dynamically discover authorization requirements by examining WWW-Authenticate headers and fetching .well-known metadata from arbitrary servers - operations that are uncommon in traditional OAuth flows.
I created this SEP based on my past experience in security architectures, my experience with OAuth (I led the design of what became OAuth 2.0 and am working on OAuth 2.1), and personal implementation experience writing an MCP Server for the Hellō Admin APIs to enable developers to register and manage their Hellō application from their IDE or CLI. I updated our OAuth infrastructure to support the MCP requirements, and while doing that, I ended up circumventing the spirit of the MCP Authorization Specification:
client_idmcpscope can be requested with thatclient_idredirect_urito be used with thatclient_idmcpscope only allows read, create, and additive updates to resources - no destructive operationsAfter discussions at the recent IETF 123 meeting in Madrid, and reviewing the auth issues in this repository, I concluded that for a number of use cases, OAuth is not a good fit between the MCP Client and MCP Server.
Problems
I've included links to related issues / PRs I came across in the repo.
OAuth is a Web Based Protocol
Not all user interfaces are web based.
OAuth Scopes are Coarse Grained Access
Many applications require fine grained access control and use a policy engine to determine what access the principal has.
Dynamic Client Registration (DCR)
DCR (RFC 7591) is not a commonly deployed OAuth pattern, and the DCR trust model of open, unauthenticated registration does not map well to widely deployed OAuth infrastructure. An OAuth client is typically registered, and the authorization server knows the identity of the client application, and the developer that registered it. Additional verification can be required for access to more sensitive scopes.
software_statementsoftware_statementandjwks_uriUntrusted Redirect URIs
The use of localhost and custom schemes removes one of the protocol mechanisms of identifying the client. An HTTPS redirect URI provides some assurance to the authorization server that the authorization request came from the registered client. Security research has demonstrated practical attacks including "OAuth Account Takeover by hijacking custom schemes" where malicious applications can claim the same custom URI schemes to intercept authorization responses
Single Authorization Mechanism
The only mechanism for the MCP Server to interact directly with the user is to return a 401 response and have the MCP Client request a scope from the configured authorization server. This prevents the MCP Server from getting access tokens from more than one authorization server and requires all authorization to be represented in a single access token. There is no mechanism for downstream servers to obtain their own access tokens.
Implementation Complexity
Every MCP Client and Server developer needs to implement discovery, registration, and token management. Any potential enhancement to resolve issues needs to be implemented by all clients for interoperability to servers that may require the functionality.
Bearer Token Access
Besides the
Mcp-Session-Id, the access token from the authorization server is the only mechanism to bind requests across a session and maintain context, and both of these are bearer tokens. There is no trusted source of the client identity, and the user identity is abstracted by the single access token. This is a barrier to adoption in high value deployment environments.Proposed Solution
To move authorization management to the MCP Server, the server needs both a binding between the instance of the MCP Client and the server, and a mechanism to request the client to have an interaction with the server.
Cryptographic Binding Between MCP Client and MCP Server
When a client instance starts a relation with a server, it generates a key pair, proves possession of the private key, shares the public key with the server on first use. The client proves possession of the private on all subsequent requests. The server can now track user and session context with the public key vs an OAuth access token. HTTP Message Signatures (RFC 9421) is the proposed cryptographic binding mechanism. See Rationale for a comparison to other mechanisms
Interaction Request
At any time, the server can request the client to present a prompt for user to interact directly with the MCP Server. This interaction request can be the response to an MCP request, or sent as an event over SSE. If the interaction request is a web interaction (other interaction channels may be defined), it will contain a description and a URL. The prompt and URL are opaque to the client. The URL should contain context to bind the user interaction to the client instance. The URL may be at the MCP Server, or could be a delegate for the MCP Server. The redirect could be used for any of the following:
Note the MCP Server can initiate an interaction with the user directly if it has a channel such as pushing a message to the user's mobile phone for a confirmation.
Benefits of Client Authentication and Server-Side Authorization
Having the client authenticate to the server, and moving authorization management to the MCP Server provides several advantages:
Non-breaking Change
The existing OAuth flows can be used by clients with existing servers that have deployed the current specification.
Improved Client Security Posture
Access and refresh tokens are now managed in a server and not by the client. Exfiltration of bearer tokens on a user's device is no longer a security risk. The client instance identity is verified with proof of possession. The
Initializecan be extended to include client posture assertions common in enterprise scenarios.Preregistered OAuth Clients
the MCP Server is now the OAuth client and can be preregistered with an HTTPS redirect URI and is able to manage client secrets, building on existing, deployed OAuth infrastructure.
Simplified Client Implementation
Clients no longer need to implement OAuth flows, dynamic client registration, server discovery, or manage sensitive bearer tokens.
Simplified Server Implementation
Servers can now use the access management systems that are currently in use for the resources and functionality to be made available over MCP. No requirement to deploy DCR or OAuth discovery endpoints.
Enterprise-Friendly
Enterprises can build a MCP Server on top of their existing authorization mechanisms for their resources including fine grained access control.
Dynamic Authorization
Servers can request authorization at any time, supporting step-up authentication and progressive consent bringing humans in the loop with the server for critical operations.
Policy Enforcement Flexibility
Servers making authorization decisions based on operation sensitivity, client posture, IP changes, and other contextual factors. They can now request additional authorization or authentication without losing context, rather than just returning an opaque to the user
Multi-Resource Support
Servers can manage multiple access tokens for different backend resources and chain authorization requests through server hierarchies
Protocol Comparison
Current OAuth Flow
sequenceDiagram participant Client as MCP Client participant Server as MCP Server participant AS as Authorization Server participant Browser as User Browser participant RS as Resource Server Note over Client, Server: Initial MCP Request Without Authorization Client->>Server: MCP request without token Server-->>Client: HTTP 401 Unauthorized with WWW-Authenticate header Note over Client, Server: Extract resource_metadata<br/>from WWW-Authenticate Client->>Server: GET /.well-known/oauth-protected-resource Server-->>Client: Resource metadata with authorization server URL Note over Client, AS: Validate RS metadata,<br/>build AS metadata URL Client->>AS: GET /.well-known/oauth-authorization-server AS-->>Client: Authorization server metadata Note over Client, AS: Register Instance of Client Client->>AS: POST /register (Dynamic Client Registration) AS-->>Client: Client Credentials Note over Client, Browser: OAuth 2.1 Authorization Flow Client->>Browser: Open Authorization URL Browser->>AS: Authorization Request AS-->>Browser: Authorization Code Browser-->>Client: Authorization Code Client->>AS: Exchange Code for Token AS-->>Client: Access Token Note over Client, Server: Authorized MCP Communication Client->>Server: MCP Request with Bearer Token Server->>RS: Resource Request RS-->>Server: Resource Response Server-->>Client: MCP ResponseProposed Server-Side OAuth Flow With SSE Interaction Request
sequenceDiagram participant Client as MCP Client participant Server as MCP Server participant AS as Authorization Server participant Browser as User Browser participant RS as Resource Server Client->>Server: MCP Request w/ HTTP Signature Server-->>Client: Interaction Request SSE Client->>Server: Interaction URL Note over Client, Browser: OAuth 2.1 Authorization Flow Server-->>Browser: Open Authorization URL Browser->>AS: Authorization Request AS-->>Browser: Authorization Code Browser-->>Server: Authorization Code Server->>AS: Exchange Code for Token AS-->>Server: Access Token Note over Server: MCP Request can now be completed Server->>RS: Request with access token RS-->>Server: Resource Response Server-->>Client: MCP Response SSEProposed Server-Side OAuth Flow With Interaction Request Response
sequenceDiagram participant Client as MCP Client participant Server as MCP Server participant AS as Authorization Server participant Browser as User Browser participant RS as Resource Server Client->>Server: MCP Request w/ HTTP Signature Server-->>Client: Interaction Request Response Note over Client, Browser: Client presents interaction to user Client->>Browser: Open Interaction URL Browser->>Server: Load interaction page Note over Server, Browser: OAuth 2.1 Authorization Flow Server-->>Browser: Redirect to Authorization Server Browser->>AS: Authorization Request AS-->>Browser: Authorization Code Browser-->>Server: Authorization Code with session binding Server->>AS: Exchange Code for Token AS-->>Server: Access Token Note over Server: Authorization complete, notify client Server->>Client: POST to completion endpoint (id=request_id) Note over Client: Client remakes original request Client->>Server: MCP Request w/ HTTP Signature (retry) Note over Server: Now authorized, can complete request Server->>RS: Request with access token RS-->>Server: Resource Response Server-->>Client: MCP ResponseSpecification
HTTP Message Signing Profile
For security and interoperability, we profile HTTP Message Signing specifying how the public key is exchanged, what the
keyidis, and which fields are included in the signature.Key Management
Clients generate a public/private key pair per MCP server using Ed25519:
{ "kty": "OKP", "crv": "Ed25519", "x": "base64url-encoded-public-key", "d": "base64url-encoded-private-key" }The
keyidis the JWK thumbprint per RFC 7638)The MCP Server uses the
keyidto identify the client instance.Client Initialization
The client includes the
public_keyand optionalcallback_urlin theclientInfoof theinitializerequest :{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { ... "clientInfo": { "public_key": { "kty": "OKP", "crv": "Ed25519", "x": "base64url-encoded-public-key", }, "interaction_completion_uri": "http://localhost:XXXX" } } }See Interaction Request for details on
interaction_completion_uriSignature
Required HTTP Headers:
Required Signed Fields
Every MCP request MUST include a signature over these fields:
@method- HTTP method@target-uri- Full request URIcontent-digest- SHA-256 of request body (if present)mcp-session-id- Session identifier (after initialization)created- Signature creation timestampReplay Protection
createdtimestampRequestIdvalues and reject non-unique valuesSignature Metadata Rules
createdis REQUIREDexpiresis NOT ALLOWED (validity defined by server policy)keyidMUST be the JWK thumbprintAlgorithm Requirements
alg="ed25519")Example Implementation
This approach provides backward compatibility and strong cryptographic guarantees while maintaining the simplicity and flexibility that makes MCP accessible to developers.
Interaction Request
An interaction can be requested by providing a SSE event if Content-Type is
text/event-streamor an error response if Content-Type isapplication/json. Atext/event-streamresponse is recommended as it allows the an interaction to be performed while a request is outstanding and a more seamless user experience.The interaction request has the following data:
typetype of interaction. Onlywebis currently definedurlURL to load on user gestureexplanationmessage to be presented to usertimeouthow long the URL is valid fortext/event-streamresponseapplication/jsonResponse{ "jsonrpc": "2.0", "id": "request_12345", "error": { "code": -32XXX, // predefined error "message": "User interaction required", "data": { "type": "web", "url": "https://mcp.example.com/oauth/authorize", "explanation": "Example requires authorization to complete this request", "timeout": 300 } } }If a
interaction_completion_uriwas provided in theinitializemessage, the server will load it with the query parameteridset to the value of the RequestID. The MCP Client can then retry its request.Rationale
Several cryptographic mechanisms could provide proof of possession for MCP client session binding. This section analyzes the trade-offs of each approach.
Mutual TLS (mTLS)
Description: Client presents a self signed certificate during TLS handshake.
Pros:
Cons:
Verdict: Wrong layer for an application
Signed JSON-RPC
Description: Client signs JSON-RPC message content using JWS or similar mechanisms.
Pros:
Cons:
Verdict: Too narrow in scope for complete session security.
HTTP Signatures (RFC 9421)
Description: Client signs HTTP requests using cryptographic signatures in HTTP headers.
Pros:
Cons:
Verdict: Optimal balance of security and implementability for MCP.
Based on the analysis above, we propose using HTTP Message Signatures (RFC 9421) as the proof of possession mechanism for MCP.
Backward Compatibility
This SEP introduces optional changes that do not break existing implementations:
clientInfoextensions are optional fieldsReference Implementation
None at this time.
Security Implications
Security Improvements
This SEP addresses several critical security concerns:
1. Dynamic Client Registration Vulnerabilities
Current Risk: DCR allows unauthenticated client registration, enabling potential phishing attacks.
Mitigation: Eliminates DCR requirement by moving OAuth to server-side.
2. Bearer Token Exposure
Current Risk: Access tokens stored on client devices can be exfiltrated.
Mitigation: Tokens managed server-side, only cryptographic proof of possession on client.
3. Untrusted Redirect URIs
Current Risk: localhost and custom URI schemes reduce client identification assurance.
Mitigation: Server manages redirects with HTTPS endpoints and proper validation.
4. Session Binding Weaknesses
Current Risk: Only bearer tokens provide session continuity.
Mitigation: Cryptographic session binding with replay protection.
New Security Considerations
1. HTTP Signature Security
Risks:
Mitigations:
2. Interaction Request Security
Risks:
Mitigations:
3. Server-Side Token Management
Risks:
Mitigations:
Threat Model Analysis
Threat: OAuth Client Impersonation / Phishing Attacks
Threat: Token Theft
Threat: Session Hijacking
Security Recommendations
For MCP Client implementations:
For MCP Server implementations: