model-context-protocol-rb
Note: An official MCP implementation has been released for Ruby, so development of this project has ceased.
An implementation of the Model Context Protocol (MCP) in Ruby.
This SDK is experimental and subject to change. The initial focus is to implement MCP server support with the goal of providing a stable API by version 0.4
. MCP client support will follow.
You are welcome to contribute.
TODO's:
- Pagination
- Prompt list changed notifications
- Resource list changed notifications
- Resource subscriptions
- Tool list changed notifications
Usage
Include model_context_protocol
in your project.
require 'model_context_protocol'
Building an MCP Server
Build a simple MCP server by registering your prompts, resources, resource templates, and tools. Then, configure and run the server.
server = ModelContextProtocol::Server.new do |config|
config.name = "MCP Development Server"
config.version = "1.0.0"
config.enable_log = true
# Environment Variables - https://modelcontextprotocol.io/docs/tools/debugging#environment-variables
# Require specific environment variables to be set
config.require_environment_variable("API_KEY")
# Set environment variables programmatically
config.set_environment_variable("DEBUG_MODE", "true")
config.registry = ModelContextProtocol::Server::Registry.new do
prompts list_changed: true do
register TestPrompt
end
resources list_changed: true, subscribe: true do
register TestResource
end
resource_templates do
register TestResourceTemplate
end
tools list_changed: true do
register TestTool
end
end
end
server.start
Messages from the MCP client will be routed to the appropriate custom handler. This SDK provides several classes that should be used to build your handlers.
Prompts
The ModelContextProtocol::Server::Prompt
base class allows subclasses to define a prompt that the MCP client can use. Define the appropriate metadata in the with_metadata
block.
Define any arguments using the with_argument
block. You can mark an argument as required, and you can optionally provide the class name of a service object that provides completions. See Completions for more information.
Then implement the call
method to build your prompt. Use the respond_with
instance method to ensure your prompt responds with appropriately formatted response data.
This is an example prompt that returns a properly formatted response:
class TestPrompt < ModelContextProtocol::Server::Prompt
with_metadata do
name "test_prompt"
description "A test prompt"
end
with_argument do
name "message"
description "The thing to do"
required true
completion TestCompletion
end
with_argument do
name "other"
description "Another thing to do"
required false
end
def call
messages = [
{
role: "user",
content: {
type: "text",
text: "Do this: #{params["message"]}"
}
}
]
respond_with messages: messages
end
end
Resources
The ModelContextProtocol::Server::Resource
base class allows subclasses to define a resource that the MCP client can use. Define the appropriate metadata in the with_metadata
block.
Then, implement the call
method to build your resource. Use the respond_with
instance method to ensure your resource responds with appropriately formatted response data.
This is an example resource that returns a text response:
class TestResource < ModelContextProtocol::Server::Resource
with_metadata do
name "Test Resource"
description "A test resource"
mime_type "text/plain"
uri "resource://test-resource"
end
def call
respond_with :text, text: "Here's the data"
end
end
This is an example resource that returns binary data:
class TestBinaryResource < ModelContextProtocol::Server::Resource
with_metadata do
name "Project Logo"
description "The logo for the project"
mime_type "image/jpeg"
uri "resource://project-logo"
end
def call
# In a real implementation, we would retrieve the binary resource
data = "dGVzdA=="
respond_with :binary, blob: data
end
end
Resource Templates
The ModelContextProtocol::Server::ResourceTemplate
base class allows subclasses to define a resource template that the MCP client can use. Define the appropriate metadata in the with_metadata
block.
This is an example resource template that provides a completion for a parameter of the URI template:
class TestResourceTemplateCompletion < ModelContextProtocol::Server::Completion
def call
hints = {
"name" => ["test-resource", "project-logo"]
}
values = hints[argument_name].grep(/#{argument_value}/)
respond_with values:
end
end
class TestResourceTemplate < ModelContextProtocol::Server::ResourceTemplate
with_metadata do
name "Test Resource Template"
description "A test resource template"
mime_type "text/plain"
uri_template "resource://{name}" do
completion :name, TestResourceTemplateCompletion
end
end
end
Tools
The ModelContextProtocol::Server::Tool
base class allows subclasses to define a tool that the MCP client can use. Define the appropriate metadata in the with_metadata
block.
Then implement the call
method to build your tool. Use the respond_with
instance method to ensure your tool responds with appropriately formatted response data.
This is an example tool that returns a text response:
class TestToolWithTextResponse < ModelContextProtocol::Server::Tool
with_metadata do
name "double"
description "Doubles the provided number"
input_schema do
{
type: "object",
properties: {
number: {
type: "string"
}
},
required: ["number"]
}
end
end
def call
number = params["number"].to_i
result = number * 2
respond_with :text, text: "#{number} doubled is #{result}"
end
end
This is an example of a tool that returns an image:
class TestToolWithImageResponse < ModelContextProtocol::Server::Tool
with_metadata do
name "custom-chart-generator"
description "Generates a chart in various formats"
input_schema do
{
type: "object",
properties: {
chart_type: {
type: "string",
description: "Type of chart (pie, bar, line)"
},
format: {
type: "string",
description: "Image format (jpg, svg, etc)"
}
},
required: ["chart_type", "format"]
}
end
end
def call
# Map format to mime type
mime_type = case params["format"].downcase
when "svg"
"image/svg+xml"
when "jpg", "jpeg"
"image/jpeg"
else
"image/png"
end
# In a real implementation, we would generate an actual chart
# This is a small valid base64 encoded string (represents "test")
chart_data = "dGVzdA=="
respond_with :image, data: chart_data, mime_type:
end
end
If you don't provide a mime type, it will default to image/png
.
class TestToolWithImageResponseDefaultMimeType < ModelContextProtocol::Server::Tool
with_metadata do
name "other-custom-chart-generator"
description "Generates a chart"
input_schema do
{
type: "object",
properties: {
chart_type: {
type: "string",
description: "Type of chart (pie, bar, line)"
}
},
required: ["chart_type"]
}
end
end
def call
# In a real implementation, we would generate an actual chart
# This is a small valid base64 encoded string (represents "test")
chart_data = "dGVzdA=="
respond_with :image, data: chart_data
end
end
This is an example of a tool that returns a resource response:
class TestToolWithResourceResponse < ModelContextProtocol::Server::Tool
with_metadata do
name "document-finder"
description "Finds a the document with the given title"
input_schema do
{
type: "object",
properties: {
title: {
type: "string",
description: "The title of the document"
}
},
required: ["title"]
}
end
end
def call
title = params["title"].downcase
# In a real implementation, we would do a lookup to get the document data
document = "richtextdata"
respond_with :resource, uri: "resource://document/#{title}", text: document, mime_type: "application/rtf"
end
end
Completions
The ModelContextProtocol::Server::Completion
base class allows subclasses to define a completion that the MCP client can use to obtain hints or suggestions for arguments to prompts and resources.
implement the call
method to build your completion. Use the respond_with
instance method to ensure your completion responds with appropriately formatted response data.
This is an example completion that returns an array of values in the response:
class TestCompletion < ModelContextProtocol::Server::Completion
def call
hints = {
"message" => ["hello", "world", "foo", "bar"]
}
values = hints[argument_name].grep(/#{argument_value}/)
respond_with values:
end
end
Installation
Add this line to your application's Gemfile:
gem 'model-context-protocol-rb'
And then execute:
bundle
Or install it yourself as:
gem install model-context-protocol-rb
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests.
Generate an executable that you can use for testing:
bundle exec rake mcp:generate_executable
This will generate a bin/dev
executable you can provide to MCP clients.
You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/dickdavis/model-context-protocol-rb.
License
The gem is available as open source under the terms of the MIT License.