Skip to content

Commit 9325779

Browse files
committed
Add mount_path support to FastMCP for proper SSE endpoint handling
This commit adds a mount_path attribute to FastMCP settings to support properly constructing SSE endpoints when servers are mounted under sub-paths. The _normalize_path helper method combines mount paths with endpoints to ensure correct session_uri generation. This fixes issues when running multiple FastMCP servers under different path prefixes in a single Starlette application.
1 parent babb477 commit 9325779

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/mcp/server/fastmcp/server.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class Settings(BaseSettings, Generic[LifespanResultT]):
7272
# HTTP settings
7373
host: str = "0.0.0.0"
7474
port: int = 8000
75+
mount_path: str = "/" # Mount path (e.g. "/github", defaults to root path)
7576
sse_path: str = "/sse"
7677
message_path: str = "/messages/"
7778

@@ -477,9 +478,37 @@ async def run_sse_async(self) -> None:
477478
server = uvicorn.Server(config)
478479
await server.serve()
479480

481+
def _normalize_path(self, mount_path: str, endpoint: str) -> str:
482+
"""
483+
Combine mount path and endpoint to return a normalized path.
484+
485+
Args:
486+
mount_path: The mount path (e.g. "/github" or "/")
487+
endpoint: The endpoint path (e.g. "/messages/")
488+
489+
Returns:
490+
Normalized path (e.g. "/github/messages/")
491+
"""
492+
# Special case: root path
493+
if mount_path == "/":
494+
return endpoint
495+
496+
# Remove trailing slash from mount path
497+
if mount_path.endswith("/"):
498+
mount_path = mount_path[:-1]
499+
500+
# Ensure endpoint starts with slash
501+
if not endpoint.startswith("/"):
502+
endpoint = "/" + endpoint
503+
504+
# Combine paths
505+
return mount_path + endpoint
506+
480507
def sse_app(self) -> Starlette:
481508
"""Return an instance of the SSE server app."""
482-
sse = SseServerTransport(self.settings.message_path)
509+
# Create normalized endpoint considering the mount path
510+
normalized_endpoint = self._normalize_path(self.settings.mount_path, self.settings.message_path)
511+
sse = SseServerTransport(normalized_endpoint)
483512

484513
async def handle_sse(request: Request) -> None:
485514
async with sse.connect_sse(

0 commit comments

Comments
 (0)