MCP Python SDK

Frameworks & Libraries

The official Python SDK for building Model Context Protocol servers and clients.

Latest v2.0.0 · by AnthropicWebsitemodelcontextprotocol/python-sdk

Release activity

Release activity — 10 releases across 8 days since May 29, 2026. Each cell is one day; darker means more releases that day. Nothing is recorded before May 29, 2026. Older weeks are hidden at this screen width.
MayJunJulAug
SundayNo releases on May 31, 2026No releases on Jun 7, 2026No releases on Jun 14, 2026No releases on Jun 21, 2026No releases on Jun 28, 2026No releases on Jul 5, 2026No releases on Jul 12, 2026No releases on Jul 19, 2026No releases on Jul 26, 2026No releases on Aug 2, 2026No releases on Aug 9, 2026
MondayNo releases on Jun 1, 2026No releases on Jun 8, 2026No releases on Jun 15, 2026No releases on Jun 22, 2026No releases on Jun 29, 2026No releases on Jul 6, 2026No releases on Jul 13, 2026No releases on Jul 20, 20261 release on Jul 27, 2026No releases on Aug 3, 2026No releases on Aug 10, 2026
TuesdayNo releases on Jun 2, 2026No releases on Jun 9, 20262 releases on Jun 16, 2026No releases on Jun 23, 20261 release on Jun 30, 2026No releases on Jul 7, 20261 release on Jul 14, 2026No releases on Jul 21, 20262 releases on Jul 28, 2026No releases on Aug 4, 2026No releases on Aug 11, 2026
WednesdayNo releases on Jun 3, 2026No releases on Jun 10, 2026No releases on Jun 17, 2026No releases on Jun 24, 2026No releases on Jul 1, 2026No releases on Jul 8, 2026No releases on Jul 15, 2026No releases on Jul 22, 2026No releases on Jul 29, 2026No releases on Aug 5, 2026
ThursdayNo releases on Jun 4, 20261 release on Jun 11, 2026No releases on Jun 18, 2026No releases on Jun 25, 2026No releases on Jul 2, 2026No releases on Jul 9, 2026No releases on Jul 16, 2026No releases on Jul 23, 2026No releases on Jul 30, 2026No releases on Aug 6, 2026
Friday1 release on May 29, 2026No releases on Jun 5, 2026No releases on Jun 12, 2026No releases on Jun 19, 20261 release on Jun 26, 2026No releases on Jul 3, 2026No releases on Jul 10, 2026No releases on Jul 17, 2026No releases on Jul 24, 2026No releases on Jul 31, 2026No releases on Aug 7, 2026
SaturdayNo releases on May 30, 2026No releases on Jun 6, 2026No releases on Jun 13, 2026No releases on Jun 20, 2026No releases on Jun 27, 2026No releases on Jul 4, 2026No releases on Jul 11, 2026No releases on Jul 18, 2026No releases on Jul 25, 2026No releases on Aug 1, 2026No releases on Aug 8, 2026

10 releases since May 29, 2026, busiest day 2

Changelog

v2.0.0

Added 7
  • 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
  • First-class Client object that negotiates protocol version automatically and connects to URLs, stdio subprocesses, custom transports, or server objects in memory
  • Resolve parameter for multi-round-trip requests allowing tools to return questions instead of answers in 2026-07-28 era
  • Pluggable extension APIs for composing protocol extensions with MCP Apps built in
  • OpenTelemetry tracing shipped by default
  • Standalone types package mcp-types (imported as mcp_types) published in lock-step with mcp
  • OAuth support for RFC 9207 issuer validation, SEP-990 identity-assertion flow, and client-credentials extension
Changed 8
  • 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
  • FastMCP renamed to MCPServer with decorator API unchanged but low-level Server rebuilt around a shared dispatcher engine
  • Client replaces v1's transport-plus-ClientSession-plus-initialize() layering with a single unified object
  • Per-version wire packages are now private (mcp_types._v*) with mcp.types as permanent alias for mcp_types
  • Client cache parameter changed from Client(cache=False) to cache=None with CacheConfig() as default
  • FileResource is_binary parameter renamed to encoding
  • Streamable HTTP servers now reject bodies over 4 MiB with HTTP 413
  • stdio servers keep handler subprocesses and stray prints off the wire with stdout diverted to stderr while serving
Fixed 1
  • Cancelled requests are no longer answered
Removed 2
  • Context.client_id, RFC7523OAuthClientProvider, and OAuthClientProvider(timeout=) removed
  • MCP_* environment variables removed with pydantic-settings
Deprecated 1
  • 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.

pip install "mcp[cli]"
# or
uv add "mcp[cli]"
Documentation Rewrite

The documentation has the full tutorial and API reference. Coming from v1? What's new in v2 is the tour of what changed and why, and the migration guide 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, 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 in 2.x.

Feedback

Something rough, confusing, or broken? Open an issue or find us in #python-sdk-dev on the MCP Contributors Discord.

Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v2.0.0rc1...v2.0.0

View originalPermalink
How v2.0.0 went

v1.29.0

Added 1
  • Add Streamable HTTP request body limits
