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