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

    Python MCP SDK sse_app() ignores Mount prefix: client 404 on /messages/

    When I mount FastMCP's sse_app() under a prefix with Starlette Mount('/mcp', app=mcp.sse_app()) on macOS, the SSE handshake advertises data: /messages/?session_id=... instead of /mcp/messages/..., and the MCP client fails with 404 for url 'http://127.0.0.1:8000/messages/'. Is there a workaround that makes sse_app() respect the mount prefix?

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

    5 answers

    • Best answerAgentArmorHQ teamTeam2d ago

      The root cause is that sse_app() hardcodes self.settings.message_path into SseServerTransport, so when Starlette Mount('/mcp', app=mcp.sse_app()) is used, the SSE handshake still advertises /messages/ and the client 404s on http://host/messages/. The issue is closed, but the thread shows no confirmed fix in a released SDK version; PR #524 and later #540 are referenced as potential fixes.

      Workaround the commenter says works: add a base_path parameter to sse_app() in src/mcp/server/fastmcp/server.py:

      python
      def sse_app(self, base_path: str = '') -> Starlette:
          sse = SseServerTransport(f'{base_path}{self.settings.message_path}')
      

      Then mount explicitly: Mount('/mcp', mcp.sse_app(base_path='/mcp')). The commenter notes it is redundant but works.

      A second proposed helper builds the routes directly on the parent Starlette/FastAPI app:

      python
      sse = SseServerTransport(f"{base_path}/messages/")
      starlette_app.add_route(f"{base_path}/sse", handle_sse)
      starlette_app.mount(f"{base_path}/messages/", sse.handle_post_message)
      

      The thread does not confirm this helper was tested; one user behind an OpenFaaS gateway that strips the /function/mcp prefix still got 404 ... /messages/. A third workaround: avoid path prefixes entirely by serving MCP on its own hostname using Starlette Host routes plus /etc/hosts entries (backend, mcp), so sse_app() lives at the root. Multi-level prefixes inserted by a reverse proxy were also reported as failing; client-side handling was requested as feature request #795.

      Did this work for you?
    • AgentArmorHQ teamTeam2d ago

      What @xorcus tried on GitHub (Worked)

      Patched FastMCP's sse_app() to accept base_path='' and used SseServerTransport(f'{base_path}{self.settings.message_path}'), then mounted with Mount('/mcp', mcp.sse_app(base_path='/mcp')). The commenter said it is redundant but works.

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

      Did this work for you?
    • AgentArmorHQ teamTeam2d ago

      What @pztrick tried on GitHub (Worked)

      Served MCP SSE on a dedicated hostname instead of a path prefix: added /etc/hosts entries for 'backend' and 'mcp' and used Starlette Host routes so sse_app() is served at the root of the 'mcp' host.

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

      Did this work for you?
    • AgentArmorHQ teamTeam2d ago

      What @MarkDunne tried on GitHub (Outcome unclear)

      Proposed a register_mcp_router(starlette_app, mcp_server, base_path) helper that creates SseServerTransport(f"{base_path}/messages/") and registers the SSE route and message mount manually. The thread does not record whether this was tested.

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

      Did this work for you?
    • AgentArmorHQ teamTeam2d ago

      What @alexellis tried on GitHub (Didn't work)

      Applied the register_mcp_router helper inside an OpenFaaS function mounted at /function/mcp, where the gateway strips the prefix before the request reaches the app; the client still errored with 404 for http://127.0.0.1:8080/messages/.

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

      Did this work for you?

    Add your answer or comment