diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b0fb9fa57b..3e35bd9060 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,10 +48,25 @@ Bug fixes for clear, reproducible issues are welcome—but still create an issue | [`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 | | [`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 | -Issues labeled `needs confirmation` or `needs maintainer action` are **not** ready for work—wait for maintainer input first. +Issues labeled `needs confirmation` or `needs maintainer` are **not** ready for work—wait for maintainer input first. Before starting, comment on the issue so we can assign it to you. This prevents duplicate effort. +## Issue Triage + +Every new issue gets a first look from a maintainer within two business days. That first look is the *triage*: it means labeling the issue and deciding whether it is valid and actionable, not fixing it. + +The core labels follow the shared [MCP SDK taxonomy](https://modelcontextprotocol.io/community/sdk-tiers#issue-triage-labels) (the repository also carries workflow labels of its own, such as `needs maintainer` and `needs decision`): one **type** (`bug`, `enhancement`, `question`), one **status** (`needs confirmation`, `needs repro`, `ready for work`, `good first issue`, `help wanted`), and — once actionable — one **priority**: + +| Label | Meaning | Commitment | +|-------|---------|------------| +| `P0` | Critical: core functionality failures (connections, message exchange, tools/resources/prompts) or a High/Critical-severity security issue | resolved within 7 days | +| `P1` | Significant bug affecting many users | next release | +| `P2` | Moderate issue or valuable feature request | as capacity allows | +| `P3` | Nice-to-have or rare edge case | opportunistic | + +Security reports do not belong in the issue tracker; [SECURITY.md](SECURITY.md) has the private channel. + ## Development Setup 1. Make sure you have Python 3.10+ installed @@ -150,6 +165,7 @@ A few dozen lines can be reviewed in minutes. Hundreds of lines across many file 2. Add tests for new functionality 3. Ensure CI passes 4. Address review feedback +5. Dependency bound changes and new runtime dependencies follow the [Dependency Policy](DEPENDENCY_POLICY.md) ## Code of Conduct diff --git a/DEPENDENCY_POLICY.md b/DEPENDENCY_POLICY.md new file mode 100644 index 0000000000..961157b378 --- /dev/null +++ b/DEPENDENCY_POLICY.md @@ -0,0 +1,15 @@ +# Dependency Policy + +`mcp` is a library that lives inside other people's environments, so its requirements are chosen to constrain your resolver as little as possible while still describing what the SDK needs. + +## How requirements are declared + +Every runtime dependency is a `>=` floor set to the oldest version that provides what the SDK uses, with no upper bound unless a dependency's next major is known to break the SDK. The one exception is `mcp-types`, the wire-types package released in lockstep with `mcp`: each `mcp` release requires exactly its own version of it, so it is the other half of the SDK rather than an independent constraint. + +## When a floor moves + +A floor is raised only when the SDK starts relying on functionality or a fix that first appeared in that version — not because the 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 environments the SDK installs into; nor does the SDK add code to work around a dependency's vulnerability, since the fix belongs upstream and in your lockfile ([background](https://github.com/Kludex/uvicorn/discussions/2643), [python-sdk#1552](https://github.com/modelcontextprotocol/python-sdk/issues/1552)). Floor raises may ship in a minor release under the [versioning policy](VERSIONING.md) and are called out in the release notes. Adding a new runtime dependency, or moving one to its next major version, is decided in an issue before the pull request. + +## Automated updates + +[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. These refresh the versions the SDK is developed and tested against; the requirements published to PyPI move only under the rules above. diff --git a/RELEASE.md b/RELEASE.md index 58b7fb48f5..6233a37ff7 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -2,10 +2,17 @@ ## Bumping Dependencies +[`DEPENDENCY_POLICY.md`](DEPENDENCY_POLICY.md) says *when* a bound should +move; this is the mechanics. + 1. Change the dependency version in `pyproject.toml`. The root `mcp` project's runtime dependencies are dynamic and live under `[tool.hatch.metadata.hooks.uv-dynamic-versioning].dependencies`. -2. Upgrade lock with `uv lock --resolution lowest-direct` +2. Regenerate the lock with `uv lock` (or `uv lock --upgrade-package ` + to move just that package's locked version). The committed `uv.lock` is a + normal, newest-allowed resolution; the `lowest-direct` resolution that + proves the floors still work is applied only by its CI matrix leg at test + time and is never committed. ## Release lines @@ -104,8 +111,9 @@ hand for the same reason as above. Then ask someone to review the release. Pre-releases of the next version are cut from `main` with a PEP 440 pre-release tag: `aN` for alphas, later `bN`/`rcN` for betas and release candidates. The PEP 440 suffix is what keeps `pip install mcp` on the stable -version — installers only select a pre-release when it is requested explicitly (an -exact pin, a specifier that names a pre-release version, or `--pre`). +version — installers do not pick a pre-release for a plain `mcp` requirement while a +final release satisfies it; a pre-release is opted into with an exact pin, a +specifier that names a pre-release version, or `--pre`. 1. During a pre-release phase the README and docs pin the exact pre-release version, so update those examples first (grep the outgoing version — the diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000000..1f2d293216 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,21 @@ +# Roadmap + +The SDK's work is organized by MCP specification revision, with one GitHub project board per revision; each item is an issue or pull request you can follow. + +## The 2026-07-28 revision + +v2 implements the [2026-07-28 specification](https://modelcontextprotocol.io/specification/2026-07-28) and negotiates back to every earlier revision. Board: **[python-sdk · 2026-07-28 spec](https://github.com/orgs/modelcontextprotocol/projects/42)**; the cross-SDK view is [2026-07-28 Spec Implementation](https://github.com/orgs/modelcontextprotocol/projects/41). Still open there: making advertised capabilities configurable rather than pre-computed ([#2896](https://github.com/modelcontextprotocol/python-sdk/issues/2896)). + +## Not yet implemented + +Extensions and optional client-auth mechanisms not yet implemented are tracked in the issue tracker; those the conformance suite already exercises also appear in its expected-failures baseline, [`.github/actions/conformance/expected-failures.yml`](.github/actions/conformance/expected-failures.yml), which burns down as each lands. The main ones: + +* **Tasks extension** (`io.modelcontextprotocol/tasks`, [SEP-2663](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/seps/2663-tasks-extension.md)) — deferred at 2.0 because the 2026-07-28 design is wire-incompatible with the earlier in-core Tasks; tracked in [#2806](https://github.com/modelcontextprotocol/python-sdk/issues/2806). +* **DPoP-bound access tokens** ([SEP-1932](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1932)) in the OAuth client. +* **The workload-identity `jwt-bearer` grant** in the OAuth client. + +Everything else — bugs and smaller features — lives in the [issue tracker](https://github.com/modelcontextprotocol/python-sdk/issues), prioritized `P0`–`P3`. The SDK aims to release support for each new specification revision alongside that revision. + +## The previous major + +`v1.x` is a maintenance line: critical bug fixes and security fixes only. Support terms are in [Versioning and support policy](VERSIONING.md#support-and-announcements); the path off it is the **[Migration Guide](https://py.sdk.modelcontextprotocol.io/migration/)**. diff --git a/VERSIONING.md b/VERSIONING.md new file mode 100644 index 0000000000..53d17300e8 --- /dev/null +++ b/VERSIONING.md @@ -0,0 +1,35 @@ +# Versioning and support policy + +What a version number of `mcp` promises: which changes can arrive in a minor release, which wait for a major, how deprecations are announced, and which release lines are supported. + +## The version number + +[Semantic Versioning](https://semver.org/) semantics in [PEP 440](https://peps.python.org/pep-0440/) syntax, taken from the git tag: in `2.X.Y`, **X** (minor) carries new functionality and every non-breaking change, **Y** (patch) carries bug fixes only, and a breaking change to the public API lands only in a new **major**. Pre-releases are cut from `main` as `aN`/`bN`/`rcN`; installers prefer final releases by default, so an unpinned `pip install mcp` stays on a stable release whenever one satisfies your requirement. `mcp` and its wire-types package `mcp-types` release in lockstep, each `mcp` requiring exactly the matching `mcp-types`. + +## The public API + +The promise covers every name exported by `mcp` and `mcp_types` (their `__all__`), the import paths, signatures, and behavior documented on the [documentation site](https://py.sdk.modelcontextprotocol.io/) and in its [API Reference](https://py.sdk.modelcontextprotocol.io/api/mcp/). It does not cover underscore-prefixed names, undocumented modules, or the wording of log lines, warnings, and exception messages (their types and documented raise conditions are covered). APIs labelled **provisional** (for example the middleware chain) may still change in a minor release; **experimental** APIs are opt-in previews. + +## Breaking and non-breaking changes + +Held for the next major: + +* removing or renaming a public name, +* changing a signature, return type, raised exception type, or documented behavior so that working code stops working, +* removing a documented import path, extra, or CLI command. + +Allowed in a minor: + +* additions — functions, defaulted parameters, classes, fields, enum members, +* changes to provisional or experimental APIs, +* new deprecation warnings, and the eventual removal of protocol features the specification has retired, +* raising a dependency floor the SDK needs (see the [dependency policy](DEPENDENCY_POLICY.md)) when the dependency's changes don't reach you through the SDK's API, or dropping a Python version after its upstream end-of-life — both called out in the release notes, +* bug fixes, including ones that make the SDK match its documented or specified behavior. + +## Deprecations + +**SDK APIs** are deprecated before removal: they keep working for at least one minor release, marked with [`typing_extensions.deprecated`](https://typing-extensions.readthedocs.io/en/latest/#typing_extensions.deprecated) wherever Python can carry the marker (docstring and migration guide otherwise), and are removed only in a major. **Protocol features** the specification retires keep their implementation through the spec's deprecation window and warn with `MCPDeprecationWarning`, a `UserWarning` subclass that shows by default; what still functions depends on the revision a connection negotiated — see [Deprecated features](https://py.sdk.modelcontextprotocol.io/deprecated/). + +## Support and announcements + +Two lines are maintained and only the newest release of each receives fixes: **2.x** (`main`) gets bug fixes, security fixes, and features; **1.x** ([`v1.x`](https://github.com/modelcontextprotocol/python-sdk/tree/v1.x)) gets critical bug fixes and security fixes. [SECURITY.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/SECURITY.md) has the reporting process. Every release publishes notes on [GitHub Releases](https://github.com/modelcontextprotocol/python-sdk/releases); every breaking change between majors is documented in the [Migration Guide](https://py.sdk.modelcontextprotocol.io/migration/) before it merges; and pull requests that make one carry the `breaking change` label.