Skip to content

v2.0.0a3

Pre-release
Pre-release

Choose a tag to compare

@maxisbey maxisbey released this 26 Jun 08:42
· 8 commits to main since this release
5873402

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

  • Pass a list to parametrize in test_docs_examples (pytest 9.1.0 compat) by @maxisbey in #2890
  • docs: add AI-assisted contribution policy to CONTRIBUTING.md by @maxisbey in #2887
  • Resolve protocol version per request and expose it as ctx.protocol_version by @maxisbey in #2886
  • tests/interaction: era-axis machinery for the requirements manifest by @maxisbey in #2909
  • ci(conformance): add 2026-07-28 carried-forward leg + bump harness to 0.2.0-alpha.4 by @maxisbey in #2911
  • Re-vendor 2026-07-28 schema and absorb spec #2907 error-code renumber by @maxisbey in #2912
  • Relax monolith ElicitRequestURLParams.elicitation_id for 2026-07-28 by @maxisbey in #2913
  • First end-to-end 2026-07-28 stateless tools/call (experimental entry + ClientSession pin) by @maxisbey in #2917
  • Add uv ecosystem to dependabot and drop weekly lockfile workflow by @Kludex in #2919
  • Return -32602 for resource not found (SEP-2164) by @Kludex in #2920
  • fix: correct MCPServer call_tool result type by @fengjikui in #2816
  • Ignore pre-2026 protocol_version pins at the StreamableHTTP transport by @maxisbey in #2923
  • Preserve empty URL paths on OAuth metadata models by @Kludex in #2925
  • Validate the iss authorization-response parameter (RFC 9207 / SEP-2468) by @Kludex in #2921
  • ci(conformance): bump harness to 0.2.0-alpha.5 preview by @maxisbey in #2927
  • Document redirect_uri wire-format change in OAuth migration note by @Kludex in #2929
  • Send application_type during Dynamic Client Registration (SEP-837) by @Kludex in #2930
  • Pass json-schema-ref-no-deref conformance scenario (SEP-2106) by @Kludex in #2924
  • Deprecate roots, sampling, and logging methods per SEP-2577 by @Kludex in #2926
  • Union previously requested scopes on step-up re-authorization (SEP-2350) by @Kludex in #2931
  • Move scope step-up test to top-level function by @Kludex in #2932
  • Bind client credentials to their authorization server (SEP-2352) by @Kludex in #2933
  • Server-side 2026-07-28 stateless support: classifier, driver split, server/discover by @maxisbey in #2928
  • OAuth client: harden SEP-2352/SEP-2350 edge cases; fix conformance comment by @maxisbey in #2936
  • Slim ServerMiddleware to (ctx, call_next) and add OpenTelemetryMiddleware by @Kludex in #2941
  • OAuth client: keep refresh_token on non-rotating refresh; restore same-origin issuer binding by @maxisbey in #2946
  • Buffer per-request StreamableHTTP streams to avoid serial-router head-of-line block by @maxisbey in #2934
  • lowlevel Server: widen on_* return types for InputRequiredResult; add subscriptions/listen slot by @maxisbey in #2967
  • Client-side 2026-07-28 support: .discover()/.adopt() + Client(mode=); request-metadata green by @maxisbey in #2950
  • Add GenAI semantic-convention attributes to OpenTelemetryMiddleware by @Kludex in #2970
  • Stop flagging snake_case is_error results as tool errors in OTel span by @Kludex in #2971
  • Client call_tool: input_responses/request_state retry params; InputRequiredResult via allow_input_required by @maxisbey in #2968
  • Split protocol types into a standalone mcp-types package by @Kludex in #2973
  • Set Development Status classifier to Production/Stable by @maxisbey in #2975
  • Conformance burn-down: server-side InputRequiredResult, Mcp-Method/Name validation, x-mcp-header filter (14 scenarios → green) by @maxisbey in #2974

New Contributors

Full Changelog: v2.0.0a2...v2.0.0a3