-
Notifications
You must be signed in to change notification settings - Fork 4
Quick Start with Rails
The model-context-protocol-rb works out of the box with any valid Rack request. Currently, this project has no plans for building a deeper Rails integration, but it is fairly simple to build it out yourself. To support modern application deployments across multiple servers, the streamable HTTP transport requires Redis as an external dependency.
Here's an example of how you can easily integrate with Rails.
Configure the MCP server in an initializer. The streamable HTTP transport uses only 2 background threads regardless of concurrent connections, preventing thread proliferation and memory issues. Redis configuration is included directly in the transport configuration block:
# config/initializers/model_context_protocol.rb
require "model_context_protocol"
ModelContextProtocol::Server.with_streamable_http_transport do |config|
config.name = "MyMCPServer"
config.title = "My MCP Server"
config.version = "1.0.0"
config.instructions = <<~INSTRUCTIONS
This server provides prompts, tools, and resources for interacting with my app.
Key capabilities:
- Does this one thing
- Does this other thing
- Oh, yeah, and it does that one thing, too
Use this server when you need to do stuff.
INSTRUCTIONS
# Redis configuration (required for streamable HTTP transport)
config.redis_url = ENV.fetch("REDIS_URL", "redis://localhost:6379/0")
config.redis_pool_size = 20
config.registry do
prompts do
register MyPrompt
end
resources do
register MyResource
end
tools do
register MyTool
end
end
endUse the provided Puma plugin to manage the MCP server lifecycle. The plugin handles both single mode (development) and clustered mode (production):
# config/puma.rb
plugin :mcpThen, set the routes:
constraints format: :json do
get "/mcp", to: "model_context_protocol#handle", as: :mcp_get
post "/mcp", to: "model_context_protocol#handle", as: :mcp_post
delete "/mcp", to: "model_context_protocol#handle", as: :mcp_delete
endImplement a controller endpoint to handle the requests. The controller passes the Rack environment and per-request context (like authenticated user info) to the server.
class ModelContextProtocolController < ActionController::API
include ActionController::Live
before_action :authenticate_user
def handle
result = ModelContextProtocol::Server.serve(
env: request.env,
session_context: {
user_id: current_user.id,
request_id: request.request_id
}
)
response.headers.merge!(result[:headers]) if result[:headers]
if result[:stream]
stream_response(result[:stream_proc])
else
render json: result[:json], status: result[:status] || 200
end
end
private
def stream_response(stream_proc)
stream_proc&.call(response.stream)
ensure
response.stream.close rescue nil
end
endThe session_context passed to Server.serve is automatically merged with the server's config.context and made available via the context method in your tools, prompts, and resources:
class MyTool < ModelContextProtocol::Server::Tool
define do
name "my_tool"
description "Does something useful"
input_schema do
{ type: "object", properties: {} }
end
end
def call
# Access per-request context via the context method
user_id = context[:user_id]
# Use user_id for authorization, logging, etc.
server_logger.info("Tool called by user #{user_id}")
respond_with content: text_content(text: "Done!")
end
endIf you need to dynamically register handlers based on user permissions, you can register all possible handlers at setup time, then use context within handlers to check authorization:
# app/mcp/tools/admin_tool.rb
class AdminTool < ModelContextProtocol::Server::Tool
define do
name "admin_tool"
description "Administrative operations"
input_schema do
{ type: "object", properties: {} }
end
end
def call
user = User.find(context[:user_id])
unless user.admin?
return respond_with error: "Unauthorized: admin access required"
end
# Proceed with admin operation...
respond_with content: text_content(text: "Admin operation completed")
end
endRead more about the server configuration options to better understand how you can customize your MCP server.
From here, you can get started building prompts, resources, resource templates, and tools.
Getting Started
Server Guide
Handlers
Testing