内容
# 模型上下文协议 Ruby 实现
[模型上下文协议(MCP)](https://spec.modelcontextprotocol.io/specification/2025-06-18/) 的 Ruby 实现。
提供简单的抽象概念,允许您通过 MCP 在本地(标准输入/输出)或生产环境(可流式传输的 HTTP,背后由 Redis 支持)提供提示、资源、资源模板和工具,且仅需付出最小的努力。
## 功能支持(服务器)
| 状态 | 功能 |
|--------|---------|
| ✅ | [提示](https://modelcontextprotocol.io/specification/2025-06-18/server/prompts) |
| ✅ | [资源](https://modelcontextprotocol.io/specification/2025-06-18/server/resources) |
| ✅ | [资源模板](https://modelcontextprotocol.io/specification/2025-06-18/server/resources#resource-templates) |
| ✅ | [工具](https://modelcontextprotocol.io/specification/2025-06-18/server/tools) |
| ✅ | [补全](https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/completion) |
| ✅ | [日志记录](https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/logging) |
| ✅ | [分页](https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/pagination) |
| ✅ | [环境变量](https://modelcontextprotocol.io/legacy/tools/debugging#environment-variables) |
| ✅ | [标准输入/输出传输](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio) |
| ✅ | [可流式传输的 HTTP 传输](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http) |
| ✅ | [列表变更通知(提示)](https://modelcontextprotocol.io/specification/2025-06-18/server/prompts#list-changed-notification) ¹ |
| ✅ | [列表变更通知(资源)](https://modelcontextprotocol.io/specification/2025-06-18/server/resources#list-changed-notification) ¹ |
| ❌ | [订阅(资源)](https://modelcontextprotocol.io/specification/2025-06-18/server/resources#subscriptions) |
| ✅ | [列表变更通知(工具)](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#list-changed-notification) ¹ |
| ✅ | [取消](https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/cancellation) |
| ✅ | [Ping](https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/ping) |
| ✅ | [进度](https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/progress) |
## 安装
将以下内容添加到您的应用程序的 Gemfile 中:
```ruby
gem 'model-context-protocol-rb'
```
然后执行:
```bash
bundle
```
或者您可以自己安装:
```bash
gem install model-context-protocol-rb
```
有关详细的安装说明,请参阅 [安装维基页面](https://github.com/dickdavis/model-context-protocol-rb/wiki/Installation)。
## 构建 MCP 服务器
通过注册您的提示、资源、资源模板和工具,构建一个简单的 MCP 服务器。来自 MCP 客户端的消息将路由到适当的自定义处理程序。
### 标准输入/输出传输(默认)
对于通过标准输入/输出进行通信的命令行 MCP 服务器:
```ruby
server = ModelContextProtocol::Server.with_stdio_transport do |config|
config.name = "MyMCPServer"
config.title = "My Server"
config.version = "1.0.0"
config.instructions = <<~INSTRUCTIONS
This server provides prompts, tools, and resources for interacting with my app.
Key capabilities:
- Does something
- Does something else
- Oh, and it does this other thing, too
Use this server when you need to do things.
INSTRUCTIONS
config.registry do
prompts do
register MyPrompt
end
resources do
register MyResource
end
tools do
register MyTool
end
end
end
server.start
```
### 可流式传输的 HTTP 传输
对于基于 HTTP 的 MCP 服务器(例如 Rails 应用程序),您需要在初始化程序中设置 MCP 服务器,并配置 Redis。Redis 使得在生产环境部署中协调多个服务器进程成为可能(例如 Puma 工作进程),而单个进程无法在内存中保存所有状态。
```ruby
# config/initializers/model_context_protocol.rb
require "model_context_protocol"
# Assuming your handlers will be organized in the app/mcp folder.
Dir[Rails.root.join("app/mcp/**/*.rb")].sort.each { |f| require f }
ModelContextProtocol::Server.with_streamable_http_transport do |config|
config.name = "MyServer"
config.title = "My Server"
config.version = "1.0.0"
config.instructions = <<~INSTRUCTIONS
This server provides prompts, tools, and resources for interacting with my app.
Key capabilities:
- Does something
- Does something else
- Oh, and it does this other thing, too
Use this server when you need to do things.
INSTRUCTIONS
config.redis_url = ENV.fetch("REDIS_URL", "redis://localhost:6379/0")
config.redis_pool_size = 20
config.redis_pool_timeout = 5
config.redis_enable_reaper = true
config.redis_reaper_interval = 60
config.redis_idle_timeout = 300
config.redis_ssl_params = {verify_mode: OpenSSL::SSL::VERIFY_NONE}
config.registry do
prompts do
register MyPrompt
end
resources do
register MyResource
end
tools do
register MyTool
end
end
end
```
如果您的应用程序使用 Puma (>= 7.0) 作为 Web 服务器,请使用提供的插件启动 MCP 服务器。
```ruby
# config/puma.rb
plugin :mcp
```
对于 Puma 6.x 或其他 Web 服务器,您需要手动实现启动和关闭 MCP 服务器的逻辑。此示例展示了如何为 Puma 6.x 执行此操作;您可以将其适配到您选择的服务器。
```ruby
# config/puma.rb
workers ENV.fetch("WEB_CONCURRENCY", 0).to_i
mcp_start = ->(*) { ModelContextProtocol::Server.start unless ModelContextProtocol::Server.running? }
mcp_shutdown = ->(*) { ModelContextProtocol::Server.shutdown }
# Clustered mode: workers fork, so start threads after fork
on_worker_boot(&mcp_start)
on_worker_shutdown(&mcp_shutdown)
# Single mode: start directly (no forking)
if ENV.fetch("WEB_CONCURRENCY", 0).to_i.zero?
mcp_start.call
at_exit(&mcp_shutdown)
end
```
然后,实现一个控制器操作来处理对 MCP 服务器的请求。
```ruby
class ModelContextProtocolController < ActionController::API
include ActionController::Live
def handle
result = ModelContextProtocol::Server.serve(
env: request.env,
session_context: { user_id: current_user.id }
)
response.headers.merge!(result[:headers]) if result[:headers]
if result[:stream]
result[:stream_proc]&.call(response.stream)
else
render json: result[:json], status: result[:status] || 200
end
ensure
response.stream.close rescue nil
end
end
```
最后,添加必要的路由:
```ruby
get "/", to: "model_context_protocol#handle", as: :mcp_get
post "/", to: "model_context_protocol#handle", as: :mcp_post
delete "/", to: "model_context_protocol#handle", as: :mcp_delete
```
有关完整的 Rails 集成示例,请参阅 [使用 Rails 快速入门](https://github.com/dickdavis/model-context-protocol-rb/wiki/Quick-Start-with-Rails) 指南。
有关完整的配置详细信息,包括所有服务器选项、Redis 配置和日志记录选项,请参阅 [构建 MCP 服务器](https://github.com/dickdavis/model-context-protocol-rb/wiki/Building-an-MCP-Server) 维基页面。
## Claude 代码插件
[mcp-rb](https://github.com/dickdavis/model-context-protocol-rb-plugin) Claude 代码插件教 Claude 如何使用此 gem 的 DSL 构建 MCP 处理程序和配置服务器。它为创建工具、提示、资源和服务器配置提供了技能。
## 提示
定义 MCP 客户端可以用来生成上下文消息序列的提示。
```ruby
class TestPrompt < ModelContextProtocol::Server::Prompt
define do
name "brainstorm_excuses"
description "A prompt for brainstorming excuses"
argument { name "tone"; required false }
end
def call
messages = message_history do
user_message { text_content(text: "Generate excuses with #{arguments[:tone]} tone") }
end
respond_with messages:
end
end
```
主要功能:
- 定义具有验证和补全提示的参数
- 使用用户和助手消息构建消息历史记录
- 支持文本、图像、音频和嵌入式资源内容
有关完整的文档和示例,请参阅 [提示](https://github.com/dickdavis/model-context-protocol-rb/wiki/Prompts) 维基页面。
## 资源
通过定义的资源向 MCP 客户端公开数据和内容。
```ruby
class TestResource < ModelContextProtocol::Server::Resource
define do
name "config.json"
description "Application configuration"
mime_type "application/json"
uri "file:///config.json"
end
def call
respond_with text: { setting: "value" }.to_json
end
end
```
主要功能:
- 定义包括 MIME 类型和 URI 在内的元数据
- 返回文本或二进制内容
- 添加受众和优先级注解
有关完整的文档和示例,请参阅 [资源](https://github.com/dickdavis/model-context-protocol-rb/wiki/Resources) 维基页面。
## 资源模板
定义参数化资源,客户端可以实例化这些资源。
```ruby
class TestResourceTemplate < ModelContextProtocol::Server::ResourceTemplate
define do
name "document-template"
description "Template for retrieving documents"
mime_type "text/plain"
uri_template "file:///{name}" do
completion :name, ["readme.txt", "config.json"]
end
end
end
```
主要功能:
- 定义带有参数的 URI 模板
- 为模板参数提供补全提示
有关完整的文档和示例,请参阅 [资源模板](https://github.com/dickdavis/model-context-protocol-rb/wiki/Resource-Templates) 维基页面。
## 工具
创建 MCP 客户端可以调用的具有验证输入的可调用函数。
```ruby
class TestToolWithStructuredContentResponse < ModelContextProtocol::Server::Tool
define do
# The name of the tool for programmatic use
name "get_weather_data"
# The human-readable tool name for display in UI
title "Weather Data Retriever"
# A short description of what the tool does
description "Get current weather data for a location"
# The JSON schema for validating tool inputs
input_schema do
{
type: "object",
properties: {
location: {
type: "string",
description: "City name or zip code"
}
},
required: ["location"]
}
end
# The JSON schema for validating structured content
output_schema do
{
type: "object",
properties: {
temperature: {
type: "number",
description: "Temperature in celsius"
},
conditions: {
type: "string",
description: "Weather conditions description"
},
humidity: {
type: "number",
description: "Humidity percentage"
}
},
required: ["temperature", "conditions", "humidity"]
}
end
# Optional security requirements for the tool
security_schemes do
[
{type: "noauth"},
{type: "oauth2", scopes: ["search.read"]}
]
end
end
def call
# Use values provided by the server as context
user_id = context[:user_id]
client_logger.info("Initiating request for user #{user_id}...")
# Use values provided by clients as tool arguments
location = arguments[:location]
client_logger.info("Getting weather data for #{location}...")
# Returns a hash that validates against the output schema
weather_data = get_weather_data(location)
# Respond with structured content
respond_with structured_content: weather_data
end
private
# Simulate calling an external API to get weather data for the provided input
def get_weather_data(location)
{
temperature: 22.5,
conditions: "Partly cloudy",
humidity: 65
}
end
end
```
主要功能:
- 定义输入和输出 JSON 模式
- 声明工具安全方案(例如,noauth,oauth2 作用域)
- 返回文本、图像、音频或嵌入式资源内容
- 支持结构化内容响应
- 可取消和进度操作
有关完整的文档和 7 个详细示例,请参阅 [工具](https://github.com/dickdavis/model-context-protocol-rb/wiki/Tools) 维基页面。
## 补全
为提示和资源模板提供参数补全提示。
```ruby
class TestCompletion < ModelContextProtocol::Server::Completion
def call
hints = { "tone" => ["whiny", "angry", "nervous"] }
values = hints[argument_name].grep(/#{argument_value}/)
respond_with values:
end
end
```
有关完整的文档,请参阅 [补全](https://github.com/dickdavis/model-context-protocol-rb/wiki/Completions) 维基页面。
## 使用 RSpec 测试
此 gem 为测试 MCP 处理程序提供了自定义的 RSpec 匹配器和帮助程序。
```ruby
require "model_context_protocol/rspec"
ModelContextProtocol::RSpec.configure!
RSpec.describe WeatherTool, type: :mcp do
it "returns weather data" do
response = call_mcp_tool(WeatherTool, { location: "New York" })
expect(response).to be_valid_mcp_tool_response
expect(response).to have_text_content(/temperature/)
end
end
```
主要功能:
- 帮助方法:`call_mcp_tool`、`call_mcp_prompt`、`call_mcp_resource`
- 类定义匹配器:`be_valid_mcp_class(:tool)`
- 文本、图像、音频和结构化内容的响应匹配器
- 提示和资源特定的匹配器
有关完整的匹配器文档和示例,请参阅 [使用 RSpec 测试](https://github.com/dickdavis/model-context-protocol-rb/wiki/Testing-with-RSpec) 维基页面。
## 开发
检出存储库后,运行 `bin/setup` 安装依赖。然后,运行 `bundle exec rspec` 运行测试。
### 生成开发服务器
生成可用于测试的可执行文件:
```bash
# generates bin/dev for STDIO transport
bundle exec rake mcp:generate_stdio_server
# generates bin/dev-http for streamable HTTP transport
bundle exec rake mcp:generate_streamable_http_server
# generates bin/dev-http-puma for streamable HTTP transport with Puma web server
bundle exec rake mcp:generate_puma_server
```
如果您需要使用 HTTPS(例如,用于需要 SSL 的客户端),请生成自签名证书:
```bash
# Create SSL directory and generate certificates
mkdir -p tmp/ssl
openssl req -x509 -newkey rsa:4096 -keyout tmp/ssl/server.key -out tmp/ssl/server.crt -days 365 -nodes -subj "/C=US/ST=Dev/L=Dev/O=Dev/CN=localhost"
```
HTTP 服务器支持 HTTP 和 HTTPS:
```bash
# Run HTTP server (default)
bin/dev-http
# Run HTTPS server (requires SSL certificates in tmp/ssl/)
SSL=true bin/dev-http
```
您还可以运行 `bin/console` 进行交互式提示。执行命令 `rp` 重新加载项目。
要将此 gem 安装到本地机器,请运行 `bundle exec rake install`.
### 版本发布
发布新版本时,请更新 `version.rb` 中的版本号,并提交 PR。PR 合并到 main 后,请运行 `bundle exec rake release`,它将:
* 创建版本的 git 标签
* 推送创建的标签
* 将 `.gem` 文件推送到 [rubygems.org](https://rubygems.org)。
然后,在 Github 上草案并发布发布说明。
## 贡献
欢迎在 Github 上提交 bug 报告和拉取请求:https://github.com/dickdavis/model-context-protocol-rb。
## 许可证
该 gem 在 [MIT License](https://opensource.org/licenses/MIT) 许可下作为开源软件提供。