Model Context Protocol (MCP) server for Rails applications
Expose your Rails app as an AI accessible interface β define tools and resources the Rails way.
π Production-Ready - Authentication, rate limiting, error handling, security
π§ Rails Integration - Generators, autoloading, middleware, Railtie
π οΈ Tools System - Callable functions with JSON Schema validation
π Resources System - Data exposure with URI templating
π Security - DNS rebinding protection, CORS, token authentication
β‘ Real-time - Server Events (SSE) foundation (full implementation coming soon)
π― Developer-Friendly - Clean DSL, generators, testing support
Add to your Gemfile
:
gem 'mcp_on_ruby'
Then run:
bundle install
rails generate mcp_on_ruby:install
# Generate MCP server files
rails generate mcp_on_ruby:install
# Create a tool
rails generate mcp_on_ruby:tool UserManager --description "Manage application users"
# Create a resource
rails generate mcp_on_ruby:resource UserStats --uri "users/{id}/stats" --template
# config/initializers/mcp_on_ruby.rb
McpOnRuby.configure do |config|
config.authentication_required = true
config.authentication_token = ENV['MCP_AUTH_TOKEN']
config.rate_limit_per_minute = 60
config.allowed_origins = [/\.yourdomain\.com$/]
end
Rails.application.configure do
config.mcp.enabled = true
config.mcp.auto_register_tools = true
config.mcp.auto_register_resources = true
end
# app/tools/user_manager_tool.rb
class UserManagerTool < ApplicationTool
def initialize
super(
name: 'user_manager',
description: 'Manage application users',
input_schema: {
type: 'object',
properties: {
action: { type: 'string', enum: ['create', 'update', 'delete'] },
user_id: { type: 'integer' },
attributes: { type: 'object' }
},
required: ['action']
}
)
end
protected
def execute(arguments, context)
case arguments['action']
when 'create'
user = User.create!(arguments['attributes'])
{ success: true, user: user.as_json }
when 'update'
user = User.find(arguments['user_id'])
user.update!(arguments['attributes'])
{ success: true, user: user.as_json }
else
{ error: 'Unsupported action' }
end
end
def authorize(context)
# Add your authorization logic
context[:authenticated] == true
end
end
# app/resources/user_stats_resource.rb
class UserStatsResource < ApplicationResource
def initialize
super(
uri: 'users/{id}/stats',
name: 'User Statistics',
description: 'Get detailed user statistics',
mime_type: 'application/json'
)
end
protected
def fetch_content(params, context)
user = User.find(params['id'])
{
user_id: user.id,
statistics: {
posts_count: user.posts.count,
comments_count: user.comments.count,
last_login: user.last_login_at,
account_created: user.created_at
},
generated_at: Time.current.iso8601
}
end
def authorize(context)
# Check if user can access this data
context[:authenticated] == true
end
end
rails server
# MCP server available at http://localhost:3000/mcp
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Rails App β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β app/tools/ β app/resources/ β
β βββ application_tool.rb βββ application_resource.rb β
β βββ user_manager_tool.rb βββ user_stats_resource.rb β
β βββ ... βββ ... β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β MCP Server Core β
β βββββββββββββββββββ βββββββββββββββββββ ββββββββββββββββ β
β β Tools β β Resources β β Transport β β
β β - Validation β β - Templating β β - HTTP β β
β β - Authorizationβ β - Authorizationβ β - SSE β β
β β - Execution β β - Content β β - Security β β
β βββββββββββββββββββ βββββββββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β JSON-RPC Protocol β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Connect your Rails MCP server with different AI clients:
π Claude Desktop - Complete setup guide with bridge script
π Advanced Usage - Custom authorization, caching, manual configuration
π Testing Guide - RSpec integration and testing patterns
π API Reference - Complete API documentation
- Ruby 2.7.0 or higher
- Rails 6.0 or higher (for full integration)
- JSON Schema validation support
Production dependencies (minimal footprint):
json-schema
(~> 3.0) - JSON Schema validationrack
(~> 2.2) - HTTP transport layerwebrick
(~> 1.7) - HTTP server
- Fork the repository
- Create your feature branch (
git checkout -b my-new-feature
) - Write tests for your changes
- Ensure all tests pass (
bundle exec rspec
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- The Model Context Protocol team at Anthropic for creating the specification
- The Ruby on Rails community for inspiration and conventions
Made with β€οΈ for the Ruby community