Ruby SDK
Официальный Ruby SDK для Model Context Protocol — создание MCP-серверов с поддержкой Rails и Rack
Официальный Ruby SDK для Model Context Protocol предоставляет полноценную поддержку создания MCP-серверов и клиентов с интеграцией в Rails и Rack-приложения.
Возможности
Заголовок раздела «Возможности»- JSON-RPC 2.0 обработка сообщений
- Инициализация протокола и согласование capabilities
- Регистрация и вызов инструментов (tools)
- Регистрация и выполнение prompts
- Регистрация и получение ресурсов (resources)
- Транспорты: stdio и Streamable HTTP (включая SSE)
- Уведомления об изменениях списков
Установка
Заголовок раздела «Установка»gem 'mcp'bundle installgem install mcpСоздание сервера
Заголовок раздела «Создание сервера»Базовый сервер
Заголовок раздела «Базовый сервер»require "mcp"
server = MCP::Server.new( name: "my_server", title: "Мой MCP Сервер", version: "1.0.0", instructions: "Используйте инструменты этого сервера")Интеграция с Rails
Заголовок раздела «Интеграция с Rails»class McpController < ApplicationController def index server = MCP::Server.new( name: "my_server", title: "Rails MCP Server", version: "1.0.0", tools: [WeatherTool, CalculatorTool], prompts: [GreetingPrompt], server_context: { user_id: current_user.id } )
render json: server.handle_json(request.body.read) endendStdio Transport
Заголовок раздела «Stdio Transport»require "mcp"
server = MCP::Server.new( name: "example_server", tools: [ExampleTool])
transport = MCP::Server::Transports::StdioTransport.new(server)transport.openСоздание инструментов
Заголовок раздела «Создание инструментов»Через класс
Заголовок раздела «Через класс»class WeatherTool < MCP::Tool title "Погода" description "Получает текущую погоду для указанной локации"
input_schema( properties: { location: { type: "string", description: "Город" }, units: { type: "string", enum: ["metric", "imperial"] } }, required: ["location"] )
output_schema( properties: { temperature: { type: "number" }, condition: { type: "string" }, humidity: { type: "integer" } }, required: ["temperature", "condition", "humidity"] )
annotations( read_only_hint: true, destructive_hint: false, idempotent_hint: true )
def self.call(location:, units: "metric", server_context:) weather = fetch_weather(location, units)
MCP::Tool::Response.new( [{ type: "text", text: weather.to_json }], structured_content: weather ) endendЧерез define
Заголовок раздела «Через define»tool = MCP::Tool.define( name: "calculator", title: "Калькулятор", description: "Выполняет математические вычисления") do |args, server_context:| expression = args["expression"] result = eval(expression) # Используйте безопасный парсер!
MCP::Tool::Response.new([{ type: "text", text: "Результат: #{result}" }])endЧерез server.define_tool
Заголовок раздела «Через server.define_tool»server.define_tool( name: "echo", description: "Возвращает переданное сообщение") do |args, server_context:| MCP::Tool::Response.new([{ type: "text", text: args["message"] }])endСоздание prompts
Заголовок раздела «Создание prompts»class GreetingPrompt < MCP::Prompt prompt_name "greeting" title "Приветствие" description "Генерирует приветственное сообщение"
arguments [ MCP::Prompt::Argument.new( name: "name", title: "Имя", description: "Имя для приветствия", required: true ) ]
def self.template(args, server_context:) MCP::Prompt::Result.new( description: "Приветствие для #{args['name']}", messages: [ MCP::Prompt::Message.new( role: "user", content: MCP::Content::Text.new("Привет!") ), MCP::Prompt::Message.new( role: "assistant", content: MCP::Content::Text.new("Привет, #{args['name']}!") ) ] ) endendРабота с ресурсами
Заголовок раздела «Работа с ресурсами»# Определение ресурсаresource = MCP::Resource.new( uri: "https://example.com/docs", name: "documentation", title: "Документация", description: "Техническая документация", mime_type: "text/html")
server = MCP::Server.new( name: "my_server", resources: [resource])
# Обработчик чтения ресурсовserver.resources_read_handler do |params| [{ uri: params[:uri], mimeType: "text/plain", text: "Содержимое ресурса: #{params[:uri]}" }]endУведомления
Заголовок раздела «Уведомления»# Создание сервера с Streamable HTTPserver = MCP::Server.new(name: "my_server")transport = MCP::Server::Transports::StreamableHTTPTransport.new(server)server.transport = transport
# Уведомление об изменении списка инструментовserver.define_tool(name: "new_tool") { |**args| { result: "ok" } }server.notify_tools_list_changed
# Уведомление об изменении promptsserver.notify_prompts_list_changed
# Уведомление об изменении ресурсовserver.notify_resources_list_changedСоздание клиента
Заголовок раздела «Создание клиента»# HTTP-клиент (требуется gem 'faraday')http_transport = MCP::Client::HTTP.new( url: "https://api.example.com/mcp", headers: { "Authorization" => "Bearer token" })
client = MCP::Client.new(transport: http_transport)
# Список инструментовtools = client.toolstools.each do |tool| puts "Tool: #{tool.name}" puts "Description: #{tool.description}"end
# Вызов инструментаresponse = client.call_tool( tool: tools.first, arguments: { message: "Hello!" })Конфигурация
Заголовок раздела «Конфигурация»MCP.configure do |config| # Обработчик исключений config.exception_reporter = ->(exception, server_context) { Bugsnag.notify(exception) do |report| report.add_metadata(:mcp, server_context) end }
# Инструментирование config.instrumentation_callback = ->(data) { Rails.logger.info "MCP: #{data.inspect}" # data содержит: method, tool_name, prompt_name, # resource_uri, error, duration }
# Версия протокола (опционально) config.protocol_version = "2025-06-18"endServer Context
Заголовок раздела «Server Context»server_context — хэш с контекстной информацией, передаваемой в tools, prompts и callbacks:
server = MCP::Server.new( name: "my_server", server_context: { user_id: current_user.id, request_id: request.uuid })
# Доступен в инструментахclass MyTool < MCP::Tool def self.call(server_context:, **args) user = User.find(server_context[:user_id]) # ... endendКастомные методы
Заголовок раздела «Кастомные методы»# Определение кастомного JSON-RPC методаserver.define_custom_method(method_name: "add") do |params| params[:a] + params[:b]end
# Запрос# {"jsonrpc": "2.0", "id": 1, "method": "add", "params": {"a": 5, "b": 3}}
# Ответ# {"jsonrpc": "2.0", "id": 1, "result": 8}Поддерживаемые методы
Заголовок раздела «Поддерживаемые методы»| Метод | Описание |
|---|---|
initialize | Инициализация протокола |
ping | Проверка доступности |
tools/list | Список инструментов |
tools/call | Вызов инструмента |
prompts/list | Список prompts |
prompts/get | Получение prompt |
resources/list | Список ресурсов |
resources/read | Чтение ресурса |
resources/templates/list | Список шаблонов ресурсов |