diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml deleted file mode 100644 index d9362afd57..0000000000 --- a/.github/workflows/deploy-docs.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Deploy Docs - -on: - push: - branches: - - main - - v1.x - paths: - - docs/** - - mkdocs.yml - - src/mcp/** - - scripts/build-docs.sh - - pyproject.toml - - uv.lock - - .github/workflows/deploy-docs.yml - workflow_dispatch: - -concurrency: - group: deploy-docs - cancel-in-progress: false - -jobs: - deploy-docs: - runs-on: ubuntu-latest - - permissions: - contents: read - pages: write - id-token: write - - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - - - name: Install uv - uses: astral-sh/setup-uv@803947b9bd8e9f986429fa0c5a41c367cd732b41 # v7.2.1 - with: - enable-cache: true - version: 0.9.5 - - - name: Build combined docs (v1.x at /, main at /v2/) - run: bash scripts/build-docs.sh site - - - name: Configure Pages - uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 - - - name: Upload Pages artifact - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 - with: - path: site - - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 diff --git a/.github/workflows/shared.yml b/.github/workflows/shared.yml index 16ba250cde..468359fef4 100644 --- a/.github/workflows/shared.yml +++ b/.github/workflows/shared.yml @@ -76,3 +76,20 @@ jobs: - name: Check doc snippets are up to date run: uv run --frozen scripts/update_doc_snippets.py --check + + # The published site is built and deployed from main, which builds this + # branch's docs (via scripts/docs/build.sh) under /v1/; this branch has no + # deploy workflow of its own. This job runs that same script so a change + # that breaks the v1 docs fails here rather than at main's next deploy. + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + + - uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + version: 0.9.5 + + - name: Build docs + run: bash scripts/docs/build.sh diff --git a/README.md b/README.md index 9eaef01af8..325060dfb1 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,9 @@ -> **This documents v1.x, the stable release line of the MCP Python SDK. v2 is in alpha.** +> **This documents v1.x, the maintenance line of the MCP Python SDK.** v2 is the current stable release: `pip install mcp` now installs 2.x. See the [v2 documentation](https://py.sdk.modelcontextprotocol.io/) and the [migration guide](https://py.sdk.modelcontextprotocol.io/migration/) for what changed and how to upgrade. > -> v2 pre-releases are published to PyPI as `2.0.0aN`. Installers never select a pre-release unless you opt in (for example `pip install mcp==2.0.0a1`), so v1.x users are unaffected. **If your package depends on `mcp`, add a `<2` upper bound to your version constraint (for example `mcp>=1.27,<2`) before the stable v2 release lands.** See the [v2 documentation](https://github.com/modelcontextprotocol/python-sdk/blob/main/README.v2.md) and the [migration guide](https://github.com/modelcontextprotocol/python-sdk/blob/main/docs/migration.md) for what's changing. -> -> v1.x remains recommended for production use. It is in maintenance mode and continues to receive critical bug fixes and security patches. +> **Staying on v1.x?** Keep a `<2` upper bound on your requirement (for example `mcp>=1.28,<2`) so an unpinned resolve stays on the 1.x line. v1.x remains supported for existing deployments and continues to receive critical bug fixes and security patches; its documentation is at . ## Table of Contents @@ -38,7 +36,7 @@ [python-badge]: https://img.shields.io/pypi/pyversions/mcp.svg [python-url]: https://www.python.org/downloads/ [docs-badge]: https://img.shields.io/badge/docs-python--sdk-blue.svg -[docs-url]: https://modelcontextprotocol.github.io/python-sdk/ +[docs-url]: https://py.sdk.modelcontextprotocol.io/v1/ [protocol-badge]: https://img.shields.io/badge/protocol-modelcontextprotocol.io-blue.svg [protocol-url]: https://modelcontextprotocol.io [spec-badge]: https://img.shields.io/badge/spec-spec.modelcontextprotocol.io-blue.svg @@ -69,13 +67,13 @@ If you haven't created a uv-managed project yet, create one: Then add MCP to your project dependencies: ```bash - uv add "mcp[cli]" + uv add "mcp[cli]<2" ``` Alternatively, for projects using pip for dependencies: ```bash -pip install "mcp[cli]" +pip install "mcp[cli]<2" ``` ### Running the standalone MCP development tools @@ -143,7 +141,7 @@ _Full example: [examples/snippets/servers/fastmcp_quickstart.py](https://github. You can install this server in [Claude Code](https://docs.claude.com/en/docs/claude-code/mcp) and interact with it right away. First, run the server: ```bash -uv run --with mcp examples/snippets/servers/fastmcp_quickstart.py +uv run --with "mcp<2" examples/snippets/servers/fastmcp_quickstart.py ``` Then add it to Claude Code: @@ -177,8 +175,8 @@ The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) lets you bui - [Low-Level Server](docs/low-level-server.md) -- direct handler registration for advanced use cases - [Protocol Features](docs/protocol.md) -- MCP primitives, server capabilities - [Testing](docs/testing.md) -- in-memory transport testing with pytest -- [API Reference](https://modelcontextprotocol.github.io/python-sdk/api/) -- [Experimental Features (Tasks)](https://modelcontextprotocol.github.io/python-sdk/experimental/tasks/) +- [API Reference](https://py.sdk.modelcontextprotocol.io/v1/api/) +- [Experimental Features (Tasks)](https://py.sdk.modelcontextprotocol.io/v1/experimental/tasks/) - [Model Context Protocol documentation](https://modelcontextprotocol.io) - [Model Context Protocol specification](https://modelcontextprotocol.io/specification/latest) - [Officially supported servers](https://github.com/modelcontextprotocol/servers) diff --git a/docs/index.md b/docs/index.md index 8462445a60..c44891c137 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,9 @@ # MCP Python SDK -!!! tip "Looking for the upcoming v2?" - See the [v2 development documentation](https://py.sdk.modelcontextprotocol.io/v2/). +!!! tip "You are viewing the v1.x maintenance-line documentation" + v2 is the current stable release: its documentation is at + . Staying on v1.x for now? Pin `mcp<2` + (for example `mcp>=1.28,<2`) so an unpinned install doesn't move you to 2.x. The **Model Context Protocol (MCP)** allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction. @@ -48,7 +50,7 @@ if __name__ == "__main__": Run the server: ```bash -uv run --with mcp server.py +uv run --with "mcp<2" server.py ``` Then open the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) and connect to `http://localhost:8000/mcp`: @@ -74,5 +76,5 @@ Full API documentation is available in the [API Reference](api.md). ## llms.txt Reading with an LLM? This documentation is also published in the [llms.txt](https://llmstxt.org/) format: -[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. +[llms.txt](https://py.sdk.modelcontextprotocol.io/v1/llms.txt) is an index of the pages, and +[llms-full.txt](https://py.sdk.modelcontextprotocol.io/v1/llms-full.txt) contains every page in a single file. diff --git a/docs/installation.md b/docs/installation.md index 6e20706a84..2352a1132f 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,16 +1,18 @@ # Installation -The Python SDK is available on PyPI as [`mcp`](https://pypi.org/project/mcp/) so installation is as simple as: +The Python SDK is available on PyPI as [`mcp`](https://pypi.org/project/mcp/). These docs describe the **v1.x maintenance line**; +the `<2` bound keeps you on it now that `pip install mcp` selects the 2.x stable release by default (the +[v2 documentation](https://py.sdk.modelcontextprotocol.io/) covers that line): === "pip" ```bash - pip install mcp + pip install "mcp<2" ``` === "uv" ```bash - uv add mcp + uv add "mcp<2" ``` The following dependencies are automatically installed: diff --git a/mkdocs.yml b/mkdocs.yml index f19a0ee3ee..684c4a1232 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,7 +5,7 @@ strict: true repo_name: modelcontextprotocol/python-sdk repo_url: https://github.com/modelcontextprotocol/python-sdk edit_uri: edit/v1.x/docs/ -site_url: https://py.sdk.modelcontextprotocol.io/ +site_url: https://py.sdk.modelcontextprotocol.io/v1/ # TODO(Marcelo): Add Anthropic copyright? # copyright: © Model Context Protocol 2025 to present diff --git a/pyproject.toml b/pyproject.toml index 9a4cf051ef..6bee7f4923 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,7 +91,7 @@ bump = true [project.urls] Homepage = "https://modelcontextprotocol.io" -Documentation = "https://py.sdk.modelcontextprotocol.io/" +Documentation = "https://py.sdk.modelcontextprotocol.io/v1/" Repository = "https://github.com/modelcontextprotocol/python-sdk" Issues = "https://github.com/modelcontextprotocol/python-sdk/issues" diff --git a/scripts/build-docs.sh b/scripts/build-docs.sh deleted file mode 100755 index 8286786091..0000000000 --- a/scripts/build-docs.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env bash -# -# Build combined v1 + v2 documentation for GitHub Pages. -# -# v1 docs (from the v1.x branch) are placed at the site root. -# v2 docs (from main) are placed under /v2/. -# -# The two lines use different toolchains: v1.x still builds with MkDocs, while -# main builds with Zensical (which needs a pre-build step to materialise the API -# reference and a post-build step for llms.txt — see scripts/docs/). Each branch -# is fetched fresh from origin and built with its own synced `docs` group, so -# the output is identical regardless of which branch triggered the workflow. -# This script is intended to run in CI; for a local v2 preview use -# `scripts/serve-docs.sh`. -# -# Usage: -# scripts/build-docs.sh [output-dir] -# -# Default output directory: site -# -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" -OUTPUT_DIR="$(cd "$REPO_ROOT" && mkdir -p "${1:-site}" && cd "${1:-site}" && pwd)" -V1_WORKTREE="$REPO_ROOT/.worktrees/v1-docs" -V2_WORKTREE="$REPO_ROOT/.worktrees/v2-docs" - -cleanup() { - cd "$REPO_ROOT" - git worktree remove --force "$V1_WORKTREE" 2>/dev/null || true - git worktree remove --force "$V2_WORKTREE" 2>/dev/null || true - rmdir "$REPO_ROOT/.worktrees" 2>/dev/null || true -} -trap cleanup EXIT - -# Build the checked-out worktree into its local `site/`, picking the toolchain -# from the branch's own files rather than hard-coding it here: a branch that -# ships the Zensical build recipe (scripts/docs/build.sh) builds with it, -# otherwise it falls back to MkDocs. This keeps the combined build correct -# regardless of which branch triggered it. Zensical requires site_dir to live -# within the project root, so both paths build to the local `site/` and let -# the caller copy it to its destination. -build_site() { - if [[ -f scripts/docs/build.sh ]]; then - bash scripts/docs/build.sh - else - uv sync --frozen --group docs - NO_MKDOCS_2_WARNING=1 uv run --frozen --no-sync mkdocs build --site-dir site - fi -} - -build_branch() { - local branch="$1" worktree="$2" dest="$3" - - echo "=== Building docs for ${branch} ===" - git fetch origin "$branch" - git worktree remove --force "$worktree" 2>/dev/null || true - rm -rf "$worktree" - git worktree add --detach "$worktree" "origin/${branch}" - - ( - cd "$worktree" - rm -rf site - build_site - mkdir -p "$dest" - cp -a site/. "$dest/" - ) -} - -rm -rf "${OUTPUT_DIR:?}"/* - -build_branch v1.x "$V1_WORKTREE" "$OUTPUT_DIR" -build_branch main "$V2_WORKTREE" "$OUTPUT_DIR/v2" - -echo "=== Combined docs built at $OUTPUT_DIR ===" diff --git a/scripts/docs/build.sh b/scripts/docs/build.sh new file mode 100755 index 0000000000..6c5ab88f62 --- /dev/null +++ b/scripts/docs/build.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# +# Build the v1.x documentation into ./site. +# +# This is the single build recipe for this branch's docs. The combined site +# is assembled and deployed from main, which fetches this branch and runs this +# script to build it under /v1/ (main's scripts/build-docs.sh picks +# scripts/docs/build.sh from each branch it builds). The `docs` CI job on +# this branch runs the same script, so what CI checks is what gets published. +# +# Usage: +# scripts/docs/build.sh +# +set -euo pipefail + +cd "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" + +uv sync --frozen --group docs +NO_MKDOCS_2_WARNING=1 uv run --frozen --no-sync mkdocs build --site-dir site