# MCP Python SDK v2.0.0a3 - Product: MCP Python SDK (https://whatsnew.fyi/product/mcp-python-sdk) - Vendor: Anthropic - Date: 2026-06-26 - Version: v2.0.0a3 - Original notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0a3 - Permalink: https://whatsnew.fyi/product/mcp-python-sdk/releases/v2.0.0a3 - Labels: Pre-release What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'. --- - **changed** — Update LATEST_PROTOCOL_VERSION to 2026-07-28 - **changed** — Replace stateless bool flag with negotiable end-to-end protocol support via Connection object with from_envelope and for_loop factories - **changed** — Refactor ServerRunner into pure handler kernel composed by three drivers: serve_one, serve_connection, and serve_loop - **changed** — Add Connection object to own per-peer state with protocol_version always set - **added** — Add ClientSession.discover() and ClientSession.adopt() methods alongside initialize() - **added** — Add Client mode parameter supporting 'legacy', 'auto', or specific version strings - **added** — Add Client prior_discover parameter - **added** — Add modern_on_request in-process driver for stateless path against in-memory servers - **changed** — Make streamable-HTTP transport version-agnostic with per-message headers via CallOptions - **removed** — Remove mcp.types module; import from mcp_types instead - **removed** — Remove mcp.shared.version module; import from mcp_types.version instead - **deprecated** — Deprecate SUPPORTED_PROTOCOL_VERSIONS in favour of HANDSHAKE_PROTOCOL_VERSIONS and MODERN_PROTOCOL_VERSIONS - **added** — Extract protocol types into standalone mcp-types package with only pydantic and typing-extensions dependencies - **changed** — Widen Server on_* return types to admit InputRequiredResult - **added** — Add subscriptions/listen handler slot - **changed** — Update ClientSession.call_tool to accept input_responses and request_state retry kwargs and return CallToolResult or InputRequiredResult - **changed** — Add allow_input_required flag to Client.call_tool and ClientSessionGroup.call_tool overloads - **changed** — Update ClientSession.send_request to accept TypeAdapter for union result parsing - **changed** — Reshape ServerMiddleware.__call__ from (ctx, method, params, call_next) to (ctx, call_next) with method and params moved to ServerRequestContext - **added** — Add OpenTelemetryMiddleware that spans requests and notifications with OpenTelemetry GenAI semantic-convention attributes - **deprecated** — Mark user-facing methods for roots, sampling, and logging/setLevel as deprecated per SEP-2577 Third v2 alpha. Pre-releases are opt-in only; `pip install mcp` still resolves to the stable 1.x line. ```bash pip install mcp==2.0.0a3 #### or uv add "mcp==2.0.0a3" ``` See the [migration guide](https://github.com/modelcontextprotocol/python-sdk/blob/main/docs/migration.md) for the full list of breaking changes. ##### Warning The public API is likely to change between alpha releases, and ideally less-so between beta releases. ##### Highlights ###### 2026-07-28 stateless protocol is now negotiable end to end (#2928, #2950) The 2026-07-28 spec revision drops the `initialize` handshake on streamable HTTP: each POST is self-describing (protocol version, client info, and capabilities ride in `params._meta`) and the server replies with a single JSON-RPC response. Both sides of that path are now wired up. Server side: `ServerRunner` is now a pure handler kernel composed by three drivers (`serve_one`, `serve_connection`, `serve_loop`). A new `Connection` object owns per-peer state with two factories - `from_envelope` for the per-request stateless path and `for_loop` for handshake-driven connections - so `protocol_version` is always set and the old `stateless: bool` flag is gone from `ServerRunner`, `ServerSession`, and `Server.run()`. The streamable-HTTP session manager routes by header: known handshake versions go to the legacy transport; everything else hits a new per-POST entry that classifies, builds a `Connection.from_envelope`, and drives `serve_one`. `server/discover` is auto-derived from registered handlers, and `lifespan` is entered once at manager startup in both modes. Client side: `ClientSession` gains `.discover()` and `.adopt()` alongside `.initialize()`, each of which installs an outbound stamp closure at connect time so the send path has no era branch. `Client` gains `mode='legacy'|'auto'|` and `prior_discover=`; `mode='auto'` probes `server/discover` and falls back to `initialize` on `-32601` or timeout. The streamable-HTTP transport is now version-agnostic (per-message headers arrive via `CallOptions`), and an in-process `modern_on_request` driver lets `Client(server, mode='auto')` run the stateless path against an in-memory server. `LATEST_PROTOCOL_VERSION` is now `"2026-07-28"`. `SUPPORTED_PROTOCOL_VERSIONS` is deprecated in favour of `HANDSHAKE_PROTOCOL_VERSIONS` and `MODERN_PROTOCOL_VERSIONS`. ###### Protocol types split into a standalone `mcp-types` package (#2973) The wire types now ship as a separate `mcp-types` distribution (imported as `mcp_types`) that depends only on `pydantic` and `typing-extensions`. Tooling and lightweight clients can serialize and validate MCP traffic without pulling in `httpx`, `starlette`, `uvicorn`, or the rest of the transport stack. `mcp.types` and `mcp.shared.version` are removed; import from `mcp_types` and `mcp_types.version` instead. The top-level `from mcp import Tool` re-exports are unchanged. The two packages are version-locked and published together from the same tag. ###### Multi-round tool calls: `InputRequiredResult` plumbed through both sides (#2967, #2968, #2974) The lowlevel `Server` `on_*` return types are widened to admit `InputRequiredResult`, and a `subscriptions/listen` handler slot is added. On the client, `ClientSession.call_tool` gains `input_responses=` and `request_state=` retry kwargs and returns `CallToolResult | InputRequiredResult`; `Client.call_tool` and `ClientSessionGroup.call_tool` are overloaded on a new `allow_input_required` flag so existing callers keep their `CallToolResult` return type. `ClientSession.send_request` now accepts a `TypeAdapter` for union result parsing. ###### `ServerMiddleware` reshaped to `(ctx, call_next)` and `OpenTelemetryMiddleware` added (#2941, #2970) `ServerMiddleware.__call__` goes from `(ctx, method, params, call_next)` to `(ctx, call_next)`; `method` and raw `params` now live on `ServerRequestContext`, and `call_next(ctx)` lets middleware rewrite the in _[Truncated at 4000 characters — full notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0a3]_