Repository navigation
Protected Resource Metadata resource erroneous when setting up authentication on server #1264
Description
Activity
- addedneeds confirmationNeeds confirmation that the PR is actually required or needed.Needs confirmation that the PR is actually required or needed.
on Aug 12, 2025 I ran into the same problem. The workaround I'm using is to define my own well known endpoint and replace the generated one. Not ideal, but I think this is the simplest and least intrusive workaround until the problem is fixed.
async def custom_well_known_endpoint(request): """ Custom .well-known/oauth-protected-resource endpoint that correctly advertises the SSE endpoint as the protected resource while serving the .well-known endpoint at the root. """ return JSONResponse({ "resource": f"{config.EXTERNAL_ADDRESS}/sse", "authorization_servers": [ f"https://login.microsoftonline.com/{config.TENANT_ID}/v2.0" ], "scopes_supported": [ "my_scope" ], "bearer_methods_supported": ["header"] })And then add it to the routes
# Override the built-in .well-known endpoint by inserting our route at the beginning app.router.routes.insert(0, Route("/.well-known/oauth-protected-resource", custom_well_known_endpoint, methods=["GET"]))Reacted by Carlos Espinaco MartínezHi @carlosemart same issue here
I think the issue is in this code:
python-sdk/src/mcp/server/fastmcp/server.py
Lines 934 to 938 in 47d35f0
protected_resource_metadata = ProtectedResourceMetadata( resource=self.settings.auth.resource_server_url, authorization_servers=[self.settings.auth.issuer_url], scopes_supported=self.settings.auth.required_scopes, ) We could fix with:
protected_resource_metadata = ProtectedResourceMetadata( resource=AnyHttpUrl(str(self.settings.auth.resource_server_url)+"mcp"), authorization_servers=[self.settings.auth.issuer_url], scopes_supported=self.settings.auth.required_scopes, )
My workarround is define a child class of FastMCP:
- I remove ".well-known" Route generated by the lib,
- and then I add a new one with the fixed resource value
class FixFastMCP(FastMCP): async def run_streamable_http_async(self) -> None: """Run the server using StreamableHTTP transport.""" import uvicorn starlette_app = self.streamable_http_app() config = uvicorn.Config( starlette_app, host=self.settings.host, port=self.settings.port, log_level=self.settings.log_level.lower(), ) # Remove existing Protected Resource Metadata endpoint (resource="http://localhost:8000/") starlette_app.router.routes = list(filter(lambda r: r.path != "/.well-known/oauth-protected-resource", starlette_app.router.routes)) # Add OAuth 2.0 Protected Resource Metadata endpoint as per RFC 9728 (resource="http://localhost:8000/mcp") from mcp.server.auth.handlers.metadata import ProtectedResourceMetadataHandler from mcp.server.auth.routes import cors_middleware from mcp.shared.auth import ProtectedResourceMetadata from starlette.routing import Route protected_resource_metadata = ProtectedResourceMetadata( resource=AnyHttpUrl(str(self.settings.auth.resource_server_url)+"mcp"), # Real fix authorization_servers=[self.settings.auth.issuer_url], scopes_supported=self.settings.auth.required_scopes, ) starlette_app.router.routes.append( Route( "/.well-known/oauth-protected-resource", endpoint=cors_middleware( ProtectedResourceMetadataHandler(protected_resource_metadata).handle, ["GET", "OPTIONS"], ), methods=["GET", "OPTIONS"], ) ) # Now run server server = uvicorn.Server(config) await server.serve()
I got VSCODE to work
- addedbugSomething isn't workingSomething isn't workingauthIssues and PRs related to Authentication / OAuthIssues and PRs related to Authentication / OAuthand removedneeds confirmationNeeds confirmation that the PR is actually required or needed.Needs confirmation that the PR is actually required or needed.
on Sep 19, 2025 - addedready for workEnough information for someone to start working onEnough information for someone to start working on
on Oct 6, 2025 francisco-perez-sorrosal commented
on Oct 28, 2025 More actionsI had the same problem; I applied the same FastMCP-wrapper, implementing the routing workaround as @JoseIbanez / @seanhoughton and also got my authentication code working.
I'd like to work on this. The
resourcefield in Protected Resource Metadata was set to the baseresource_server_urlwithout the transport path—appending the path (e.g.,/mcpor/sse) fixes the RFC 9728 validation mismatch.PR: #2189
- addedP2Moderate issues affecting some users, edge cases, potentially valuable featureModerate issues affecting some users, edge cases, potentially valuable feature
on Mar 5, 2026 I would like to take the docs/example follow-up described in the review of #2189.
I verified on current
mainthat:examples/snippets/servers/oauth_server.pystill configuresresource_server_urlwithout/mcp.AuthSettings.resource_server_urldoes not say that it must be the complete public MCP resource URL, including the transport path.- the simple-auth example accepts
--transport=ssewhile its default resource URL is fixed to/mcp.
I will not append an internal Starlette route in library code; that would break mounted apps and reverse proxies. The proposed PR will update the examples and API documentation so the configured resource identifier matches the public endpoint for the selected transport, with focused tests for the example configuration.
If that scope is still wanted, please assign this issue to me.
AI assistance disclosure: I used Codex to inspect current
main, the closed #2189 review, and the affected examples. I verified the file locations and proposed scope in the local checkout.+1 — this is the classic Inspector-green / real-client-red seam: PRM
resourcevs endpoint path mismatch (and trailing-slash identity) passes loose checks then fails strict RFC 9728 clients.We've been cataloguing those OAuth/PRM/needs-auth client gaps as a Compat Blind Spot Scorecard: https://compatlab-waitlist.vercel.app — permission-only. Happy to share other client-specific failure shapes back here if useful.
Initial Checks
Description
I am getting the following error when I try to enable MCP server authentication and configure it in VSCODE copilot:
Error Error sending message to http://localhost:8000/mcp: Error: Protected Resource Metadata resource "http://localhost:8000/" does not match MCP server resolved resource "http://localhost:8000/mcp". The MCP server must follow OAuth spec https://datatracker.ietf.org/doc/html/rfc9728#PRConfigurationValidationFrom what I have seen, the error is caused because the metada that is returned in the endpoint "/.well-known/oauth-protected-resource" in the resource field does not match the url of the MCP server to be configured to use copilot and what is specified in the definition if they should match. You can see here https://datatracker.ietf.org/doc/html/rfc9728#PRConfigurationValidation
I have made a small snippet of code available here https://github.com/carlosemart/python-mcp-oauth-example in which you can see that the well-know answer is:
{ "resource": "http://localhost:8000/", "authorization_servers": [ "https://auth.example.com/" ], "scopes_supported": [ "user" ], "bearer_methods_supported": [ "header" ] }and in the resource field you should see "http://localhost:8000/mcp" which is the url that is configured in VSCODE.
Example Code
Python & MCP Python SDK