fix: add protected resource metadata + GET /token for Claude Desktop

Claude Desktop needs:
- /.well-known/oauth-protected-resource (RFC 9728)
- GET method on /token endpoint (sends params via query string)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mikkel Georgsen 2026-03-30 10:46:18 +00:00
parent 15e3582787
commit a21dd3ebbb
2 changed files with 22 additions and 6 deletions

View file

@ -24,6 +24,7 @@ logger = logging.getLogger("mcp_bridge")
# Paths that don't require auth
PUBLIC_PATHS = {
"/.well-known/oauth-authorization-server",
"/.well-known/oauth-protected-resource",
"/authorize",
"/token",
"/api/health",

View file

@ -132,12 +132,15 @@ async def token_endpoint(request: Request) -> JSONResponse:
- grant_type=client_credentials (direct)
"""
try:
content_type = request.headers.get("content-type", "")
if "application/json" in content_type:
data = await request.json()
if request.method == "GET":
data = dict(request.query_params)
else:
form = await request.form()
data = dict(form)
content_type = request.headers.get("content-type", "")
if "application/json" in content_type:
data = await request.json()
else:
form = await request.form()
data = dict(form)
except Exception:
return JSONResponse(
{"error": "invalid_request", "error_description": "Could not parse request body"},
@ -253,9 +256,21 @@ async def oauth_metadata(request: Request) -> JSONResponse:
})
async def protected_resource_metadata(request: Request) -> JSONResponse:
"""OAuth 2.0 Protected Resource Metadata (RFC 9728)."""
base = str(request.base_url).rstrip("/")
return JSONResponse({
"resource": base,
"authorization_servers": [base],
"scopes_supported": ["mcp"],
"bearer_methods_supported": ["header"],
})
# Routes to add to the app
auth_routes = [
Route("/.well-known/oauth-authorization-server", oauth_metadata, methods=["GET"]),
Route("/.well-known/oauth-protected-resource", protected_resource_metadata, methods=["GET"]),
Route("/authorize", authorize_endpoint, methods=["GET"]),
Route("/token", token_endpoint, methods=["POST"]),
Route("/token", token_endpoint, methods=["GET", "POST"]),
]