Skip to content

Back to the catalog

MCP Python SDK v2.2.0
github.comrepo

MCP Python SDK v2.2.0

Release notes for MCP Python SDK v2.2.0, the reference Python implementation of the Model Context Protocol. Key changes: HTTP client redirects are now restricted to the same origin as the endpoint, idle Streamable HTTP sessions expire after 30 minutes (with a 10,000-session cap), OAuth authorization server metadata issuer checks are now enforced on the legacy discovery path, and new deprecation warnings push toward requiring explicit `issuer=` and `validate_token_resource` settings ahead of a 3.0 release.

TL;DR MCP Python SDK 2.2.0 tightens redirect scoping, expires idle Streamable HTTP sessions, and enforces OAuth issuer validation, with deprecations previewing breaking changes in 3.0.
Also seen from another angle🛡️ Security →
Document

What it claims

v2.2.0 changes several defaults in the MCP Python SDK (pip install -U mcp) that can break existing 2.x servers and clients on upgrade. The headline shifts are around HTTP redirect handling, idle session expiry, and OAuth issuer validation — plus two new deprecation warnings that foreshadow required arguments in 3.0.

Behaviour changes to check before upgrading

  • Redirects are origin-scoped (#3397). Client(...), streamable_http_client and sse_client follow a redirect only if it stays on the same scheme/host/port (or upgrades http→https on the same host). Anything else fails with MCPError (SSE fails with httpx2.HTTPStatusError); the session stays usable. If the redirect target is really your server, set it as the endpoint URL directly. follow_redirects on a passed-in httpx2.AsyncClient is no longer used for MCP requests.
  • Idle stateful Streamable HTTP sessions now expire (#3395). A stateful session with nothing in flight for 30 minutes is closed; the client's next request gets a 404 and must re-initialize. Clients that keep the GET stream open (the SDK's own Client does) are unaffected, as are stateless servers and 2026-07-28 connections. A server also caps at 10,000 concurrent sessions — beyond that, new sessions get a 503.
  • Stricter OAuth issuer checks on the legacy path (#3398). Authorization-server metadata whose issuer isn't the server's own origin is rejected with OAuthFlowError: Authorization server metadata issuer mismatch. A 403 that isn't an insufficient_scope challenge is returned rather than retried; a 5xx/429 fetching protected-resource metadata now stops the flow instead of falling back to legacy endpoints.

Turning the new defaults off

mcp.run(transport="streamable-http", session_idle_timeout=None, max_sessions=None)

Same arguments exist on streamable_http_app() and run_streamable_http_async().

Deprecations aimed at 3.0

  • ClientCredentialsOAuthProvider / PrivateKeyJWTOAuthProvider without issuer= warn now; 3.0 will require it.
  • AuthSettings with resource_server_url set but validate_token_resource unset warns; 3.0 defaults it to True.
  • Both still work in 2.x — this bites mainly if your tests promote warnings to errors.

Also new: AuthSettings.validate_token_resource (accept only tokens your TokenVerifier reports as issued for this server, #3447). Fix: $refs in a tool's outputSchema now resolve within that schema only; unresolvable ones surface as RuntimeError: Invalid schema for tool ... (#3394).

Limits

The tasks extension (SEP-2663), DPoP (SEP-1932), and the jwt-bearer grant are not yet implemented; the repo's ROADMAP.md tracks them.

Organisations named here

  • Model Context Protocol

Technologies named here

  • MCP Python SDK
  • Client
  • streamable_http_client
  • sse_client
  • ClientCredentialsOAuthProvider
  • PrivateKeyJWTOAuthProvider
  • AuthSettings
  • TokenVerifier
  • streamable_http_app / run_streamable_http_async
  • Model Context Protocol
  • Python