Tooling And Dependencies

This doc lists every gem, library, and runtime component the generic MCP feature relies on — including authentication. Use it as a pre-flight checklist before copying code into a target project.

Required Gems

These are non-optional for the MCP runtime itself.

Gem Version Purpose
rails 7+ (8.x recommended) Framework. Rack mount, Active Record, routes, thread-locals, Current attributes.
mcp ~> 0.10.0 The Ruby Model Context Protocol gem. Provides MCP::Server, MCP::Tool, MCP::Tool::Response, and MCP::Server::Transports::StreamableHTTPTransport.
puma >= 5.0 Threaded web server. The Rack app assumes thread-local state cleanup under a threaded server.

Add to the Gemfile:

gem "rails", "~> 8.1"
gem "mcp", "~> 0.10.0"
gem "puma", ">= 5.0"

Used by this package for authentication, authorization, and UX polish. If your target app uses a different stack, map the equivalents.

Authentication

Gem Purpose Alternatives
devise Session-based user authentication. Provides authenticate_user!, current_user, and authenticated :user do ... end route blocks. Rails 8 built-in auth generator, Clearance, Sorcery, custom session layer
devise-passwordless Magic-link login. Optional if you want users to receive a tokenized email instead of typing a password.
devise_invitable Invite-based signup. Optional.
devise-i18n Localized Devise messages. Optional.
omniauth + omniauth-google-oauth2 + omniauth-rails_csrf_protection OAuth login. Optional. omniauth-github, omniauth-apple, etc.

What the MCP runtime actually needs:

  • a current_user helper available in controllers
  • a way to run before_action :authenticate_user! on Mcp::BaseController
  • a User model with an id that can own mcp_tokens

Any auth stack that provides those three things will work. Devise is the default assumption because Rails apps most commonly use it.

Authorization

Gem Purpose
pundit Policy classes. Used by Mcp::TokenPolicy to scope token CRUD to current_user.mcp_tokens.

If you do not use Pundit, inline the scoping in the controller:

@token = current_user.mcp_tokens.find(params[:id])

Frontend / View Layer

Gem Purpose
turbo-rails Hotwire Turbo for the token management UI. Optional if you are not shipping a UI.
stimulus-rails Copy-to-clipboard and permission-toggle interactivity. Optional.
tailwindcss-rails Styling for token forms. Optional.
importmap-rails ES module imports without a bundler. Optional.

None of these are required by the MCP runtime itself — they only matter if you port the token management UI.

Runtime Components You Need In The App

Current attributes

This package relies on a thread-safe Current singleton for propagating the acting user during MCP dispatch:

# app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
  attribute :user
end

Used in Mcp::RackApp#before_dispatch to set Current.user = mcp_token.user so any downstream Active Record callback can see the acting user. It is cleared in after_dispatch.

Rails 8 ships ActiveSupport::CurrentAttributes as standard — no extra gem required.

ActiveSupport::Concern

Used by Mcp::Tools::Concerns::Formattable, Listable, and ToolMetadata. Ships with Rails.

SecureRandom and Digest::SHA256

Standard library. Used for:

  • generating raw tokens (SecureRandom.hex(32))
  • hashing them for storage (Digest::SHA256.hexdigest(raw))

No extra gems needed.

ActiveModel::Type::Boolean

Ships with Rails. Used in Mcp::Token.sanitize_permissions to coerce form checkbox values ("1"/"0"/true/false) to real booleans before writing to the permissions JSON column.

ActionController::Parameters

Standard Rails. The token controller uses params.dig(:mcp_token, :permissions) to read permission checkboxes from the form.

MCP SDK Contract

The mcp gem exposes:

  • MCP::Tool — base class for all tools. Mcp::BaseTool inherits from it.
  • MCP::Tool::Response — wrapper for tool output. The Formattable concern uses it to emit { type: "text", text: ... } content blocks.
  • MCP::Server — the JSON-RPC dispatcher. Built per request by Mcp::ServerBuilder.build(context).
  • MCP::Server::Transports::StreamableHTTPTransport — the HTTP transport this package uses. Streamable HTTP is the transport MCP hosts like Claude Desktop and Claude Code accept via a URL.

Version pin: gem "mcp", "~> 0.10.0". Other 0.x versions may introduce breaking changes to MCP::Tool::Response or the transport constructor — pin strictly.

Client-Side Requirements

The MCP host (the AI client) must speak Streamable HTTP transport with token-in-URL authentication.

Known-good clients:

  • Claude Desktop — add the server under mcpServers in the desktop config with a url field
  • Claude Code (CLI)claude mcp add with a URL argument
  • Claude web/API — wherever Streamable HTTP MCP is supported

Sample configuration:

{
  "mcpServers": {
    "my-app": {
      "url": "https://your-app.com/mcp/YOUR_TOKEN"
    }
  }
}

If your target MCP client only supports stdio transport, you need an adapter or a local proxy — the package does not cover that case.

Database

  • Primary database: any Active Record adapter (SQLite, PostgreSQL, MySQL). The migrations use standard column types (:string, :json, :datetime, :integer).
  • JSON column: permissions on mcp_tokens and arguments / result_summary on mcp_activity_logs use t.json. On SQLite and MySQL this is a TEXT under the hood. On PostgreSQL, switch to t.jsonb if you want indexed queries on specific permission keys.
  • No caching gem required. The in-memory rate limiter lives in the Rack app instance.

Background Jobs

The generic package does not require any background job processing. Mcp::ActivityLog.log_tool_call runs synchronously inside the tool call.

If you want to offload logging under high load, wrap the logging call in your project's existing job framework (ActiveJob, Sidekiq, solid_queue, GoodJob). Keep the synchronous default until you have measured contention.

Testing

Gem Purpose
Minitest (Rails default) Model, controller, Rack, and tool tests
rack-test Required for Rack app tests — simulates requests against the mounted MCP endpoint

If your project uses RSpec, swap in rspec-rails and rack-test equivalents. The test matrix in 05_security_ops_and_testing.md is framework-agnostic.

Optional But Nice To Have

Gem Why you might want it
pagy Pagination for the activity log viewer. Not needed for tool-level pagination — Listable does that inline.
pretender Admin impersonation for debugging a user's MCP surface. Optional.
noticed In-app notifications when tokens are revoked or created. Optional.

Minimum Viable Dependency List

If you want the absolute smallest Gemfile addition to stand up the MCP endpoint:

gem "rails"
gem "mcp", "~> 0.10.0"
gem "puma"
# + whatever auth stack gives you `current_user` and `authenticate_user!`

Everything else is ergonomics.

Dependency Check Before You Start Porting

Before copying any files into the target project, confirm:

  • Rails 7+ (ideally 8.x)
  • current_user helper available in controllers (any auth stack)
  • A User model with a primary key suitable for a foreign key
  • ActiveSupport::CurrentAttributes available (standard in modern Rails)
  • mcp gem version pin agreed (~> 0.10.0)
  • Routes file can accept mount Mcp::RackApp.new, at: "/mcp" before any authenticated blocks
  • A target resource model to back the Item CRUD example (or plan to rename before porting)

Once all six are green, proceed with Phase 1 of the playbook.