MCP protocol server for Rails projects providing introspection tools for models, routes, database schema, controllers, files, and configuration
This Rails MCP server has a solid foundation with 12 well-intentioned tools, mostly covering inspection and analysis of Rails projects. However, it suffers from several structural issues that prevent it from reaching production quality. Most tools have descriptions, and parameter schemas are present with types, but there are critical gaps in output schema documentation, error handling guidance, and some parameter descriptions are generic. The meta-tool pattern (execute_tool + search_tools) is clever for context efficiency but adds complexity that undermines clarity. Several tools lack sufficient detail in descriptions to guide LLM selection, and none document their output structure, a critical omission for tool composition.
Analyze controllers using Rails introspection and/or Prism static analysis (callbacks, filters, strong params, renders)
Compare environment configurations and find inconsistencies
Analyze ActiveRecord models using Rails introspection and/or Prism static analysis
Execute a Rails MCP analyzer by name. Use search_tools first to discover available analyzers and their parameters, then invoke them through this meta-tool. This approach reduces context usage by not loading all tool definitions upfront.
Read the contents of a specific file
List HTTP routes via Rails introspection with filtering by controller, verb, or path
Get database schema - all tables or specific table details
No output schemas documented for any tool. LLMs cannot infer what fields to expect from responses, breaking tool composition and forcing agents to guess at field names for chaining.
execute_tool is a meta-dispatcher that accepts arbitrary tool_name strings. This indirection obscures the actual tool contract from the LLM, it cannot statically validate parameters or understand what each tool returns without calling search_tools first. This violates the single-responsibility principle and adds cognitive load.
Error handling lacks recovery guidance. Tools return generic error strings (e.g., 'Error executing analyzer') without indicating whether the error is retryable, user-fixable, or fatal, or what the agent should do next.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 63 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 42 | - | v1 |
List files matching a pattern in a directory
Load Rails, Turbo, Stimulus, Kamal, or custom documentation guides
Get Rails version, directory structure, and project overview
Search available Rails MCP tools by keyword or category. Use this to discover tools before invoking them with execute_tool. Workflow: 1. Call search_tools to find relevant tools 2. Call execute_tool(tool_name: "tool_name", params: {...}) to run them. Categories: models, database, routing, controllers, files, project, guides
Select a Rails project to work with from configured projects
analyze_environment_config has no visible input schema or parameter documentation.
Parameter descriptions are often generic and fail to specify format, constraints, or valid values. E.g., 'Filter by HTTP verb' does not enumerate GET, POST, PUT, PATCH, DELETE; 'analysis_type' description lacks clear guidance on when to use 'introspection' vs 'static' vs 'full'.
Tools that process directories or patterns (list_files, get_file) do not specify path traversal guards or character restrictions. An LLM could pass '../../../etc/passwd' and bypass expected boundaries.
No pagination or result limit guidance. project_info, get_routes, analyze_models, and get_schema can return large result sets but lack limit/offset/page parameters or documentation of maximum result sizes, risking context window exhaustion.
The naming pattern 'execute_tool' is too generic. It reads as a procedural action ('execute') rather than describing what happens. A better name might be 'invoke_analyzer' or expose each tool directly with verb_noun names (get_routes, analyze_models, etc.).
search_tools implements tool discovery via a user-facing tool, but LLMs often fail to call it first. The server relies on agents remembering to invoke search_tools before execute_tool, which breaks the fail-safe principle. Exposing tools directly with clear names reduces friction.