Open
Description
Describe the bug
When creating mcp using SSE server, await transport.handlePostMessage(req, res);
expects reqbody. Not providing is failing run
Machine config:
Tried with node 20 and 22.
Mac M3
@modelcontextprotocol/sdk - 1.7.0
To Reproduce
Steps to reproduce the behavior:
- Run
node index.js
to run mcp server - Run
node client.js
to run mcp client
index.js
// Create an MCP server
const server = new McpServer({
name: "Demo",
version: "1.0.0",
});
// Add an addition tool
server.tool("add", { a: z.number(), b: z.number() }, async ({ a, b}) => ({
content: [{ type: "text", text: String(a + b) }],
}));
const axiosInstance = axios.create({
httpsAgent: new https.Agent({
rejectUnauthorized: false,
}),
});
server.tool("pullTestResults", { a: z.number() }, async ({ a }) => {
let result = await axiosInstance.get(`https://xyz/test-case/api-result?count=${a}`);
return {
content: [{ type: "text", text: JSON.stringify(result.data) }],
};
});
const app = express();
app.use(express.json());
const transports = {};
app.get("/sse", async (req, res) => {
const transport = new SSEServerTransport('/messages', res);
transports[transport.sessionId] = transport;
res.on("close", () => {
delete transports[transport.sessionId];
});
await server.connect(transport);
});
app.post("/messages", async (req, res) => {
const sessionId = req.query.sessionId;
const transport = transports[sessionId];
if (transport) {
await transport.handlePostMessage(req, res);
} else {
res.status(400).send('No transport found for sessionId');
}
});
const port = 3000;
app.listen(port, () => {
console.log(`HTTP server listening on port ${port}`);
});
client.js
// Create an MCP client
const client = new Client(
{
name: "DemoClient",
version: "1.0.0"
},
{
capabilities: {}
}
);
const transport = new SSEClientTransport(new URL(`http://localhost:3000/sse`));
// Connect to the server using stdio transport
await client.connect(transport);
const tools = await client.listTools();
console.log(tools)
const resp = await client.callTool({
name: "pullTestResults",
arguments: {
a: "2024-12-04_18-13-21-190087751"
}
})
console.log(resp)
Issue exist in both client or api way.
Api way
curl --location 'http://localhost:3000/messages?sessionId=40652e8f-2633-40b8-98f8-5258fbbcb06a' \
--header 'Content-Type: application/json' \
--data '{
"jsonrpc": "2.0",
"id": "a29ba38d-fed4-49f0-bbba-6c8b1f4606c9",
"method": "tools/call",
"params": {
"name": "pullTestResults",
"arguments": {
"a": "2024-12-04_18-13-21-190087751"
}
}
}'
Expected behavior
List out tools and execute pullTestResults tool.
Logs
throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`);
^
Error: Error POSTing to endpoint (HTTP 400): InternalServerError: stream is not readable
Workaround for this issue is to send reqbody to handlePostMessage
function.
..... same as index.js
await transport.handlePostMessage(req, res, req.body);