Skip to content

rubyonai/mcp_on_ruby

Repository files navigation

MCP on Ruby

Gem Version License: MIT Ruby Version

Model Context Protocol (MCP) server for Rails applications

Expose your Rails app as an AI accessible interface β€” define tools and resources the Rails way.

MCP


Features

πŸš€ 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

Installation

Add to your Gemfile:

gem 'mcp_on_ruby'

Then run:

bundle install
rails generate mcp_on_ruby:install

Quick Start

1. Install and Configure

# 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

2. Configure MCP Server

# 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

3. Create Tools

# 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

4. Create Resources

# 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

5. Start Your Server

rails server
# MCP server available at http://localhost:3000/mcp

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        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                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Examples

Connect your Rails MCP server with different AI clients:

πŸ‘‰ Claude Desktop - Complete setup guide with bridge script

Documentation

πŸ‘‰ Advanced Usage - Custom authorization, caching, manual configuration
πŸ‘‰ Testing Guide - RSpec integration and testing patterns
πŸ‘‰ API Reference - Complete API documentation

Requirements

  • Ruby 2.7.0 or higher
  • Rails 6.0 or higher (for full integration)
  • JSON Schema validation support

Dependencies

Production dependencies (minimal footprint):

  • json-schema (~> 3.0) - JSON Schema validation
  • rack (~> 2.2) - HTTP transport layer
  • webrick (~> 1.7) - HTTP server

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Write tests for your changes
  4. Ensure all tests pass (bundle exec rspec)
  5. Commit your changes (git commit -am 'Add some feature')
  6. Push to the branch (git push origin my-new-feature)
  7. Create a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • 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