Open
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
The read_stream_writer
then sends this exception to the read_stream
:
python-sdk/src/mcp/client/sse.py
Line 107 in c2ca8e0
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
No labels