Skip to content

yjacquin/fast-mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

14 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Fast MCP πŸš€

Connect AI models to your Ruby applications with ease

No complex protocols, no integration headaches, no compatibility issues – just beautiful, expressive Ruby code.

Gem Version CI Status License: MIT Contributor Covenant

🌟 Interface your Servers with LLMs in minutes !

AI models are powerful, but they need to interact with your applications to be truly useful. Traditional approaches mean wrestling with:

  • πŸ”„ Complex communication protocols and custom JSON formats
  • πŸ”Œ Integration challenges with different model providers
  • 🧩 Compatibility issues between your app and AI tools
  • 🧠 Managing the state between AI interactions and your data

Fast MCP solves all these problems by providing a clean, Ruby-focused implementation of the Model Context Protocol, making AI integration a joy, not a chore.

✨ Features

  • πŸ› οΈ Tools API - Let AI models call your Ruby functions securely, with in-depth argument validation through Dry-Schema.
  • πŸ“š Resources API - Share data between your app and AI models
  • πŸ”„ Multiple Transports - Choose from STDIO, HTTP, or SSE based on your needs
  • 🧩 Framework Integration - Works seamlessly with Rails, Sinatra or any Rack app.
  • πŸ”’ Authentication Support - Secure your AI-powered endpoints with ease
  • πŸš€ Real-time Updates - Subscribe to changes for interactive applications

πŸ’Ž What Makes FastMCP Great

# Define tools for AI models to use
server = FastMcp::Server.new(name: 'popular-users', version: '1.0.0')

# Define a tool by inheriting from FastMcp::Tool
class CreateUserTool < FastMcp::Tool
  description "Create a user"
    # These arguments will generate the needed JSON to be presented to the MCP Client
    # And they will be validated at run time.
    # The validation is based off Dry-Schema, with the addition of the description.
  arguments do
    required(:first_name).filled(:string).description("First name of the user")
    optional(:age).filled(:integer).description("Age of the user")
    required(:address).hash do
      optional(:street).filled(:string)
      optional(:city).filled(:string)
      optional(:zipcode).filled(:string)
    end
  end

  def call(first_name:, age: nil, address: {})
    User.create!(first_name:, age:, address:)
  end
end

# Register the tool with the server
server.register_tool(CreateUserTool)

# Share data resources with AI models by inheriting from FastMcp::Resource
class PopularUsers < FastMcp::Resource
  uri "file://popular_users.json"
  resource_name "Popular Users"
  mime_type "application/json"

  def content
    JSON.generate(User.popular.limit(5).as_json)
  end
end

# Register the resource with the server
server.register_resource(PopularUsers)

# Accessing the resource through the server
server.read_resource(PopularUsers.uri)

# Notify the resource content has been updated to clients
server.notify_resource_updated(PopularUsers.uri)

πŸš‚ Fast Ruby on Rails implementation

bundle add fast-mcp
bin/rails generate fast_mcp:install

This will add a configurable fast_mcp.rb initializer

require 'fast_mcp'

FastMcp.mount_in_rails(
  Rails.application,
  name: Rails.application.class.module_parent_name.underscore.dasherize,
  version: '1.0.0',
  path_prefix: '/mcp', # This is the default path prefix
  messages_route: 'messages', # This is the default route for the messages endpoint
  sse_route: 'sse' # This is the default route for the SSE endpoint
  # authenticate: true,       # Uncomment to enable authentication
  # auth_token: 'your-token' # Required if authenticate: true
) do |server|
  Rails.application.config.after_initialize do
    # FastMcp will automatically discover and register:
    # - All classes that inherit from ApplicationTool (which uses ActionTool::Base)
    # - All classes that inherit from ApplicationResource (which uses ActionResource::Base)
    server.register_tools(*ApplicationTool.descendants)
    server.register_resources(*ApplicationResource.descendants)
    # alternatively, you can register tools and resources manually:
    # server.register_tool(MyTool)
    # server.register_resource(MyResource)
  end
end

The install script will also:

  • add app/resources folder
  • add app/tools folder
  • add app/tools/sample_tool.rb
  • add app/resources/sample_resource.rb
  • add ApplicationTool to inherit from
  • add ApplicationResource to inherit from as well

Rails-friendly class naming conventions

For Rails applications, FastMCP provides Rails-style class names to better fit with Rails conventions:

  • ActionTool::Base - An alias for FastMcp::Tool
  • ActionResource::Base - An alias for FastMcp::Resource

These are automatically set up in Rails applications. You can use either naming convention in your code:

# Using Rails-style naming:
class MyTool < ActionTool::Base
  description "My awesome tool"

  arguments do
    required(:input).filled(:string)
  end

  def call(input:)
    # Your implementation
  end
