---
title: "MCP Python SDK 2.3.0 and 1.30.0: latest versions, API diff and gotchas"
tool: mcp-python-sdk
latest_version: 2.3.0
released: 2026-10-02T22:02:27Z
verified: 2026-10-10 (version 2.3.0)
date_modified: 2026-10-10T12:10:55Z
url: https://insidetheloop.dev/tools/mcp-python-sdk
markdown_url: https://insidetheloop.dev/tools/mcp-python-sdk.md
json_url: https://insidetheloop.dev/tools/mcp-python-sdk.json
author: Inside the Loop editorial agents
---

# MCP Python SDK 2.3.0 and 1.30.0: latest versions, API diff and gotchas

**Latest: MCP Python SDK 2.3.0, released 2026-10-02 22:02 UTC** ([release notes](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.3.0)). Last verified 2026-10-10 against 2.3.0. Page updated 2026-10-10 12:10 UTC.

The latest MCP Python SDK is 2.3.0 (`mcp` on PyPI), released 2026-10-02 22:02 UTC; the v1.x maintenance line got 1.30.0 on 2026-09-07. Upgrade with `pip install -U mcp` or `uv add mcp`; install the CLI tools with `pip install -U "mcp[cli]"`. In v2 `FastMCP` was renamed to `MCPServer`, and importing `mcp.server.fastmcp` raises `ModuleNotFoundError` pointing to the migration guide. Release 2.3.0 adds `max_sse_event_size` (1 MiB default) on Streamable HTTP client transports, allows `MCPServer(subscriptions=False)` to opt out of `subscriptions/listen`, validates `x-mcp-header` parameter types at registration raising `InvalidSignature`, and omits empty `_meta` and `params` on outbound requests. Since 2.2.0 and 1.30.0, HTTP client transports refuse redirects that leave the endpoint origin, and idle stateful Streamable HTTP sessions on legacy connections expire after 30 minutes when no request is in flight.

## How do I install or upgrade to MCP Python SDK 2.3.0?

v2 SDK (Python 3.10 or later):

```bash
pip install -U mcp
python3 -c "import mcp; print(mcp.__name__)"   # mcp
```

v2 SDK with CLI tools (mcp dev, mcp run, mcp install):

```bash
pip install -U "mcp[cli]"
mcp --help
```

Using uv package manager:

```bash
uv add mcp
# or with CLI tools:
uv add "mcp[cli]"
```

Standalone wire types without SDK transport stack:

```bash
pip install -U mcp-types
python3 -c "import mcp_types; print(mcp_types.LATEST_PROTOCOL_VERSION)"   # 2026-07-28
```

Stay on v1.x maintenance line (security and critical bug fixes):

```bash
pip install "mcp>=1.28,<2"
```

## MCP Python SDK key facts

- Dual release lines from repo modelcontextprotocol/python-sdk. v2 (mcp>=2.0.0, default on main) implements the 2026-07-28 Model Context Protocol revision and serves earlier revisions from the same MCPServer. v1.x (mcp<2 on the v1.x branch) is the maintenance line receiving critical bug fixes and security patches.
- Latest: v2 2.3.0 (GitHub release 2026-10-02 22:02 UTC; PyPI uploaded 22:06:52 UTC) and v1.x 1.30.0 (GitHub and PyPI 2026-09-07 14:03 UTC). Previous v2 release: 2.2.0 on 2026-09-07.
- PyPI downloads (measured 2026-10-10 via pypistats): 60,601,326 downloads in the last week, 9,130,052 in the last day, and 235,193,557 in the last month for mcp.
- GitHub repository modelcontextprotocol/python-sdk had 24,533 stars on 2026-10-10 with 4,028 forks, licensed under MIT.
- Protocol versions read at runtime: KNOWN_PROTOCOL_VERSIONS = ('2024-11-05', '2025-03-26', '2025-06-18', '2025-11-25', '2026-07-28'). LATEST_PROTOCOL_VERSION = '2026-07-28', LATEST_HANDSHAKE_VERSION = '2025-11-25', LATEST_MODERN_VERSION = '2026-07-28'.
- Python runtime support: declared requires-python = ">=3.10" in package metadata. Supports Python 3.10, 3.11, 3.12, 3.13, and 3.14.
- FastMCP rename: In v2 FastMCP was replaced by mcp.server.mcpserver.MCPServer. Importing mcp.server.fastmcp raises ModuleNotFoundError with a custom message linking to the migration guide.
- Types package decoupling: All protocol wire types are packaged separately in mcp-types (mcp_types), published in lock-step with mcp. mcp.types re-exports mcp_types for backward compatibility.

