An intelligent MCP (Model Context Protocol) server for Ruby on Rails projects that provides AST-based code parsing, knowledge graph navigation, and advanced analysis capabilities. Features native Ruby AST parsing with automatic fallback to regex-based parsing when Ruby is not available.
| Feature | Vanilla Claude Code / Cursor | Rails AST MCP Server |
|---|---|---|
| Rails DSL Understanding | Basic text search | Full understanding of associations, validations, callbacks, scopes |
| Symbol Search | File-by-file scanning | Indexed database with instant FTS5 search |
| Call Graph Analysis | Not available | Trace method dependencies and call relationships |
| Test Discovery | Manual search | Automatic test file detection |
| Performance | Searches entire codebase each time | Pre-indexed SQLite database with sub-second queries |
| Memory Usage | Loads files into context | Efficient database queries, minimal context usage |
| Rails Patterns | Generic code understanding | Rails-specific: models, controllers, services, jobs, etc. |
| AST Parsing | Not available | Native Ruby AST parsing (when Ruby installed) |
- Context Efficiency: Instead of loading entire files into Claude's context window, you can query specific symbols and relationships
- Rails Intelligence: Understands Rails DSL - knows that
has_many :postscreates methods likeposts,posts=,posts<<, etc. - Speed: Pre-indexed database means instant searches vs scanning files every time
- Accurate Symbol Detection: Native Ruby AST parsing (when available) ensures 100% accurate symbol detection
- 🔍 Smart Symbol Search: Find classes, methods, modules across your Rails codebase
- 📊 Call Graph Analysis: Trace method calls and dependencies
- 🧪 Test Discovery: Automatically find related test files
- 📁 Rails-aware: Understands Rails conventions and patterns
- 🚀 Hybrid Parsing: Native Ruby AST when available, regex fallback otherwise
- ⚡ Fast Search: SQLite FTS5 full-text search for instant results
- 🎯 Context Efficient: Minimizes token usage by returning only relevant code
- 🗄️ Schema Awareness: Parses db/schema.rb to understand database structure
- 🔗 Association Suggestions: Automatically suggests Rails associations from foreign keys
- ✅ Validation Generation: Suggests validations based on database constraints
# Add the server for your Rails project (requires full path)
claude mcp add rails-ast npx -- -y rails-ast-mcp-server /path/to/your/rails/project
# Example:
claude mcp add rails-ast npx -- -y rails-ast-mcp-server /Users/you/sources/my-rails-app
# Restart Claude Code to activate the serverImportant: Always use the full absolute path to your Rails project
The server accepts a single argument for the repository path:
# Specify the Rails project path as an argument
npx rails-ast-mcp-server /path/to/rails/project
# Or use current directory
npx rails-ast-mcp-server .You can also configure the server using environment variables:
| Variable | Description | Default | Example |
|---|---|---|---|
REPO_PATH |
Path to your Rails project | Current directory (.) |
/Users/me/myapp |
DB_PATH |
SQLite database location | {project}/.rails-index/repo.db |
/tmp/rails.db |
RUBY_AST_PARSER |
Custom Ruby parser path | Built-in parser | /opt/parser.rb |
AUTO_INDEX |
Enable auto-indexing on startup | true |
false |
# Example with environment variables
REPO_PATH=/path/to/rails/app DB_PATH=/tmp/index.db npx rails-ast-mcp-server
# Disable auto-indexing
AUTO_INDEX=false npx @hiteshganjoo/rails-mcp-indexerThe indexer now includes intelligent auto-indexing capabilities:
- Automatically indexes your Rails project when the server starts
- Only indexes if:
- Database doesn't exist (first run)
- Repository path has changed
- Database is empty
- Skips indexing if the existing index is valid
- Can be disabled with
AUTO_INDEX=false
- Database is now stored at
{project}/.rails-index/repo.dbby default - Each Rails project gets its own index
- No more conflicts when switching between projects
- Only re-indexes files that have changed since last index
- Checks file modification times vs last index time
- Much faster than full reindex for large projects
- Automatically detects when a full reindex is needed:
- When switching to a different Rails project
- When the database is corrupted or missing
- When explicitly requested via the
reindextool
Create a .mcp.json file in your Rails project root:
{
"rails-indexer": {
"repoPath": ".",
"dbPath": ".rails-index/repo.db",
"autoIndex": true
}
}Search for symbols (classes, methods, modules) in your codebase.
{
"query": "User", // Search query
"k": 10, // Number of results (default: 10)
"file_types": ["model"] // Optional: Filter by file types
}Extract code snippets from files.
{
"file_path": "app/models/user.rb",
"start_line": 10, // Optional
"end_line": 20, // Optional
"symbol_name": "validate" // Optional: Extract specific symbol
}Analyze call relationships between methods.
{
"symbol": "User.authenticate",
"direction": "both", // "callers" | "callees" | "both"
"depth": 2 // Analysis depth
}Find code patterns similar to a given snippet.
{
"code_snippet": "validates :email, presence: true",
"k": 5, // Number of results
"min_similarity": 0.7 // Minimum similarity score
}Find test files related to an implementation file.
{
"file_path": "app/models/user.rb"
}Reindex the codebase.
{
"paths": ["app/models"], // Optional: Specific paths
"full": false // Full reindex
}List all database tables from schema.rb.
// No parameters requiredGet detailed information about a database table including columns, indexes, and constraints.
{
"table_name": "users"
}Get foreign key relationships for a table.
{
"table_name": "orders"
}Suggest Rails associations and validations based on database schema.
{
"table_name": "posts"
}Returns:
- Rails association declarations (belongs_to, has_many, has_one)
- Validation suggestions based on constraints
- Model name inference
The indexer automatically parses db/schema.rb to provide database-aware features:
- Parses
db/schema.rbduring reindex - Extracts tables, columns, indexes, and foreign keys
- Stores schema metadata in SQLite for fast queries
Based on foreign keys in your schema, the indexer suggests:
belongs_toassociations for foreign key columnshas_manyorhas_onebased on unique constraints- Proper
dependentoptions from ON DELETE rules inverse_ofrelationships
Automatically suggests validations based on:
- NOT NULL constraints →
presence: true - Unique indexes →
uniqueness: true - String column limits →
length: { maximum: X } - Numeric columns →
numericalityvalidations
The indexer automatically recognizes these Rails patterns:
| Type | Pattern | Example |
|---|---|---|
model |
app/models/**/*.rb |
User, Post, Comment |
controller |
app/controllers/**/*.rb |
UsersController |
service |
app/services/**/*.rb |
AuthenticationService |
job |
app/jobs/**/*.rb, app/sidekiq/**/*.rb |
SendEmailJob |
policy |
app/policies/**/*.rb |
UserPolicy |
mailer |
app/mailers/**/*.rb |
UserMailer |
helper |
app/helpers/**/*.rb |
ApplicationHelper |
concern |
app/*/concerns/**/*.rb |
Searchable |
spec |
spec/**/*_spec.rb, test/**/*_test.rb |
user_spec.rb |
migration |
db/migrate/**/*.rb |
add_email_to_users.rb |
- Parsing: Hybrid approach - native Ruby AST parser when Ruby is available, regex fallback otherwise
- Indexing: Stores parsed data in SQLite with FTS5 for fast search
- MCP Protocol: Exposes tools via Model Context Protocol for AI assistants
The indexer works without Ruby installation, but having Ruby installed provides more accurate parsing:
| Ruby Version | Support Level | Features |
|---|---|---|
| No Ruby | ✅ Full Support | Regex-based parser, all features work |
| Ruby 2.7+ | ✅ Enhanced | Native AST parsing via parser gem |
| Ruby 3.3+ | ✅ Enhanced | Native AST parsing via prism (built-in) |
When Ruby is detected during installation, the package automatically:
- Detects your Ruby version
- Installs appropriate parser gems
- Uses native AST parsing for 100% accurate symbol detection
- Falls back to regex parsing if native parsing fails
┌──────────────────┐ ┌──────────────────┐
│ Claude/AI Agent │────▶│ MCP Protocol │
└──────────────────┘ └──────────────────┘
│
▼
┌──────────────────┐
│ Rails MCP Server│
└──────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Ruby Parser │ │ Indexer │ │ Database │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
└───────────────┼───────────────┘
▼
┌──────────────────┐
│ Rails Codebase │
└──────────────────┘
- Node.js 18+
- TypeScript 5+
# Clone the repository
git clone https://github.com/ganjooh/rails-ast-mcp-server
cd rails-ast-mcp-server
# Install dependencies
npm install
# Build the project
npm run build
# Test with sample Rails app
REPO_PATH=./sample_rails_app npm start# Run tests
npm test
# Test with MCP Inspector
npx @modelcontextprotocol/inspector npm startUser: "Find all authentication methods in my Rails app"
Claude: *Searches through multiple files, uses significant context*
"Let me search through your codebase...
Reading app/models/user.rb...
Reading app/controllers/application_controller.rb...
Reading app/controllers/sessions_controller.rb..."
[Uses 5000+ tokens just to find methods]
User: "Find all authentication methods in my Rails app"
Claude: *Instantly queries the index*
Found 5 authentication-related methods:
- User.authenticate (app/models/user.rb:37)
- SessionsController#create (app/controllers/sessions_controller.rb:8)
- ApplicationController#authenticate_user! (app/controllers/application_controller.rb:15)
[Uses only 200 tokens with precise results]
# Ask Claude Code:
"Where is the User.authenticate method defined?"
# Rails MCP Indexer instantly returns: app/models/user.rb:37-41
# Vanilla Claude Code would need to:
# - Search through all model files
# - Parse each file to find the method
# - Use significant context tokens# Ask Claude Code:
"What associations does the User model have?"
# Rails MCP Indexer knows:
# - has_many :posts
# - has_many :comments, through: :posts
# - has_one :profile
# - belongs_to :organization
# Vanilla Claude Code would need to load and parse the entire User model# Ask Claude Code:
"Find tests for the User model"
# Rails MCP Indexer instantly returns:
# - spec/models/user_spec.rb
# - spec/requests/users_spec.rb
# - test/models/user_test.rb
# Vanilla Claude Code would manually search through spec/ and test/ directories// Example: Search for authentication-related symbols
const result = await mcpClient.callTool('search_symbols', {
query: 'authenticate',
k: 5,
file_types: ['model', 'controller']
});
// Example: Get call graph for a method
const graph = await mcpClient.callTool('call_graph', {
symbol: 'User.authenticate',
direction: 'both',
depth: 2
});
// Example: Find similar validation patterns
const similar = await mcpClient.callTool('find_similar', {
code_snippet: 'validates :email, presence: true, uniqueness: true',
k: 5
});- Check Node.js version:
node --version(should be 18+) - Verify paths: Ensure REPO_PATH points to valid Rails project
- Check logs: Run with
DEBUG=* npm start
- Run reindex: Use the
reindextool withfull: true - Check permissions: Ensure write access to DB_PATH directory
- Verify file patterns: Check if your Rails structure matches expected patterns
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Built with Model Context Protocol SDK for seamless AI integration.