Description
Issue Description
When using RemoteAuthProvider with FastMCP, the OAuth protected resource metadata endpoint (/.well-known/oauth-protected-resource) always returns the base server URL as the resource field, rather than the actual MCP endpoint URL (/mcp/). This causes OAuth clients (like Claude Desktop) to attempt authentication and subsequent MCP requests to the wrong endpoint, resulting in 404 errors.
Expected Behavior
The OAuth discovery endpoint should return the MCP endpoint URL in the resource field so that OAuth clients know where to send authenticated MCP requests.
Expected Response:
{
"resource": "https://my-server.com/mcp/",
"authorization_servers": ["https://accounts.google.com"],
"scopes_supported": [],
"bearer_methods_supported": ["header"]
}
Actual Behavior
The OAuth discovery endpoint always returns the base server URL, regardless of the resource_server_url parameter.
Actual Response:
{
"resource": "https://my-server.com/",
"authorization_servers": ["https://accounts.google.com"],
"scopes_supported": [],
"bearer_methods_supported": ["header"]
}
Reproduction Steps
- Create a FastMCP server with
RemoteAuthProvider:
from fastmcp import FastMCP
from fastmcp.server.auth import RemoteAuthProvider
from fastmcp.server.auth.providers.jwt import JWTVerifier
from pydantic import AnyHttpUrl
import os
# Configure token verification
token_verifier = JWTVerifier(
jwks_uri="https://www.googleapis.com/oauth2/v3/certs",
issuer="https://accounts.google.com",
audience="your-google-client-id"
)
# Create RemoteAuthProvider with full MCP endpoint URL
auth = RemoteAuthProvider(
token_verifier=token_verifier,
authorization_servers=[AnyHttpUrl("https://accounts.google.com")],
resource_server_url="https://my-server.com/mcp/" # Note: includes /mcp/ path
)
mcp = FastMCP(name="Test Server", auth=auth)
@mcp.tool
def test_tool() -> str:
return "Hello"
if __name__ == "__main__":
mcp.run()
- Deploy the server and test the OAuth discovery endpoint:
curl https://my-server.com/.well-known/oauth-protected-resource
- Observe that the
resource field points to https://my-server.com/ instead of https://my-server.com/mcp/
Environment
- FastMCP Version: 2.11.1
- Python Version: 3.11
- Deployment: Google Cloud Run (HTTP transport)
- OAuth Provider: Google OAuth
Impact
This prevents OAuth-enabled MCP servers from working with OAuth clients like Claude Desktop, as the clients receive incorrect endpoint information during discovery and subsequently make requests to the wrong URL.
Workaround Attempts
I tried several approaches to override the OAuth discovery endpoint, but none were successful:
- Custom subclass with
customize_auth_routes:
class CustomRemoteAuthProvider(RemoteAuthProvider):
def customize_auth_routes(self, app):
super().customize_auth_routes(app)
@app.get("/.well-known/oauth-protected-resource")
async def custom_protected_resource_metadata():
return {
"resource": "https://my-server.com/mcp/",
"authorization_servers": ["https://accounts.google.com"],
"scopes_supported": [],
"bearer_methods_supported": ["header"]
}
- Direct FastAPI route override:
@mcp.http_app().get("/.well-known/oauth-protected-resource") # This fails
async def custom_oauth_protected_resource():
return {"resource": "https://my-server.com/mcp/", ...}
Both approaches either failed to execute or were ignored by the existing route.
Proposed Solutions
-
Fix the resource_server_url parameter: Make RemoteAuthProvider respect the full URL path provided in resource_server_url, including /mcp/ or other paths.
-
Add configuration option: Provide a separate parameter like mcp_endpoint_url to explicitly specify the MCP endpoint URL for OAuth discovery.
-
Provide override method: Add a documented way to override the OAuth discovery endpoints, such as a working customize_auth_routes method or similar.
Additional Context
According to the [MCP OAuth specification](https://spec.modelcontextprotocol.io/specification/server/authentication/#oauth-20-authentication), the resource field in the protected resource metadata should point to the actual protected resource (the MCP endpoint), not just the server's base URL.
The server logs show that FastMCP correctly serves the MCP endpoint at /mcp/, but the OAuth discovery points clients to /, causing a mismatch:
INFO: Starting MCP server on http://0.0.0.0:8080/mcp/
...
WARNING: GET / HTTP/1.1" 404 Not Found # OAuth client trying wrong endpoint
INFO: GET /.well-known/oauth-protected-resource HTTP/1.1" 200 OK # Discovery works
Example Code
Version Information
FastMCP version: 2.11.1.dev4+ec52e74
MCP version: 1.12.3
Python version: 3.10.17
Platform: macOS-15.5-arm64-arm-64bit
FastMCP root path: /Users/nickyoungblut/dev/python/arc-example-mcp/.venv/lib/python3.10/site-packages
Additional Context
No response
Description
Issue Description
When using
RemoteAuthProviderwith FastMCP, the OAuth protected resource metadata endpoint (/.well-known/oauth-protected-resource) always returns the base server URL as theresourcefield, rather than the actual MCP endpoint URL (/mcp/). This causes OAuth clients (like Claude Desktop) to attempt authentication and subsequent MCP requests to the wrong endpoint, resulting in 404 errors.Expected Behavior
The OAuth discovery endpoint should return the MCP endpoint URL in the
resourcefield so that OAuth clients know where to send authenticated MCP requests.Expected Response:
{ "resource": "https://my-server.com/mcp/", "authorization_servers": ["https://accounts.google.com"], "scopes_supported": [], "bearer_methods_supported": ["header"] }Actual Behavior
The OAuth discovery endpoint always returns the base server URL, regardless of the
resource_server_urlparameter.Actual Response:
{ "resource": "https://my-server.com/", "authorization_servers": ["https://accounts.google.com"], "scopes_supported": [], "bearer_methods_supported": ["header"] }Reproduction Steps
RemoteAuthProvider:resourcefield points tohttps://my-server.com/instead ofhttps://my-server.com/mcp/Environment
Impact
This prevents OAuth-enabled MCP servers from working with OAuth clients like Claude Desktop, as the clients receive incorrect endpoint information during discovery and subsequently make requests to the wrong URL.
Workaround Attempts
I tried several approaches to override the OAuth discovery endpoint, but none were successful:
customize_auth_routes:Both approaches either failed to execute or were ignored by the existing route.
Proposed Solutions
Fix the
resource_server_urlparameter: MakeRemoteAuthProviderrespect the full URL path provided inresource_server_url, including/mcp/or other paths.Add configuration option: Provide a separate parameter like
mcp_endpoint_urlto explicitly specify the MCP endpoint URL for OAuth discovery.Provide override method: Add a documented way to override the OAuth discovery endpoints, such as a working
customize_auth_routesmethod or similar.Additional Context
According to the [MCP OAuth specification](https://spec.modelcontextprotocol.io/specification/server/authentication/#oauth-20-authentication), the
resourcefield in the protected resource metadata should point to the actual protected resource (the MCP endpoint), not just the server's base URL.The server logs show that FastMCP correctly serves the MCP endpoint at
/mcp/, but the OAuth discovery points clients to/, causing a mismatch:Example Code
Version Information
Additional Context
No response