# MCP Rust SDK (rmcp): установка, версии и редакции протокола

> Официальный Rust SDK для MCP - пакет rmcp 3.5.0, установка, редакции протокола, режимы жизненного цикла клиента и то, что обычный вызов serve остаётся в эпохе Legacy.

Страница: https://mcpdoc.ru/sdk/rust/
Указатель сайта: https://mcpdoc.ru/llms.txt

Rust SDK - официальный пакет `rmcp` для серверов и клиентов MCP. Выпуск 3.5.0 понимает обе эпохи протокола. Клиент, запущенный обычным вызовом `serve()`, начинает со старого рукопожатия `initialize`; новую эпоху включает вызов `serve_with_lifecycle` с режимом `Discover` или `Auto`. Сервер по Streamable HTTP обслуживает редакцию 2026-07-28 без сеансов сам, без настроек. Расширение Tasks реализовано.

сверено с выпуском 3.5.0 4 октября 2026

Совместимость Dual-era работает с обеими эпохами и выбирает по собеседнику

- **Проверенная версия:** 3.5.0, выпуск от 2026-09-28

- **Новейшая поддерживаемая редакция:** 2026-07-28

- **С сервером только Modern:** работает

- **С сервером только Legacy:** работает

- **Переход на старую редакцию:** вручную

- **Использует устаревшее:** Roots, Sampling, Logging, динамическая регистрация клиента (DCR)

- **Сохраняет удалённое в редакции 2026-07-28:** сессии, рукопожатие initialize

- **Расширение Tasks:** есть

- **Расширение MCP Apps:** нет

- **Проверено:** 2026-10-04

