rails-ai-context
Provides tools for inspecting Stimulus controllers, actions, and targets within a Rails application, giving AI assistants context about the frontend JavaScript framework usage in the app.
Provides tools for understanding Turbo configuration and usage in a Rails application, including Turbo frames, streams, and drive behavior.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@rails-ai-context show me the schema for the users table"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Contents
A closer look: the schema, the model, the inherited filters, the trace, the app that cannot boot, the six rules
Related MCP server: Synapse
What it does
An assistant writing Rails code knows what an average Rails app looks like. Yours has its own columns,
associations, filters and test setup, and the assistant starts every session with none of that. It
writes a migration for a column that exists, calls user.posts when the association is user.articles,
scaffolds FactoryBot into a fixture suite, and misses the before_action a parent controller adds. You
catch it, fix it, re-prompt, and something next to it breaks.
rails-ai-context gives the assistant 35 tools that read the app itself, over MCP from the AI tool or from the command line. Every answer is read from the app and says how sure it is, and most end with a hint for the next call.
When | What the assistant gets | A real line from an answer |
It asks about a table | Columns with types, nulls and defaults, the indexes, the model on the table |
|
Before it calls an association | Associations with their options, validations including the implicit ones, enums, scopes, callbacks, concerns |
|
Before it writes an action | The actions, every filter with where it was inherited from, strong parameters, the layout |
|
Before it writes a test | The framework, where the factories or fixtures live, their traits, a template in the app's style | Factories: spec/factories (3 files) |
It traces a method | The definition and source, what it calls, every caller grouped by file and kind, the tests | app/services/article_publisher.rb (Service) · 11: return false unless @article.publishable? |
When the app cannot boot | The same tools, from | [STATIC] Static mode (static mode requested with --no-boot). Serving static analysis; runtime-only data is marked [UNAVAILABLE]. |
Each line comes from the sample app in this repository, a blog with Devise, an admin namespace, a JSON API, a Sidekiq job and a FactoryBot suite. The website records the whole answers every time it is built, by running the gem at that commit: crisnahine.github.io/rails-ai-context.
The install writes the files each AI tool reads, so the assistant knows the tools exist and how to ask: the MCP config, one root context file with six anti-hallucination rules, and rules that load when a model, a controller or a migration is open. The tools are read-only, the SQL tool runs inside a read-only transaction, and files that hold secrets are never served.
Try it in your Rails app
Open your AI tool at the root of your Rails app and paste this. It installs the gem, sets up the AI tool you are in, checks the result and tells you the one step left.
Install the rails-ai-context gem in this Rails app so you can read its schema, models, routes and code through its tools instead of guessing.
1. Run `ruby -v` and `bundle exec rails -v`. rails-ai-context needs Ruby 3.1+ and Rails 7.0+. If either is older, stop and tell me.
2. Pick TOOL, the key for the AI tool you are: claude (Claude Code), cursor (Cursor), copilot (GitHub Copilot in VS Code), opencode (OpenCode), codex (Codex CLI). If you are another AI tool, stop and tell me to use the "Another MCP client" prompt instead.
3. Run `bundle add rails-ai-context --group development --version '>= 5.35.0'`. If the Gemfile already lists it, run `bundle update rails-ai-context --conservative` instead. Then run `bundle exec rails-ai-context version`: it must print 5.35.0 or newer, the first version with the flags used below. If it is older, the Gemfile pins it: change its rails-ai-context line to `gem "rails-ai-context", ">= 5.35.0", group: :development` and run `bundle update rails-ai-context --conservative`. If Bundler refuses (a frozen or deployment bundle), run `gem install rails-ai-context -v '>= 5.35.0'` instead and use `rails-ai-context init --tools TOOL --defaults` in step 4.
4. Run `bundle exec rails generate rails_ai_context:install --tools TOOL --defaults`. If it fails because the app can't boot, run `bundle exec rails-ai-context init --tools TOOL --defaults` instead; that one reads the source files when the app won't start.
5. Run `bundle exec rails-ai-context tool onboard` (or `rails-ai-context tool onboard` if you used gem install) and check it describes this app.
6. Tell me which files changed, then the "Next step" lines the install printed for TOOL, word for word. I have to do that step before your rails-ai-context MCP tools appear.Rather type it yourself? In the Gemfile:
bundle add rails-ai-context --group development
bin/rails generate rails_ai_context:install --tools claude --defaultsStandalone, with no Gemfile change:
gem install rails-ai-context
rails-ai-context init --tools claude --defaultsAs a Claude Code plugin, which adds the MCP server and gives each session the six rules, and writes no context files. It runs the installed gem, so install that first, and run it in the app's folder:
gem install rails-ai-context
claude plugin install rails-ai-context --marketplace crisnahine/rails-ai-context --scope projectCommit the .claude/settings.json it writes; the install generator and init then leave Claude Code's
.mcp.json to the plugin (details).
--tools takes claude, cursor, copilot, opencode, codex or all. Without --defaults the
generator asks which AI tools you use and what to write. Re-running is safe: it keeps what you have,
adds what is missing, and in a CLAUDE.md you wrote it touches only the block between its
<!-- BEGIN/END rails-ai-context --> markers.
You need Ruby 3.1 or newer and Rails 7.0 to 8.1, on Linux, macOS or Windows. Optional:
brakeman for security_scan, listen for watch, ripgrep for a faster search_code.
Then one step in your AI tool
Every AI tool holds a new project MCP server back until you say yes. The install prints the step for each tool you picked:
Claude Code | Cursor | GitHub Copilot | OpenCode | Codex CLI |
New session in the app's folder, approve | Restart, turn it on under MCP in Customize | Trust the workspace, send a chat message. Check with "MCP: List Servers". Copilot CLI: trust the folder, check with | Restart in the app's folder. Check with | Trust the project, start a new session. Check with |
Then ask something only your app knows, such as "what columns does the users table have?", and watch
it call rails_get_schema instead of guessing. Every other setup has a prompt: no
Gemfile change, CLI only, MCP only, a whole team, a folder of apps, nothing committed, MCP over HTTP,
Ruby in Docker, another MCP client.
A closer look
Every block below is the gem's own output for the sample app, read without booting it, trimmed: the tier line and the report line that end every answer are cut, and each note names what else is. The website shows each answer whole, recorded at the commit it was built from.
The schema, with the model on it
$ rails-ai-context --app-path site/sample_app tool schema --table users --no-boot
## Table: users
**Models:** User
**Primary key:** id
| Column | Type | Null | Default |
|--------|------|------|---------|
| id | bigint | **NO** | |
| email | string | **NO** | "" |
| encrypted_password | string | **NO** | "" |
| name | string | yes | |
| role | integer | **NO** | 0 |
| active | boolean | **NO** | true |
| api_token | string | yes | |
### Indexes
- `index_users_on_api_token` on (api_token) (unique)
- `index_users_on_email` on (email) (unique)
_Next: `rails_get_model_details(model:"User")` for associations, validations, scopes._Trimmed to seven of its twelve columns and two of its three indexes. With the app booted, the columns
come from the database connection; here they come from db/schema.rb, and db/structure.sql or the
migrations would do.
Before it calls an association
$ rails-ai-context --app-path site/sample_app tool model_details --model Article --no-boot
# Article [STATIC]
**Table:** `articles`
**File:** `app/models/article.rb` (32 lines)
**Structure:** class definition(1-1) → includes(2-3) → associations(4-6) → macros(7-8) → validations(9-12) → callbacks(13-15) → scopes(16-18) → instance methods(19-22) → private(23-24) → instance methods(25-32)
## Associations
- `belongs_to` **author** (class: User) (inverse_of: :articles) (fk: author_id)
- `has_many` **comments** dependent: destroy
## Validations
- `presence` on author _(implicit from belongs_to)_
- `presence` on title
- `length` on title (maximum: 120)
- `presence` on slug
- `uniqueness` on slug
- `presence` on body (if: :published?)
## Enums
- `status`: draft(0), in_review(1), published(2) [integer]
## Scopes
- `recent` → order(published_at: :desc, created_at: :desc) [STATIC]
- `by_author` → where(author: user) [STATIC]
- `published` → where(status: :published).where.not(published_at: nil) [STATIC]
## Callbacks
- `before_validation`: :assign_slug (on: :create)
- `after_commit (on: :update)`: :notify_author (if: :saved_change_to_status?)
## Concerns
- **Publishable** - publishable?, publish!The model is read with the Prism parser. A scope with a literal body is [VERIFIED], one built at
runtime is [INFERRED], and in the static tier every record is capped at [STATIC], since no record
can claim more than the tier that carries it. The columns, the primary key, the static-tier note on
associations, the instance methods and the next-call hint are trimmed out above. The published scope
is declared in the Publishable concern, and the Concerns section lists the methods each concern brings.
Before it writes an action
$ rails-ai-context --app-path site/sample_app tool controllers --controller admin/articles --no-boot
# Admin::ArticlesController
**Parent:** `Admin::BaseController`
**Layout:** `admin` (declared in Admin::BaseController)
## Actions
- `index`
- `publish`
- `show`
## Filters
- `before` **authenticate_user!** _(from ApplicationController)_
- `before` **require_admin** _(from Admin::BaseController)_
- `before` **set_article** (only: show, publish)Every filter that applies, with where it was inherited from, so the assistant never misses the
authenticate_user! two classes up. The schema hints for the models the controller touches, and the
next-call hints, follow in the full answer.
Tracing a method
$ rails-ai-context --app-path site/sample_app tool search_code --pattern 'publishable?' --match_type trace --no-boot
# Trace: `publishable?`
## Definition
**app/models/concerns/publishable.rb:8** in `module Publishable`
```ruby
def publishable?
in_review? && body.present? && author.active?
end
```
## Called from (4 sites)
### app/controllers/admin/articles_controller.rb (Controller) → `POST /admin/articles/:id/publish`
13: if @article.publishable?
### app/models/concerns/publishable.rb (Model)
13: raise ArgumentError, "#{self.class.name} #{id} is not ready to publish" unless publishable?
### app/services/article_publisher.rb (Service)
11: return false unless @article.publishable?
### lib/tasks/articles.rake (Other)
5: PublishArticleJob.perform_later(article) if article.publishable?
## Tested by (1 reference)
- `spec/models/article_spec.rb` (1 reference)One call in place of a file-by-file search: the definition, what it calls, its siblings, every caller grouped by file and labelled by kind, with the route a controller caller answers, and the tests. The "Calls internally" and "Sibling methods" sections are trimmed out above.
When the app cannot boot
The app-reading commands try a full boot for live reflection. When the boot fails, from a missing
environment variable, an unreachable service or a broken initializer, they answer from the static
tier instead of dying: routes from config/routes.rb, the schema from db/schema.rb,
db/structure.sql or the migrations, models and controllers from their source. Every answer carries
a tier line, a section that needs a booted app says [UNAVAILABLE] with the reason, and
--no-boot asks for that tier outright:
_[STATIC] Static mode (static mode requested with --no-boot). Serving static analysis; runtime-only data is marked [UNAVAILABLE]. Run `bundle exec rails-ai-context --app-path site/sample_app doctor` for details._32 of the 40 introspectors answer here. Each declares which of three kinds it is: it reads files only, it needs live reflection, or it answers from another source such as the schema dump. What a tier can say is a declaration, so an answer never guesses at what it could not read (ADR-0002). The routes engines and gems draw at boot, and an association a gem adds at boot, are not listed, and the answer says so.
The six rules
The root context file carries six rules the assistant reads before writing code. That file is
AGENTS.md, which Cursor, OpenCode and Codex read and CLAUDE.md imports, or CLAUDE.md itself when
none of those three is chosen; Copilot reads its own copy in .github/copilot-instructions.md.
Verify before you write. Never reference a column, association, route, helper, method, class, partial or gem that a tool call in this turn did not confirm.
Mark every assumption with
[ASSUMPTION]. "I'd need to check X first" is a good answer.Training data describes average Rails. This app isn't average. When something feels obviously standard, query anyway.
Check the inheritance chain before every edit: inherited filters, concerns, includes, STI parents.
Empty tool output is information. "0 callers found" means investigate, or ask.
Stale context lies. Re-query after writes.
On by default. Turn off with config.anti_hallucination_rules = false if you prefer your own. In an
MCP-only or CLI setup, the ground rules prompt gives
the assistant the same rules for one session.
The tools
Every tool is read-only and answers from your app. Over MCP each name carries a rails_ prefix
(rails_get_schema). From the CLI the short name works: schema, get_schema and rails_get_schema
all resolve. About half take detail=summary|standard|full.
Category | Tools |
Search and trace |
|
Understand |
|
Schema and models |
|
Controllers and routes |
|
Views and frontend |
|
Testing and quality |
|
App config and services |
|
Data and debugging |
|
Four worth knowing on day one:
search_codewithmatch_type=tracereturns the definition, the source, every caller grouped by file and labelled by kind, and the tests, in one call.get_controllersreturns the action source with inherited filters, strong params and the render map.get_model_detailsreturns associations, validations, scopes, enums and macros from the AST, each tagged[VERIFIED]or[INFERRED].queryruns read-only SQL inside a read-only transaction, with a timeout, a row limit and column redaction.
Parameters for all 35 are in the tools reference; worked examples in
recipes. MCP clients can also read five resource templates, such as
rails-ai-context://models/{name} and rails-ai-context://controllers/{name}/{action}, and nine
static resources, such as rails://schema and rails://routes.
How it works
40 introspectors read the app, one per kind of fact: the schema, the models, the routes, the
controllers, the views, the jobs, the gems, the conventions and so on. Each returns a hash and is
registered under a key, so a preset is a list of keys: :full runs all 40 and :standard runs 17.
The models and the controllers are read with Prism, Ruby's own parser. Each file is parsed once into a
cache keyed by its content, and a single walk over the tree feeds every listener at the same time:
associations, validations, scopes, enums, callbacks, macros, strong parameters. A listener tags each
record by how it was read: [VERIFIED] for a literal, [INFERRED] for an expression that only runs at
runtime. Introspection is cached with a fingerprint of the app's files, so an edit to a model is seen
on the next call without a restart.
A tool composes its answer from that context, hydrates it with schema hints for the models it touches, cuts it at the response budget, and ends it with a tier line and, for most tools, a hint for the next call. Three transports reach the same registry: MCP over stdio, MCP over HTTP mounted inside the app, and the command line with no server at all.
Architecture has the modules and the request lifecycle, Introspectors the catalogue of listeners and the rule for what is read from the AST, and the ADRs the decisions with their reasons.
What it costs
It is free and MIT licensed. What you pay is tokens, and only when the assistant asks:
A tool answer is sized by its
detaillevel and cut atmax_tool_response_chars, 200,000 characters by default. Start withsummaryand drill down.The root context file is held to 12,000 bytes in its default compact mode, and a rule file to 8,000, since they share the agent's context with your own instructions.
The last line of every answer, which asks the assistant to offer you an issue when the gem itself answered wrong, costs about 40 tokens.
config.report_issue_line = falseleaves it out.
Questions you should ask first
Does it send my code anywhere? No. The tools run on your machine, in your app's process or in a
child of it. Two things go online: search_docs fetches Rails guides from GitHub when called with
fetch: true, and the standalone binary asks rubygems.org for the latest version at most once a day,
in a child process that sends nothing about the app. RAILS_AI_CONTEXT_NO_UPDATE_CHECK=1 turns that
off, and it is off in CI.
Can it read my secrets? Files that hold them are never served: .env, config/master.key,
credentials.yml.enc, config/database.yml, keys and certificates, on a list you can extend. Logs
are redacted before they leave the process, get_config shows credential key names without values,
and query never returns an encrypted column. Security has every layer.
Can it change my database? No. Every tool is read-only. query allows SELECT, WITH, SHOW,
EXPLAIN and DESCRIBE, runs inside a read-only transaction with a statement timeout, caps the rows,
redacts secret columns, and on PostgreSQL plans the statement first and refuses a plan that reaches a
secret column by another name.
What does it write into my repository? The MCP config for each AI tool you picked, one root
context file with a copy for Copilot, rules files per tool, its own config and a .gitignore line.
A re-run keeps your lines and adds what is missing; uninstall takes back only what it wrote. A team
that wants no AI files in the repo can skip the install: the tools work with none of it.
Is the HTTP endpoint safe? Mounted inside the app it inherits your routing, auth and middleware.
Outside development and test it refuses every request with a 403 unless you set
config.allow_http_in_production = true, since it has no authentication of its own.
Which AI tools? Claude Code, Cursor, GitHub Copilot, OpenCode and Codex CLI get context files and
MCP config written for them. Any other MCP client, such as Claude Desktop, Windsurf, Zed or a JetBrains
IDE (Copilot or AI Assistant), gets an entry from rails-ai-context mcp-entry. A tool with no MCP at all
gets the CLI setup, where the context files name the shell commands.
Still wondering about something? The FAQ
answers the rest: install, the tools, configuration, context files, performance, security, and how it
compares to a hand-written CLAUDE.md or pasting schema.rb into the prompt.
What it will not do
Write to your app or your database from a tool. Every tool reads. The assistant still decides what to do with the facts, and the six rules ask it to verify before writing; nothing enforces that.
Say more than it read. Without a boot, 32 of 40 introspectors answer and the rest say
[UNAVAILABLE].query,runtime_infoanddoctorneed a booted app, andquerya database.Support Rails 9. The gemspec caps
railtiesbelow 9.0, and the standalone binary warns when it boots one. Compatibility has the CI matrix: 17 Ruby and Rails pairs on Linux, plus macOS and Windows legs.Time-limit
queryon SQLite under Windows. There is noforkthere, so that query runs without its limit, and the MCP configs start the server throughcmd /d /c, since a gem's executables on Windows are batch files.
Install options and configuration
Three setups, picked at install time with a flag, or afterwards with the change the setup prompt:
Setup | Writes | Flag | Good for |
MCP + context files | MCP config and context files |
| Most apps |
CLI only | Context files that name shell commands |
| Tools without MCP, or no server to approve |
MCP only | MCP config only |
| Teams that keep their own |
MCP over stdio is the default. Each AI tool gets its own config file (.mcp.json,
.cursor/mcp.json, .vscode/mcp.json and .github/mcp.json, opencode.json, .codex/config.toml) that starts
bundle exec rails-ai-context serve, or rails-ai-context serve standalone. MCP over HTTP mounts
the server inside your app:
# config/routes.rb
mount RailsAiContext::Engine, at: "/mcp" if defined?(RailsAiContext::Engine)The if keeps the routes file loading where the gem is not installed, as in production, where Bundler
skips the development group. There is also a standalone HTTP process:
rails-ai-context serve --transport http --port 6029. The CLI runs the same 35 tools with no server:
bin/rails 'ai:tool[search_code]' pattern="publishable?" match_type=trace
rails-ai-context tool schema --table users --detail fullThe commands, in the Gemfile and standalone:
In the Gemfile | Standalone | What it does |
|
| Set up (both take |
|
| Start the MCP server (stdio) |
|
| Start the MCP server (HTTP) |
|
| Run one tool |
|
| List the tools |
|
| Regenerate the context files |
|
| Diagnostics and a readiness score |
|
| Regenerate on file change |
|
| Run a multi-tool preset ( |
|
| Remove what the gem wrote, keep what you wrote |
|
| Print an MCP entry for Claude Desktop, Windsurf, Zed and other clients |
The binary finds the app the way bin/rails does, so it runs from any subdirectory. Flags shared by
the app-reading commands: --app-path PATH to target another directory, --environment ENV to set
RAILS_ENV, and --no-boot to answer from source. The full list is in the CLI reference.
A Gemfile install writes an initializer and .rails-ai-context.yml; a standalone install writes the
YAML file alone, with the same keys. Every option with its default is in
Configuration:
# config/initializers/rails_ai_context.rb
if defined?(RailsAiContext) && RailsAiContext.respond_to?(:configure)
RailsAiContext.configure do |config|
config.ai_tools = %i[claude cursor] # which AI tools to generate for
config.tool_mode = :mcp # :mcp (default) or :cli
config.preset = :full # :full (40 introspectors) or :standard (17)
end
endRegister your own tools next to the built-in ones:
# app/mcp_tools/rails_get_business_metrics.rb
class RailsGetBusinessMetrics < MCP::Tool
tool_name "rails_get_business_metrics"
description "Key business metrics for this app"
input_schema(properties: { period: { type: "string" } })
def self.call(period: "week", server_context: nil)
MCP::Tool::Response.new([{ type: "text", text: "Users this #{period}: #{User.recent.count}" }])
end
end
# config/initializers/rails_ai_context.rb
config.custom_tools = ["RailsGetBusinessMetrics"]Test them with the bundled helper (RSpec or Minitest):
include RailsAiContext::TestHelper
response = execute_tool("business_metrics", period: "month")
assert_tool_response_includes(response, "Users")See Custom tools.
Every MCP call fires an ActiveSupport::Notifications event:
ActiveSupport::Notifications.subscribe("rails_ai_context.tools.call") do |event|
ms = (event.payload[:duration].to_f * 1000).round
Rails.logger.info "[MCP] #{event.payload[:tool_name]} #{ms}ms"
endTo take it out again:
bundle exec rails-ai-context uninstall && bundle remove rails-ai-context # in the Gemfile
rails-ai-context uninstall # standaloneIt removes the context files, the MCP entries, its config, its .gitignore lines and its pre-commit
hook, and keeps what you wrote: your lines in CLAUDE.md, other servers in an MCP config, a hook you
edited. Or paste the uninstall prompt.
Troubleshooting
bundle exec rails-ai-context doctor (or bin/rails ai:doctor) boots the app, checks every file the
install wrote, the MCP configs and the plugins, and prints a readiness score with what to fix. It needs
a bootable app, since diagnosing the boot is its job. The fix it prompt
hands the same checks to the assistant, and Troubleshooting has the
problems people hit most: a server the AI tool never lists, a boot that fails, a Windows path, a
bundle that resolves the wrong Rails.
Development
git clone https://github.com/crisnahine/rails-ai-context.git
cd rails-ai-context
bundle install
bundle exec rspec # the suite, on an in-memory SQLite app under spec/internal
bundle exec rubocop --parallel # rubocop-rails-omakase style
bundle exec rake e2e # fresh Rails apps per install path; minutes; TEST_POSTGRES=1 adds a PostgreSQL specThe website is site/, filled in by scripts/site.rb from the repository: the install prompt from
docs/PROMPTS.md, the tool list from the registry, every docs/ page rendered beside it, and the
answers recorded by running the gem against site/sample_app. To see it before pushing:
bundle exec ruby scripts/site.rb _site
python3 -m http.server 8000 -d _site.github/workflows/pages.yml builds it on every pull request and deploys it from main. CONTRIBUTING.md has the layout of lib/, how to add an
introspector, a tool or a Prism listener, and how to run the specs against real database servers.
Contributing and security
Pull requests are welcome; CONTRIBUTING.md has the process, and the code of conduct applies to everyone taking part. Bugs go to the issue tracker with the Ruby, Rails and gem versions and the steps to reproduce. A security problem goes by email, the way SECURITY.md says, and never in a public issue. Only the latest 5.x release gets security fixes.
Learn more
The short tour, with every answer recorded at the commit it was built from | |
Let your AI tool install, change, remove or use the gem | |
Up and running in 5 minutes | |
Claude Code, Cursor, Copilot, OpenCode, Codex CLI, HTTP transport | |
Every command, parameter and option | |
All 35 tools with every parameter | |
Real workflows, end to end | |
Commands, flags and argument syntax | |
Use without a Gemfile entry | |
Every option with its default | |
Build and test your own tools | |
System design and internals | |
All 40 introspectors and the AST engine | |
SQL safety layers and file blocking | |
Supported versions, operating tiers, app shape matrix | |
Common problems and fixes | |
Frequently asked questions | |
Every release, newest first |
If it saves you a correction loop, star it on GitHub, and if it saves you time, consider sponsoring the project.
Available Tools
35 toolsrails_analyze_featureARead-onlyIdempotent
Full-stack feature analysis: models, controllers, routes, services, jobs, views, Stimulus controllers, tests, related models, callbacks, concerns, and environment dependencies. Use when: exploring an unfamiliar feature, onboarding to a codebase area, or tracing a feature across layers. Pass feature:"authentication" or feature:"User" for broad cross-cutting discovery.
Inputs: feature (required).
rails_dependency_graphARead-onlyIdempotent
Generates a dependency graph showing how models connect through their associations. Output as Mermaid diagram syntax or plain text. Use when: understanding feature architecture, tracing data flow, planning refactors. Key params: model (center graph on model), depth (1-3), format (mermaid/text).
Inputs: depth, model, format, show_sti, +1 more.
rails_diagnoseARead-only
One-call error diagnosis: parses the error, classifies it, gathers controller/model/schema context, shows recent git changes, pulls relevant logs, and suggests a fix. Use when: you hit an error and need to understand why. Key params: error (required - paste the error message), file, line, action (controller#action).
Inputs: error (required), file, line, action.
rails_generate_testARead-onlyIdempotent
Generate test scaffolding that matches your project's actual test patterns - framework, factories, assertion style. Use when: adding tests for a model, controller, or service. Generates copy-paste-ready test files. Key params: model (e.g. 'User'), controller (e.g. 'PostsController'), file (e.g. 'app/services/foo.rb').
Inputs: file, type, model, controller.
rails_get_callbacksARead-onlyIdempotent
Get ActiveRecord model callbacks grouped by type, in Rails event order: before/after/around for validation, save, create, update, destroy. Use when: understanding side effects, debugging callback chains, or checking what happens on save/create/destroy. Specify model:"User" for one model's callbacks. detail:"full" includes callback method source code. The list is what the model, its base classes and its concerns declare, and within one type the order is the order Rails runs them, a before_ or around_ callback with prepend: true first, and after_commit in the order the app's setting gives.
Inputs: model, detail.
rails_get_component_catalogARead-onlyIdempotent
Returns ViewComponent and Phlex component catalog: props, slots, previews, which views render each component. Use when: building views with components, understanding component API, finding reusable components. Key params: component (filter by name), detail level.
Inputs: limit, detail, offset, component.
rails_get_concernARead-onlyIdempotent
Get ActiveSupport::Concern details: public methods, included modules, and which models/controllers include it. Use when: understanding shared behavior, checking concern interfaces, or finding where a concern is used. Specify name:"Searchable" for full detail, or omit for a list of all concerns. Filter with type:"model" or type:"controller".
Inputs: name, type, detail.
rails_get_configARead-onlyIdempotent
Get the app's configuration, one section per call. section: app (default: database, auth, assets, cache, session, queue, Action Cable, middleware, initializers), gems (notable gems by category), frontend (JS framework, build tool, TypeScript, package manager), api (serializers, GraphQL, versioning, CORS, rate limiting, pagination), engines (mounted engines and Rack apps), conventions (architecture and patterns), autoload (Zeitwerk paths, inflections), active_support (concerns, notifications, on_load hooks), env (names of environment variables and credentials keys), env_config (config/environments/*.rb per environment), i18n (locales, locale files, coverage).
Inputs: limit, detail, locale, offset, +3 more.
rails_get_contextARead-onlyIdempotent
Get cross-layer context in a single call - combines schema, model, controller, routes, views, stimulus, and tests. Use when: you need full context for implementing a feature or modifying an action. Specify controller:"PostsController" action:"create" to get everything for that action in one call.
Inputs: model, action, feature, include, +1 more.
rails_get_controllersARead-onlyIdempotent
Get controller details: actions, before_action filters, strong params, and parent class. Use when: adding/modifying controller actions, checking what filters apply, or reading action source code. Filter with controller:"PostsController", drill into action:"create" for source code with line numbers.
Inputs: limit, action, detail, offset, +1 more.
rails_get_edit_contextARead-onlyIdempotent
Get targeted code context for surgical edits: returns matching lines with surrounding code and line numbers. Use when: you need to edit a specific method or section without reading the entire file. Requires file:"app/models/user.rb" and near:"def activate" (or line:42) to locate the code region.
Inputs: file (required), line, near, context_lines.
rails_get_helper_methodsARead-onlyIdempotent
Get Rails helper modules: method signatures, the view helpers controllers declare with helper_method, framework helpers in use, and which views call each helper. Use when: finding available view helpers, checking what helper methods exist, or understanding shared view logic. Specify helper:"ApplicationHelper" for full detail, or omit to list all helpers with method counts.
Inputs: limit, detail, helper, offset.
rails_get_job_patternARead-onlyIdempotent
Analyze background jobs in app/jobs/, app/workers/ and app/sidekiq/: queues, retries, perform signatures, guards, and what they call. Use when: understanding job infrastructure, adding a new job, or tracing async workflows. Specify job:"SendWelcomeEmail" for full detail, or omit to list all jobs with queue names and retry config.
Inputs: job, detail.
rails_get_mailersARead-onlyIdempotent
Get ActionMailer mailers: every mailer class with its delivery actions, delivery method, own defaults, layout and callbacks, template formats per action and preview class, the queue deliver_later uses, interceptors and observers, and the Action Mailbox mailboxes with the routing that sends inbound mail to each. Use when: adding an email, checking which mailer sends what, or finding the action to preview/test. Filter with mailer:"UserMailer". Omit for all mailers.
Inputs: limit, mailer, offset.
rails_get_model_detailsARead-onlyIdempotent
Get ActiveRecord model details: associations, validations, scopes, enums, callbacks, concerns. Use when: understanding model relationships, adding validations, checking existing scopes/callbacks. Specify model:"User" for full detail, or omit for a list. detail:"full" shows association lists.
Inputs: limit, model, detail, offset.
rails_get_partial_interfaceARead-onlyIdempotent
Analyze a partial's interface: local variables it expects, where it's rendered from, and what methods are called on each local. Use when: rendering a partial, understanding what locals to pass, or refactoring partial dependencies. Specify partial:"shared/status_badge" to see its full interface. Supports both underscore-prefixed and non-prefixed names.
Inputs: partial (required), detail.
rails_get_routesARead-onlyIdempotent
Get routing table: HTTP verbs, paths, controller#action, route names. Use when: building links/redirects, checking available endpoints, verifying route helpers exist. Filter with controller:"users", use detail:"summary" for counts or detail:"full" for route names.
Inputs: limit, detail, offset, app_only, +1 more.
rails_get_schemaARead-onlyIdempotent
Get database schema: tables, columns, types, indexes, foreign keys. Use when: writing migrations, checking column types/constraints, understanding table relationships. Filter to one table with table:"users", control detail with detail:"summary"|"standard"|"full".
Inputs: limit, table, detail, format, +1 more.
rails_get_service_patternARead-onlyIdempotent
Analyze service objects in app/services/, app/interactions/ and app/interactors/: patterns, interfaces, dependencies, and side effects. Use when: understanding how services are structured, adding a new service, or tracing what a service does. Specify service:"CreateOrder" for full detail, or omit to detect the common pattern and list all services.
Inputs: detail, service.
rails_get_stimulusARead-onlyIdempotent
Get Stimulus controllers: targets, values, actions, outlets, classes. Use when: wiring up data-controller attributes in views, adding targets/values, or checking existing Stimulus behavior. Filter with controller:"filter-form" for one controller's full API, or list all with detail:"summary".
Inputs: limit, detail, offset, controller.
rails_get_test_infoARead-onlyIdempotent
Get test infrastructure and existing test files: framework, factories, fixtures, CI config, coverage setup. Use when: writing new tests, checking what factories/fixtures exist, or finding the test file for a model/controller. Use model:"User" or controller:"Posts" to see existing tests. detail:"full" lists factory and fixture names.
Inputs: model, detail, controller.
rails_get_turbo_mapARead-onlyIdempotent
Map Turbo Streams and Frames across the app: model broadcasts, channel subscriptions, frame tags, and DOM target mismatches. Use when: debugging Turbo Stream delivery, adding real-time updates, or understanding broadcast→subscription wiring. Filter with stream:"notifications" for a specific stream, or controller:"messages" for one controller's Turbo usage.
Inputs: detail, stream, controller.
rails_get_viewARead-onlyIdempotent
Get view templates, partials, and their Stimulus/partial references. Use when: editing ERB views, checking which partials a page renders, or finding Stimulus controller usage. Filter with controller:"posts" for all views, or path:"posts/index.html.erb" for one file's content.
Inputs: path, detail, controller.
rails_migration_advisorARead-onlyIdempotent
Generates migration code for schema changes. Given an action (add_column, remove_column, rename_column, add_index, add_association, change_type), generates the migration, flags irreversible operations, and shows affected models. Use when: adding fields, changing schema, planning database changes. Key params: action, table, column, type, new_name (for rename_column).
Inputs: table (required), action (required), type, column, +2 more.
rails_onboardARead-onlyIdempotent
Get a narrative walkthrough of the Rails application - stack, data model, authentication, key flows, background jobs, frontend, testing, getting started instructions, and the app's custom rake tasks, generators and Railties. Use when: first encountering a project, onboarding a new developer, or orienting an AI agent. Key params: detail (summary/standard/full).
Inputs: detail.
rails_performance_checkARead-onlyIdempotent
Static analysis for Rails performance anti-patterns: N+1 query risks, missing counter_cache, Model.all in controllers, missing foreign key indexes, eager loading candidates. Use when: reviewing code for performance, before deploying, or investigating slow pages. Key params: model (filter by model), category (filter by issue type), detail level.
Inputs: model, detail, category.
rails_queryARead-only
Execute read-only SQL queries against the database. Use when: checking data patterns, verifying migrations, debugging data issues. Safety: SQL validation + database-level READ ONLY + statement timeout + row limit. Development/test only by default. Key params: sql (SELECT only), limit (default 100), format (table/csv).
Inputs: sql (required), limit, format, explain, +1 more.
rails_read_logsARead-only
Read recent log entries with level filtering and sensitive data redaction. Use when: debugging errors, checking recent activity, investigating failed requests. Key params: lines (default 50), level (ERROR/WARN/INFO/DEBUG/FATAL/all), file, search. Search matches the redacted line, so a filtered value cannot be searched for.
Inputs: file, level, lines, search.
rails_review_changesARead-only
PR/commit review context: shows changed files with relevant schema/model/route context per file, detects warnings (missing indexes, removed validations, changed associations, new routes without tests). Use when: reviewing changes before merging, understanding what a commit changed and its impact. Key params: ref (default 'HEAD' for uncommitted, or 'main', 'HEAD~3', commit SHA).
Inputs: ref, files.
rails_runtime_infoARead-only
Live runtime state: database connection pool, table sizes, pending migrations, cache stats, job queues. Use when: debugging performance, checking database health, verifying deployment state, or understanding infrastructure. Key params: detail (summary/standard/full), section (database/cache/jobs/connections).
Inputs: detail, section, database.
rails_search_codeARead-onlyIdempotent
Search the Rails codebase with smart modes. Use match_type:"trace" to see where a method is defined, who calls it, and what it calls - in one call. Use match_type:"definition" for definitions only, "call" for call sites only, "class" for class/module definitions. Requires pattern:"method_name". Narrow with path:"app/models" and file_type:"rb".
Inputs: pattern (required), path, limit, offset, +6 more.
rails_search_docsARead-onlyIdempotent
Search a bundled index of the Rails guides and the Turbo, Stimulus and Hotwire Native handbooks. Use when: you need to reference Rails conventions, API details, or best practices. Pass query:"active record callbacks" to find matching topics. Filter with source:"guides", "turbo", "stimulus" or "hotwire". Set fetch:true to retrieve full content from GitHub (cached 24h).
Inputs: query (required), fetch, limit, source.
rails_security_scanARead-onlyIdempotent
Run Brakeman static security analysis on Rails app. Use when: after editing controllers/models/views, reviewing code for vulnerabilities, or before deploying. Filter with files:["app/controllers/users_controller.rb"], set confidence:"high" to reduce noise.
Inputs: files, checks, detail, confidence.
rails_session_contextBRead-only
Track what you've already queried to avoid redundant calls. Use action:"status" to see what tools you've called, action:"summary" for a compressed recap, action:"reset" to clear session, or mark:"tool:param" to record a query. Helps maintain focus during long development sessions.
Inputs: mark, action.
rails_validateARead-onlyIdempotent
Validate syntax and semantics of Ruby, ERB, and JavaScript files in a single call. Use when: after editing files, before committing, to catch syntax errors and Rails-specific issues. Pass files:["app/models/user.rb"], use level:"rails" for semantic checks (missing partials, route helpers, column refs in validates/permit/callbacks).
Inputs: files (required), level.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 35 tools
Most tools map to a distinct Rails artifact (schema, routes, callbacks, mailers, jobs, stimulus, turbo), but several boundaries blur: rails_analyze_feature and rails_get_context both promise 'full-stack context in one call' across the same layers, and rails_get_context vs rails_get_edit_context differ only by a word while doing very different things. rails_onboard also overlaps with rails_get_config, and rails_get_model_details subsumes rails_get_callbacks. Descriptions are detailed enough that an agent can usually recover, but misselection is a real risk.
All names use a uniform rails_ prefix and snake_case verb_noun form, which is highly readable. The only inconsistency is the verb layer: a large get_* family coexists with bare verbs (analyze_feature, search_code, review_changes, query, validate, onboard), so the 'get' prefix is applied unevenly. Predictable overall, minor deviation.
35 tools is heavy, sitting above the comfortable 3-15 band, and a few are redundant (analyze_feature vs get_context, session_context as a meta-bookkeeping utility). However, the server targets an entire Rails application surface, so most tools do correspond to a genuine distinct artifact type. Borderline over-scoped rather than gratuitous.
Coverage is unusually broad: schema, models, controllers, routes, views, partials, helpers, services, jobs, mailers, Stimulus, Turbo, components, tests, migrations, config, logs, security and performance, plus read-only SQL and docs search. Minor gaps remain around authorization policies (Pundit/CanCan), ActiveStorage/ActionText attachments, and API/GraphQL schema introspection. No dead ends for the core read-and-understand workflow.
Maintenance
Related MCP Connectors
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
Read-only AI coding tools for change verification, release readiness, capacity, and guidance.
Read-only MCP tools for AI agent discovery, structured resources, and NIULAI information.
A registry of AI agent tools — MCP servers, APIs, CLIs, SDKs — kept current by automated ingestion.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceProvides MCP tools that help AI agents get their bearings in a codebase with unified SQL views over code, git, docs, and conversations, powered by DuckDB.6Apache 2.0
- FlicenseNot gradedqualityDmaintenanceProvides structural code intelligence via 26 MCP tools, enabling AI assistants to query code symbols, dependencies, and call graphs accurately without file-pasting.-
- AlicenseAqualityCmaintenanceEnables AI coding agents to efficiently explore codebases by providing structural outlines, module digests, symbol bodies, and AST-aware grep via MCP.410 npm1MIT

Tidewave Railsofficial
AlicenseNot gradedqualityCmaintenanceBetter agentic Rails development, runtime-level tools for your agent to talk to your running app.475Apache 2.0