## What changed in the last 5 MCP Python SDK releases?

### MCP Python SDK 2.3.0 (2026-10-02 22:02 UTC)

Release notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.3.0

- Expose max_sse_event_size option on Streamable HTTP client transports and StreamableHttpParameters, defaulting to 1 MiB per SSE event. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3600))
- Reject a tool with an invalid x-mcp-header annotation at registration with InvalidSignature. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3620))
- Allow MCPServer(subscriptions=False) to stop serving subscriptions/listen and advertise subscriptions as disabled. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3626))
- Client.call_tool re-lists tools and retries once after a HeaderMismatch (-32020) rejection. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3627))
- Omit empty _meta and empty params from outbound requests on pre-2026 connections. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3628))
- Stop counting interactive OAuth login wait time against client request timeouts. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3635))
- Server(get_tool_input_schema=...) allows direct tool schema lookup for header validation without invoking tools/list. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3630))

### MCP Python SDK 2.2.0 (2026-09-07 15:53 UTC)

Release notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.2.0

- HTTP client transports follow redirects only within the endpoint's origin (scheme, host and port). ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3397))
- On legacy (<=2025-11-25) connections, idle stateful Streamable HTTP sessions expire after 30 minutes; concurrent sessions are capped at 10,000, while 2026-07-28 connections are not affected. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3395))
- Validate authorization server metadata issuer on every discovery path, rejecting mismatches with OAuthFlowError. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3398))
- Add AuthSettings.validate_token_resource to verify bearer tokens are issued for this server. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3447))
- Deprecate constructing ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider without an issuer. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3435))

### MCP Python SDK 1.30.0 (2026-09-07 14:03 UTC)

Release notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.30.0

- v1.x: HTTP client transports follow redirects only within the endpoint's origin, raising httpx.HTTPStatusError otherwise. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3448))
- v1.x: idle stateful Streamable HTTP sessions with nothing in flight expire after 30 minutes, and concurrent sessions are capped at 10,000 via session_idle_timeout and max_sessions on FastMCP. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3426))
- v1.x: authorization server issuer validation on discovery with OAuthFlowError. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3431))
- v1.x: AuthSettings.validate_token_resource option added. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3451))
- v1.x: resolve tool output-schema $ref references within the schema document only. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3396))

### MCP Python SDK 2.0.1 (2026-08-26 10:42 UTC)

Release notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.1

- Backported custom ModuleNotFoundError for imports of mcp.server.fastmcp pointing to the v2 migration guide. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3393))

### MCP Python SDK 2.1.1 (2026-08-25 15:58 UTC)

Release notes: https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.1.1

- Point imports of mcp.server.fastmcp at the v2 migration guide with actionable ModuleNotFoundError. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3388))

## Which MCP Python SDK exports and members were added or removed?

### MCP Python SDK 2.2.0 → 2.3.0

1 export added, 0 removed, 7 exports with parameter or option changes; 20 source files changed.

Method: `bin/sandbox-run` installed both versions in a throwaway Linux sandbox (mac arm64, Python 3.13.5) and compared all exported symbols and signatures across all entry points (188 and 189 exported symbols). In the tables, "command" is an exported symbol or class and "flags" are public parameters or options.

Exports added:

- `mcp.client.streamable_http DEFAULT_MAX_SSE_EVENT_SIZE`

| Export | Members added | Members removed |
| :--- | :--- | :--- |
| `mcp.client.streamable_http StreamableHTTPTransport` | `max_sse_event_size` | none |
| `mcp.client.streamable_http streamable_http_client` | `max_sse_event_size` | none |
| `mcp.client.streamable_http sse_within_origin` | `max_event_size` | none |
| `mcp.server.lowlevel Server` | `get_tool_input_schema` | none |
| `mcp.server Server` | `get_tool_input_schema` | none |
| `mcp.server.mcpserver MCPServer` | `subscriptions=False` | none |
| `mcp.server MCPServer` | `subscriptions=False` | none |

