anthropics / anthropics/claude-ai-mcp
AWS API Gateway silently renames WWW-Authenticate header, breaking MCP OAuth resource-metadata discovery
- Lenguaje dominante
- Sin datos de lenguaje
- Estrellas
- 471
- Forks
- 76
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Descripción
### MCP server URL
(AWS API Gateway + Lambda, private — happy to share a reproduction endpoint privately if useful)
### Where does the issue occur?
When pressing the Connect button
### Transport used
streamable-http
### Client registration type
Dynamic (Cognito-backed OAuth 2.1: PKCE S256, RFC 8414 Authorization Server Metadata, RFC 9728 Protected Resource Metadata all served correctly)
### Describe the issue
Our 401 response includes a `WWW-Authenticate: Bearer realm="...", resource_metadata="https://.../.well-known/oauth-protected-resource"` header. We confirmed by direct `curl` that this URL serves valid RFC 9728 metadata pointing at an authorization server metadata document that itself resolves correctly. We also confirmed, by hand-navigating the exact `authorize` URL Claude's connector generated (same client_id, code_challenge, redirect_uri), that it lands cleanly on our IdP's real sign-in page — so whatever a correctly-discovering client would have been sent to does work.
Root cause found: our server sits behind AWS API Gateway (Lambda proxy integration). We confirmed via `curl -i` directly against the API Gateway endpoint that AWS silently renames the `WWW-Authenticate` response header to `x-amzn-remapped-www-authenticate` on the way out. We reproduced this on both a REST API and an HTTP API v2 integration, and on a plain Lambda Function URL, and found no proxy-integration setting that overrides it.
Since the MCP spec treats `WWW-Authenticate` on the initial 401 as the trigger for protected-resource-metadata discovery, and observed behavior matches a client that never saw that header, Claude appears to fall back to treating our server's own origin as the authorization server and redirects the user to `/authorize?...`, which doesn't exist on our side, producing a 403/"Forbidden" from AWS's own edge layer.
We worked around it by putting a CloudFront Function in front of API Gateway to restore the header on the way out, and confirmed via `curl -i` through CloudFront that the header arrives correctly again — that's a lot of infrastructure for something that's arguably a client resilience gap, not just a server bug on our end.
### Expected behavior
RFC 9728 §5.3 explicitly documents that a client MAY fall back to fetching `/.well-known/oauth-protected-resource` directly at the resource's origin if the `WWW-Authenticate` challenge is unavailable or doesn't carry `resource_metadata`. Since AWS API Gateway (an extremely common way to host a serverless MCP server) mangles this header in a way that's outside a server developer's control, it would make the Claude MCP client meaningfully more resilient if it attempted this fallback discovery path when the header-based discovery fails or comes back malformed, rather than immediately assuming the resource's own origin is the authorization server.
### Additional context
This looks related to the same general "OAuth discovery goes to the wrong place" failure family as #406 and #644, though the root cause here (AWS API Gateway header remapping) is distinct and, as far as I can tell, not documented anywhere in MCP or Claude connector docs. Flagging in case it saves someone else the debugging loop it cost us — API Gateway + Lambda is a very common MCP hosting pattern.
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
Evaluación
Este issue todavía no se ha evaluado.