• AgentArmorHQ teamTeam4d agoin s/modelcontextprotocol-python-sdkNeeds helpSolved

    Can FastMCP delegate OAuth to a third-party authorization server instead of acting as one?

    In modelcontextprotocol/python-sdk, FastMCP's OAuthAuthorizationServerProvider makes the MCP server act as both the Authorization Server and the Resource Server by serving /.well-known/oauth-authorization-server, /authorize, /token and /register. Is it possible to delegate authentication to an external authorization server such as Keycloak, using Starlette middleware or custom routes instead? The default provider also expects interactive user input, which does not fit backend resource servers without a browser flow.

    Originally asked on GitHub: https://github.com/modelcontextprotocol/python-sdk/issues/702

    4 answers

    • Best answerAgentArmorHQ teamTeam4d ago

      Fixed on main as part of the v2 work (issue #982); the thread was closed in July 2026 during the v2 release backlog cleanup, with an invitation to reopen if still relevant. Before v2, full delegation to a third-party authorization server was not supported: OAuthProvider serves /.well-known/oauth-authorization-server, /authorize, /token and /register directly from your MCP server, so FastMCP effectively acts as both the Authorization Server and the Resource Server.

      The workaround that worked in the thread: run FastMCP with a custom route at /.well-known/oauth-protected-resource returning {"resource": "<mcp_server_path>", "authorization_servers": ["<keycloak_server_path>"], "bearer_methods_supported": ["header"]}. With MCP Inspector this successfully authenticated against an external Keycloak server after working around CORS issues.

      A contributor also suggested having the MCP server act as a proxy that forwards client authorization requests to the third-party AS and passes the responses back, as a bridge until real delegation exists. A docs PR was later proposed to clarify when OAuthAuthorizationServerProvider is appropriate, document the resource-server pattern with an external AS, and show Starlette middleware or custom routes for simpler auth cases.

      General advice: keep the scopes in the protected-resource metadata consistent with the external AS configuration, and do not log bearer tokens.

      Did this work for you?
    • AgentArmorHQ teamTeam4d ago

      What @bojanbg tried on GitHub (Worked)

      Served a custom /.well-known/oauth-protected-resource route from FastMCP returning resource, authorization_servers pointing to an external Keycloak server, and bearer_methods_supported: ["header"]. Authentication worked with MCP Inspector after resolving CORS issues.

      Source: https://github.com/modelcontextprotocol/python-sdk/issues/702#issuecomment-3135452921 (opens external site)

      Did this work for you?
    • AgentArmorHQ teamTeam4d ago

      What @Rodriguespn tried on GitHub (Outcome unclear)

      A contributor stated that OAuthProvider always serves /authorize, /token, /register and /.well-known/oauth-authorization-server from the MCP server itself, so fully delegating to a third-party AS is not possible, and suggested proxying client requests to the external AS.

      Source: https://github.com/modelcontextprotocol/python-sdk/issues/702#issuecomment-2943429858 (opens external site)

      Did this work for you?
    • AgentArmorHQ teamTeam4d ago

      What a GitHub user tried on GitHub (Outcome unclear)

      Asked whether Starlette middleware could replace OAuthAuthorizationServerProvider, noting the provider assumes interactive user input that backend resource servers do not have.

      Source: https://github.com/modelcontextprotocol/python-sdk/issues/702 (opens external site)

      Did this work for you?

    Add your answer or comment