# MCP Python SDK changelog > The official Python SDK for building Model Context Protocol servers and clients. - Vendor: Anthropic - Category: Frameworks & Libraries - Official site: https://github.com/modelcontextprotocol/python-sdk - Tracked by: What's New (https://whatsnew.fyi/product/mcp-python-sdk) - Harvested from: GitHub (modelcontextprotocol/python-sdk) - Entries below: 10 (newest first) 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'. ## Releases ### v2.0.0 - Date: 2026-07-28 - Version: v2.0.0 - Original notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0 - Permalink: https://whatsnew.fyi/product/mcp-python-sdk/releases/v2.0.0 - **added** — Support for the 2026-07-28 revision of the Model Context Protocol with stateless requests, no handshake, server/discover, subscriptions/listen, and multi-round-trip requests - **added** — First-class Client object that negotiates protocol version automatically and connects to URLs, stdio subprocesses, custom transports, or server objects in memory - **added** — Resolve parameter for multi-round-trip requests allowing tools to return questions instead of answers in 2026-07-28 era - **added** — Pluggable extension APIs for composing protocol extensions with MCP Apps built in - **added** — OpenTelemetry tracing shipped by default - **added** — Standalone types package mcp-types (imported as mcp_types) published in lock-step with mcp - **added** — OAuth support for RFC 9207 issuer validation, SEP-990 identity-assertion flow, and client-credentials extension - **changed** — MCPServer now speaks both 2026-07-28 and 2025-era protocol revisions from the same server over Streamable HTTP and stdio with automatic version negotiation - **changed** — FastMCP renamed to MCPServer with decorator API unchanged but low-level Server rebuilt around a shared dispatcher engine - **changed** — Client replaces v1's transport-plus-ClientSession-plus-initialize() layering with a single unified object - **changed** — Per-version wire packages are now private (mcp_types._v*) with mcp.types as permanent alias for mcp_types - **changed** — Client cache parameter changed from Client(cache=False) to cache=None with CacheConfig() as default - **changed** — FileResource is_binary parameter renamed to encoding - **changed** — Streamable HTTP servers now reject bodies over 4 MiB with HTTP 413 - **changed** — stdio servers keep handler subprocesses and stray prints off the wire with stdout diverted to stderr while serving - **fixed** — Cancelled requests are no longer answered - **removed** — Context.client_id, RFC7523OAuthClientProvider, and OAuthClientProvider(timeout=) removed - **removed** — MCP_* environment variables removed with pydantic-settings - **deprecated** — v1.x line moved to maintenance mode and will only receive security fixes #### MCP Python SDK v2 Stable Release This is v2.0.0, the stable v2 release of the MCP Python SDK. It supports the 2026-07-28 revision of the Model Context Protocol and serves every earlier revision from the same server. `pip install mcp` now installs 2.x. ```bash pip install "mcp[cli]" #### or uv add "mcp[cli]" ``` ###### Documentation Rewrite The [documentation](https://py.sdk.modelcontextprotocol.io/) has the full tutorial and API reference. Coming from v1? [What's new in v2](https://py.sdk.modelcontextprotocol.io/whats-new/) is the tour of what changed and why, and the [migration guide](https://py.sdk.modelcontextprotocol.io/migration/) lists every breaking change with before-and-after code. ###### V1 Maintenance mode **v1.x is in maintenance mode and will only receive security fixes from now on** The 1.x line lives on the [`v1.x` branch](https://github.com/modelcontextprotocol/python-sdk/tree/v1.x), continues to receive critical bug fixes and security patches, and is documented at https://py.sdk.modelcontextprotocol.io/v1/. If your project is not ready to migrate, keep a `<2` upper bound on your requirement (for example `mcp>=1.28,<2`). ##### Highlights ###### One SDK, both protocol eras v2 speaks the 2026-07-28 revision (stateless requests with no handshake, `server/discover`, `subscriptions/listen`, multi-round-trip requests) and still serves every 2025-era client from the same `MCPServer`, over Streamable HTTP and stdio, with nothing to configure. `Client(target)` negotiates the version automatically. ###### `FastMCP` is now `MCPServer`, and there is a first-class `Client` The decorator API is unchanged; the low-level `Server` is rebuilt around a shared dispatcher engine, and one `Client` object replaces v1's transport-plus-`ClientSession`-plus-`initialize()` layering. It connects to a URL, a stdio subprocess, a custom transport, or straight to a server object in memory for tests. ###### Multi-round-trip requests and resolver dependency injection At 2026-07-28 the server can no longer call the client, so tools return the question instead. A `Resolve(fn)` parameter is filled by your function invisibly to the model and can put a question to the user; one tool body serves both eras. ###### Extension APIs, OpenTelemetry, and a standalone types package Servers and clients compose protocol extensions through pluggable extension APIs (MCP Apps built in); OpenTelemetry tracing ships on by default; every protocol type is its own package, `mcp-types` (imported as `mcp_types`), published in lock-step with `mcp`. ###### Hardened stdio and auth stdio servers keep handler subprocesses and stray prints off the wire, and stdout is diverted to stderr while serving. OAuth adds RFC 9207 issuer validation, the SEP-990 identity-assertion flow, and the client-credentials extension. ##### Coming from a v2 pre-release Since the last release candidate: the per-version wire packages are private (`mcp_types._v*`), `mcp.types` is a permanent alias for `mcp_types`, the auth registration request model is split from the registered-client record, cancelled requests are no longer answered, and log notifications are gated on the per-request log-level opt-in at 2026-07-28. Since the betas: `Client(cache=False)` is now `cache=None` with `CacheConfig()` the default; `Context.client_id`, `RFC7523OAuthClientProvider`, and `OAuthClientProvider(timeout=)` are removed; the client-credentials providers take `scope=`; `message_handler` receives notifications and exceptions only; `FileResource(is_binary=)` becomes `encoding`; `MCP_*` env vars are gone with `pydantic-settings`; Streamable HTTP servers reject bodies over 4 MiB with HTTP 413. The migration guide covers all of it. ##### Known gaps The tasks extension (SEP-2663) is not part of this release. On the client, the DPoP proof binding (SEP-1932) and the workload-identity `jwt-bearer` grant are not implemented; both are additive and can land i _[Truncated at 4000 characters — full notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0]_ ### v1.29.0 - Date: 2026-07-28 - Version: v1.29.0 - Original notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.29.0 - Permalink: https://whatsnew.fyi/product/mcp-python-sdk/releases/v1.29.0 - **changed** — Route Context.report_progress() to the originating request stream - **added** — Add Streamable HTTP request body limits - **fixed** — Reject trailing newline in tool-name validation ##### What's Changed * [v1.x] Route Context.report_progress() to the originating request stream by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2994 * [v1.x] docs: publish llms.txt and markdown renditions of the docs by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3029 * [v1.x] docs: pin mkdocs<2 by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3074 * [v1.x] Add Streamable HTTP request body limits by @Kludex in https://github.com/modelcontextprotocol/python-sdk/pull/3101 * [v1.x] fix: reject trailing newline in tool-name validation by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3086 * [v1.x] ci: pick the docs toolchain per worktree in build-docs.sh by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3082 * [v1.x] Move the v1.x docs to /v1/ and mark v1.x as the maintenance line by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3177 **Full Changelog**: https://github.com/modelcontextprotocol/python-sdk/compare/v1.28.1...v1.29.0 ### v2.0.0rc1 - Date: 2026-07-27 - Version: v2.0.0rc1 - Original notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0rc1 - Permalink: https://whatsnew.fyi/product/mcp-python-sdk/releases/v2.0.0rc1 - Labels: Pre-release - **changed** — Client(cache=False) is now Client(cache=None); CacheConfig() is the default and None switches the response cache off - **removed** — Context.client_id is removed; read _meta via ctx.request_context.meta or the authenticated client via get_access_token().client_id - **removed** — RFC7523OAuthClientProvider and JWTParameters are removed; use ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider, or IdentityAssertionOAuthProvider - **changed** — Client-credentials OAuth providers now take scope= instead of scopes= - **removed** — OAuthClientProvider(timeout=...) parameter is removed - **changed** — message_handler receives ServerNotification | Exception only; the RequestResponder arm and mcp.shared.session module are removed - **changed** — FileResource(is_binary=...) is replaced by encoding: str | None - **removed** — MCP_* environment variables no longer configure MCPServer and pydantic-settings is dropped from runtime dependencies - **changed** — Streamable HTTP servers reject request bodies over 4 MiB with HTTP 413; raise max_request_body_size to accept larger messages - **changed** — Request-side clientInfo _meta key is now optional; serverInfo moved out of server/discover result body into every 2026-era result's _meta - **changed** — client.server_info is now Implementation | None - **added** — stdio server decides the protocol era from the client's opening request, enabling subscriptions/listen and other 2026-07-28 features over stdio - **changed** — stdio_server() serves from private duplicates of stdin/stdout and points file descriptors 0 and 1 away from the JSON-RPC stream to prevent corruption from stray output - **changed** — Tool results validated against an output schema are now much faster with compiled and cached JSON Schema validator First v2 release candidate. Pre-releases are opt-in only; `pip install mcp` still resolves to the stable 1.x line. ```bash pip install mcp==2.0.0rc1 #### or uv add "mcp==2.0.0rc1" ``` The [documentation](https://py.sdk.modelcontextprotocol.io/v2/) has the full tutorial and API reference, and the [migration guide](https://py.sdk.modelcontextprotocol.io/v2/migration/) covers coming from v1. Stable v2 is planned for 2026-07-28 alongside the spec release - keep pinning an exact version until then. ##### Highlights ###### API cleanup ahead of stable (breaking for beta users) The last pre-release pass over the public surface; every item has a migration guide entry. - `Client(cache=False)` is now `Client(cache=None)`: `CacheConfig()` is the default and `None` switches the response cache off (#3164). - `Context.client_id` is removed - read `_meta` via `ctx.request_context.meta`, or the authenticated client via `get_access_token().client_id` (#3167). - `RFC7523OAuthClientProvider` and `JWTParameters` are removed - use `ClientCredentialsOAuthProvider`, `PrivateKeyJWTOAuthProvider`, or `IdentityAssertionOAuthProvider` (#3169). - The client-credentials providers take `scope=`, not `scopes=` (#3166). - `OAuthClientProvider(timeout=...)` is removed; it never bounded anything (#3165). - `message_handler` receives `ServerNotification | Exception` only; the dead `RequestResponder` arm and the `mcp.shared.session` module are gone (#3168). - `FileResource(is_binary=...)` is replaced by `encoding: str | None` (#3171). - `MCP_*` environment variables never configured `MCPServer` and are no longer advertised; `pydantic-settings` is dropped from the runtime dependencies (#3170). - Streamable HTTP servers reject request bodies over 4 MiB with HTTP 413; raise `max_request_body_size` if you accept larger messages (#3095). ###### Aligned with the final 2026-07-28 identity shape (#3143) The request-side `clientInfo` `_meta` key is optional (the required pair is `protocolVersion` + `clientCapabilities`), and `serverInfo` moved out of the `server/discover` result body into every 2026-era result's `_meta`; `client.server_info` is now `Implementation | None`. This tracks spec change [#3002](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3002) and fixes interop with servers that already omit body `serverInfo`. ###### The full 2026-07-28 revision over stdio (#3152) A stdio (or in-memory) server now decides the protocol era from the client's opening request, so `subscriptions/listen` and every other 2026-07-28 feature serve over stdio, not only Streamable HTTP. ###### stdio servers keep handlers off the wire (#3117) `stdio_server()` serves from private duplicates of stdin/stdout and points fd 0 at the null device and fd 1 at stderr while it runs, so a stray `print()` or a chatty child process can no longer corrupt the JSON-RPC stream. This fixes the classic print-corrupts-the-wire class ([#409](https://github.com/modelcontextprotocol/python-sdk/issues/409)) and the Windows tool-call hang ([#671](https://github.com/modelcontextprotocol/python-sdk/issues/671)). ##### Notes - Tool results validated against an output schema are much faster: the JSON Schema validator is compiled once and cached (#3134). - The tasks extension (SEP-2663) is not in this release, and will not be in v2.0.0. - If you install under uv's `exclude-newer` cooldown: `mcp` pins `mcp-types` to the exact same version, so exempt both packages - `exclude-newer-package = { mcp = false, mcp-types = false }`. ##### What's Changed * Add Streamable HTTP request body limits by @Kludex in https://github.com/modelcontextprotocol/python-sdk/pull/3095 * docs: document Windows stdio subprocess stdin handling by @AndreKalberer in https://github.com/modelcontextprotocol/python-sdk/pull/3079 * docs: make API reference rendering independent of page order by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3107 _[Truncated at 4000 characters — full notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0rc1]_ ### v2.0.0b2 - Date: 2026-07-14 - Version: v2.0.0b2 - Original notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0b2 - Permalink: https://whatsnew.fyi/product/mcp-python-sdk/releases/v2.0.0b2 - Labels: Pre-release - **changed** — Replace httpx and httpx-sse with httpx2 (>=2.5.0) as the HTTP stack - **changed** — TLS verification now uses the operating system trust store via truststore instead of certifi's bundle - **changed** — Logger names changed from httpx to httpx2 and httpcore.* to httpcore2.* - **changed** — SSE GET streams now send Accept header with application/json, text/event-stream instead of exactly text/event-stream - **added** — Add client-side subscriptions/listen with context manager, async iteration, and typed events - **added** — Request cancellation now works on 2026 transports by closing POST/SSE streams or sending notifications/cancelled over stdio - **added** — Resolver dependency injection now supports Sample and ListRoots requests in addition to Elicit - **fixed** — Tool-name validation now rejects names with a trailing newline Second v2 beta. Pre-releases are opt-in only; `pip install mcp` still resolves to the stable 1.x line. ```bash pip install mcp==2.0.0b2 #### or uv add "mcp==2.0.0b2" ``` The [documentation](https://py.sdk.modelcontextprotocol.io/v2/) has the full tutorial and API reference, and the [migration guide](https://py.sdk.modelcontextprotocol.io/v2/migration/) covers coming from v1. Stable v2 is still targeted for 2026-07-28 alongside the spec release - keep pinning an exact version. ##### Highlights ###### httpx is replaced by httpx2 (#2972) The SDK's HTTP stack now runs on [httpx2](https://pypi.org/project/httpx2/) (`>=2.5.0`), the next-generation httpx fork with SSE support built in, replacing `httpx` + `httpx-sse`. Most code needs no changes; if you pass your own `http_client` into a transport, change the import to `httpx2`. Runtime behavior that changes: - TLS verification uses the operating system trust store (via `truststore`) instead of certifi's bundle. `SSL_CERT_FILE` / `SSL_CERT_DIR` are honored first. - Loggers are renamed: `httpx` -> `httpx2`, `httpcore.*` -> `httpcore2.*` - update logging filters that match on those names. - SSE GET streams send `Accept: application/json, text/event-stream` (previously exactly `text/event-stream`). ###### Client-side subscriptions/listen (#3047) The client half of `subscriptions/listen` (SEP-2575), promised in the b1 notes: one context manager, `async for` consumption, typed events. ```python async with client.listen(tools_list_changed=True, resource_subscriptions=["note://todo"]) as sub: print(sub.honored) # the subset the server agreed to deliver async for event in sub: match event: case ToolsListChanged(): tools = await client.list_tools() case ResourceUpdated(uri=uri): body = await client.read_resource(uri) ``` Entering waits for the server's acknowledgment, so `sub.honored` is always populated and pre-ack failures raise instead of degrading silently. ###### Request cancellation works on the 2026 transports (#3046) Cancelling or timing out a client request now actually stops it: over streamable HTTP the request's own POST/SSE stream is closed (the spec's cancellation signal), and over stdio the client sends `notifications/cancelled`. Callers can also supply the request id for a call - the seam the listen driver builds on. ###### Resolvers can sample and list roots (#3049) Resolver dependency injection now covers all three multi-round-trip request kinds (SEP-2322): a dependency can return `Sample(...)` or `ListRoots()` in addition to `Elicit(...)`, so a tool can ask the client's LLM or fetch its roots mid-call, on both protocol eras. ##### Notes - Tool-name validation now rejects names with a trailing newline (#3076). - The tasks extension is still in review and will ship in a later pre-release. - If you install under uv's `exclude-newer` cooldown: `mcp` pins `mcp-types` to the exact same version, so exempt both packages - `exclude-newer-package = { mcp = false, mcp-types = false }`. ##### What's Changed * De-flake conformance CI: solo re-verification, spawn-storm reduction, result artifacts by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3043 * Harden the dual-era stream loop's era-lock and rejection semantics by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3040 * docs: restructure into topical sections and add the four most-asked-for pages by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3044 * docs: add a "What's new in v2" page by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3054 * docs: modernize the site theme by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/3057 * docs: restructure the migration guide around topical groups with a navigation layer by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/ _[Truncated at 4000 characters — full notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0b2]_ ### v2.0.0b1 - Date: 2026-06-30 - Version: v2.0.0b1 - Original notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0b1 - Permalink: https://whatsnew.fyi/product/mcp-python-sdk/releases/v2.0.0b1 - Labels: Pre-release - **added** — First v2 beta with full support for the 2026-07-28 MCP specification - **added** — ServerRunner as a pure handler kernel with thin transport drivers - **changed** — FastMCP renamed to MCPServer with snake_case fields and constructor-based handler parameters - **added** — New Client that auto-discovers server protocol version with server/discover and falls back to initialize - **added** — Protocol types as standalone mcp_types package depending only on pydantic and typing-extensions - **added** — Resolver dependency injection for tools to declare typed parameter requirements - **added** — RFC 6570 URI templates for resource definitions with full operator set and path-security validation - **added** — Extension APIs on both server and client sides with pluggable composition support - **added** — Server middleware with (ctx, call_next) pattern and OpenTelemetry tracing with GenAI semantic conventions - **added** — Stateless core with self-describing requests and server/discover without session handshake - **added** — Multi-round-trip requests for tools, prompts, and resources to ask for input mid-call - **added** — Header-based routing and caching with Mcp-Method, Mcp-Name, and Mcp-Param headers - **added** — Subscriptions/listen with pluggable event bus support - **added** — 2026-07-28 protocol negotiation over stdio with auto-mode for clients - **added** — SEP-990 identity assertion (ID-JAG) for enterprise IdP flows - **deprecated** — Roots, sampling, and logging/setLevel per SEP-2577 with advisory warnings only First v2 beta, and the first release with full support for the [2026-07-28 MCP specification](https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/). Pre-releases are opt-in only; `pip install mcp` still resolves to the stable 1.x line. ```bash pip install mcp==2.0.0b1 #### or uv add "mcp==2.0.0b1" ``` The [documentation](https://py.sdk.modelcontextprotocol.io/v2/) has the full tutorial and API reference, and the [migration guide](https://py.sdk.modelcontextprotocol.io/v2/migration/) covers coming from v1. Beta means the architecture is settled and changes from here should be much smaller than between alphas, but the API can still shift before stable v2, targeted for 2026-07-28 alongside the spec release - keep pinning an exact version. ##### What's new in v2 The whole v2 line so far (alphas included), condensed: - **A new core.** The session-centric v1 internals are replaced by a dispatcher/runner pipeline built for the stateless 2026 protocol: `ServerRunner` is a pure handler kernel, transports are thin drivers over it, and one endpoint serves both protocol eras side by side. - **`FastMCP` is now `MCPServer`.** The decorator API stays; the low-level `Server` takes handlers as constructor parameters, fields are snake_case, and traffic is validated against the negotiated spec version on the wire. - **A new `Client`.** `Client(target, mode='auto')` speaks every protocol version - it probes `server/discover` and falls back to `initialize` automatically. The target can be a URL, a stdio subprocess, a custom transport, or a server object in memory (great for tests). - **Protocol types are a standalone package.** `mcp-types` (imported as `mcp_types`) depends only on `pydantic` and `typing-extensions`, so tooling can speak MCP without the transport stack. Published in lock-step with `mcp`. - **Resolver dependency injection.** Tools declare what they need as typed parameters; a resolver can compute the value server-side or ask the user, with questions delivered over elicitation on 2025 sessions and multi-round-trip requests on 2026 sessions. - **RFC 6570 URI templates.** Resource templates support the full operator set - query parameters, path segments, explode modifiers - with path-security validation built in. - **Extension APIs on both sides.** Servers compose protocol extensions - including MCP Apps - through a pluggable API; clients mirror it with `Client(extensions=[...])`. - **Middleware and observability.** Server middleware is `(ctx, call_next)`, and OpenTelemetry tracing ships on by default with GenAI semantic conventions. - **Docs rebuilt on tested examples.** Every snippet in the [book](https://py.sdk.modelcontextprotocol.io/v2/) is an executable, CI-tested file, plus a story-style examples suite and llms.txt renditions for agents. ##### 2026-07-28 spec support Client and server: - **Stateless core**: self-describing requests with no handshake, `server/discover`, scale-out on plain HTTP with no session affinity - progress and log notifications stream within the same single POST exchange. - **Multi-round-trip requests**: tools, prompts, and resources can ask for input mid-call; clients auto-resolve through their existing callbacks; on `MCPServer`, `requestState` is sealed by default (authenticated encryption) so clients cannot read or forge it. - **Header-based routing and caching**: `Mcp-Method` / `Mcp-Name` / `Mcp-Param-*` headers stamped by the client and validated by the server (SEP-2243), and `ttlMs` / `cacheScope` caching hints stamped by servers and honored by the client-side response cache (SEP-2549). - **subscriptions/listen**: served with a pluggable event bus (SEP-2575); the client-side listen driver follows in a later pre-release. - **2026-07-28 over stdio (#3038)**: auto-mode clients negotiate the new revision over stdio too - existing alpha clients upgrade with zero code changes. - **Enterprise auth**: SEP-990 identity assertion (ID-JAG) for enterpri _[Truncated at 4000 characters — full notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0b1]_ ### v2.0.0a3 - 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 - **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]_ ### v2.0.0a2 - Date: 2026-06-16 - Version: v2.0.0a2 - Original notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0a2 - Permalink: https://whatsnew.fyi/product/mcp-python-sdk/releases/v2.0.0a2 - Labels: Pre-release - **added** — Add generated per-version protocol types for 2025-11-25 and 2026-07-28 schemas alongside the hand-maintained superset monolith in mcp.types - **added** — Implement version-gated wire validation that selects the negotiated protocol version's type set at runtime for validating inbound requests, notifications, and results - **added** — Add dispatcher keyword-only constructor argument to ClientSession to support passing a pre-built dispatcher instead of read/write stream pair - **changed** — Rewrite ClientSession to run on JSONRPCDispatcher receive path instead of inline, allowing server-initiated requests to run concurrently - **changed** — Make validation stricter by returning INTERNAL_ERROR for spec-invalid handler output and rejecting spec-invalid server output at clients - **changed** — Strip fields that only exist in newer spec versions from outbound results before they reach older peers - **removed** — Remove BaseSession class - **fixed** — Fix server-initiated request callbacks blocking the whole session when slow or deadlocking when sending requests themselves - **fixed** — Contain raising notification or request callbacks at the dispatcher to prevent them from taking down the connection - **fixed** — Implement timed-out or caller-cancelled request handling by sending notifications/cancelled to the peer - **fixed** — Fix server-to-client cancellation to actually interrupt the running client callback Second 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.0a2 #### or uv add "mcp==2.0.0a2" ``` See the [migration guide](https://github.com/modelcontextprotocol/python-sdk/blob/main/docs/migration.md) for the full list of breaking changes. ##### Highlights ###### Full 2026-07-28 types added along with per-version protocol types and version-gated wire validation (#2849) The SDK now ships three type sets: - `mcp.types` - the hand-maintained superset monolith. This remains the public API you import from; it covers every field from every supported spec version. - `mcp.types.v2025_11_25` - generated verbatim from the 2025-11-25 schema (also serves earlier versions). - `mcp.types.v2026_07_28` - generated verbatim from the 2026-07-28 schema. The generated per-version packages are wired into both `ServerRunner` and `ClientSession` via `mcp.types.methods`, which maps each `(method, version)` pair to its request/result/notification types. At runtime, the negotiated protocol version selects which generated set is used to validate traffic on the wire: - Inbound requests and notifications are validated against the negotiated version's types. A spec method that does not exist at that version returns `METHOD_NOT_FOUND`; a malformed payload returns `INVALID_PARAMS`. - Inbound results (in both directions) are validated against the negotiated version's result type before being parsed into the monolith type. - Outbound results are serialized through the negotiated version's type, so fields that only exist in a newer spec version are stripped before they reach an older peer. User code keeps working with the monolith `mcp.types`; the per-version packages are an internal validation layer. `2026-07-28` is modeled but not yet negotiable - `SUPPORTED_PROTOCOL_VERSIONS` is unchanged in this alpha. This makes validation stricter than a1: handlers that returned spec-invalid output (for example `Tool(inputSchema={})` without `"type": "object"`) now fail with `INTERNAL_ERROR`, and clients now reject spec-invalid server output that was previously tolerated. ###### ClientSession now runs on the dispatcher (#2838) `ClientSession` has been rewritten to sit on the same `JSONRPCDispatcher` receive path that `ServerRunner` adopted in a1, and `BaseSession` is removed. The public surface (constructor, typed request methods, `initialize()`, context-manager lifecycle) is unchanged, but the internals fix several long-standing v1 issues: - Server-initiated requests (sampling, elicitation, roots) now run concurrently instead of inline in the receive loop, so a slow callback no longer blocks the whole session and a callback that itself sends a request no longer deadlocks. - A raising notification or request callback is contained at the dispatcher and no longer takes down the connection. - Timed-out or caller-cancelled requests now send `notifications/cancelled` to the peer. - Server-to-client cancellation now actually interrupts the running client callback. A new keyword-only `dispatcher=` constructor argument lets you pass a pre-built dispatcher (for example `DirectDispatcher` for in-process embedding) instead of the read/write stream pair. ##### What's Changed * Fix unknown-method error code and add a protocol version registry by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2836 * Flush the stdio subprocess's coverage data before the clean-exit line by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2840 * Fix 404 links in v1 README to renamed example files by @jerome3o-anthropic in https://github.com/modelcontextprotocol/python-sdk/pull/2822 * [v2] ClientSession runs on JSONRPCDispatcher; BaseSession removed by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2838 * ci(conformance): pin harness to 0.2.0-alpha.3 with expected-failures baseline by @maxisbey in https://git _[Truncated at 4000 characters — full notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0a2]_ ### v1.28.0 - Date: 2026-06-16 - Version: v1.28.0 - Original notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.28.0 - Permalink: https://whatsnew.fyi/product/mcp-python-sdk/releases/v1.28.0 - **added** — Support Python 3.14 - **fixed** — Omit null optional fields from task result payloads - **deprecated** — WebSocket transport (mcp.client.websocket.websocket_client and mcp.server.websocket.websocket_server) will be removed in v2; use the streamable HTTP transport instead - **deprecated** — Experimental tasks API (ClientSession.experimental, Server.experimental, ServerSession.experimental, and experimental_task_handlers= kwarg) will be removed in v2 as tasks were removed from the MCP specification ##### Deprecations Two API surfaces now emit `DeprecationWarning` ahead of their removal in v2. Nothing is removed in 1.x, and the warnings fire only when the deprecated API is *called* - importing the modules stays silent. - **WebSocket transport** - `mcp.client.websocket.websocket_client` and `mcp.server.websocket.websocket_server`. WebSocket was never part of the MCP specification; use the streamable HTTP transport instead. The TypeScript SDK has likewise removed its WebSocket client for v2 (modelcontextprotocol/typescript-sdk#1783). - **Experimental tasks API** - `ClientSession.experimental`, `Server.experimental`, `ServerSession.experimental`, and the `experimental_task_handlers=` kwarg on `ClientSession`. Tasks (SEP-1686) were removed from the MCP specification and are expected to return as a separate MCP extension. If your test suite runs with `filterwarnings = ["error"]` and exercises these paths, add a scoped ignore such as `ignore:The experimental tasks API is deprecated:DeprecationWarning` or `ignore:The WebSocket .* transport is deprecated:DeprecationWarning`. See #2828 for full details. ##### What's Changed * [v1.x] Support Python 3.14 by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2769 * fix: omit null optional fields from task result payloads by @liuzemei in https://github.com/modelcontextprotocol/python-sdk/pull/2809 * [v1.x] Deprecate the WebSocket transport and the experimental tasks entry points by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2828 * [v1.x] Add a v2 status banner to the README by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2835 * [v1.x] Deflake the child process cleanup tests by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2839 ##### New Contributors * @liuzemei made their first contribution in https://github.com/modelcontextprotocol/python-sdk/pull/2809 **Full Changelog**: https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.2...v1.28.0 ### v2.0.0a1 - Date: 2026-06-11 - Version: v2.0.0a1 - Original notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0a1 - Permalink: https://whatsnew.fyi/product/mcp-python-sdk/releases/v2.0.0a1 - Labels: Pre-release - **added** — New Dispatcher pipeline on the server side to replace ServerSession - **changed** — Server interface now uses handlers as constructor parameters instead of decorators - **changed** — Server handler return values are no longer auto-wrapped - **added** — Server middleware, partially added - **changed** — Type changes throughout including snake_case field names and stricter validation - **changed** — FastMCP is renamed to MCPServer #### First V2 Alpha Release This is the first alpha of v2 of the MCP Python SDK. Publishing this alpha changes nothing for existing users. Installers don't pick up pre-releases unless you explicitly opt in, so if you do nothing you stay on v1.x. ##### Why v2 The upcoming MCP spec release (2026-07-28) has [significant protocol changes](https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/), including moving from a stateful, bidirectional protocol to stateless request/response. The v1 SDK is built around long-lived sessions, so supporting the new spec means replacing the SDK's core. Since that's breaking anyway, v2 also fixes some long-standing API problems. ##### What's in this alpha - A new Dispatcher pipeline replaces ServerSession on the server side (ServerSession remains as a thin proxy). The same change is coming to ClientSession, which will most likely stay as a shim. - The low level Server interface has changed quite a bit: handlers are now constructor parameters instead of decorators, and return values are no longer auto-wrapped. - Server middleware, partially added. - Type changes throughout, including snake_case field names and stricter validation. - FastMCP is renamed to MCPServer. The full list is in the [migration guide](https://github.com/modelcontextprotocol/python-sdk/blob/main/docs/migration.md), which is currently the most complete documentation for v2. **NOTE:** that this alpha release **only** implements the 2025-11-25 spec revision. Support for 2026-07-28 feature will be added over time through each alpha release with full 2026-07-28 support targeted for beta release on 2026-06-30. ##### Stability and timeline Right now v2 is very breaking, and each alpha will likely contain breaking changes from the previous one, so pin exact versions if you try it. Before the stable release we plan to add a good amount of backwards compatibility shims to reduce the breakage. Alphas run from now through late June, with a beta targeted for 2026-06-30 and stable v2 targeted for 2026-07-27 (the spec releases 2026-07-28). v1.x is the only stable version of the SDK for now: it stays in maintenance mode and continues to get critical bug fixes and security patches. ###### **TLDR**: - **Today (v2.0.0.a1)** - Only 2025-11-25 spec functionality support - **Today -> 2026-06-30** - New MCP 2026-07-28 spec functionality will be added to v2 alpha versions and released regularly during this time - Each alpha release during this should be considered breaking - **2026-06-30 (estimated)** - A beta version of the SDK will be released with full MCP 2026-07-28 spec support - **2026-07-01 -> 2026-07-27** - Bug fixes and cleanup - Ideally significantly less breaking that each alpha release, although not guaranteed - **2026-07-28** - A stable v2.0.0 version of the Python SDK will be released along side the MCP 2026-07-28 spec release. ##### What you should do If you maintain a package that depends on mcp, add an upper bound now. 84% of the 10,000+ PyPI packages that depend on mcp declare no upper bound, and they'll all resolve to v2 the day the stable release ships. Add `<2` to your existing constraint, for example `mcp>=1.27,<2`, and your users stay on v1 until you've migrated. If you want to try v2: ```shell pip install mcp==2.0.0a1 #### or uv add mcp==2.0.0a1 ``` One ask: only pin an mcp pre-release from a pre-release of your own package, otherwise you'll drag your users onto the alpha. Feedback is much appreciated in [#python-sdk-dev on the MCP Contributors Discord](https://discord.gg/6CSzBmMkjX), or open an issue with the `v2-alpha` label. ### v1.27.2 - Date: 2026-05-29 - Version: v1.27.2 - Original notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.27.2 - Permalink: https://whatsnew.fyi/product/mcp-python-sdk/releases/v1.27.2 - **added** — Add subject and claims to AccessToken - **changed** — Bind transport sessions to the authenticated principal - **changed** — Scope experimental tasks to the session that created them ##### What's Changed * [v1.x] ci: deploy docs to py.sdk.modelcontextprotocol.io via Pages artifact by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2635 * [v1.x] Add subject and claims to AccessToken by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2690 * [v1.x] Bind transport sessions to the authenticated principal by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2719 * [v1.x] Scope experimental tasks to the session that created them by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/2720 **Full Changelog**: https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.1...v1.27.2