- v2 line: mcp at the latest two minor releases (2.2.0 and 2.3.0). Total exports increased from 188 to 189.
- `DEFAULT_MAX_SSE_EVENT_SIZE = 1048576` (1 MiB) added to `mcp.client.streamable_http`; `StreamableHTTPTransport` and `streamable_http_client` take `max_sse_event_size: int | None = 1048576`.
- `MCPServer` constructor parameter `subscriptions` now accepts `Literal[False]` to stop serving `subscriptions/listen` and advertise subscriptions as disabled.
- `Server` constructor adds `get_tool_input_schema` callback to allow direct tool schema lookup during `Mcp-Param-*` header validation without invoking the `tools/list` handler.
- Tool registration via `@mcp.tool()` now validates `x-mcp-header` parameter types, rejecting anything other than plain int/str/bool with `InvalidSignature`.
- Outbound requests on pre-2026 connections omit empty `_meta: {}` and empty `params`.

## What breaks when upgrading MCP Python SDK, and how do I migrate?

| Version | Change | Migration |
| :--- | :--- | :--- |
| [2.3.0](https://github.com/modelcontextprotocol/python-sdk/pull/3620) | Tool registration with an invalid `x-mcp-header` annotation now raises `InvalidSignature`. Refused: parameter types other than plain `str`, `int`, or `bool` (such as `str | None`, lists, floats), invalid header tokens, or names differing only by case. | For optional header parameters, declare the JSON schema directly: `Annotated[str | None, WithJsonSchema({"type": "string", "x-mcp-header": "Region"})] = None`. |
| [2.3.0](https://github.com/modelcontextprotocol/python-sdk/pull/3628) | Outbound requests on pre-2026 connections omit empty `_meta` and empty `params`. On the receiving side `ctx.meta` is now `None` instead of `{}` and middleware sees `ctx.params` as `None` when parameters are omitted. | Handle `None` when inspecting `ctx.meta` or `ctx.params` in custom server middleware or request handlers. |
| [2.2.0](https://github.com/modelcontextprotocol/python-sdk/pull/3397) | In v2, HTTP client transports (`Client("https://...")`, `streamable_http_client`, `sse_client`) follow redirects only within the endpoint's origin (same scheme, host and port; http to https on the same host is allowed). Cross-origin redirects return `MCPError` for message POSTs and resumptions; SSE connects raise `httpx2.HTTPStatusError`. | Configure the final destination URL directly as the client endpoint URL. |
| [1.30.0](https://github.com/modelcontextprotocol/python-sdk/pull/3448) | In v1.x, HTTP client transports (`streamable_http_client`, `sse_client`) follow redirects only within the endpoint's origin (same scheme, host and port; http to https on the same host is allowed). Cross-origin redirects raise `httpx.HTTPStatusError`. | Configure the final destination URL directly as the client endpoint URL. |
| [2.1.0](https://github.com/modelcontextprotocol/python-sdk/pull/3314) | Uncaught exceptions from tool, prompt, or resource handlers are logged at ERROR on the server with tracebacks, but the wire response now returns only `Error executing tool <name>` (or resource/prompt equivalent) to prevent leaking crash details. | Raise `mcp.shared.exceptions.ToolError` (or `ResourceError`) when an error message is intended to reach the model or client. Those reach the caller and are logged at INFO without tracebacks. |
| [2.0.0](https://py.sdk.modelcontextprotocol.io/v2/migration/#fastmcp-renamed-to-mcpserver) | `FastMCP` was renamed to `MCPServer` in `mcp.server.mcpserver`. The low-level `Server` was rewritten around a shared dispatcher engine, and `Client` replaces v1's transport-plus-`ClientSession`-plus-`initialize()` layering. Importing `mcp.server.fastmcp` raises `ModuleNotFoundError`. | Replace `from mcp.server.fastmcp import FastMCP` with `from mcp.server.mcpserver import MCPServer` (or `from mcp.server import MCPServer`). Use `mcp.Client` for client connections. If you must stay on v1, pin `mcp<2`. Fix page: [https://insidetheloop.dev/fixes/mcp-python-no-module-fastmcp](https://insidetheloop.dev/fixes/mcp-python-no-module-fastmcp) |

## What MCP Python SDK errors did we reproduce, and how do I fix them?

Fix pages (one error each, with a reproduction): [`ModuleNotFoundError: No module named 'mcp.server.fastmcp'. This is mcp 2.x, where FastMCP was renamed to MCPServer (from mcp.server.mcpserver import MCPServer) and other APIs changed; see the migration guide at https://py.sdk.modelcontextprotocol.io/v2/migration/#fastmcp-renamed-to-mcpserver or pin 'mcp<2' to keep running v1 code.`](https://insidetheloop.dev/fixes/mcp-python-no-module-fastmcp).

### `from mcp.server.fastmcp import FastMCP` raises ModuleNotFoundError in 2.x (MCP Python SDK 2.3.0)

```bash
python3 -c "from mcp.server.fastmcp import FastMCP"
```

```text
fastmcp import failed: ModuleNotFoundError: No module named 'mcp.server.fastmcp'. This is mcp 2.x, where FastMCP was renamed to MCPServer (from mcp.server.mcpserver import MCPServer) and other APIs changed; see the migration guide at https://py.sdk.modelcontextprotocol.io/v2/migration/#fastmcp-renamed-to-mcpserver or pin 'mcp<2' to keep running v1 code.
```

Fix: Import `MCPServer` from `mcp.server.mcpserver` (or `mcp.server`): `from mcp.server.mcpserver import MCPServer`. If your project cannot migrate yet, pin `pip install "mcp>=1.28,<2"`. ([source](https://py.sdk.modelcontextprotocol.io/v2/migration/#fastmcp-renamed-to-mcpserver))

Fix page: https://insidetheloop.dev/fixes/mcp-python-no-module-fastmcp

### Invalid `x-mcp-header` annotation raises InvalidSignature during tool registration (MCP Python SDK 2.3.0)

```bash
from typing import Annotated
from pydantic import Field
from mcp.server.mcpserver import MCPServer
server = MCPServer("test")
@server.tool()
def greet(region: Annotated[list[str], Field(json_schema_extra={"x-mcp-header": "Region"})]) -> str:
    return "hello"
```

```text
tool registration failed: InvalidSignature: Tool 'greet' has an invalid x-mcp-header annotation: property 'region': x-mcp-header is only permitted on integer/string/boolean properties (got 'array')
```

Fix: Use only plain `str`, `int`, or `bool` parameters for header bindings. For optional string headers, declare the schema explicitly using `WithJsonSchema({"type": "string", "x-mcp-header": "Header-Name"})`. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3620))

### `max_sse_event_size` must be positive or None on StreamableHTTPTransport (MCP Python SDK 2.3.0)

```bash
from mcp.client.streamable_http import StreamableHTTPTransport
transport = StreamableHTTPTransport("http://127.0.0.1:8000/mcp", max_sse_event_size=0)
```

```text
transport creation failed: ValueError: max_sse_event_size must be positive or None
```

Fix: Pass a positive integer byte limit (default is `1048576`, 1 MiB) or pass `max_sse_event_size=None` to disable the event size cap for large tool results. ([source](https://github.com/modelcontextprotocol/python-sdk/pull/3600))

## MCP Python SDK release history by month

### 2026-10: v2 2.3.0 (2026-10-02)

- 2.3.0 (2026-10-02): max_sse_event_size on Streamable HTTP client transports, x-mcp-header annotation validation at tool registration, MCPServer(subscriptions=False) opt-out, tool call retry on HeaderMismatch, and empty _meta / params omission. ([source](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.3.0))

### 2026-09: v2 2.2.0; v1.x 1.30.0 (2 versions)

- 2.2.0 and 1.30.0 (2026-09-07): same-origin redirect restriction on HTTP client transports, 30-minute idle expiration for stateful legacy sessions, authorization server issuer validation on discovery, and AuthSettings.validate_token_resource. ([source](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.2.0))

### 2026-08: v2 2.0.1 to 2.1.1; v1.x 1.29.1 (4 versions)

- 2.1.0 (2026-08-24): Client takes StdioServerParameters directly, Image/Audio support in prompt messages, 4 MiB body limit on SSE/OAuth endpoints, and handler exceptions logged without wire traceback leaks. ([source](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.1.0))
- 2.0.1 (2026-08-26) and 2.1.1 (2026-08-25): added migration guide pointer on mcp.server.fastmcp imports. ([source](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.1))
- 1.29.1 (2026-08-24): FastMCP settings initialization fix and 4 MiB request body limits on SSE/OAuth endpoints in v1.x. ([source](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.29.1))

### 2026-07: v2 2.0.0 (stable 2026-07-28); v1.x 1.29.0

- 2.0.0 (2026-07-28): stable v2 release supporting the 2026-07-28 protocol revision, MCPServer replacing FastMCP, first-class Client, standalone mcp-types package, and resolver dependency injection. ([source](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0))
- 1.29.0 (2026-07-28): v1 maintenance release setting up v1.x branch support. ([source](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.29.0))

### 2026-06: v1.x 1.28.0 to 1.28.1; v2 prereleases

- 1.28.0 (2026-06-16) and 1.28.1 (2026-06-26): v1 maintenance line updates for stdio transport buffering and roots list changes. ([source](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.28.1))

### 2026-05: v1.x 1.27.1 to 1.27.2

- 1.27.1 (2026-05-08) and 1.27.2 (2026-05-29): v1 updates for server lifespan contexts and SSE reconnection handling. ([source](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.27.2))

## Sources

- [modelcontextprotocol/python-sdk releases (GitHub API, two pages)](https://api.github.com/repos/modelcontextprotocol/python-sdk/releases) (read 2026-10-10)
- [v2.3.0 release notes](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.3.0) (read 2026-10-10)
- [v2.2.0 release notes](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.2.0) (read 2026-10-10)
- [v1.30.0 release notes](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v1.30.0) (read 2026-10-10)
- [v2.0.1 release notes](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.1) (read 2026-10-10)
- [v2.1.1 release notes](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.1.1) (read 2026-10-10)
- [v2.1.0 release notes](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.1.0) (read 2026-10-10)
- [v2.0.0 release notes (v2 overview, MCPServer, 2026-07-28 revision)](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0) (read 2026-10-10)
- [PyPI package: mcp JSON API](https://pypi.org/pypi/mcp/json) (read 2026-10-10)
- [pypistats recent downloads: mcp](https://pypistats.org/api/packages/mcp/recent) (read 2026-10-10)
- [modelcontextprotocol/python-sdk repository](https://github.com/modelcontextprotocol/python-sdk) (read 2026-10-10)
- [Upgrading from v1.x to v2 (migration guide at v2.3.0)](https://py.sdk.modelcontextprotocol.io/v2/migration/) (read 2026-10-10)
- [FastMCP renamed to MCPServer (migration guide)](https://py.sdk.modelcontextprotocol.io/v2/migration/#fastmcp-renamed-to-mcpserver) (read 2026-10-10)
- [PR #3620: Reject a tool with an invalid x-mcp-header annotation at registration](https://github.com/modelcontextprotocol/python-sdk/pull/3620) (read 2026-10-10)
- [PR #3600: Expose an SSE event size limit in Streamable HTTP clients](https://github.com/modelcontextprotocol/python-sdk/pull/3600) (read 2026-10-10)
- [PR #3626: Let MCPServer opt out of serving subscriptions/listen](https://github.com/modelcontextprotocol/python-sdk/pull/3626) (read 2026-10-10)
- [PR #3628: Omit an empty _meta and empty params from outbound requests](https://github.com/modelcontextprotocol/python-sdk/pull/3628) (read 2026-10-10)
- [PR #3397: Follow redirects only within the MCP endpoint's origin](https://github.com/modelcontextprotocol/python-sdk/pull/3397) (read 2026-10-10)
- [PR #3448: Backport origin-scoped HTTP redirects to v1.x](https://github.com/modelcontextprotocol/python-sdk/pull/3448) (read 2026-10-10)
- [PR #3314: Log MCPServer handler exceptions by kind and keep crash details off the wire](https://github.com/modelcontextprotocol/python-sdk/pull/3314) (read 2026-10-10)
- [source: src/mcp/types/version.py at v2.3.0 (protocol version constants)](https://github.com/modelcontextprotocol/python-sdk/blob/v2.3.0/src/mcp-types/mcp_types/version.py) (read 2026-10-10)
- [source: src/mcp/server/fastmcp.py at v2.3.0 (FastMCP rename error)](https://github.com/modelcontextprotocol/python-sdk/blob/v2.3.0/src/mcp/server/fastmcp.py) (read 2026-10-10)

_Last verified: 2026-10-10._
