Present v2 as the stable release across the README, docs, and policies (#3178)
This commit is contained in:
parent
78e6fbb7e4
commit
6f69a3758e
5 changed files with 74 additions and 88 deletions
|
|
@ -2,30 +2,24 @@
|
|||
|
||||
The Python SDK is on PyPI as [`mcp`](https://pypi.org/project/mcp/). It requires **Python 3.10+**.
|
||||
|
||||
These docs describe **v2**, currently a release candidate, so the version pin is not optional yet:
|
||||
These docs describe **v2**, the current stable release line:
|
||||
|
||||
=== "uv"
|
||||
|
||||
```bash
|
||||
uv add "mcp[cli]==2.0.0rc1"
|
||||
uv add "mcp[cli]"
|
||||
```
|
||||
|
||||
=== "pip"
|
||||
|
||||
```bash
|
||||
pip install "mcp[cli]==2.0.0rc1"
|
||||
pip install "mcp[cli]"
|
||||
```
|
||||
|
||||
!!! warning "Why the pin"
|
||||
Installers never select a pre-release unless you name one, so an unpinned `uv add "mcp[cli]"`
|
||||
gives you the latest **v1.x** release, which these docs do not describe. Check the
|
||||
[release history](https://pypi.org/project/mcp/#history) for the newest pre-release before you copy
|
||||
the line above.
|
||||
|
||||
The same applies to one-off commands: `uv run --with "mcp==2.0.0rc1" ...`, not `uv run --with mcp ...`.
|
||||
|
||||
If your *package* depends on `mcp`, add a `<2` upper bound (for example `mcp>=1.27,<2`) before
|
||||
the stable v2 lands so the major version bump doesn't surprise you.
|
||||
!!! note "Coming from v1?"
|
||||
v2 is a major version with breaking changes; the **[Migration Guide](../migration.md)**
|
||||
covers every one. If your *package* depends on `mcp` and isn't ready to migrate, keep a
|
||||
`<2` upper bound (for example `mcp>=1.28,<2`) so an unpinned resolve stays on the 1.x line.
|
||||
|
||||
## What gets installed
|
||||
|
||||
|
|
|
|||
|
|
@ -23,17 +23,12 @@ That is the last line of Python on this page. From here down it is all host conf
|
|||
Every host below gets the same command:
|
||||
|
||||
```bash
|
||||
uv run --with "mcp[cli]==2.0.0rc1" mcp run /absolute/path/to/server.py
|
||||
uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py
|
||||
```
|
||||
|
||||
One command for all of them because `uv run --with` resolves the pinned SDK into a fresh environment on the spot: it works from any directory, needs no project and no virtual environment to activate, and always gets the exact `mcp` version these docs describe. That matters here more than anywhere else, because a host launches your server from *its* working directory with a near-empty environment, not from your shell.
|
||||
One command for all of them because `uv run --with` resolves the SDK into a fresh environment on the spot: it works from any directory and needs no project and no virtual environment to activate. That matters here more than anywhere else, because a host launches your server from *its* working directory with a near-empty environment, not from your shell.
|
||||
|
||||
It is also the command `mcp install` writes into Claude Desktop's config for you (below), so what you type by hand and what the tool generates agree.
|
||||
|
||||
!!! warning "The version pin is not optional"
|
||||
v2 of this SDK is a release candidate, and installers never select a pre-release unless you name one. An
|
||||
unpinned `--with "mcp[cli]"` gives you the latest **v1.x**, which these docs do not describe.
|
||||
Use the exact pin from **[Installation](installation.md)**.
|
||||
It is also the command `mcp install` writes into Claude Desktop's config for you (below), so what you type by hand and what the tool generates agree, apart from the exact version pin the tool adds.
|
||||
|
||||
!!! tip "If a host can't find `uv`"
|
||||
A host spawns your server with a minimal `PATH`, and `uv` may not be on it. Replace the bare
|
||||
|
|
@ -74,7 +69,7 @@ There is nothing to be mystified by. This is the entry it writes:
|
|||
"run",
|
||||
"--frozen",
|
||||
"--with",
|
||||
"mcp[cli]==2.0.0rc1",
|
||||
"mcp[cli]==2.0.0",
|
||||
"mcp",
|
||||
"run",
|
||||
"/absolute/path/to/server.py"
|
||||
|
|
@ -84,12 +79,12 @@ There is nothing to be mystified by. This is the entry it writes:
|
|||
}
|
||||
```
|
||||
|
||||
That's the launch command from the section above with two additions: the absolute path to `uv`, and `--frozen` so `uv` never rewrites a lockfile it happens to be near. It lands in `claude_desktop_config.json`, which lives at:
|
||||
That's the launch command from the section above with three additions: the absolute path to `uv`, `--frozen` so `uv` never rewrites a lockfile it happens to be near, and an exact pin to the `mcp` version you have installed. It lands in `claude_desktop_config.json`, which lives at:
|
||||
|
||||
* **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||
* **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
||||
|
||||
You can write that file by hand. `mcp install` exists so you don't make the two classic mistakes (a relative path, a missing version pin) while doing it.
|
||||
You can write that file by hand. `mcp install` exists so you don't make the classic mistake (a relative path) while doing it.
|
||||
|
||||
Fully quit Claude Desktop (not just its window) and reopen it.
|
||||
|
||||
|
|
@ -107,7 +102,7 @@ Fully quit Claude Desktop (not just its window) and reopen it.
|
|||
There is no file to edit. Register the server with the `claude` CLI; everything after `--` is the launch command.
|
||||
|
||||
```bash
|
||||
claude mcp add bookshop -- uv run --with "mcp[cli]==2.0.0rc1" mcp run /absolute/path/to/server.py
|
||||
claude mcp add bookshop -- uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py
|
||||
```
|
||||
|
||||
Run `/mcp` inside a Claude Code session to confirm `bookshop` is connected and its tools are listed.
|
||||
|
|
@ -121,7 +116,7 @@ Create `.cursor/mcp.json` in your project root.
|
|||
"mcpServers": {
|
||||
"bookshop": {
|
||||
"command": "uv",
|
||||
"args": ["run", "--with", "mcp[cli]==2.0.0rc1", "mcp", "run", "/absolute/path/to/server.py"]
|
||||
"args": ["run", "--with", "mcp[cli]", "mcp", "run", "/absolute/path/to/server.py"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -139,7 +134,7 @@ Create `.vscode/mcp.json` in your project root.
|
|||
"bookshop": {
|
||||
"type": "stdio",
|
||||
"command": "uv",
|
||||
"args": ["run", "--with", "mcp[cli]==2.0.0rc1", "mcp", "run", "/absolute/path/to/server.py"]
|
||||
"args": ["run", "--with", "mcp[cli]", "mcp", "run", "/absolute/path/to/server.py"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -156,7 +151,7 @@ Two differences from Cursor's file, and they are the only two: the wrapper key i
|
|||
Before you touch any host config, run the launch command yourself:
|
||||
|
||||
```bash
|
||||
uv run --with "mcp[cli]==2.0.0rc1" mcp run /absolute/path/to/server.py
|
||||
uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py
|
||||
```
|
||||
|
||||
Nothing prints, and it doesn't return. That silence is correct: a stdio server is waiting for a host to speak first on stdin (`Ctrl-C` to stop it). A traceback or an immediate exit is the real bug, and now you can read it instead of guessing at it through a host.
|
||||
|
|
@ -174,8 +169,8 @@ For anything past those three, **[Troubleshooting](../troubleshooting.md)** is t
|
|||
## Recap
|
||||
|
||||
* A **host** (Claude Desktop, an IDE) runs an MCP client that launches your server as a child process over stdio. Connecting means giving it one launch command.
|
||||
* That command is `uv run --with "mcp[cli]==2.0.0rc1" mcp run /absolute/path/to/server.py`: version-pinned, no venv to activate, works from any directory. The pin is mandatory while v2 is pre-release.
|
||||
* **Claude Desktop** is the one host `mcp install` configures for you. It writes that same command (plus the absolute path to `uv`) into `claude_desktop_config.json`, so you never have to.
|
||||
* That command is `uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py`: no venv to activate, works from any directory.
|
||||
* **Claude Desktop** is the one host `mcp install` configures for you. It writes that same command (plus the absolute path to `uv`, `--frozen`, and an exact pin to the version you have installed) into `claude_desktop_config.json`, so you never have to.
|
||||
* **Claude Code** is `claude mcp add bookshop -- <launch command>`. **Cursor** is `.cursor/mcp.json` under `mcpServers`. **VS Code** is `.vscode/mcp.json` under `servers`, each entry with a `type`.
|
||||
* Absolute paths everywhere, restart the host after editing its config, and never let anything but the SDK write to stdout.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# MCP Python SDK
|
||||
|
||||
!!! info "You are viewing the v2 documentation"
|
||||
The v1.x documentation is at [/v1/](https://py.sdk.modelcontextprotocol.io/v1/).
|
||||
New to v2, or coming from v1? **[What's new in v2](whats-new.md)** is the five-minute tour of what changed.
|
||||
Trying v2? [Tell us what you find](https://github.com/modelcontextprotocol/python-sdk/issues/new?template=v2-feedback.yaml) — it is the most useful thing you can do for the SDK right now.
|
||||
!!! info "This documents v2, the current stable release line"
|
||||
New to v2, or coming from v1? **[What's new in v2](whats-new.md)** is the five-minute tour of what changed, and the **[Migration Guide](migration.md)** covers every breaking change.
|
||||
Still on v1.x? Its documentation lives at the [v1.x docs](https://py.sdk.modelcontextprotocol.io/v1/).
|
||||
Something rough or confusing? [Tell us](https://github.com/modelcontextprotocol/python-sdk/issues/new?template=v2-feedback.yaml).
|
||||
|
||||
The **Model Context Protocol (MCP)** lets applications provide context to LLMs in a standardized way, separating the concern of *providing* context from the LLM interaction itself.
|
||||
|
||||
|
|
@ -22,22 +22,17 @@ Python 3.10+.
|
|||
=== "uv"
|
||||
|
||||
```bash
|
||||
uv add "mcp[cli]==2.0.0rc1"
|
||||
uv add "mcp[cli]"
|
||||
```
|
||||
|
||||
=== "pip"
|
||||
|
||||
```bash
|
||||
pip install "mcp[cli]==2.0.0rc1"
|
||||
pip install "mcp[cli]"
|
||||
```
|
||||
|
||||
The `[cli]` extra gives you the `mcp` command; you'll want it for development.
|
||||
|
||||
!!! warning "Pin the version while v2 is pre-release"
|
||||
Installers never select a pre-release unless you name one, so an unpinned `uv add "mcp[cli]"`
|
||||
gives you the latest **v1.x** release, which this documentation does not describe. Check
|
||||
[PyPI](https://pypi.org/project/mcp/#history) for the newest pre-release before you copy the line
|
||||
above. See [Installation](get-started/installation.md) for the details.
|
||||
See [Installation](get-started/installation.md) for what each dependency is for.
|
||||
|
||||
## Example
|
||||
|
||||
|
|
@ -98,5 +93,5 @@ You wrote two Python functions with type hints and a docstring. The SDK does the
|
|||
* Migrating from v1? Start with the **[Migration Guide](migration.md)**.
|
||||
* Hunting for an exact signature? The **[API Reference](api/mcp/index.md)** is generated from the source.
|
||||
* Reading with an LLM? This documentation is also published in the [llms.txt](https://llmstxt.org/) format:
|
||||
[llms.txt](https://py.sdk.modelcontextprotocol.io/v2/llms.txt) is an index of the pages, and
|
||||
[llms-full.txt](https://py.sdk.modelcontextprotocol.io/v2/llms-full.txt) contains every page in a single file.
|
||||
[llms.txt](https://py.sdk.modelcontextprotocol.io/llms.txt) is an index of the pages, and
|
||||
[llms-full.txt](https://py.sdk.modelcontextprotocol.io/llms-full.txt) contains every page in a single file.
|
||||
|
|
|
|||
|
|
@ -186,8 +186,8 @@ in `httpx2`; build an `ssl.SSLContext` and configure it instead.
|
|||
|
||||
Both commands run your server through a fresh `uv run --with ...` environment. In v1 the
|
||||
`mcp` requirement in that command was unpinned, so the spawned environment resolved to the
|
||||
newest stable release rather than the version you had installed; with a v2 pre-release
|
||||
installed, `mcp dev server.py` built a v1 environment that could not import a v2 server.
|
||||
newest stable release rather than the version you had installed; while v2 was in
|
||||
pre-release, `mcp dev server.py` built a v1 environment that could not import a v2 server.
|
||||
Both commands now pin the requirement to the version you are running
|
||||
(`mcp==<installed version>`). Source builds and other unpublished versions, which have
|
||||
nothing on PyPI to pin to, keep the unpinned form.
|
||||
|
|
|
|||
|
|
@ -4,13 +4,10 @@ Two things happened at once in v2. The **SDK was rebuilt**: a new engine under b
|
|||
|
||||
This page is the tour of both halves, one section per headline, each ending in the page that owns the topic. It is not the porting manual. That is the **[Migration Guide](migration.md)**: every breaking change, with before and after code.
|
||||
|
||||
!!! note "v2 is a release candidate"
|
||||
`pip install mcp` still installs v1.x: you opt into v2 with an exact version pin, and the
|
||||
API can still move before the stable release, which lands alongside the spec release.
|
||||
**[Installation](get-started/installation.md)** has the copy-paste install line and the
|
||||
pinning rules. And if anything in v2 breaks, surprises, or slows you down,
|
||||
[tell us](https://github.com/modelcontextprotocol/python-sdk/issues/new?template=v2-feedback.yaml):
|
||||
before the stable release, that is the most useful thing you can send us.
|
||||
!!! note "v2 is the stable line"
|
||||
`pip install mcp` installs 2.x, and **[Installation](get-started/installation.md)** has the
|
||||
copy-paste install line. If anything in v2 breaks, surprises, or slows you down,
|
||||
[tell us](https://github.com/modelcontextprotocol/python-sdk/issues/new?template=v2-feedback.yaml).
|
||||
|
||||
## The SDK: v1 to v2
|
||||
|
||||
|
|
@ -191,13 +188,13 @@ That file is the pitch in one place: one server, one `Resolve`-backed tool, and
|
|||
|
||||
### Change notifications become one stream
|
||||
|
||||
At 2026-07-28 the standalone HTTP GET stream and `resources/subscribe` are replaced by `subscriptions/listen`: the client opens one long-lived stream and names the notification kinds it wants. `MCPServer` serves it out of the box; you publish with `await ctx.notify_resource_updated(uri)` (and `notify_tools_changed()`, and so on), a middleware can refuse a listen request per caller, and multi-replica deployments plug in a shared `SubscriptionBus`. On the client (since `2.0.0b2`), `async with client.listen(...)` opens the stream: the filter goes in as keyword arguments, typed change events come back, and `sub.honored` is the subset the server agreed to deliver.
|
||||
At 2026-07-28 the standalone HTTP GET stream and `resources/subscribe` are replaced by `subscriptions/listen`: the client opens one long-lived stream and names the notification kinds it wants. `MCPServer` serves it out of the box; you publish with `await ctx.notify_resource_updated(uri)` (and `notify_tools_changed()`, and so on), a middleware can refuse a listen request per caller, and multi-replica deployments plug in a shared `SubscriptionBus`. On the client, `async with client.listen(...)` opens the stream: the filter goes in as keyword arguments, typed change events come back, and `sub.honored` is the subset the server agreed to deliver.
|
||||
|
||||
**[Subscriptions](handlers/subscriptions.md)** covers publishing and serving, **[its Clients twin](client/subscriptions.md)** the watching end, and **[Deploy & scale](run/deploy.md)** the bus.
|
||||
|
||||
### The rest, quickly
|
||||
|
||||
* **Identity is optional, per-message metadata.** The request-side `clientInfo` `_meta` key is optional (the required pair is `protocolVersion` + `clientCapabilities`), and `serverInfo` moved out of the `server/discover` result body: servers stamp it into every 2026-era result's `_meta` instead (since `2.0.0rc1`; [spec #3002](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3002)). The SDK always stamps; `client.server_info` is `None` when a server does not identify itself (for example, a middleware stripped the key). **[The low-level Server](advanced/low-level-server.md)** shows the stamp on the wire.
|
||||
* **Identity is optional, per-message metadata.** The request-side `clientInfo` `_meta` key is optional (the required pair is `protocolVersion` + `clientCapabilities`), and `serverInfo` moved out of the `server/discover` result body: servers stamp it into every 2026-era result's `_meta` instead ([spec #3002](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3002)). The SDK always stamps; `client.server_info` is `None` when a server does not identify itself (for example, a middleware stripped the key). **[The low-level Server](advanced/low-level-server.md)** shows the stamp on the wire.
|
||||
* **Requests are routable without parsing bodies.** Modern HTTP requests carry `Mcp-Method` (and, for the three tool-ish calls, `Mcp-Name`); a tool input-schema property annotated with `x-mcp-header` is mirrored into an `Mcp-Param-*` header and cross-checked by the server ([SEP-2243](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2243)). Gateways and rate limiters can route on headers alone; the **[Migration Guide](migration.md#servers-validate-mcp-param-headers-against-the-request-body-sep-2243)** has the rules.
|
||||
* **Results carry cache hints.** List and read results declare `ttlMs` and `cacheScope` ([SEP-2549](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2549)); you set them per method with `cache_hints=`, and `Client` honors them with a built-in response cache. A server that sends no hints (every pre-2026 server) sees identical, uncached traffic. **[Caching hints](client/caching.md)**.
|
||||
* **Extensions are first class.** Servers and clients declare optional capability bundles under reverse-DNS identifiers ([SEP-2133](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2133)); the built-in `Apps` extension (MCP Apps) is the reference. **[Extensions](advanced/extensions.md)** and **[MCP Apps](advanced/apps.md)**.
|
||||
|
|
@ -208,5 +205,5 @@ At 2026-07-28 the standalone HTTP GET stream and `resources/subscribe` are repla
|
|||
## Upgrading from v1?
|
||||
|
||||
* The **[Migration Guide](migration.md)** is the complete, exact list of what to change; this page was the why.
|
||||
* **v1.x is not going anywhere.** It stays the stable line, with critical fixes and security patches, and nothing about the 2026-07-28 spec release breaks it. If you publish a library that depends on `mcp`, add an upper bound (for example `mcp>=1.27,<2`) so stable v2 does not surprise your users.
|
||||
* **v1.x is not going anywhere.** It moves to maintenance, keeps getting critical fixes and security patches, and nothing about the 2026-07-28 spec release breaks it; its docs live at [/v1/](https://py.sdk.modelcontextprotocol.io/v1/). If you publish a library that depends on `mcp` and are not ready to migrate, keep an upper bound (for example `mcp>=1.28,<2`) so an unpinned resolve stays on 1.x.
|
||||
* Something rough, confusing, or broken? **[File v2 feedback](https://github.com/modelcontextprotocol/python-sdk/issues/new?template=v2-feedback.yaml)**; it all gets read.
|
||||
|
|
|
|||
Loading…
Reference in a new issue