-
Notifications
You must be signed in to change notification settings - Fork 222
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.