Skip to content

Commit fbefbf6

Browse files
committed
Address review: state policy, stop restating mechanics owned elsewhere
The second review round found the same class of problem as the first: the policy pages paraphrased behavior that other files own (deprecated features, pre-release selection, the CI matrix, SECURITY.md), and each paraphrase drifted from the code. Trim them back to the commitments and link to the owning page instead: - versioning.md: pre-release selection described by reference to PEP 440 rather than a closed list; provisional examples given as examples; the SDK-API deprecation promise stated as policy (marked wherever Python can carry a marker, docstring plus migration guide otherwise); protocol deprecations defer per-connection behavior to deprecated.md and legacy-clients.md instead of enumerating it. - roadmap.md: the open items are "carried as expected failures until they land", without tier-scoring commentary. - DEPENDENCY_POLICY.md: floors "the suite exercises" cannot go false; versioning.md is the single authority on release kinds; a dependency's new major is decided in an issue like a new dependency; SECURITY.md is a reporting process, not response commitments. - RELEASE.md: the lowest-direct lock is never committed (it is written, in CI's checkout); name the no-final-release pre-release fallback. - CONTRIBUTING.md: the label is `needs maintainer`. No-Verification-Needed: doc-only change
1 parent e8bee4d commit fbefbf6

5 files changed

Lines changed: 15 additions & 14 deletions

