NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #121 most downloaded on PyPI
Model Context Protocol SDK
Last release 2 days ago
02 Oct 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
2 years old
73 releases · first in 2024
One column per month.
pip install -U mcp . Docs: https://py.sdk.modelcontextprotocol.io/
pip install -U mcp. Docs: https://py.sdk.modelcontextprotocol.io/
Mostly fixes, plus three new options. A few things behave differently, so skim these first:
httpx2>=2.10.0 is now required (#3600)
>=2.5.0. The new max_sse_event_size option needs it.httpx2 below 2.10.A tool with an invalid x-mcp-header annotation fails at registration (#3620)
@mcp.tool(), add_tool and Tool.from_function raise InvalidSignature, naming the tool and the problem.str, int or bool parameter (so also str | None, float, lists and enums), a header name that isn't a valid token, and two names that differ only by case.Annotated[str | None, WithJsonSchema({"type": "string", "x-mcp-header": "Region"})] = None.Empty _meta and params are no longer sent (#3628)
"_meta": {} on every request. Some servers reject that. It is now left out, as in v1.ping and list requests without a cursor go out with no params member.ctx.meta is None rather than {}, and middleware sees ctx.params as None for a request without params.initialize leaves out experimental when none is configured (#3614)
"experimental": {}. server/discover already left it out.capabilities.experimental on a legacy connection should handle None.Mcp-Param-* validation looks the tool up by name (#3630)
MCPServer no longer runs tools/list for every tools/call, so middleware no longer sees that extra request.tools/list no longer affects it.An interactive OAuth login no longer counts against request timeouts (#3635)
OAuthClientProvider waits on redirect_handler and callback_handler.Client(mode="auto") settling on 2025-11-25 when the login took longer than 10 seconds.callback_handler if you need one.max_sse_event_size= on streamable_http_client and StreamableHttpParameters. The default stays 1 MiB per SSE event; raise it, or pass None, for larger tool results (#3600).MCPServer(subscriptions=False) stops serving subscriptions/listen and advertises listChanged and subscribe as false (#3626).Server(get_tool_input_schema=...) lets a low-level server supply a tool's schema for header validation without running its tools/list handler (#3630).Client.call_tool re-lists the tools and retries once after a HeaderMismatch (-32020) rejection (#3627).ctx: Context[AppState] works on prompts and resource templates, not only on tools (#3624)."structuredContent": null is checked against the output schema instead of being treated as missing (#3621).progress_callback that raises no longer fails the call on an in-process Client(server) (#3623).mode="auto", connecting to a server without server/discover now shows one ERROR span for the probe (#3629).stdio_client resolves the executable off the event loop on Windows (#3510).Full Changelog: v2.2.0...v2.3.0
Two new MCPDeprecationWarning s ( #3435 , #3447 )
pip install -U mcp. Docs: https://py.sdk.modelcontextprotocol.io/
A few defaults changed in this release. If you run a server or client on 2.x, skim these first:
HTTP client redirects are only followed within the endpoint's origin (#3397)
Client("https://..."), streamable_http_client and sse_client follow a redirect only if it stays on the same scheme, host and port (or upgrades http to https on the same host).MCPError and the session stays usable (an SSE connect fails with httpx2.HTTPStatusError). If that other URL is the server you meant, use it as the endpoint URL.follow_redirects setting on an httpx2.AsyncClient you pass in is no longer used for MCP requests, so you don't need it for the trailing-slash redirect any more.Idle Streamable HTTP sessions now expire (legacy <=2025-11-25 spec( (#3395)
Client does) are not affected. Neither are stateless servers or 2026-07-28 connections.mcp.run(transport="streamable-http", session_idle_timeout=None, max_sessions=None) (also on streamable_http_app() and run_streamable_http_async()).The OAuth client checks the authorization server's issuer on the legacy path too (#3398)
issuer isn't the server's own origin is now rejected with OAuthFlowError: Authorization server metadata issuer mismatch. The protected-resource-metadata path has done this since 2.0.insufficient_scope challenge is returned to the caller instead of retried.Two new MCPDeprecationWarnings (#3435, #3447)
ClientCredentialsOAuthProvider / PrivateKeyJWTOAuthProvider without issuer=. Pass your authorization server's issuer URL; 3.0 will require it.AuthSettings with resource_server_url set but validate_token_resource unset. Set it to True or False; 3.0 defaults it to True.AuthSettings.validate_token_resource: only accept tokens your TokenVerifier reports as issued for this server (#3447).issuer= on ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider (#3398).session_idle_timeout= and max_sessions= on the Streamable HTTP server entry points (#3395).DELETE frees its session immediately, and a refused opening request no longer leaves a session behind (#2455, #3228, #3300).$refs in a tool's outputSchema resolve within that schema only; an unresolvable one surfaces as RuntimeError: Invalid schema for tool ... (#3394).The tasks extension (SEP-2663), DPoP (SEP-1932) and the jwt-bearer grant are not implemented yet; https://github.com/modelcontextprotocol/python-sdk/blob/main/ROADMAP.md tracks them.
Full Changelog: v2.1.1...v2.2.0
Point imports of mcp.server.fastmcp at the migration guide by @maxisbey in #3388
Full Changelog: v2.1.0...v2.1.1
Stop framing breaking changes as a workflow in AGENTS.md by @maxisbey in #3286
Client accepts StdioServerParameters directly: Client(StdioServerParameters(command="uv", args=["run", "server.py"])) (#3321).Image and Audio, prompt functions may return bare content blocks, and Message / UserMessage / AssistantMessage are exported from mcp.server.mcpserver (#3320).SseServerTransport and MCPServer.sse_app() take max_request_body_size, and the SSE message endpoint answers 405 to non-POST requests (#3336).Error executing tool <name> (or the resource/prompt equivalent) rather than the exception text. Raise ToolError / ResourceError when the message is meant for the model; those still reach the client and are logged at INFO without a traceback.TextContent, EmbeddedResource, Image, Audio, or lists/unions of them no longer advertises outputSchema or returns structuredContent; its content is unchanged. Pass structured_output=True to keep the previous shape.NotRequired keys are omitted instead of serialized as null, and registration no longer fails on Python 3.10 (#3224, #3227); recursive return types get an object-rooted outputSchema that pre-2026 clients accept (#3337).notifications/cancelled is acknowledged with 202 instead of rejected with 400 (#3324).list_tools() (#3223), and accept boolean sub-schemas in tool schema properties (#3353).mcp install reads and preserves a Claude Desktop config containing non-ASCII text on any Windows code page (#3296).Full Changelog: v2.0.0...v2.1.0
One off backport of the FastMCP import warning for 2.0.x , this is due to a lot of people running into this error and making issues on other repos abo
One off backport of the FastMCP import warning for 2.0.x, this is due to a lot of people running into this error and making issues on other repos about it. Ideally either pin mcp<2 or upgrade to 2.
Full Changelog: v2.0.0...v2.0.1
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…
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]"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.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).
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 ClientThe 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.
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.
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.
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.
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.
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.
Something rough, confusing, or broken? Open an issue or find us in #python-sdk-dev on the MCP Contributors Discord.
Full Changelog: v2.0.0rc1...v2.0.0
Remove the deprecated RFC7523OAuthClientProvider by @maxisbey in #3169
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.
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).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).max_request_body_size if you accept larger messages (#3095).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.
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_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).
exclude-newer cooldown: mcp pins mcp-types to the exact same version, so exempt both packages - exclude-newer-package = { mcp = false, mcp-types = false }.Full Changelog: v2.0.0b2...v2.0.0rc1
Second v2 beta. Pre-releases are opt-in only; pip install mcp still resolves to the stable 1.x line.
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.
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:
truststore) instead of certifi's bundle. SSL_CERT_FILE / SSL_CERT_DIR are honored first.httpx -> httpx2, httpcore.* -> httpcore2.* - update logging filters that match on those names.Accept: application/json, text/event-stream (previously exactly text/event-stream).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.
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.
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.
exclude-newer cooldown: mcp pins mcp-types to the exact same version, so exempt both packages - exclude-newer-package = { mcp = false, mcp-types = false }.Full Changelog: v2.0.0b1...v2.0.0b2
Spec deprecations : roots, sampling, and logging/setLevel are deprecated per SEP-2577 - advisory warnings only; everything keeps working for sessions…
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.
The whole v2 line so far (alphas included), condensed:
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.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).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.Client(extensions=[...]).(ctx, call_next), and OpenTelemetry tracing ships on by default with GenAI semantic conventions.Client and server:
server/discover, scale-out on plain HTTP with no session affinity - progress and log notifications stream within the same single POST exchange.MCPServer, requestState is sealed by default (authenticated encryption) so clients cannot read or forge it.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).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.
mcp, add a <2 upper bound now (for example mcp>=1.27,<2) so the stable release doesn't surprise your users.Full Changelog: v2.0.0a3...v2.0.0b1
See the migration guide for the full list of breaking changes.
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.
The public API is likely to change between alpha releases, and ideally less-so between beta releases.
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.
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.
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.
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).
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.
iss authorization-response parameter (RFC 9207 / SEP-2468) by @Kludex in #2921redirect_uri wire-format change in OAuth migration note by @Kludex in #2929application_type during Dynamic Client Registration (SEP-837) by @Kludex in #2930(ctx, call_next) and add OpenTelemetryMiddleware by @Kludex in #2941mcp-types package by @Kludex in #2973Full Changelog: v2.0.0a2...v2.0.0a3
See the migration guide for the full list of breaking changes.
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.
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:
METHOD_NOT_FOUND; a malformed payload returns INVALID_PARAMS.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 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:
notifications/cancelled to the peer.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.
Full Changelog: v2.0.0a1...v2.0.0a2
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…
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.
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.
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.
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.
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.
Two new DeprecationWarning s ( #3431 , #3451 )
Maintenance release of the 1.x line. 2.x is the current line; 1.x docs are at https://py.sdk.modelcontextprotocol.io/v1/.
A few defaults changed in this release. If you run a server or client on 1.x, skim these first:
HTTP client redirects are only followed within the endpoint's origin (#3448)
streamable_http_client and sse_client follow a redirect only if it stays on the same scheme, host and port (or upgrades http to https on the same host).httpx.HTTPStatusError. If that other URL is the server you meant, use it as the endpoint URL.follow_redirects setting on an httpx.AsyncClient you pass in is no longer used for MCP requests, so you don't need it for the trailing-slash redirect any more.OAuthClientProvider applies the same rule to its own requests.Idle Streamable HTTP sessions now expire (#3426)
FastMCP(..., session_idle_timeout=None, max_sessions=None).The OAuth client checks the authorization server's issuer (#3431)
issuer doesn't match the server it was fetched for is now rejected with OAuthFlowError: Authorization server metadata issuer mismatch.Two new DeprecationWarnings (#3431, #3451)
ClientCredentialsOAuthProvider / PrivateKeyJWTOAuthProvider without issuer=. Pass your authorization server's issuer URL.AuthSettings with resource_server_url set but validate_token_resource unset. Set it to True or False.AuthSettings.validate_token_resource: only accept tokens your TokenVerifier reports as issued for this server (#3451).issuer= on ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider (#3431).session_idle_timeout= and max_sessions= on FastMCP (#3426).Full Changelog: v1.29.1...v1.30.0
[v1.x] Complete the FastMCP Settings model at import time by @maxisbey in #3352
Full Changelog: v1.29.0...v1.29.1
[v1.x] Route Context.report_progress() to the originating request stream by @maxisbey in #2994
Full Changelog: v1.28.1...v1.29.0
[v1.x] Buffer per-request StreamableHTTP streams; store priming event before dispatch by @maxisbey in #2948
Full Changelog: v1.28.0...v1.28.1
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 A…
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.
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).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.
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.2...v1.28.0
[v1.x] ci: deploy docs to py.sdk.modelcontextprotocol.io via Pages artifact by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/26
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.1...v1.27.2
[v1.x] fix: catch PydanticUserError when generating output schema (pydantic 2.13 compat) by @maxisbey in https://github.com/modelcontextprotocol/pytho
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.0...v1.27.1
fix: remove unused requests dependency from simple-chatbot example by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/1959
requests dependency from simple-chatbot example by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/1959Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.26.0...v1.27.0
ci: add all-green job to pull-request-checks workflow by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/1929
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.25.0...v1.26.0
`main` — v2 development (breaking changes)
Starting with this release, the repository has adopted a new branching strategy for v2 development:
main — v2 development (breaking changes)v1.x — v1 maintenance (security and critical bug fixes only, with very rare feature additions ported from main)Users who need to stay on v1.x should pin to mcp>=1.25,<2.
The current plan is to work through v2 and have it released some time in Q1. This also relies on the next upcoming spec release which will heavily change how the transport layer works, which in turn will guide a lot of how we architect v2.
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.24.0...v1.25.0
feat: client-side support for SEP-1577 sampling with tools by @jlowin in https://github.com/modelcontextprotocol/python-sdk/pull/1722
streamable_http_client which accepts httpx.AsyncClient instead of httpx_client_factory by @Kludex in https://github.com/modelcontextprotocol/python-sdk/pull/1177Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.23.3...v1.24.0
refactor(auth): remove unused _register_client method by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/1748
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.23.2...v1.23.3
fix: add lifespan context manager to StreamableHTTP mounting examples by @TheMailmans in https://github.com/modelcontextprotocol/python-sdk/pull/1669
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.23.1...v1.23.2
chore: update LATEST_PROTOCOL_VERSION to 2025-11-25 by @felixweinberger in https://github.com/modelcontextprotocol/python-sdk/pull/1715
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.23.0...v1.23.1
This release brings us up to speed with the latest MCP spec 2025-11-25. Take a look at the latest spec as well as the release blog post.
This release brings us up to speed with the latest MCP spec 2025-11-25. Take a look at the latest spec as well as the release blog post.
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.22.0...v1.23.0
feat: Pass through and expose additional parameters in ClientSessionGroup.call_tool and .connect_to_server by @inaku-Gyan in https://github.com/modelc
ClientSessionGroup.call_tool and .connect_to_server by @inaku-Gyan in https://github.com/modelcontextprotocol/python-sdk/pull/1576jsonschema library by @wuliang229 in https://github.com/modelcontextprotocol/python-sdk/pull/1596Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.21.1...v1.22.0
This is a hotfix release to address a critical bug in OAuth scope handling that caused failures on 401 responses.
This is a hotfix release to address a critical bug in OAuth scope handling that caused failures on 401 responses.
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.21.1...v1.21.2
Add everything-server for comprehensive MCP conformance testing by @felixweinberger in https://github.com/modelcontextprotocol/python-sdk/pull/1587
func_metadata() implementation by @Viicos in https://github.com/modelcontextprotocol/python-sdk/pull/1496Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.21.0...v1.21.1
docs: use article "an" before "MCP" instead of "a" by @koic in https://github.com/modelcontextprotocol/python-sdk/pull/1558
ClientSessionGroup doc string by @inaku-Gyan in https://github.com/modelcontextprotocol/python-sdk/pull/1572Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.20.0...v1.21.0
fix: replace deprecated dev-dependencies in examples/clients by @yukuanj in https://github.com/modelcontextprotocol/python-sdk/pull/1518
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.19.0...v1.20.0
fix: uv CVE-2025-62518 astral-tokio-tar issue GHSA-j5gw-2vrg-8fgx by @cclauss in https://github.com/modelcontextprotocol/python-sdk/pull/1505
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.18.0...v1.19.0
[client] Implement MCP OAuth scope selection and step-up authorization by @dogacancolak in https://github.com/modelcontextprotocol/python-sdk/pull/132
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.17.0...v1.18.0
Add documentation structure by @Kludex in https://github.com/modelcontextprotocol/python-sdk/pull/1425
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.16.0...v1.17.0
Add error log for client stdio by @pengwa in https://github.com/modelcontextprotocol/python-sdk/pull/924
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/1.15.0...v1.16.0
Return HTTP 403 for invalid Origin headers by @pja-ant in https://github.com/modelcontextprotocol/python-sdk/pull/1353
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.14.1...v1.15.0
fix(fastmcp): propagate mimeType in resource template list by @pchoudhury22 in https://github.com/modelcontextprotocol/python-sdk/pull/1186
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.14.0...v1.14.1
Update simple-resource example to use non-deprecated read_resource return type by @pja-ant in https://github.com/modelcontextprotocol/python-sdk/pull/…
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.13.1...v1.14.0
chore: uncomment .idea/ in .gitignore by @maxisbey in https://github.com/modelcontextprotocol/python-sdk/pull/1287
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.13.0...v1.13.1
Add pyright strict mode on the whole project by @Kludex in https://github.com/modelcontextprotocol/python-sdk/pull/1254
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.12.4...v1.13.0
chore: Remove unused prompt_manager.py file by @chughtapan in https://github.com/modelcontextprotocol/python-sdk/pull/1229
response_modes_supported member of OAuthMetadata by @joesavage-silabs in https://github.com/modelcontextprotocol/python-sdk/pull/1243Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.12.3...v1.12.4
server: skip duplicate response on CancelledError by @lukacf in https://github.com/modelcontextprotocol/python-sdk/pull/1153
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.12.2...v1.12.3
update codeowners group by @ihrpr in https://github.com/modelcontextprotocol/python-sdk/pull/1191
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.12.1...v1.13.0
Add CODEOWNERS file for sdk by @ihrpr in https://github.com/modelcontextprotocol/python-sdk/pull/1169
RequestId is not coerced as int by @Kludex in https://github.com/modelcontextprotocol/python-sdk/pull/1178Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.12.0...v1.12.1
Ensure failed oauth registration response is read before accessing response.text by @jlowin in https://github.com/modelcontextprotocol/python-sdk/pull
inline_snapshot.Is on parametrized test by @Kludex in https://github.com/modelcontextprotocol/python-sdk/pull/945Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.11.0...v1.12.0
Update MCP to use Pydantic>=2.11 by @medaminezghal in https://github.com/modelcontextprotocol/python-sdk/pull/1041
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.10.1...v1.11.0
Remove setting global logging config by @njbrake in https://github.com/modelcontextprotocol/python-sdk/pull/1048
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.10.0...v1.10.1
feat: implement MCP-Protocol-Version header requirement for HTTP transport by @felixweinberger in https://github.com/modelcontextprotocol/python-sdk/p
/.well-known/oauth-authorization-server dropping path by @ihrpr in https://github.com/modelcontextprotocol/python-sdk/pull/1014Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.9.4...v1.10.0
Support Cursor OAuth client registration by @sam-tombury in https://github.com/modelcontextprotocol/python-sdk/pull/895
total_seconds instead of seconds on timeout by @Kludex in https://github.com/modelcontextprotocol/python-sdk/pull/896FileUrl on the resources/list call in the simple-resource example by @nandsha in https://github.com/modelcontextprotocol/python-sdk/pull/907Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.9.3...v1.9.4
improve server logging by @samuelcolvin in https://github.com/modelcontextprotocol/python-sdk/pull/867
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.9.2...v1.9.3
llamallama-3.2-90b-vision-preview is deprecated by @Arash-IND in https://github.com/modelcontextprotocol/python-sdk/pull/523
ClientSessionGroup cleanup logic by @mkeid in https://github.com/modelcontextprotocol/python-sdk/pull/787OAuthAuthorizationServerProvider snippet in README.md by @alvarobartt in https://github.com/modelcontextprotocol/python-sdk/pull/830Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.9.1...v1.9.2
Add OAuth authentication client for HTTPX by @ihrpr in https://github.com/modelcontextprotocol/python-sdk/pull/751
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.9.0...v1.9.1
Now the latest protocol version for Python SDK is 2025-03-26
Now the latest protocol version for Python SDK is 2025-03-26
ClientSessionGroup for managing multiple session connections. by @mkeid in https://github.com/modelcontextprotocol/python-sdk/pull/639Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.8.1...v1.9.0
Fix streamable http sampling by @ihrpr in https://github.com/modelcontextprotocol/python-sdk/pull/693
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.8.0...v1.8.1
This is the first release supporting the new Streamable HTTP transport from protocol version 2025-03-26, which supersedes the SSE transport from proto
This is the first release supporting the new Streamable HTTP transport from protocol version 2025-03-26, which supersedes the SSE transport from protocol version 2024-11-05. 🎉 Please report any issues at https://github.com/modelcontextprotocol/python-sdk/issues
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.7.0...v1.8.0
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.7.0...v1.7.1
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.7.0...v1.7.1
Add support for serverside oauth by @praboud-ant in https://github.com/modelcontextprotocol/python-sdk/pull/255
Docs: Change README to correct pip installation command for MCP CLI support by @codingjenny in https://github.com/modelcontextprotocol/python-sdk/pull/394
Fix python -m command error by @xuzexin-hz in https://github.com/modelcontextprotocol/python-sdk/pull/387
Docs : Enhance README to suggest commands for creating a new UV project before adding mcp dependency. by @anupsajjan in https://github.com/modelcontextprotocol/python-sdk/pull/408
Fix lifespan_context access example in README by @SigureMo in https://github.com/modelcontextprotocol/python-sdk/pull/437
Match ruff version on CI and local by @Kludex in https://github.com/modelcontextprotocol/python-sdk/pull/471
Fix @mcp.tool() Failing to Detect Context Argument When Type Variables Are Used in Context by @jkawamoto in https://github.com/modelcontextprotocol/python-sdk/pull/358
Support custom client info throughout client APIs by @jerome3o-anthropic in https://github.com/modelcontextprotocol/python-sdk/pull/474
Fix tests for Pydantic 2.11 by @medaminezghal in https://github.com/modelcontextprotocol/python-sdk/pull/465
Move uvicorn import to usage by @danlapid in https://github.com/modelcontextprotocol/python-sdk/pull/502
Python lint: Ruff rules for comprehensions and performance by @cclauss in https://github.com/modelcontextprotocol/python-sdk/pull/512
Format files with ruff by @ihrpr in https://github.com/modelcontextprotocol/python-sdk/pull/562
replace inefficient use of to_jsonable_python by @samuelcolvin in https://github.com/modelcontextprotocol/python-sdk/pull/545
add a timeout arguments on per-request basis (as per MCP specifications) by @grll in https://github.com/modelcontextprotocol/python-sdk/pull/601
add pytest-pretty dev dependency by @samuelcolvin in https://github.com/modelcontextprotocol/python-sdk/pull/546
Properly clean up response streams in BaseSession by @bhosmer-ant in https://github.com/modelcontextprotocol/python-sdk/pull/515
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.6.0...v1.7.0
Fix #201: Move incoming message stream from BaseSession to ServerSession by @dsp-ant in https://github.com/modelcontextprotocol/python-sdk/pull/325
Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.5.0...v1.6.0
Strict types on the client side by @Kludex in https://github.com/modelcontextprotocol/python-sdk/pull/285
cwd to StdioServerParameters by @samuelcolvin in https://github.com/modelcontextprotocol/python-sdk/pull/292env is provided by @maxguru in https://github.com/modelcontextprotocol/python-sdk/pull/327Full Changelog: https://github.com/modelcontextprotocol/python-sdk/compare/v1.4.1...v1.4.2
Your coding agent can read these notes before it upgrades. Set up the MCP server →