rails-mcp-server: a Rails introspection bridge for MCP clients
A Ruby gem implementation of a Model Context Protocol (MCP) server for Rails projects. This server allows LLMs (Large Language Models) to interact with Rails projects through the Model Context Protocol.
At a glance
- What is it?
- rails-mcp-server is a Ruby gem that exposes Rails project structure, routes, models and schema to an LLM over the Model Context Protocol. Version 2.0.0 removed the one tool that executed Ruby, which tells you where the project draws its line.
- Who is it for?
- Adopt rails-mcp-server if you already drive an MCP-capable client against one or more Rails codebases and you want routes, models, schema and controller-view relationships surfaced without pasting files into a prompt. Skip it if your workflow is a single shell session: rails routes, db:schema:dump and ripgrep answer the same questions with fewer moving parts, and the HTTP mode with --bind-all adds a listening socket you then have to reason about.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 29 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap rails-mcp-server fills between an LLM and a Rails codebase
An LLM working on a Rails app has no way to ask the app questions. It sees the files you paste and nothing else. Routes live in config/routes.rb plus whatever engines contribute at boot. Model associations are spread across app/models. The schema is the source of truth for columns, but reading db/schema.rb by hand for every question does not scale. rails-mcp-server exists to close that gap: it is a Model Context Protocol server, written in Ruby, that a client such as Claude Desktop connects to and then calls tools against. The target user is an engineer who already has an MCP-capable client and wants the assistant to reason about routes, models, associations, schema and controller-view wiring without a manual copy-paste step. It is not a code generator and, since v2.0.0, it is not an execution environment either.
Progressive tool discovery and the multi-project switch
The README lists a context-efficient architecture with progressive tool discovery. The mechanism implied by that phrase is that the server does not dump its entire tool list into the model's context at once; tools are surfaced as they become relevant. For a Rails app with dozens of models, that matters, because a flat dump of every tool plus every model name would consume context before any real question is asked. The second structural decision is multi-project support. Each key in projects.yml is a project name, and the README states that name is what you pass to the switch_project tool. So one server process can hold several codebases and the model selects the active one by name rather than the operator restarting the server per repository. Model inspection uses Prism static analysis, per the feature list, which means associations are read from source rather than by booting the application. That is a deliberate trade: static analysis is fast and does not require a working database, but it can only see what is syntactically present.
Installing the gem and the executables it puts on your PATH
Installation is a single gem command:
gem install rails-mcp-server
The README states four executables become available: rails-mcp-server (the server), rails-mcp-config (an interactive TUI), rails-mcp-setup-claude (described as a legacy Claude Desktop setup script) and rails-mcp-server-download-resources (also described as legacy). The config tool is the recommended path and covers project management, downloading Rails, Turbo, Stimulus and Kamal documentation, importing custom markdown guides, and Claude Desktop integration. It uses Gum for the interface if Gum is installed and falls back to a basic terminal otherwise, so Gum is optional rather than a dependency. Configuration follows the XDG Base Directory Specification: on macOS that is $XDG_CONFIG_HOME/rails-mcp or ~/.config/rails-mcp when XDG_CONFIG_HOME is unset, and on Windows %APPDATA%\rails-mcp. The server creates those directories and an empty projects.yml on first run. The file format is a flat map of name to path, which the README illustrates with store, blog and ecommerce entries pointing at ~/projects/store, ~/projects/rails-blog and an absolute path. One detail the README raises and then truncates: Ruby version manager users have two different Rubies in play, and the server handles that, but the supplied material cuts off before explaining how. Treat that as unresolved.
STDIO, HTTP and what --bind-all actually changes
The server runs in two modes. STDIO is the default and is what a desktop client spawns directly. HTTP mode starts a server on port 6029 unless you pass -p, and exposes two endpoints: a JSON-RPC endpoint at /mcp/messages and an SSE endpoint at /mcp/sse. HTTP mode binds to localhost unless you add --bind-all, which switches the bind address to 0.0.0.0, permits access from local network ranges such as 192.168.x.x and 10.x.x.x, and accepts connections from .local domain names. The README is explicit that origin and IP validation remain active in that configuration and that --bind-all belongs on trusted networks only. That is the right framing but it deserves emphasis: the flag exists so you can test from a second device, and the moment you enable it you have a service listening on your network that can read Rails source. Logging goes to ./log by default and the level is set with --log-level, accepting debug, info or error.
Why v2.0.0 deleting execute_ruby is the most informative thing in the changelog
The release history reads as a sequence of retreats. v1.6.0 is described as execute_ruby sandbox hardening plus dependency and security updates. v1.6.1 is execute_ruby process-execution hardening. v2.0.0 is titled remove execute_ruby (introspection-only). Three releases, two rounds of hardening, then removal. The maintainers tried to make arbitrary Ruby execution safe inside an MCP server and concluded that the surface was not worth defending. That is a defensible call and it is also a limitation you should internalise before adopting: the server tells the model about your Rails app, it does not run code in it, and it does not let the model run code either. If your workflow assumed the model could evaluate a snippet against the app, that workflow is gone as of 2.0.0. The remaining feature set is read-oriented: browse files and structures, view routes with filtering, inspect models and relationships, read schema, analyse controller-view relationships, analyse environment configurations, and serve bundled Rails, Turbo, Stimulus and Kamal documentation. Pin your version deliberately. Anyone who installed before August 2026 and relied on execute_ruby will find prompts and scripts that reference it failing after an upgrade, and the failure will look like a missing tool rather than a version problem.
Where a plain shell beats an MCP server
The honest alternative for a single Rails repository is not another MCP server. It is the Rails CLI plus grep. bin/rails routes prints the routing table with filtering options that overlap with what the server exposes. bin/rails db:schema:dump produces the schema the server reads. ripgrep over app/models answers association questions in milliseconds. The difference in approach is that these tools put output in front of you, the human, and you decide what reaches the model. rails-mcp-server puts the same information behind a protocol so the model can pull it on demand without you in the loop. That is a real gain when you are working across several projects and the model needs to switch context repeatedly, or when you are in a client where pasting large files is awkward. It is pure overhead when you are already in a terminal, know the answer is one command away, and would rather read the output yourself. There is also a trust dimension: the shell commands run with your full user privileges and no protocol layer, while the MCP server runs as a process your client spawns and, in HTTP mode, as a socket. Neither is inherently safer, but they fail differently and you should know which one you are choosing.
Maintenance cost and the MIT licence in practice
The gem is MIT licensed, which permits commercial and private use, modification and redistribution provided the copyright notice and permission notice are retained. That is the standard permissive arrangement and it imposes no copyleft obligation on your application. This is not legal advice; if the distinction matters to your organisation, have counsel read the LICENSE file in the repository rather than a summary. On maintenance, the material supports a few concrete observations. The last push is dated 2026-08-17 and v2.0.0 landed on 2026-08-04, so the project was active within the window covered here. Three releases in roughly two weeks, two of them security hardening for the same feature, followed by that feature's removal, suggests a maintainer who responds to problems rather than one who ships and forgets. It also suggests a small surface: the feature list is stable and the v2.0.0 change was subtractive. Your upgrade cost is therefore mostly about the execute_ruby removal and about the configuration format, which is a flat YAML map and unlikely to churn. The dependency footprint is not something the supplied material lets me assess, so treat that as something to check with gem dependency before you add it to a locked bundle.
Editorial conclusion
Adopt rails-mcp-server if you already drive an MCP-capable client against one or more Rails codebases and you want routes, models, schema and controller-view relationships surfaced without pasting files into a prompt. Skip it if your workflow is a single shell session: rails routes, db:schema:dump and ripgrep answer the same questions with fewer moving parts, and the HTTP mode with --bind-all adds a listening socket you then have to reason about. Before wiring it into a client, run rails-mcp-config, confirm the paths in projects.yml resolve, and check which tools your client actually receives, because the v2.0.0 changelog removes execute_ruby and any prompt or script that depended on it will now fail.
Community notes