MCP · Python SDK · 2026 Spec

MCP Python SDK v2.1.0: What Changed for Developers Shipping on the 2026 Spec

The first minor release since v2.0.0 stabilized around the 2026-07-28 specification. Three changes deserve attention: a simpler client constructor, stricter error handling that keeps exception details out of model responses, and SSE/OAuth hardening that closes a DoS surface.

The MCP Python SDK v2.1.0 landed this week — the first minor release since v2.0.0 stabilized around the 2026-07-28 specification. If you're running MCP servers in production, three changes in this release deserve attention: a simpler client constructor, stricter error handling that keeps exception details out of model responses, and SSE/OAuth hardening that closes a DoS surface.

The Headline: Client Now Takes StdioServerParameters Directly

# Before v2.1.0
from mcp.client.stdio import StdioServerParameters
from mcp.client import Client

params = StdioServerParameters(command="uv", args=["run", "server.py"])
client = Client(params)

# After v2.1.0 — same code works, but the Client signature now accepts
# StdioServerParameters natively without the intermediate step
client = Client(StdioServerParameters(command="uv", args=["run", "server.py"]))

This is a small ergonomic win, but it signals the SDK's direction: the high-level Client is becoming the primary interface, and the transport-specific parameter classes are first-class citizens. The same pattern now works for SseServerParameters and StreamableHttpServerParameters — one import, one line, ready to connect.

Error Handling: Exceptions No Longer Leak to the Model

This is the behavioral change that will bite you if you're not aware of it.

In v2.0.x, an unhandled exception in a tool handler would serialize the full traceback and send it to the client. The model would see the raw Python exception text. That's a security issue (internal paths, secrets in stack traces) and a reliability issue (models don't parse tracebacks well).

In v2.1.0:

  • Unexpected exceptions are logged once at ERROR with full traceback (server-side only)
  • The client receives a generic message: Error executing tool
  • If you want the model to see a specific error, raise ToolError, ResourceError, or PromptError — those are logged at INFO without traceback and the message reaches the client intact
from mcp.server.mcpserver import ToolError

@server.tool()
async def risky_operation(x: int) -> str:
    if x < 0:
        raise ToolError("x must be non-negative")  # Model sees this
    return await do_work(x)  # Unexpected exceptions become generic "Error executing tool risky_operation"

This aligns with the 2026-07-28 spec's error code allocation: -32000 to -32019 remain implementation-defined, -32020 to -32099 are reserved for MCP-defined errors. ToolError maps cleanly to that reserved range.

Prompt Messages Now Accept Image and Audio Blocks

The 2026-07-28 spec added Image and Audio content block types. v2.0.0 supported them in tool results. v2.1.0 extends that to prompt messages — both the messages you send to prompts and the messages prompts can return.

from mcp.types import Image, Audio

@server.prompt()
async def analyze_media(image: Image, audio: Audio) -> list[Message]:
    return [
        UserMessage(content=[image, audio, "Analyze both together"]),
        AssistantMessage(content="Here's my analysis..."),
    ]

Prompt functions can also now return bare content blocks (text, image, audio) instead of wrapping everything in Message objects. The SDK coerces them. Message, UserMessage, and AssistantMessage are now exported from mcp.server.mcpserver for convenience.

SSE Transport and OAuth Endpoints Get the 4 MiB Body Limit

The 4 MiB request body limit has existed for stdio and streamable HTTP since v2.0.0. v2.1.0 extends it to:

  • SSE transport (SseServerTransport, MCPServer.sse_app())
  • OAuth endpoints (token, authorization, registration)

Both SseServerTransport and MCPServer.sse_app() now accept max_request_body_size to override the default. The SSE message endpoint also returns 405 Method Not Allowed for non-POST requests — a small hardening that prevents accidental GETs from hitting the message handler.

If you're running an MCP server behind a load balancer or proxy that buffers bodies, verify your proxy limits exceed 4 MiB or set max_request_body_size lower to match.

Pre-2026 Session Compatibility Fixes

Two fixes improve backward compatibility with 2025-era clients:

  • Pre-2026 sessions now ignore cache-hint fields from later revisions instead of failing list_tools()
  • Boolean sub-schemas in tool schema properties are now accepted (previously rejected as invalid)

If you operate a gateway or proxy that serves mixed-version clients, these reduce the chance of a version mismatch breaking a session mid-flight.

Windows: mcp install Preserves Non-ASCII Config

A long-standing Windows issue: mcp install would corrupt Claude Desktop config files containing non-ASCII characters (accented paths, non-Latin usernames) because it read the file with the system code page instead of UTF-8. v2.1.0 fixes this — the config is read and written as UTF-8 regardless of the active code page.

What This Means for Your Stack

If you... Action
Use Client with stdio servers Simplify your connection code — pass StdioServerParameters directly
Have tool handlers that can raise Audit for bare raise Exception(...) and convert to ToolError where the model should see the message
Run SSE transport in production Set max_request_body_size to match your infrastructure limits
Support mixed-version clients Test list_tools() with a 2025-era client after upgrade
Install on Windows with non-ASCII paths Upgrade to v2.1.0 — the config corruption bug is fixed

The Bigger Picture

v2.1.0 is a maintenance release, but it reveals the SDK's maturation. The 2026-07-28 spec was a major break (stateless core, no initialize handshake, extensions framework). v2.0.0 implemented it. v2.1.0 hardens the edges: security (error leakage), operability (body limits), and compatibility (Windows, legacy clients).

The next spec revision will likely focus on the roadmap items the MCP maintainers highlighted post-2026-07-28: agent communication primitives, server discovery via .well-known metadata, and enterprise auth (CIMD, issuer-bound credentials). The SDK will track those. For now, v2.1.0 is the stable baseline for anyone shipping on the 2026 spec.


If this was useful, you can support my open-source work on Ko-fi or check out my services.