-
Notifications
You must be signed in to change notification settings - Fork 850
Open
Description
Expected Behavior
A resource server implementator should be able to, in a single authentication flow:
- Validate sender-constrained tokens such as DPoP (RFC 9449), which require the HTTP method and request URL in addition to headers
- Return proper HTTP 401/403 responses with WWW-Authenticate challenges (RFC 6750 §3) when validation fails
- Pass verified claims into the McpTransportContext for use by tool handlers
- Perform expensive operations like token introspection (RFC 7662) exactly once per request
Current Behavior
The transport security model splits authentication into two hooks, each covering part of what we find is needed for a complete OAuth 2.1 flow:
┌─────────────────────────────┬─────────────────┬─────────┐
│ Capability │ validateHeaders │ extract │
├─────────────────────────────┼─────────────────┼─────────┤
│ HTTP method & URL │ No │ Yes │
├─────────────────────────────┼─────────────────┼─────────┤
│ Can return 401/403 │ Yes │ No │
├─────────────────────────────┼─────────────────┼─────────┤
│ Can store claims in context │ No │ Yes │
└─────────────────────────────┴─────────────────┴─────────┘
@FunctionalInterface
public interface ServerTransportSecurityValidator {
void validateHeaders(Map<String, List<String>> headers)
throws ServerTransportSecurityException;
}
public interface McpTransportContextExtractor<T> {
McpTransportContext extract(T request);
}
It seems these capabilities are all needed together but currently live in separate hooks:
- validateHeaders doesn't have access to HTTP method and URL — DPoP proof validation (RFC 9449 §4.3) requires htm (method) and htu (URL), so we can't fully validate DPoP-bound tokens at this stage.
- extract doesn't have a way to signal authentication errors — When we need to defer validation to extract (because validateHeaders lacked sufficient context), authentication failures end up surfacing as 500s or unstructured exceptions rather than proper 401/403
responses. - Validated claims can't flow from validation to context — validateHeaders returns void, so even after successful validation there's no way to pass the resulting claims into the McpTransportContext without external coordination.
Context
We are integrating OAuth 2.1in our MCP servers with JWT validation, token introspection, and DPoP sender-constraining. With the current interface design, we've had to resort to workarounds like ThreadLocal caching between the two hooks, or accepting duplicate verification and introspection calls per request. These work, but feel like they could be improved at the framework level.
References:
- RFC 9449 — DPoP
- RFC 6750 — Bearer Token Usage
- RFC 7662 — Token Introspection
- MCP SDK version: 1.0.0 (io.modelcontextprotocol.sdk:mcp-core)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels