Skip to content

[Fix] SSE client to support MCP server mounted under a base path on a different ASGI server #524

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

Conversation

rkondra-eightfold
Copy link

@rkondra-eightfold rkondra-eightfold commented Apr 15, 2025

What does this PR do?

  • Fixes incorrect resolution of the /messages endpoint URL in the SSE client when the FastAPI app is mounted under a base path (e.g., /mcp).
  • You can now provide a server_mount_path to ensure correct endpoint resolution.

Motivation and Context

Problem

# Create a FastAPI app
app = FastAPI()
# Create an MCP server and link it to the FastAPI app
server = FastMCP('test_app')
# Mount the server's SSE API on /mcp
app.mount('/mcp', server.sse_app())
  • The server sends a relative endpoint like /messages?session_id=...,
  • the client resolves it using urljoin(base_url, relative_path)
  • When the app is mounted (e.g., /mcp/sse), this strips the subpath and constructs an invalid endpoint (e.g., http://host/messages?session_id=... instead of http://host/mcp/messages?session_id=...).

Fix

This PR:

  • Extracts the origin and mounted path prefix from the SSE base URL
  • Correctly reassembles the endpoint URL using that prefix
        async with sse_client(base_url, server_mount_path='/mcp') as (read, write):
            async with ClientSession(read, write) as session:
                await session.initialize()  # Initialize the session
                print('✅ Connection established!')

How Has This Been Tested?

server:

from fastapi import FastAPI
from models import User
from mcp.server.fastmcp import FastMCP

# Create a FastAPI app
app = FastAPI()

# Create an MCP server and link it to the FastAPI app
server = FastMCP('test_app')

# Mount the server's SSE API on /mcp
app.mount('/mcp', server.sse_app())

# Start the server when this file is run directly
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

client:

import asyncio
from mcp import ClientSession
from mcp.client.sse import sse_client

async def run():
    base_url = 'http://0.0.0.0:8000/mcp/sse'  # Make sure the URL is correct for the SSE connection
    print(f'🔗 Connecting to SSE MCP server at {base_url}...')

    try:
        async with sse_client(base_url, server_mount_path='/mcp') as (read, write):
            async with ClientSession(read, write) as session:
                await session.initialize()  # Initialize the session
                print('✅ Connection established!')
    except Exception as e:
        print(f'[ERROR] Connection to SSE server failed: {e}')


# Run the test
if __name__ == '__main__':
    print('🚀 Running MCP SSE client tests...\n')
    asyncio.run(run())

This test should pass now.

Breaking Changes

None identified, backward compatible

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

NA

@rkondra-eightfold rkondra-eightfold changed the title [Fix] SSE client to support FastAPI apps mounted under a base path [Fix] SSE client to support MCP server mounted under a base path on a different ASGI server Apr 15, 2025
@tim-watcha
Copy link

I believe this PR addresses the symptoms rather than the root cause of the issue. The problem originates on the server side, where FastMCP doesn't consider the mount path when generating session URIs.

I've submitted PR #540 which fixes this issue at its source by adding a mount_path setting to FastMCP and implementing proper path normalization. This ensures that when FastMCP is mounted under a sub-path (e.g., /github), it correctly generates session URIs that include this path (e.g.,
/github/messages/?session_id=xxx).

While this client-side fix works as a workaround, addressing the server-side issue provides a more complete solution.

@rkondra-eightfold
Copy link
Author

Hi @tim-watcha makes sense. Thank you for the fix 🚀

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

Successfully merging this pull request may close these issues.

2 participants