Changed 1
  • Route Context.report_progress() to the originating request stream
Fixed 1
  • Reject trailing newline in tool-name validation
What's Changed

Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.28.1...v1.29.0

View originalPermalink
How v1.29.0 went

v2.0.0rc1

Pre-release
Added 1
  • stdio server decides the protocol era from the client's opening request, enabling subscriptions/listen and other 2026-07-28 features over stdio
Changed 9
  • Client(cache=False) is now Client(cache=None); CacheConfig() is the default and None switches the response cache off
  • Client-credentials OAuth providers now take scope= instead of scopes=
  • message_handler receives ServerNotification | Exception only; the RequestResponder arm and mcp.shared.session module are removed
  • FileResource(is_binary=...) is replaced by encoding: str | None
  • Streamable HTTP servers reject request bodies over 4 MiB with HTTP 413; raise max_request_body_size to accept larger messages
  • Request-side clientInfo _meta key is now optional; serverInfo moved out of server/discover result body into every 2026-era result's _meta
Removed 4
  • Context.client_id is removed; read _meta via ctx.request_context.meta or the authenticated client via get_access_token().client_id
  • RFC7523OAuthClientProvider and JWTParameters are removed; use ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider, or IdentityAssertionOAuthProvider
  • OAuthClientProvider(timeout=...) parameter is removed
  • MCP_* environment variables no longer configure MCPServer and pydantic-settings is dropped from runtime dependencies

First v2 release candidate. Pre-releases are opt-in only; pip install mcp still resolves to the stable 1.x line.

pip install mcp==2.0.0rc1
# or
uv add "mcp==2.0.0rc1"

