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
MCP OAuth Stage 2: well-known PRM, AS metadata, JWKS endpoints
Sub-issue of #86. Adds the three discovery documents under /.well-known/* that MCP clients fetch to find the authorization server and the public keys for verifying tokens.
Context
PR #89 (Stage 1) shipped the RFC 7591 Dynamic Client Registration endpoint. This stage adds the documents that MCP clients consume to discover that endpoint and the rest of the OAuth surface. Without these, a client that hits the protected resource and receives a 401 + WWW-Authenticate: Bearer resource_metadata="..." (issued by Stage 5's withMCPAuth) has nowhere to follow up.
What this adds
/.well-known/oauth-protected-resource — RFC 9728 Protected Resource Metadata. The discovery entry point. Advertises the canonical resource URI and the authorization server.
/.well-known/oauth-authorization-server — RFC 8414 Authorization Server Metadata. Advertises authorize / token / register / JWKS endpoints, supported algorithms and methods, and RFC 8707 resource parameter support.
/.well-known/jwks.json — placeholder returning an empty key set until Stage 4 generates and persists signing keys in harper_oauth_mcp_keys.
New MCP config fieldsmcp.issuer and mcp.resource — derived from the request when unset, configurable for production deployments behind proxies or with pinned identity requirements.
CORS headers on all three documents so browser-based MCP clients and discovery tools can fetch cross-origin.
Mounting via server.http(handler, { urlPath }) — well-known paths don't fit the existing Resource API mounted at /oauth/*, so they use Harper's middleware mechanism directly. Config read via getter at request time so live config changes apply without re-registering routes.
Spec requirements
RFC 9728 (MUST): PRM document at /.well-known/oauth-protected-resource with resource + authorization_servers fields
RFC 8414 (MUST): AS metadata at /.well-known/oauth-authorization-server; issuer field required, must match request origin
MCP OAuth Stage 2: well-known PRM, AS metadata, JWKS endpoints
Sub-issue of #86. Adds the three discovery documents under
/.well-known/*that MCP clients fetch to find the authorization server and the public keys for verifying tokens.Context
PR #89 (Stage 1) shipped the RFC 7591 Dynamic Client Registration endpoint. This stage adds the documents that MCP clients consume to discover that endpoint and the rest of the OAuth surface. Without these, a client that hits the protected resource and receives a
401 + WWW-Authenticate: Bearer resource_metadata="..."(issued by Stage 5'swithMCPAuth) has nowhere to follow up.What this adds
/.well-known/oauth-protected-resource— RFC 9728 Protected Resource Metadata. The discovery entry point. Advertises the canonical resource URI and the authorization server./.well-known/oauth-authorization-server— RFC 8414 Authorization Server Metadata. Advertises authorize / token / register / JWKS endpoints, supported algorithms and methods, and RFC 8707resourceparameter support./.well-known/jwks.json— placeholder returning an empty key set until Stage 4 generates and persists signing keys inharper_oauth_mcp_keys.mcp.issuerandmcp.resource— derived from the request when unset, configurable for production deployments behind proxies or with pinned identity requirements.server.http(handler, { urlPath })— well-known paths don't fit the existing Resource API mounted at/oauth/*, so they use Harper's middleware mechanism directly. Config read via getter at request time so live config changes apply without re-registering routes.Spec requirements
/.well-known/oauth-protected-resourcewithresource+authorization_serversfields/.well-known/oauth-authorization-server;issuerfield required, must match request origincode_challenge_methods_supported: ["S256"],resource_parameter_supported: true(RFC 8707)Acceptance
/.well-known/oauth-protected-resourceserves spec-compliant JSON withresourceandauthorization_servers/.well-known/oauth-authorization-serverserves spec-compliant JSON includingregistration_endpoint,code_challenge_methods_supported: ["S256"],jwks_uri,id_token_signing_alg_values_supported: ["RS256", "EdDSA"],resource_parameter_supported: true/.well-known/jwks.jsonserves{"keys": []}placeholder; Stage 4 populatesAccess-Control-Allow-Origin: *andAccess-Control-Allow-Methods: GET, OPTIONSmcp.issuerandmcp.resourceconfig fields exist; defaults derive from request origindocs/configuration.mdincluding Host-header security caveat for issuer derivationAll acceptance items shipped in PR #90.
Dependencies
mcpconfig block infrastructurewithMCPAuthreturns 401 +WWW-Authenticatepointing at this PRM)Out of scope
🤖 Generated with Claude Code