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

> Официальный Ruby SDK для MCP, gem mcp 1.6.1 - какие редакции протокола он понимает, как клиент выбирает эпоху, что принимает сервер и что остаётся неизвестным

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

Ruby SDK - официальный SDK первого уровня (Tier 1), gem `mcp`. Выпуск 1.6.1 понимает редакцию `2026-07-28` и четыре предыдущие, то есть работает в обеих эпохах. Клиент по умолчанию сам определяет эпоху сервера, сервер отвечает и новым, и старым клиентам без настройки.

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

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

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

- **Новейшая поддерживаемая редакция:** 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/ruby-sdk/releases/tag/v1.6.1)

## Что это

В [README выпуска](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/README.md) пакет назван так: «The official Ruby SDK for Model Context Protocol servers and clients». В нём есть и сервер, и клиент.

В [списке официальных SDK](https://modelcontextprotocol.io/docs/sdk) у Ruby стоит первый уровень (Tier 1). Что означает уровень, описано в [правилах уровней SDK](https://modelcontextprotocol.io/community/sdk-tiers): первый уровень - это полная реализация протокола и обязательства по сопровождению.

Кто сопровождает SDK, ни README, ни список официальных SDK не говорят.

## Выпуск и установка

Проверенный выпуск - 1.6.1 от 27 сентября 2026. Дата взята со [страницы пакета на RubyGems](https://rubygems.org/gems/mcp/versions/1.6.1) и из [выпуска на GitHub](https://github.com/modelcontextprotocol/ruby-sdk/releases/tag/v1.6.1). Предварительных выпусков новее него нет.

Нужен Ruby 2.7.0 или новее - так записано в [`mcp.gemspec`](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/mcp.gemspec) и в [руководстве по установке](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/docs/installation.md).

```ruby title="Gemfile"
gem "mcp"
```

```bash title="Установка без Bundler"
gem install mcp
```

Клиенту для HTTP нужен ещё gem `faraday` версии 2.0 или новее. Чтобы читать ответы в виде потока SSE, нужен `event_stream_parser`. Сервер сам решает, чем ответить: обычным JSON или потоком. Поэтому клиенту, который подключается к чужим серверам, руководство советует поставить оба пакета.

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

Список записан в [`lib/mcp/configuration.rb`](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/lib/mcp/configuration.rb) и повторён в [документации о версиях](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/docs/protocol-versions.md).

| Редакция | Эпоха | Как устанавливается связь |
|---|---|---|
| `2026-07-28` | Modern | без рукопожатия, версия едет в каждом запросе |
| `2025-11-25` | Legacy | рукопожатие `initialize` |
| `2025-06-18` | Legacy | рукопожатие `initialize` |
| `2025-03-26` | Legacy | рукопожатие `initialize` |
| `2024-11-05` | Legacy | рукопожатие `initialize` |

Для вас это значит следующее. Сервер, собранный на этом выпуске, обслуживает и клиента Modern, и клиента Legacy. Клиент, собранный на нём, подключится и к серверу только Modern, и к серверу только Legacy.

По [журналу изменений](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/CHANGELOG.md) редакция `2026-07-28` появилась в выпуске 1.1.0, а жизненный цикл без состояния был завершён в 1.2.0.

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

По [описанию жизненного цикла клиента](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/docs/_client/lifecycle.md) вызов `MCP::Client#connect` на встроенных транспортах `MCP::Client::HTTP` и `MCP::Client::Stdio` сначала отправляет `server/discover`. Если сервер отвечает как Modern, клиент работает по новому порядку. Если нет, клиент переходит на рукопожатие `initialize`.

Поведение можно задать явно:

```ruby title="Выбор жизненного цикла"
client.connect                                 # negotiate automatically (default)
client.connect(mode: :modern)                  # require the modern lifecycle; fails on legacy-only servers
client.connect(mode: :legacy)                  # force the classic initialize handshake
client.connect(protocol_version: "2025-11-25") # an explicit legacy version pins the handshake, no probe
```

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

Два замечания из той же документации:

- Собственный транспорт, у которого `connect` не принимает параметр `mode:`, всегда получает старый порядок вызова.
- Запросы от сервера к клиенту, которые принимают обработчики `on_elicitation` и `on_sampling`, существуют только в старом жизненном цикле. Для них документация советует `mode: :legacy`. В новой эпохе те же обработчики отвечают на вложенные запросы многошагового обмена: клиент выполняет их и повторяет исходный вызов.

Когда сервер начинает отвечать как Modern, `server_info["protocolVersion"]` возвращает `nil`: у ответа `server/discover` другая форма. Документация советует читать версию через `client.protocol_version` - этот метод работает в обеих эпохах.

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

По [документации о версиях](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/docs/protocol-versions.md) встроенные транспорты обслуживают обе эпохи одновременно, настройка для этого не нужна.

- Запросы Modern сервер проверяет по одному: версия берётся из `_meta` каждого запроса.
- В рукопожатии сервер по умолчанию предлагает `2025-11-25`. Версию рукопожатия можно закрепить через `MCP::Configuration.new(protocol_version:)`.
- Рукопожатие никогда не договаривается о версии Modern. Клиенту, который просит в `initialize` версию `2026-07-28`, сервер предложит последнюю версию рукопожатия.

Транспортов у сервера два: stdio и Streamable HTTP. Класс `MCP::Server::Transports::StreamableHTTPTransport` - обычное приложение Rack, его можно подключить в Rails. Подробности - в [описании транспортов сервера](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/docs/_server/transports.md).

По документации выпуска в старом жизненном цикле `StreamableHTTPTransport` держит сеансы и потоки SSE в памяти одного процесса. Нескольким процессам нужна привязка клиента к одному экземпляру. Запросы Modern и режим `stateless: true` сеансов не используют. У Modern есть две оговорки: поток `subscriptions/listen` живёт в том процессе, который его принял, а `requestState` переходит между процессами только при общем ключе `RequestStateSecurity`.

Тот же транспорт по умолчанию проверяет заголовки `Host` и `Origin` и отклоняет чужие значения ответом 403. За обратным прокси списки разрешённых значений нужно расширить параметрами `allowed_hosts:` и `allowed_origins:`.

## Минимальный сервер

```ruby title="server.rb"
require "mcp"

# Create a simple tool
class ExampleTool < MCP::Tool
  description "A simple example tool that echoes back its arguments"
  input_schema(
    properties: {
      message: { type: "string" },
    },
    required: ["message"]
  )

  class << self
    def call(message:, server_context:)
      MCP::Tool::Response.new([{
        type: "text",
        text: "Hello from example tool! Message: #{message}",
      }])
    end
  end
end

# Set up the server
server = MCP::Server.new(
  name: "example_server",
  tools: [ExampleTool],
)

# Create and start the transport
transport = MCP::Server::Transports::StdioTransport.new(server)
transport.open
```

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

## Минимальный клиент

```ruby title="client.rb"
stdio_transport = MCP::Client::Stdio.new(
  command: "bundle",
  args: ["exec", "ruby", "path/to/server.rb"],
  env: { "API_KEY" => "my_secret_key" },
  read_timeout: 30
)
client = MCP::Client.new(transport: stdio_transport)

# Negotiate the protocol lifecycle before sending any requests.
client.connect

# List available tools.
tools = client.tools
tools.each do |tool|
  puts "Tool: #{tool.name} - #{tool.description}"
end

# Call a specific tool.
response = client.call_tool(
  tool: tools.first,
  arguments: { message: "Hello, world!" }
)

# Close the transport when done.
stdio_transport.close
```

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

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

**Tasks.** В выпуске не реализовано. В [плане развития](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/ROADMAP.md) сказано, что расширение Tasks пока не реализовано и остаётся в планах.

**MCP Apps.** Есть помощники для стороны сервера - модуль `MCP::Apps`. По [документации расширения](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/docs/_extensions/mcp-apps.md) он объявляет расширение `io.modelcontextprotocol/ui`, описывает ресурс с адресом `ui://` и связывает инструмент с этим ресурсом. Показ интерфейса, изолированная рамка и согласие пользователя - задача программы-хоста, а не SDK. Поэтому в блоке совместимости стоит «частично».

## Устаревшие функции в выпуске

| Функция | Как с ней обходится выпуск 1.6.1 |
|---|---|
| Roots, Sampling, Logging | Поддерживаются на всём протяжении линии 1.x. При подключении Modern клиент выдаёт предупреждение, если объявлены Roots или Sampling. Срок удаления не назначен |
| `initialize` и сеансы | Работают в старой эпохе. Отказ от неё план развития оставляет на будущий мажорный выпуск |
| Динамическая регистрация клиента (RFC 7591) | Клиент OAuth применяет её при необходимости. [Документация авторизации](https://github.com/modelcontextprotocol/ruby-sdk/blob/v1.6.1/docs/_client/authorization.md) называет её устаревшей с `2026-07-28` и предлагает Client ID Metadata Documents |
| HTTP+SSE из `2024-11-05` | Не реализован намеренно: SDK даёт только Streamable HTTP |

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

На 4 октября 2026 ветка `main` опережает метку `v1.6.1` на 16 изменений. Файл `lib/mcp/configuration.rb` в ней совпадает с выпуском: список редакций тот же. Раздел «Unreleased» в журнале изменений на `main` пуст.

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

- Кто сопровождает SDK: README и список официальных SDK этого не говорят.
- Есть ли в SDK что-либо для показа MCP Apps на стороне хоста: документация выпуска описывает только сторону сервера.
- Срок удаления Roots, Sampling и Logging из SDK: план развития прямо говорит, что он не назначен.

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

- [Все SDK](https://mcpdoc.ru/sdk/) - сравнение официальных SDK по эпохам.
- [Обнаружение: server/discover](https://mcpdoc.ru/protocol/discovery/) - запрос, с которого клиент начинает проверку эпохи.
- [Две эпохи на одном сервере](https://mcpdoc.ru/deployment/dual-era/) - как обслуживать старых и новых клиентов.
- [Устаревшие функции](https://mcpdoc.ru/protocol/deprecations/) - сроки для Roots, Sampling, Logging и HTTP+SSE.
