You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The MCP Python SDK client (mcp.client.sse) incorrectly appends the session ID as a query parameter when sending messages to the /messages endpoint, which violates the Model Context Protocol schema specification. This causes standard-compliant servers to return a 400 Bad Request error.
Environment
MCP Python SDK Version: 1.3.0
Python Version: 3.12.9
Node.js Version: v22.14.0 (server)
HTTP Libraries:
httpx: 0.28.1
httpx-sse: 0.4.0
aiohttp: 3.11.13
aiohttp-sse-client: 0.2.1
Server Type: Express.js with MCP SDK (TypeScript)
Date Reported: 2025-02-28
Server Configuration
The server used in this environment is the perplexity-mcp service, a TypeScript implementation using:
Express.js web framework
MCP TypeScript SDK for Server implementation
SSEServerTransport from the official MCP SDK
Endpoints:
/sse - For establishing SSE connections
/messages - For receiving JSON-RPC messages
/tools/:toolName and /execute-tool - Alternative direct API endpoints
The server is configured to expect standard MCP messages according to the protocol specification, with the message endpoint expecting messages at /messages without query parameters.
Steps to Reproduce
Establish an SSE connection with Python client to an TypeScript MCP server at /sse endpoint
Successfully receive a session ID from the server during the connection initialization
Attempt to execute a tool using client_session.call_tool() or directly via the write_stream
Observe that the request is made to /messages?sessionId=<session_id> instead of just /messages
Observed Behavior
2025-02-28 01:56:33 2025-02-27 23:56:33.646 - INFO - httpx - [-] - HTTP Request: POST http://perplexity-mcp:3000/messages?sessionId=57ce9ed6-e453-4e1d-b515-7943e7341270 "HTTP/1.1 400 Bad Request"
2025-02-28 01:56:33 2025-02-27 23:56:33.647 - ERROR - mcp.client.sse - [-] - Error in post_writer: Client error '400 Bad Request' for url 'http://perplexity-mcp:3000/messages?sessionId=57ce9ed6-e453-4e1d-b515-7943e7341270'
The SDK attempts to send the message to /messages?sessionId=<session_id> rather than following the MCP specification which requires messages to be sent to /messages.
The session ID is not part of this schema and should not be included in the URL.
Recommended Fix for MCP Python SDK
The Python SDK should be modified to send messages to /messages without appending the session ID as a query parameter. This would likely involve:
Modifying the post_writer method in the SSE client
Ensuring the session ID is managed internally or included in the message body if needed
Following the JSON-RPC specification for message formatting
Impact
This issue affects all implementations that:
Use the MCP Python SDK client for communication
Interact with servers that strictly follow the MCP specification
Need to execute tools or send messages over the established SSE connection
Without the workaround, tool execution fails with 400 Bad Request errors, preventing the intended functionality from working.
Additional Notes
This bug reveals a common challenge with protocol implementations: even small deviations from specifications can cause interoperability issues. Server implementations should consider being more lenient and accommodating different client behaviors when possible, while client libraries should strive to adhere strictly to specifications.
For now, we recommend implementing the server-side workaround described above. Or sticking with Stdio protocol. Long-term, we hope to see this issue fixed in the official MCP Python SDK.
The text was updated successfully, but these errors were encountered:
Send messages to /messages without any query parameters
Include any session identification in the message body if needed according to the JSON-RPC format
Where are you seeing this in the spec? My impression is that the spec does not say this. The closest section I am aware of describes HTTP with SSE and there only says that the initial SSE and it only says that the sse endpoint replies with the messages endpoint. The client does not build that url or change it. Further, the json rpc RPC spec describes is a different part of the protocol, at a higher level above transport. This is all well within the spec.
Second on the implementation: The python client is not involved in anything related to a session id. The server sets this and the session id is transparent to the client. If there is a bug here in the server sdk, its not from what was described here as far as i can tell.
Bug Report: MCP Python SDK Client Appends sessionId as Query Parameter
Issue Description
The MCP Python SDK client (
mcp.client.sse
) incorrectly appends the session ID as a query parameter when sending messages to the/messages
endpoint, which violates the Model Context Protocol schema specification. This causes standard-compliant servers to return a 400 Bad Request error.Environment
Server Configuration
The server used in this environment is the
perplexity-mcp
service, a TypeScript implementation using:SSEServerTransport
from the official MCP SDK/sse
- For establishing SSE connections/messages
- For receiving JSON-RPC messages/tools/:toolName
and/execute-tool
- Alternative direct API endpointsThe server is configured to expect standard MCP messages according to the protocol specification, with the message endpoint expecting messages at
/messages
without query parameters.Steps to Reproduce
/sse
endpointclient_session.call_tool()
or directly via thewrite_stream
/messages?sessionId=<session_id>
instead of just/messages
Observed Behavior
The SDK attempts to send the message to
/messages?sessionId=<session_id>
rather than following the MCP specification which requires messages to be sent to/messages
.Expected Behavior
According to the MCP specification, the client should:
/sse
/messages
without any query parametersSpecifically, the Base Protocol section of the specification defines:
Per the Messages section of the specification, all messages should follow the JSON-RPC 2.0 format:
The session ID should be managed internally by the client and server, not exposed as a query parameter.
Root Cause Analysis
The MCP Python SDK client has an implementation issue in the SSE client where it:
/sse
post_writer
method where it builds the URL with the session ID as a query parameterLooking at the schema in the MCP specification, the
tools/call
method should be formatted as:The session ID is not part of this schema and should not be included in the URL.
Recommended Fix for MCP Python SDK
The Python SDK should be modified to send messages to
/messages
without appending the session ID as a query parameter. This would likely involve:post_writer
method in the SSE clientImpact
This issue affects all implementations that:
Without the workaround, tool execution fails with 400 Bad Request errors, preventing the intended functionality from working.
Additional Notes
This bug reveals a common challenge with protocol implementations: even small deviations from specifications can cause interoperability issues. Server implementations should consider being more lenient and accommodating different client behaviors when possible, while client libraries should strive to adhere strictly to specifications.
For now, we recommend implementing the server-side workaround described above. Or sticking with Stdio protocol. Long-term, we hope to see this issue fixed in the official MCP Python SDK.
The text was updated successfully, but these errors were encountered: