The official Ruby SDK for the Model Context Protocol. Maintained in collaboration with Shopify. Trusted by 600+ developers.
Documentation
MCP Ruby SDK

The official Ruby SDK for Model Context Protocol servers and clients.
Installation
Add this line to your application's Gemfile:
gem 'mcp'And then execute:
$ bundle installOr install it yourself as:
$ gem install mcpYou may need to add additional dependencies depending on which features you wish to access.
Building an MCP Server
The MCP::Server class is the core component that handles JSON-RPC requests and responses.
It implements the Model Context Protocol specification, handling model context requests and responses.
Key Features
- Implements JSON-RPC 2.0 message handling
- Supports protocol initialization and capability negotiation
- Manages tool registration and invocation
- Supports prompt registration and execution
- Supports resource registration and retrieval
- Supports stdio & Streamable HTTP (including SSE) transports
- Supports notifications for list changes (tools, prompts, resources)
Supported Methods
initialize- Initializes the protocol and returns server capabilitiesping- Simple health checktools/list- Lists all registered tools and their schemastools/call- Invokes a specific tool with provided argumentsprompts/list- Lists all registered prompts and their schemasprompts/get- Retrieves a specific prompt by nameresources/list- Lists all registered resources and their schemasresources/read- Retrieves a specific resource by nameresources/templates/list- Lists all registered resource templates and their schemas
Custom Methods
The server allows you to define custom JSON-RPC methods beyond the standard MCP protocol methods using the define_custom_method method:
server = MCP::Server.new(name: "my_server")
# Define a custom method that returns a result
server.define_custom_method(method_name: "add") do |params|
params[:a] + params[:b]
end
# Define a custom notification method (returns nil)
server.define_custom_method(method_name: "notify") do |params|
# Process notification
nil
endKey Features:
- Accepts any method name as a string
- Block receives the request parameters as a hash
- Can handle both regular methods (with responses) and notifications
- Prevents overriding existing MCP protocol methods
- Supports instrumentation callbacks for monitoring
Usage Example:
# Client request
{
"jsonrpc": "2.0",
"id": 1,
"method": "add",
"params": { "a": 5, "b": 3 }
}
# Server response
{
"jsonrpc": "2.0",
"id": 1,
"result": 8
}Error Handling:
- Raises
MCP::Server::MethodAlreadyDefinedErrorif trying to override an existing method - Supports the same exception reporting and instrumentation as standard methods
Notifications
The server supports sending notifications to clients when lists of tools, prompts, or resources change. This enables real-time updates without polling.
Notification Methods
The server provides the following notification methods:
notify_tools_list_changed- Send a notification when the tools list changesnotify_prompts_list_changed- Send a notification when the prompts list changesnotify_resources_list_changed- Send a notification when the resources list changesnotify_progress- Send a progress notification for long-running operationsnotify_log_message- Send a structured logging notification message
Notification Format
Notifications follow the JSON-RPC 2.0 specification and use these method names:
notifications/tools/list_changednotifications/prompts/list_changednotifications/resources/list_changednotifications/progressnotifications/message
Progress
The MCP Ruby SDK supports progress tracking for long-running tool operations,
following the MCP Progress specification.
How Progress Works
1. Client Request: The client sends a progressToken in the _meta field when calling a tool
2. Server Notification: The server sends notifications/progress messages back to the client during tool execution
3. Tool Integration: Tools call server_context.report_progress to report incremental progress
Server-Side: Tool with Progress
Tools that accept a server_context: parameter can call report_progress on it.
The server automatically wraps the context in an MCP::ServerContext instance that provides this method:
class LongRunningTool (exception, server_context) {
# Your exception reporting logic here
# For example with Bugsnag:
Bugsnag.notify(exception) do |report|
report.add_metadata(:model_context_protocol, server_context)
end
}
config.instrumentation_callback = ->(data) {
puts "Got instrumentation data #{data.inspect}"
}
endor by creating an explicit configuration and passing it into the server.
This is useful for systems where an application hosts more than one MCP server but
they might require different instrumentation callbacks.
configuration = MCP::Configuration.new
configuration.exception_reporter = ->(exception, server_context) {
# Your exception reporting logic here
# For example with Bugsnag:
Bugsnag.notify(exception) do |report|
report.add_metadata(:model_context_protocol, server_context)
end
}
configuration.instrumentation_callback = ->(data) {
puts "Got instrumentation data #{data.inspect}"
}
server = MCP::Server.new(
# ... all other options
configuration:,
)Server Context and Configuration Block Data
server_context
The server_context is a user-defined hash that is passed into the server instance and made available to tools, prompts, and exception/instrumentation callbacks. It can be used to provide contextual information such as authentication state, user IDs, or request-specific data.
Type:
server_context: { [String, Symbol] => Any }Example:
server = MCP::Server.new(
name: "my_server",
server_context: { user_id: current_user.id, request_id: request.uuid }
)This hash is then passed as the server_context argument to tool and prompt calls, and is included in exception and instrumentation callbacks.
Request-specific _meta Parameter
The MCP protocol supports a special [_meta parameter](https://modelcontextprotocol.io/specification/2025-06-18/basic#general-fields) in requests that allows clients to pass request-specific metadata. The server automatically extracts this parameter and makes it available to tools and prompts as a nested field within the server_context.
Access Pattern:
When a client includes _meta in the request params, it becomes available as server_context[:_meta]:
class MyTool (exception, server_context) { ... }##### Instrumentation Callback
The instrumentation callback receives a hash with the following possible keys:
method: (String) The protocol method called (e.g., "ping", "tools/list")tool_name: (String, optional) The name of the tool calledtool_arguments: (Hash, optional) The arguments passed to the toolprompt_name: (String, optional) The name of the prompt calledresource_uri: (String, optional) The URI of the resource callederror: (String, optional) Error code if a lookup failedduration: (Float) Duration of the call in secondsclient: (Hash, optional) Client information withnameandversionkeys, from the initialize request
[!NOTE]
tool_name,prompt_nameandresource_uriare only populated if a matching handler is registered.This is to avoid potential issues with metric cardinality.
Type:
instrumentation_callback = ->(data) { ... }
# where data is a Hash with keys as described aboveExample:
MCP.configure do |config|
config.instrumentation_callback = ->(data) {
puts "Instrumentation: #{data.inspect}"
}
endServer Protocol Version
The server's protocol version can be overridden using the protocol_version keyword argument:
configuration = MCP::Configuration.new(protocol_version: "2024-11-05")
MCP::Server.new(name: "test_server", configuration: configuration)If no protocol version is specified, the latest stable version will be applied by default.
The latest stable version includes new features from the draft version.
This will make all new server instances use the specified protocol version instead of the default version. The protocol version can be reset to the default by setting it to nil:
MCP::Configuration.new(protocol_version: nil)If an invalid protocol_version value is set, an ArgumentError is raised.
Be sure to check the MCP spec for the protocol version to understand the supported features for the version being set.
Exception Reporting
The exception reporter receives two arguments:
exception: The Ruby exception object that was raisedserver_context: A hash containing contextual information about where the error occurred
The server_context hash includes:
- For tool calls:
{ tool_name: "name", arguments: { ... } } - For general request handling:
{ request: { ... } }
When an exception occurs:
1. The exception is reported via the configured reporter
2. For tool calls, a generic error response is returned to the client: { error: "Internal error occurred", isError: true }
3. For other requests, the exception is re-raised after reporting
If no exception reporter is configured, a default no-op reporter is used that silently ignores exceptions.
Tools
MCP spec includes Tools which provide functionality to LLM apps.
This gem provides a MCP::Tool class that can be used to create tools in three ways:
1. As a class definition:
class MyTool [!NOTE]
> This **Tool Annotations** feature is supported starting from `protocol_version: '2025-03-26'`.
### Tool Output Schemas
Tools can optionally define an `output_schema` to specify the expected structure of their results. This works similarly to how `input_schema` is defined and can be used in three ways:
1. **Class definition with output_schema:**class WeatherTool = 2.0'
Example usage:http_transport = MCP::Client::HTTP.new(url: "https://api.example.com/mcp")
client = MCP::Client.new(transport: http_transport)
List available tools
tools = client.tools
tools.each do |tool|
puts "Bearer my_token"
}
)
client = MCP::Client.new(transport: http_transport)
client.tools # will make the call using Bearer auth
You can add any custom headers needed for your authentication scheme, or for any other purpose. The client will include these headers on every request.
### Tool Objects
The client provides a wrapper class for tools returned by the server:
- `MCP::Client::Tool` - Represents a single tool with its metadata
This class provides easy access to tool properties like name, description, input schema, and output schema.
## Conformance Testing
The `conformance/` directory contains a test server and runner that validate the SDK against the MCP specification using [`@modelcontextprotocol/conformance`](https://github.com/modelcontextprotocol/conformance).
See [conformance/README.md](conformance/README.md) for usage instructions.
## Documentation
- [SDK API documentation](https://rubydoc.info/gems/mcp)
- [Model Context Protocol documentation](https://modelcontextprotocol.io)Similar MCP
Based on tags & features
Trending MCP
Most active this week