fix: prefix auth routes with issuer_url base path for gateway deployments
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().
# issuer_url = "https://example.com/custom/path"
# Before: routes at /authorize, /token, etc. (unreachable behind gateway)
# After: routes at /custom/path/authorize, /custom/path/token, etc.
Backward compatible: when issuer_url has no path (or just /), issuer_path is empty and routes stay at root.
Changes
src/mcp/server/auth/routes.py: Extractissuer_pathfromissuer_urland prefix all route pathstests/server/auth/test_routes.py: Add 3 tests for default paths, custom base path, and trailing slash handling
Test plan
- All 12
test_routes.pytests pass (9 existing + 3 new) - All 4
test_error_handling.pytests pass (no regression) - All 42
test_auth_integration.pytests pass (no regression) - Ruff format + lint clean