Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sse_app() ignores mount prefix, resulting in 404 from client #412

Open
allieus opened this issue Apr 2, 2025 · 2 comments
Open

sse_app() ignores mount prefix, resulting in 404 from client #412

allieus opened this issue Apr 2, 2025 · 2 comments

Comments

@allieus
Copy link

allieus commented Apr 2, 2025

Describe the bug

When mounting sse_app() from FastMCP with a URL prefix using Starlette’s Mount, the SSE stream still returns the default /messages/ endpoint without the prefix. This causes the MCP client to resolve an incorrect URL (e.g., /messages/ instead of /mcp/messages/), resulting in a 404 error.

To Reproduce

Steps to reproduce the behavior:

  1. Define an MCP server as below:
from mcp.server.fastmcp import FastMCP
from starlette.applications import Starlette
from starlette.routing import Mount

mcp = FastMCP(
    # sse_path="/sse",  # default
    # message_path="/messages/",  # default
)


application = Starlette(
    routes=[
        Mount("/mcp", app=mcp.sse_app()),  # HERE !!!
    ]
)
  1. Start the server and navigate to http://127.0.0.1:8000/mcp/sse in your browser
  2. Observe the response in the browser. You will receive an SSE event like:
event: endpoint
data: /messages/?session_id=...

At this point, the MCP client performs a urljoin operation between the SSE URL (http://127.0.0.1:8000/mcp/sse) and the endpoint path (/messages/). This causes the resolved endpoint URL to become http://127.0.0.1:8000/messages/.

  1. The client tries to connect to http://127.0.0.1:8000/messages/, which results in a 404.

Expected behavior

The SSE stream should return the correct full path reflecting the prefix, e.g.:

data: /mcp/messages/?session_id=...

This would allow the client to connect to the actual valid message endpoint.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: macOS
  • Browser : Arc
  • Version : 1.87.1 (60573)

Smartphone (please complete the following information):

  • Device: N/A
  • OS: N/A
  • Browser : N/A
  • Version : N/A

Additional context

This behavior seems to originate from hardcoded endpoint generation inside sse_app():

session_uri = f"{quote(self._endpoint)}?session_id={session_id.hex}"

It would be great to have support for specifying a prefix in sse_app() or for the prefix to be auto-detected from the ASGI scope.

Thank you!

@JorgeRuizITCL
Copy link

This might be related with #386

@richardhundt
Copy link

This might be related with #386

The clients shouldn't be patching the endpoints. The server should just give it the right endpoint during the handshake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants