Skip to content

MCP Python SDK Client Appends sessionId as Query ParameterΒ #236

Open
@jruokola

Description

@jruokola

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

  • 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

  1. Establish an SSE connection with Python client to an TypeScript MCP server at /sse endpoint
  2. Successfully receive a session ID from the server during the connection initialization
  3. Attempt to execute a tool using client_session.call_tool() or directly via the write_stream
  4. 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.

Expected Behavior

According to the MCP specification, the client should:

  1. Establish a connection to /sse
  2. Receive a session ID from the server
  3. Send messages to /messages without any query parameters
  4. Include any session identification in the message body if needed according to the JSON-RPC format

Specifically, the Base Protocol section of the specification defines:

"The protocol uses JSON-RPC 2.0 messages to establish communication between hosts, clients, and servers."

Per the Messages section of the specification, all messages should follow the JSON-RPC 2.0 format:

{
  "jsonrpc": "2.0",
  "id": "unique-request-id",
  "method": "method-name",
  "params": {
    // Method-specific parameters
  }
}

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:

  1. Correctly establishes the SSE connection to /sse
  2. Receives and stores the session ID internally
  3. Incorrectly appends the session ID as a query parameter when posting messages
  4. This appears to be in the post_writer method where it builds the URL with the session ID as a query parameter

Looking at the schema in the MCP specification, the tools/call method should be formatted as:

{
  "jsonrpc": "2.0",
  "id": "request-id",
  "method": "tools/call",
  "params": {
    "name": "tool-name",
    "arguments": {
      // Tool-specific arguments
    }
  }
}

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:

  1. Modifying the post_writer method in the SSE client
  2. Ensuring the session ID is managed internally or included in the message body if needed
  3. Following the JSON-RPC specification for message formatting

Impact

This issue affects all implementations that:

  1. Use the MCP Python SDK client for communication
  2. Interact with servers that strictly follow the MCP specification
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions