| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
Friendly ping — happy to address any feedback or make changes if needed. Let me know if there's anything blocking review. |
Sorry, something went wrong.
|
.well-known is only compliant at domain root, see https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#protected-resource-metadata-discovery-requirements and https://datatracker.ietf.org/doc/html/rfc8615#section-3 :
This prefixing also competes with Mounting the app under a prefix, like in https://gofastmcp.com/deployment/http#mounting-strategy ? Which is why FastMCP has get_well_known_routes to extract those routes before Mounting, while patching up .well-known at https://github.com/PrefectHQ/fastmcp/blob/53b20168c892b05b86ea8bf576a33b95936dda26/fastmcp_slim/fastmcp/server/auth/auth.py#L831-L872. Prefixing the rest of the endpoints makes sense, but afaict FastMCP has hardcoded references to /authorize, /token, etc which may break. For trusted reverse proxying we could get the scheme and host via X-Forwarded-*, and even the dynamic base path via X-Forwarded-Prefix. It would be nice if someone took a long hard look at all the various pieces in play here, like proxy forwarding headers and path stripping, FastMCP path (which annoyingly cannot be "", which means you can't avoid the last / with Mount), uvicorn --root-path, Starlette Mount, etc. and avoid overrides and hardcoding. I get the feeling that a lot of this belongs in middleware and not in route construction. E.g. if the routes were named, they could be referenced and resolved by handlers during runtime when they need to be injected into the response with request.url_for(...), which would make them respect namespacing and rewriting middleware. Just my 2c |
Sorry, something went wrong.
|
Good catch, thanks — and you're right that this needed a real fix, not just a caveat. Pushed a3918ebe: the .well-known/oauth-authorization-server route now inserts the well-known suffix between the authority and the issuer's path, per RFC 8414 §3.1 (https://example.com/.well-known/oauth-authorization-server/custom/path), instead of appending it after the path. The old placement (/custom/path/.well-known/...) isn't a valid well-known URI under RFC 8615 §3, exactly as you flagged. The /authorize, /token, /register, /revoke routes are unaffected by this correction — they're plain URLs registered under the issuer's own path, not well-known URIs, so RFC 8615's root-only constraint doesn't apply to them. On the broader Mount/forwarded-headers point: agreed that's a real and larger design question (how this interacts with Starlette Mount, X-Forwarded-Prefix, and hardcoded FastMCP paths), but it's bigger than this PR's scope — this fix is narrowly about not violating RFC 8615 in the route construction itself. Happy to see a follow-up issue for the mounting/proxying story if that'd be useful. |
Sorry, something went wrong.
When an MCP server is deployed behind a gateway with a custom base path (e.g., /custom/path), the OAuth auth routes (.well-known, /authorize, /token, /register, /revoke) were hardcoded at root, making them unreachable through the gateway. Extract the path component from issuer_url and prefix it to all auth route registrations. This matches the metadata URLs already built by build_metadata(), which correctly use issuer_url + path. Backward compatible: when issuer_url has no path, routes stay at root. Github-Issue: modelcontextprotocol#1335 Reported-by: whitewg77
The .well-known/oauth-authorization-server route was prefixed with the issuer's base path *after* the well-known suffix (e.g. /custom/path/.well-known/oauth-authorization-server), which RFC 8615 3 does not recognize as a well-known URI. RFC 8414 3.1 requires the suffix to be inserted between the authority and the path component instead: /.well-known/oauth-authorization-server/custom/path. The /authorize, /token, /register, /revoke routes are unaffected - they're plain URLs under the issuer's namespace, not well-known URIs.
| Back | FazBrowse Home | New Git URL |
Summary
Fixes #1335 — When an MCP server is deployed behind a gateway with a custom base path (e.g., https://gateway/custom/path/mcp), the OAuth auth routes (.well-known, /authorize, /token, /register, /revoke) are hardcoded at root, making them unreachable through the gateway.
Root cause: create_auth_routes() registers routes at fixed root paths (/.well-known/oauth-authorization-server, /authorize, etc.) regardless of the issuer_url path. Meanwhile, build_metadata() correctly builds metadata URLs using issuer_url + path, creating a mismatch.
Fix: Extract the path component from issuer_url and prefix it to all auth route registrations. This aligns the actual route paths with the metadata URLs already built by build_metadata().
Backward compatible: when issuer_url has no path (or just /), issuer_path is empty and routes stay at root.
Changes
Test plan