File tree

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Bug fixes for clear, reproducible issues are welcome—but still create an issue
4848
| [`help wanted`](https://github.com/modelcontextprotocol/python-sdk/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) | Experienced contributors | Maintainers probably won't get to this |
4949
| [`ready for work`](https://github.com/modelcontextprotocol/python-sdk/issues?q=is%3Aopen+is%3Aissue+label%3A%22ready+for+work%22) | Maintainers | Triaged and ready for a maintainer to pick up |
5050

51-
Issues labeled `needs confirmation` or `needs maintainer action` are **not** ready for work—wait for maintainer input first.
51+
Issues labeled `needs confirmation` or `needs maintainer` are **not** ready for work—wait for maintainer input first.
5252

5353
Before starting, comment on the issue so we can assign it to you. This prevents duplicate effort.
5454

DEPENDENCY_POLICY.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313

1414
A minimum version is raised only when the SDK starts relying on functionality, a fix, or an API that first appeared in that version. It is not raised because a dependency published a security advisory. The `>=` bound already lets — and expects — you to run the newest release your other constraints allow, so a higher floor would only shrink the set of environments the SDK installs into without changing what any correctly-updated environment resolves to. The SDK also does not add code to work around a vulnerability in a dependency; the fix belongs upstream and in your lockfile. ([Background](https://github.com/Kludex/uvicorn/discussions/2643) on this stance from another library that adopted it, and [python-sdk#1552](https://github.com/modelcontextprotocol/python-sdk/issues/1552).)
1515

16-
Every declared floor is exercised: CI runs the full test suite both against the locked dependency set and against a `lowest-direct` resolution, on every supported Python version, so a floor that has quietly become false fails the build rather than a user's install.
16+
The floors are tested, not just declared: CI runs the test suite against a `lowest-direct` resolution as well as the locked set, on every supported Python version, so a floor the suite exercises cannot quietly become false.
1717

18-
Raising a floor within the same major version of a dependency is a minor-release change and is called out in the release notes; see the [versioning policy](https://py.sdk.modelcontextprotocol.io/versioning/). Adding a new required runtime dependency is a maintainer decision made in an issue before the pull request, not a side effect of a feature.
18+
Raising a floor is a minor-release change, called out in the release notes; the [versioning policy](https://py.sdk.modelcontextprotocol.io/versioning/) is the authority on what may ship in which kind of release. Adding a new required runtime dependency, or moving an existing one to its next major version, is a maintainer decision made in an issue before the pull request, not a side effect of a feature.
1919

2020
## Automated updates
2121

2222
[Dependabot](https://github.com/modelcontextprotocol/python-sdk/blob/main/.github/dependabot.yml) opens monthly, grouped pull requests for the `uv` lockfile and for GitHub Actions, with a 14-day cooldown on newly published versions. These refresh the versions the SDK is developed and tested against (`uv.lock`); they never change the requirements published to PyPI, which move only under the rules above.
2323

2424
## Security in the SDK itself
2525

26-
Vulnerabilities in the SDK's own code — as opposed to its dependencies — follow the reporting process and response commitments in [SECURITY.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/SECURITY.md).
26+
Vulnerabilities in the SDK's own code — as opposed to its dependencies — follow the reporting process in [SECURITY.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/SECURITY.md).

RELEASE.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ move; this is the mechanics.
1212
to move just that package's locked version). The committed `uv.lock` is a
1313
normal, newest-allowed resolution; the `lowest-direct` resolution that
1414
proves the floors still work is applied only by its CI matrix leg at test
15-
time and never written to the lock.
15+
time and is never committed.
1616

1717
## Release lines
1818

@@ -111,8 +111,9 @@ hand for the same reason as above. Then ask someone to review the release.
111111
Pre-releases of the next version are cut from `main` with a PEP 440
112112
pre-release tag: `aN` for alphas, later `bN`/`rcN` for betas and release
113113
candidates. The PEP 440 suffix is what keeps `pip install mcp` on the stable
114-
version — installers only select a pre-release when it is requested explicitly (an
115-
exact pin, a specifier that names a pre-release version, or `--pre`).
114+
version — installers select a pre-release only when it is requested explicitly (an
115+
exact pin, a specifier that names a pre-release version, or `--pre`) or when no
116+
final release satisfies the requirement at all.
116117

117118
1. During a pre-release phase the README and docs pin the exact pre-release
118119
version, so update those examples first (grep the outgoing version — the

docs/roadmap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ The 2026-07-28 revision moved some functionality out of the core protocol into n
2121
* **DPoP-bound access tokens** ([SEP-1932](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1932)) in the OAuth client.
2222
* **The workload-identity `jwt-bearer` grant** in the OAuth client.
2323

24-
None of these gates conformance todayextension scenarios are informational in the tier scoring — but each is a real gap for anyone who needs the feature, and they are the current queue.
24+
None of these blocks a releaseeach is carried as an expected failure in that baseline until it lands — but each is a real gap for anyone who needs the feature, and together they are the current queue.
2525

2626
## Continuous work
2727

docs/versioning.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Releases follow [Semantic Versioning](https://semver.org/) semantics, written in
1010
* **`X` (minor)** — new functionality and every non-breaking change.
1111
* **`Y` (patch)** — bug fixes only.
1212
* **The leading `2` (major)** — the only place a breaking change to the public API can land.
13-
* **Pre-releases** are cut from `main` as `2.X.YaN` (alpha), `2.X.YbN` (beta), and `2.X.YrcN` (release candidate). Installers select a pre-release only when a requirement asks for one explicitly — an exact pin, a specifier that itself names a pre-release version (such as `mcp>=2.1.0b1`), or `--pre` — so an unpinned `pip install mcp` always lands on a stable release.
13+
* **Pre-releases** are cut from `main` as `2.X.YaN` (alpha), `2.X.YbN` (beta), and `2.X.YrcN` (release candidate). Installers prefer final releases by default (PEP 440's [pre-release handling](https://peps.python.org/pep-0440/#handling-of-pre-releases)), so an unpinned `pip install mcp` stays on a stable release; you get a pre-release by asking for one, for example with an exact pin or `--pre`.
1414

1515
`mcp` and its wire-types package [`mcp-types`](https://pypi.org/project/mcp-types/) release in lockstep at the same version: each `mcp` release requires exactly the matching `mcp-types` (`mcp-types==2.X.Y`).
1616

@@ -26,7 +26,7 @@ It does not cover names beginning with an underscore, modules and attributes tha
2626

2727
Two labels mark APIs that sit outside the promise while they settle:
2828

29-
* **Provisional** — shipped and supported, but the signature or semantics may still change in a minor release. The middleware chain is the current example, and its documentation says so.
29+
* **Provisional** — shipped and supported, but the signature or semantics may still change in a minor release. The middleware chain and the `Dispatcher` lifecycle are examples; each is labelled provisional in its own documentation.
3030
* **Experimental** — behind an explicit opt-in and expected to change; treat it as a preview.
3131

3232
## What counts as a breaking change
@@ -43,7 +43,7 @@ These do not, and can ship in a minor release:
4343
* new functions, parameters with defaults, classes, fields, and enum members,
4444
* changes to provisional or experimental APIs,
4545
* new deprecation warnings, and the eventual removal of a protocol feature the specification has retired (see [Deprecations](#deprecations)),
46-
* raising a dependency's minimum version when the SDK needs newer functionality, or dropping a Python version that upstream has ended support forboth called out in the release notes (the [dependency policy](https://github.com/modelcontextprotocol/python-sdk/blob/main/DEPENDENCY_POLICY.md) covers the first),
46+
* raising a dependency's minimum version when the SDK needs newer functionality (see the [dependency policy](https://github.com/modelcontextprotocol/python-sdk/blob/main/DEPENDENCY_POLICY.md)), as long as the dependency's own changes do not reach you through the SDK's public API — if they would, the rules above apply — or dropping a Python version that upstream has ended support for; both are called out in the release notes,
4747
* bug fixes, including fixes that make the SDK match documented or specified behavior it should have had all along.
4848

4949
When a fix is arguably both a bug fix and a behavior change, the deciding question is whether reasonable code written against the *documented* behavior breaks. If it does, the change is breaking.
@@ -52,9 +52,9 @@ When a fix is arguably both a bug fix and a behavior change, the deciding questi
5252

5353
There are two kinds, warned differently on purpose.
5454

55-
**SDK API deprecations** — a name or parameter this SDK is retiring. The API keeps working, marked with [`typing_extensions.deprecated`](https://typing-extensions.readthedocs.io/en/latest/#typing_extensions.deprecated), so static type checkers flag every call site and Python emits a `DeprecationWarning` at runtime. A deprecated API survives at least one minor release with its warning in place, and is removed only in a major version: something deprecated during 2.x is not removed before 3.0.
55+
**SDK API deprecations** — a name or parameter this SDK is retiring. It is deprecated before it is removed: it keeps working for at least one minor release, marked wherever Python can carry a marker — callables and classes get [`typing_extensions.deprecated`](https://typing-extensions.readthedocs.io/en/latest/#typing_extensions.deprecated), which static type checkers flag and which warns at runtime; things that cannot carry one, such as module-level constants, are deprecated in their docstring and the migration guide — and it is removed only in a major version: something deprecated during 2.x is not removed before 3.0.
5656

57-
**Protocol deprecations** — a feature the MCP specification has retired (for example the SEP-2577 set in the 2026-07-28 revision). The SDK keeps implementing these through the specification's deprecation window, but what still works depends on the revision a connection negotiated: on a connection speaking an older revision they behave as before; on a 2026-07-28 connection a retired feature may have no wire support left at all (server-initiated sampling and roots have no back-channel to travel over, and `ping` no longer exists), so the call warns and then fails. Either way the call site warns with `MCPDeprecationWarning`, a `UserWarning` subclass, so the warning is visible by default rather than hidden the way `DeprecationWarning` is outside `__main__`. **[Deprecated features](deprecated.md)** lists every one, exactly what happens on each kind of connection, its replacement, and how to silence the warning when you genuinely serve older clients.
57+
**Protocol deprecations** — a feature the MCP specification has retired (for example the SEP-2577 set in the 2026-07-28 revision). The SDK keeps implementing these through the specification's deprecation window, and deprecation warnings for them use `MCPDeprecationWarning`, a `UserWarning` subclass, so they show by default rather than being hidden the way `DeprecationWarning` is outside `__main__`. Whether a retired feature can still do anything on a given connection depends on the protocol revision that connection negotiated; **[Deprecated features](deprecated.md)** and **[Serving legacy clients](run/legacy-clients.md)** describe the behavior, the replacements, and how to silence the warning when you genuinely serve older clients.
5858

5959
## Supported release lines
6060

@@ -74,4 +74,4 @@ Python versions are supported from the version in the package's `requires-python
7474
* **Release notes** — every release publishes curated notes on [GitHub Releases](https://github.com/modelcontextprotocol/python-sdk/releases): highlights, anything known-incomplete, and a full change list. Pre-releases say what changed since the previous pre-release.
7575
* **The migration guide** — every breaking change between majors is documented in **[Migration Guide](migration.md)** with before-and-after code; a change is not merged for a major release without its entry.
7676
* **The `breaking change` label** — pull requests that make a breaking change carry it, so the set is queryable ahead of a major release.
77-
* **Deprecation warnings** — as above, one release of warning at minimum before an SDK API is removed.
77+
* **Deprecations** — as above, at least one minor release of deprecation before an SDK API is removed.

0 commit comments

Comments
 (0)