- 
                Notifications
    You must be signed in to change notification settings 
- Fork 307
Description
🔧 MultiServerMCPClient does not support base_path for SSE connections to servers hosted on nested paths
Summary
The current implementation of MultiServerMCPClient in langchain_mcp_adapters does not support the base_path parameter when connecting to SSE endpoints that are hosted on a nested path (e.g., https://domain.com/subdomain instead of the root https://domain.com/).
This makes it incompatible with MCP backends that are reverse-proxied or deployed under a subpath rather than the domain root.
Details
The underlying mcp library (as of v1.6.0) supports a base_path parameter for correctly composing full POST message URLs returned from the SSE endpoint event.
However, the connect_to_server_via_sse method in MultiServerMCPClient currently does not pass any base_path into the sse_client(...) call, even though this is required for correct communication when the server is not deployed at the domain root.
For example, the following line:
sse_transport = await self.exit_stack.enter_async_context(
    sse_client(url, headers, timeout, sse_read_timeout)
)...results in incorrect message endpoints like:
https://domain.com/mcp/message?...
When it should be:
https://domain.com/subdomain/mcp/message?...
This leads to 404 errors when the actual endpoint is hosted behind a prefix.
Expected Behavior
Allow users to specify a configuration like:
{
  "url": "https://domain.com/subdomain/sse",
  "transport": "sse",
  "base_path": "/subdomain"
}…and have base_path passed into the sse_client(...) call to ensure message URLs are correctly composed.
Suggested Fix
- Update the connect_to_server_via_sse method to accept base_path
- Pass base_path into sse_client(...) (supported since mcp>=1.6.0)
- Preserve backward compatibility by defaulting to ""
Example patch:
async def connect_to_server_via_sse(..., base_path: str = "", ...):
    ...
    sse_transport = await self.exit_stack.enter_async_context(
        sse_client(
            url,
            headers=headers,
            timeout=timeout,
            sse_read_timeout=sse_read_timeout,
            base_path=base_path,
        )
    )Current Workarounds
- Monkeypatching connect_to_server_via_sse to manually inject base_path
- Using a reverse proxy to rewrite /mcp/... to /subdomain/mcp/...
 Both are viable but brittle or require external infrastructure.
Environment
- langchain_mcp_adapters: latest (as of May 2025)
- mcp: 1.7.1
- Platform: LangChain + LangGraph
- Use case: MCP SSE servers reverse-proxied behind a nested path
Related
- modelcontextprotocol/python-sdk PR #386 – adds base_path support in sse_message_reader
Request
Let me know if you'd be open to a PR — I'm happy to contribute this improvement.