- **Источник:** [github.com](https://github.com/modelcontextprotocol/rust-sdk/releases/tag/rmcp-v3.5.0)

## Что это

Это SDK из репозитория [modelcontextprotocol/rust-sdk](https://github.com/modelcontextprotocol/rust-sdk/tree/rmcp-v3.5.0). В [списке официальных SDK](https://modelcontextprotocol.io/docs/sdk) он отнесён к первому уровню (Tier 1).

В репозитории два пакета: `rmcp` - основная реализация протокола, и `rmcp-macros` - процедурные макросы для описания инструментов. Ветка одна, 3.x. Выпуск 3.5.0 опубликован на [crates.io](https://crates.io/crates/rmcp) 28 сентября 2026.

Клиент и сервер включаются признаками Cargo. По [`Cargo.toml` пакета](https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.5.0/crates/rmcp/Cargo.toml), по умолчанию включены `base64`, `macros` и `server`; клиентская часть включается признаком `client`.

## Установка и среда

```bash title="Установка"
cargo add rmcp --features server
```

Команда взята из [README выпуска](https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.5.0/README.md). Нужен Rust 1.88 или новее, редакция языка 2024: так записано в [корневом `Cargo.toml`](https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.5.0/Cargo.toml) и в данных crates.io. Основные зависимости по README - `tokio` и `serde`; схемы JSON в диалекте 2020-12 строит `schemars`.

## Какие редакции понимает выпуск

Список версий в [`model.rs`](https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.5.0/crates/rmcp/src/model.rs): 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25, 2026-07-28.

В том же файле две константы, которые нужно различать:

- `ProtocolVersion::LATEST` - самая новая известная версия, в этом выпуске 2026-07-28;
- `ProtocolVersion::LATEST_WITH_INITIALIZE` - самая новая версия, в которой ещё есть рукопожатие `initialize`, то есть 2025-11-25.

README формулирует поддержку так: SDK реализует редакцию 2026-07-28 и остаётся совместимым с 2025-11-25 и более ранними версиями. Чем эпохи различаются, описано на странице [о версиях протокола](https://mcpdoc.ru/protocol/versions/).

## Что отправляет клиент по умолчанию

По README, `serve()` использует старый жизненный цикл: клиент отправляет `initialize`, получает согласованные сведения о сервере и отправляет `notifications/initialized`. Комментарий в [`service/client.rs`](https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.5.0/crates/rmcp/src/service/client.rs) подтверждает: поведение `ServiceExt::serve` осталось старой инициализацией.

Другой порядок выбирается явно, вызовом `ClientServiceExt::serve_with_lifecycle` с одним из значений `ClientLifecycleMode`:

| Режим | Что уходит в сеть | Со старым сервером |
|---|---|---|
| `Initialize` | рукопожатие `initialize`; то же, что `serve()` | работает |
| `Discover` | `server/discover`, затем данные клиента в каждом запросе | ошибка, отката нет |
| `Auto` | пробный `server/discover` | откат на `initialize` |

В режиме `Auto` откат происходит, когда сервер сообщает, что он старый, или не отвечает 10 секунд. Версию для отката задаёт поле `legacy_version`.

```rust title="Клиент с выбором жизненного цикла"
use rmcp::{ClientLifecycleMode, ClientServiceExt, ProtocolVersion, model::ClientConfig};

// Start directly with server/discover and include client metadata on every request.
let client = ClientConfig::default()
    .serve_with_lifecycle(
        transport,
        ClientLifecycleMode::Discover {
            preferred_versions: vec![ProtocolVersion::V_2026_07_28],
        },
    )
    .await?;

// Or probe the discover lifecycle and fall back when a legacy server reports
// that server/discover is not implemented or does not respond within 10 seconds.
let client = ClientConfig::default()
    .serve_with_lifecycle(
        transport,
        ClientLifecycleMode::Auto {
            preferred_versions: vec![ProtocolVersion::V_2026_07_28],
            legacy_version: Some(ProtocolVersion::V_2025_11_25),
        },
    )
    .await?;
```

Пример взят из документации выпуска 3.5.0 и здесь не запускался.

Это отрывок из README: переменная `transport` в нём создаётся отдельно. По README, при запуске через `server/discover` уведомление `notifications/initialized` не отправляется, а каждый следующий запрос несёт версию протокола, сведения о клиенте и его возможности в `_meta`.

Клиент, написанный через `serve()`, после перехода на 3.5.0 продолжит открывать соединение рукопожатием `initialize`, даже если сервер умеет 2026-07-28. Чтобы клиент работал в эпохе Modern, нужен `serve_with_lifecycle`.

## Что принимает сервер

Серверный обработчик в [`handler/server.rs`](https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.5.0/crates/rmcp/src/handler/server.rs) содержит метод `discover` и отвечает на запрос `server/discover`.

Для Streamable HTTP README описывает правило так: редакцию 2026-07-28 `rmcp` обслуживает без сеансов сам. В ней нет `Mcp-Session-Id`, отдельного потока `GET` и `DELETE`, возобновления по `Last-Event-ID`.

Настройка `legacy_session_mode` в `StreamableHttpServerConfig` относится только к версиям старше 2026-07-28. По [`tower.rs`](https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.5.0/crates/rmcp/src/transport/streamable_http_server/tower.rs), её значение по умолчанию - `true`: старые клиенты получают сеанс. Вызов `with_legacy_session_mode(false)` обслуживает без сеансов и старые версии.

```rust title="Сервер на stdio с одним инструментом"
use rmcp::{handler::server::wrapper::Parameters, schemars, tool, tool_router, ServiceExt, transport::stdio};

#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
struct AddParams {
    a: i32,
    b: i32,
}

#[derive(Clone)]
struct Calculator;

#[tool_router(server_handler)]
impl Calculator {
    #[tool(description = "Add two numbers")]
    fn add(&self, Parameters(AddParams { a, b }): Parameters<AddParams>) -> String {
        (a + b).to_string()
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let service = Calculator.serve(stdio()).await?;
    service.waiting().await?;
    Ok(())
}
```

Пример взят из документации выпуска 3.5.0 и здесь не запускался.

Транспорты подключаются признаками Cargo. По таблице в README: stdio - `transport-io`, запуск дочернего процесса на стороне клиента - `transport-child-process`, сервер Streamable HTTP - `transport-streamable-http-server` (служба Tower, которую можно подключить к любому маршрутизатору), клиент Streamable HTTP - `transport-streamable-http-client-reqwest`.

## Расширения

**Tasks.** Реализовано. По README, `rmcp` реализует расширение MCP Tasks (SEP-2663, `io.modelcontextprotocol/tasks`). Клиент объявляет расширение в своих возможностях, а сервер для каждого запроса решает, оформлять ли вызов `tools/call` как задачу. Клиент опрашивает `tasks/get`, отвечает на запросы ввода через `tasks/update` и может запросить отмену через `tasks/cancel`. На стороне сервера задачами управляет `rmcp::task_manager::TaskManager`.

**MCP Apps.** Отдельной реализации нет. В выпуске есть только общая карта возможностей `extensions`, а идентификатор `io.modelcontextprotocol/ui` встречается как пример ключа в одном тесте в [`capabilities.rs`](https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.5.0/crates/rmcp/src/model/capabilities.rs). Программного интерфейса для Apps и раздела о них в README нет. То есть объявить возможность можно, а всё остальное вы пишете сами.

Что такое расширения и как о них договариваются стороны - на странице [о расширениях](https://mcpdoc.ru/protocol/extensions/).

## Устаревшее, что выпуск ещё содержит

- **Roots, Sampling, Logging.** В README каждая из трёх возможностей помечена как устаревшая по SEP-2577 с оговоркой, что пока она полностью работает и будет удалена в одном из будущих выпусков.
- **Сеансы и `initialize`.** Сохранены для версий старой эпохи: `legacy_session_mode` на сервере и `serve()` на клиенте.
- **Динамическая регистрация клиента.** По [документу об OAuth](https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.5.0/docs/OAUTH_SUPPORT.md), клиент выбирает способ регистрации по порядку: заранее выданные данные клиента, затем Client ID Metadata Documents, затем динамическая регистрация как запасной путь.
- **HTTP+SSE.** Старого транспорта из двух адресов в выпуске нет, и это решение проекта: [README выпуска](https://github.com/modelcontextprotocol/rust-sdk/blob/rmcp-v3.5.0/README.md) называет его осознанным отказом и сообщает, что ни клиентского, ни серверного транспорта HTTP+SSE SDK не поставляет и возвращать не будет. К серверу, который умеет только HTTP+SSE, клиент на `rmcp` не подключится. Признак `client-side-sse` - это разбор потока SSE внутри клиента Streamable HTTP, а не старый транспорт.

Общий список - на странице [об устаревших возможностях](https://mcpdoc.ru/protocol/deprecations/).

## Выпуск и ветка main

На 4 октября 2026 ветка `main` опережает метку `rmcp-v3.5.0` на четыре изменения: два касаются служебной автоматики репозитория, одно - уведомления хранилищ учётных данных при отклонённом токене обновления, одно - примера. Константы версий протокола совпадают с выпуском, номер версии пакета в `main` по-прежнему 3.5.0. Пробных выпусков новее 3.5.0 на crates.io нет.

Выпуски `rmcp-v3.0.0-beta.4` и `rmcp-v3.0.0-beta.5` на GitHub не отмечены как предварительные, хотя по названию это бета-версии. Если вы отбираете выпуски по этому признаку, они попадут в список стабильных.

## Что неизвестно

- Помечена ли динамическая регистрация клиента как устаревшая в коде выпуска: документ об OAuth называет её запасным путём, но об устаревании не говорит.
- Содержимое опубликованного архива пакета отдельно не распаковывалось: сверялись исходники по метке выпуска и данные crates.io.

## Что читать дальше

- [Все официальные SDK](https://mcpdoc.ru/sdk/)
- [Версии протокола и эпохи](https://mcpdoc.ru/protocol/versions/)
- [Запрос server/discover](https://mcpdoc.ru/protocol/discovery/)
- [Сервер двух эпох](https://mcpdoc.ru/deployment/dual-era/)