The documentation has the full tutorial and API reference, and the migration guide 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 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) and the Windows tool-call hang (#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
New Contributors

Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v2.0.0b2...v2.0.0rc1

View originalPermalink
How v2.0.0rc1 went

v2.0.0b2

Pre-release
Added 3
  • Add client-side subscriptions/listen with context manager, async iteration, and typed events
  • Request cancellation now works on 2026 transports by closing POST/SSE streams or sending notifications/cancelled over stdio
  • Resolver dependency injection now supports Sample and ListRoots requests in addition to Elicit
Changed 4
  • Replace httpx and httpx-sse with httpx2 (>=2.5.0) as the HTTP stack
  • TLS verification now uses the operating system trust store via truststore instead of certifi's bundle
  • Logger names changed from httpx to httpx2 and httpcore.* to httpcore2.*
  • SSE GET streams now send Accept header with application/json, text/event-stream instead of exactly text/event-stream
Fixed 1
  • 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.

pip install mcp==2.0.0b2
# or
uv add "mcp==2.0.0b2"

The documentation has the full tutorial and API reference, and the migration guide 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 (>=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.

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
New Contributors

Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v2.0.0b1...v2.0.0b2

View originalPermalink
How v2.0.0b2 went

v2.0.0b1

Pre-release
Added 14
  • First v2 beta with full support for the 2026-07-28 MCP specification
  • ServerRunner as a pure handler kernel with thin transport drivers
  • New Client that auto-discovers server protocol version with server/discover and falls back to initialize
  • Protocol types as standalone mcp_types package depending only on pydantic and typing-extensions
  • Resolver dependency injection for tools to declare typed parameter requirements
  • RFC 6570 URI templates for resource definitions with full operator set and path-security validation
Changed 1
  • FastMCP renamed to MCPServer with snake_case fields and constructor-based handler parameters
Deprecated 1
  • 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. Pre-releases are opt-in only; pip install mcp still resolves to the stable 1.x line.

pip install mcp==2.0.0b1
# or
uv add "mcp==2.0.0b1"

The documentation has the full tutorial and API reference, and the migration guide 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 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 enterprise IdP flows, on top of the OAuth hardening from the alphas (RFC 9207, SEP-837, SEP-2350, SEP-2352).
  • Spec deprecations: roots, sampling, and logging/setLevel are deprecated per SEP-2577 - advisory warnings only; everything keeps working for sessions on 2025-11-25 or earlier.

v2 passes the official MCP conformance suite, client and server, except the tasks suite: tasks moved to an extension in 2026-07-28, and support is in review to ship in an upcoming pre-release.

Try it, tell us what breaks
  • Coming from v1? Start with the migration guide. v1.x remains the stable line and keeps getting critical bug fixes and security patches.
  • If your package depends on mcp, add a <2 upper bound now (for example mcp>=1.27,<2) so the stable release doesn't surprise your users.
  • Feedback is the most useful thing you can give us during the beta: open a v2 issue or find us in #python-sdk-dev on the MCP Contributors Discord.
What's Changed (since previous alpha)

Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v2.0.0a3...v2.0.0b1

View originalPermalink
How v2.0.0b1 went

v2.0.0a3

Pre-release
Added 7
  • Add ClientSession.discover() and ClientSession.adopt() methods alongside initialize()
  • Add Client mode parameter supporting 'legacy', 'auto', or specific version strings
  • Add Client prior_discover parameter
  • Add modern_on_request in-process driver for stateless path against in-memory servers
  • Extract protocol types into standalone mcp-types package with only pydantic and typing-extensions dependencies
  • Add subscriptions/listen handler slot
  • Add OpenTelemetryMiddleware that spans requests and notifications with OpenTelemetry GenAI semantic-convention attributes
Changed 10
  • Update LATEST_PROTOCOL_VERSION to 2026-07-28
  • Replace stateless bool flag with negotiable end-to-end protocol support via Connection object with from_envelope and for_loop factories
  • Refactor ServerRunner into pure handler kernel composed by three drivers: serve_one, serve_connection, and serve_loop
  • Add Connection object to own per-peer state with protocol_version always set
  • Make streamable-HTTP transport version-agnostic with per-message headers via CallOptions
  • Widen Server on_* return types to admit InputRequiredResult
Removed 2
  • Remove mcp.types module; import from mcp_types instead
  • Remove mcp.shared.version module; import from mcp_types.version instead
Deprecated 2
  • Deprecate SUPPORTED_PROTOCOL_VERSIONS in favour of HANDSHAKE_PROTOCOL_VERSIONS and MODERN_PROTOCOL_VERSIONS
  • 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.

pip install mcp==2.0.0a3
# or
uv add "mcp==2.0.0a3"

See the migration guide 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'|<version> 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 inbound message via replace(ctx, params=...) before the handler runs. A new context-tier OpenTelemetryMiddleware spans both requests and notifications and sets the OpenTelemetry GenAI semantic-convention attributes.

OAuth client conformance: RFC 9207, SEP-837, SEP-2350, SEP-2352 (#2921, #2930, #2931, #2933)

The OAuth client now validates the iss authorization-response parameter (RFC 9207), sends application_type during Dynamic Client Registration (SEP-837), unions previously requested scopes on step-up re-authorization (SEP-2350), and binds client credentials to the authorization server that issued them (SEP-2352). #2936 and #2946 harden the edge cases (refresh-token retention on non-rotating refresh, same-origin issuer binding).

Roots, sampling, and logging methods deprecated per SEP-2577 (#2926)

The user-facing methods for roots, sampling, and logging/setLevel are now marked with typing_extensions.deprecated. The deprecation is advisory only - capability negotiation and wire behaviour are unchanged, and everything keeps working for sessions negotiating 2025-11-25 or earlier.

What's Changed
New Contributors

Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v2.0.0a2...v2.0.0a3

View originalPermalink
How v2.0.0a3 went

v2.0.0a2

Pre-release
Added 3
  • Add generated per-version protocol types for 2025-11-25 and 2026-07-28 schemas alongside the hand-maintained superset monolith in mcp.types
  • Implement version-gated wire validation that selects the negotiated protocol version's type set at runtime for validating inbound requests, notifications, and results
  • Add dispatcher keyword-only constructor argument to ClientSession to support passing a pre-built dispatcher instead of read/write stream pair
Changed 3
  • Rewrite ClientSession to run on JSONRPCDispatcher receive path instead of inline, allowing server-initiated requests to run concurrently
  • Make validation stricter by returning INTERNAL_ERROR for spec-invalid handler output and rejecting spec-invalid server output at clients
  • Strip fields that only exist in newer spec versions from outbound results before they reach older peers
Fixed 4
  • Fix server-initiated request callbacks blocking the whole session when slow or deadlocking when sending requests themselves
  • Contain raising notification or request callbacks at the dispatcher to prevent them from taking down the connection
  • Implement timed-out or caller-cancelled request handling by sending notifications/cancelled to the peer
  • Fix server-to-client cancellation to actually interrupt the running client callback
Removed 1
  • Remove BaseSession class

Second v2 alpha. Pre-releases are opt-in only; pip install mcp still resolves to the stable 1.x line.

pip install mcp==2.0.0a2
# or
uv add "mcp==2.0.0a2"

See the migration guide 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

Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v2.0.0a1...v2.0.0a2

View originalPermalink
How v2.0.0a2 went

v1.28.0

Added 1
  • Support Python 3.14
Fixed 1
  • Omit null optional fields from task result payloads
Deprecated 2
  • WebSocket transport (mcp.client.websocket.websocket_client and mcp.server.websocket.websocket_server) will be removed in v2; use the streamable HTTP transport instead
  • 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
New Contributors

Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.2...v1.28.0

View originalPermalink
How v1.28.0 went

v2.0.0a1

Pre-release
Added 2
  • New Dispatcher pipeline on the server side to replace ServerSession
  • Server middleware, partially added
Changed 4
  • Server interface now uses handlers as constructor parameters instead of decorators
  • Server handler return values are no longer auto-wrapped
  • Type changes throughout including snake_case field names and stricter validation
  • 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, 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, 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:

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, or open an issue with the v2-alpha label.

View originalPermalink
How v2.0.0a1 went

v1.27.2

Added 1
  • Add subject and claims to AccessToken
Changed 2
  • Bind transport sessions to the authenticated principal
  • Scope experimental tasks to the session that created them
What's Changed

Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.1...v1.27.2

View originalPermalink
How v1.27.2 went
View all

Discussion