# Terminal
bundle add fast-mcp
bin/rails g fast_mcp:install
rails g model user name email age:integer
npx @modelcontextprotocol/inspector
# app/resources/application_resource.rb
# frozen_string_literal: true
class ApplicationResource < ActionResource::Base
# write your custom logic to be shared across all resources here
end
# app/resources/sample_resource.rb
# frozen_string_literal: true
class SampleResource < ApplicationResource
uri "examples/users"
resource_name "Users"
description "A user resource for demonstration"
mime_type "application/json"
def content
JSON.generate(User.all.as_json)
end
end
# app/tools/application_tool.rb
# frozen_string_literal: true
class ApplicationTool < ActionTool::Base
# write your custom logic to be shared across all tools here
end
# app/tools/sample_tool.rb
# frozen_string_literal: true
class SampleTool < ApplicationTool
description "Greet a user"
arguments do
required(:id).filled(:integer).description("ID of the user to greet")
optional(:prefix).filled(:string).description("Prefix to add to the greeting")
end
def call(id:, prefix: "Hey")
user = User.find(id)
"#{prefix} #{user.name} !"
end
end
# app/tools/users_create_tool.rb
# frozen_string_literal: true
class UsersCreateTool < ApplicationTool
description "Create a user"
arguments do
required(:name).filled(:string).description("Name of the user")
required(:email).filled(:string).description("Email of the user")
required(:age).filled(:integer).description("Age of the user")
end
def call(name:, email:, age:)
user = User.create!(name: name, email: email, age: age)
"User created: #{user.inspect}"
end
end
# config/initializers/fast_mcp.rb
# frozen_string_literal: true
# FastMcp - Model Context Protocol for Rails
# This initializer sets up the MCP middleware in your Rails application.
#
# In Rails applications, you can use:
# - ActionTool::Base as an alias for FastMcp::Tool
# - ActionResource::Base as an alias for FastMcp::Resource
#
# All your tools should inherit from ApplicationTool which already uses ActionTool::Base,
# and all your resources should inherit from ApplicationResource which uses ActionResource::Base.
# Mount the MCP middleware in your Rails application
# You can customize the options below to fit your needs.
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
# Add allowed origins below, it defaults to Rails.application.config.hosts
allowed_origins: [ "localhost", "127.0.0.1", "[::1]", "b69340af24ec.ngrok-free.app", /.*\.example\.com/ ],
localhost_only: false, # Set to false to allow connections from other hosts
# whitelist specific ips to if you want to run on localhost and allow connections from other IPs
# allowed_ips: ['127.0.0.1', '::1']
# 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