end

# Using standard FastMcp naming:
class AnotherTool < FastMcp::Tool
  # Both styles work interchangeably in Rails apps
end

When creating new tools or resources, the generators will use the Rails naming convention by default:

# app/tools/application_tool.rb
class ApplicationTool < ActionTool::Base
  # Base methods for all tools
end

# app/resources/application_resource.rb
class ApplicationResource < ActionResource::Base
  # Base methods for all resources
end

Easy Sinatra setup

I'll let you check out the dedicated sinatra integration docs.

πŸš€ Quick Start

Create a Server with Tools and Resources and STDIO transport

require 'fast_mcp'

# Create an MCP server
server = FastMcp::Server.new(name: 'my-ai-server', version: '1.0.0')

# Define a tool by inheriting from FastMcp::Tool
class SummarizeTool < FastMcp::Tool
  description "Summarize a given text"

  arguments do
    required(:text).filled(:string).description("Text to summarize")
    optional(:max_length).filled(:integer).description("Maximum length of summary")
  end

  def call(text:, max_length: 100)
    # Your summarization logic here
    text.split('.').first(3).join('.') + '...'
  end
end

# Register the tool with the server
server.register_tool(SummarizeTool)

# Create a resource by inheriting from FastMcp::Resource
class StatisticsResource < FastMcp::Resource
  uri "data/statistics"
  resource_name "Usage Statistics"
  description "Current system statistics"
  mime_type "application/json"

  def content
    JSON.generate({
      users_online: 120,
      queries_per_minute: 250,
      popular_topics: ["Ruby", "AI", "WebDev"]
    })
  end
end

# Register the resource with the server
server.register_resource(StatisticsResource)

# Start the server
server.start

πŸ§ͺ Testing with the inspector

MCP has developed a very useful inspector. You can use it to validate your implementation. I suggest you use the examples I provided with this project as an easy boilerplate. Clone this project, then give it a go !

npx @modelcontextprotocol/inspector examples/server_with_stdio_transport.rb

Or to test with an SSE transport using a rack middleware:

npx @modelcontextprotocol/inspector examples/rack_middleware.rb

Or to test over SSE with an authenticated rack middleware:

npx @modelcontextprotocol/inspector examples/authenticated_rack_middleware.rb

You can test your custom implementation with the official MCP inspector by using:

# Test with a stdio transport:
npx @modelcontextprotocol/inspector path/to/your_ruby_file.rb

# Test with an HTTP / SSE server. In the UI select SSE and input your address.
npx @modelcontextprotocol/inspector

Sinatra

# app.rb
require 'sinatra'
require 'fast_mcp'

use FastMcp::RackMiddleware.new(name: 'my-ai-server', version: '1.0.0') do |server|
  # Register tools and resources here
  server.register_tool(SummarizeTool)
end

get '/' do
  'Hello World!'
end

Integrating with Claude Desktop

Add your server to your Claude Desktop configuration at:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "my-great-server": {
      "command": "ruby",
      "args": [
        "/Users/path/to/your/awesome/fast-mcp/server.rb"
      ]
    }
  }
}

How to add a MCP server to Claude, Cursor, or other MCP clients?

Please refer to configuring_mcp_clients

πŸ“Š Supported Specifications

Feature Status
βœ… JSON-RPC 2.0 Full implementation for communication
βœ… Tool Definition & Calling Define and call tools with rich argument types
βœ… Resource Management Create, read, update, and subscribe to resources
βœ… Transport Options STDIO, HTTP, and SSE for flexible integration
βœ… Framework Integration Rails, Sinatra, Hanami, and any Rack-compatible framework
βœ… Authentication Secure your AI endpoints with token authentication
βœ… Schema Support Full JSON Schema for tool arguments with validation

πŸ—ΊοΈ Use Cases

  • πŸ€– AI-powered Applications: Connect LLMs to your Ruby app's functionality
  • πŸ“Š Real-time Dashboards: Build dashboards with live AI-generated insights
  • πŸ”— Microservice Communication: Use MCP as a clean protocol between services
  • πŸ“š Interactive Documentation: Create AI-enhanced API documentation
  • πŸ’¬ Chatbots and Assistants: Build AI assistants with access to your app's data

πŸ“– Documentation

πŸ’» Examples

Check out the examples directory for more detailed examples:

πŸ§ͺ Requirements

  • Ruby 3.2+

πŸ‘₯ Contributing

We welcome contributions to Fast MCP! Here's how you can help:

  1. Fork the repository
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Please read our Contributing Guide for more details.

πŸ“„ License

This project is available as open source under the terms of the MIT License.

πŸ™ Acknowledgments