-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Open
Labels
bugSomething isn't workingSomething isn't workingneeds confirmationNeeds confirmation that the PR is actually required or needed.Needs confirmation that the PR is actually required or needed.
Description
Describe the bug
When using the sse_client function to connect to a remote MCP server, if the MCP server sets an incorrect base URL (like http://localhost:8080), the sse_client will raise an exception in the following code:
python-sdk/src/mcp/client/sse.py
Line 81 in c2ca8e0
| raise ValueError(error_msg) |
The read_stream_writer then sends this exception to the read_stream:
python-sdk/src/mcp/client/sse.py
Line 107 in c2ca8e0
| await read_stream_writer.send(exc) |
However, since the read_stream has not been yielded yet, the exception will never be received.
As a result, the sse_client will be blocked indefinitely.
To Reproduce
- Set up an MCP server with an incorrect base URL on a remote server, for example:
import express, { Request, Response } from 'express';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import { z } from 'zod';
const server = new McpServer({
name: 'example-server',
version: '1.0.0',
});
server.tool(
"calculate-bmi",
{
weightKg: z.number(),
heightM: z.number()
},
async ({ weightKg, heightM }) => ({
content: [{
type: "text",
text: String(weightKg / (heightM * heightM))
}]
})
);
const app = express();
const transports: { [sessionId: string]: SSEServerTransport } = {};
app.get('/sse', async (_: Request, res: Response) => {
// set baseUrl for the transport
const baseUrl = 'http://localhost:8080';
const transport = new SSEServerTransport(`${baseUrl}/messages`, res);
transports[transport.sessionId] = transport;
res.on('close', () => {
delete transports[transport.sessionId];
});
await server.connect(transport);
});
app.post('/messages', async (req: Request, res: Response) => {
const sessionId = req.query.sessionId as string;
const transport = transports[sessionId];
if (transport) {
await transport.handlePostMessage(req, res);
} else {
res.status(400).send('No transport found for sessionId');
}
});
app.listen(8080);- Try to connect to the remote MCP server, for example:
import asyncio
from mcp.client.sse import sse_client
async def run():
try:
async with sse_client("http://{your_remote_server}:8080/sse"):
print("Connected to SSE endpoint successfully.")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
asyncio.run(run())Expected behavior
The sse_client should raise an exception and exit gracefully.
Logs
None
Additional context
None
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingneeds confirmationNeeds confirmation that the PR is actually required or needed.Needs confirmation that the PR is actually required or needed.