An open API service indexing awesome lists of open source software.

https://github.com/ganjooh/rails-ast-mcp-server

Intelligent code indexing and retrieval system for Ruby on Rails projects with MCP integration
https://github.com/ganjooh/rails-ast-mcp-server

ai-tools ast claude code-indexing developer-tools mcp model-context-protocol rails ruby ruby-on-rails

Last synced: 2 months ago
JSON representation

Intelligent code indexing and retrieval system for Ruby on Rails projects with MCP integration

Awesome Lists containing this project

README

          

# Rails AST MCP Server

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.

## Why Use Rails AST MCP Server?

### Advantages Over Vanilla Claude Code / Cursor

| 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) |

### Key Benefits

1. **Context Efficiency**: Instead of loading entire files into Claude's context window, you can query specific symbols and relationships
2. **Rails Intelligence**: Understands Rails DSL - knows that `has_many :posts` creates methods like `posts`, `posts=`, `posts<<`, etc.
3. **Speed**: Pre-indexed database means instant searches vs scanning files every time
4. **Accurate Symbol Detection**: Native Ruby AST parsing (when available) ensures 100% accurate symbol detection

## Features

- πŸ” **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

## Quick Start

### Claude Code

```bash
# 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 server
```

**Important:** Always use the full absolute path to your Rails project

## Configuration

### Command Line Arguments

The server accepts a single argument for the repository path:

```bash
# 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 .
```

### Environment Variables

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` |

```bash
# 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-indexer
```

### Auto-Indexing Features (v2.1.0+)

The indexer now includes intelligent auto-indexing capabilities:

#### 1. **Automatic Index on Startup**
- 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`

#### 2. **Project-Specific Database**
- Database is now stored at `{project}/.rails-index/repo.db` by default
- Each Rails project gets its own index
- No more conflicts when switching between projects

#### 3. **Incremental Indexing**
- 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

#### 4. **Smart Reindexing Detection**
- 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 `reindex` tool

### Project-Specific Configuration

Create a `.mcp.json` file in your Rails project root:

```json
{
"rails-indexer": {
"repoPath": ".",
"dbPath": ".rails-index/repo.db",
"autoIndex": true
}
}
```

## Available Tools

### πŸ” search_symbols

Search for symbols (classes, methods, modules) in your codebase.

```typescript
{
"query": "User", // Search query
"k": 10, // Number of results (default: 10)
"file_types": ["model"] // Optional: Filter by file types
}
```

### πŸ“ get_snippet

Extract code snippets from files.

```typescript
{
"file_path": "app/models/user.rb",
"start_line": 10, // Optional
"end_line": 20, // Optional
"symbol_name": "validate" // Optional: Extract specific symbol
}
```

### πŸ“Š call_graph

Analyze call relationships between methods.

```typescript
{
"symbol": "User.authenticate",
"direction": "both", // "callers" | "callees" | "both"
"depth": 2 // Analysis depth
}
```

### πŸ”„ find_similar

Find code patterns similar to a given snippet.

```typescript
{
"code_snippet": "validates :email, presence: true",
"k": 5, // Number of results
"min_similarity": 0.7 // Minimum similarity score
}
```

### πŸ§ͺ find_tests

Find test files related to an implementation file.

```typescript
{
"file_path": "app/models/user.rb"
}
```

### πŸ”„ reindex

Reindex the codebase.

```typescript
{
"paths": ["app/models"], // Optional: Specific paths
"full": false // Full reindex
}
```

### πŸ—„οΈ db_tables

List all database tables from schema.rb.

```typescript
// No parameters required
```

### πŸ“Š db_table

Get detailed information about a database table including columns, indexes, and constraints.

```typescript
{
"table_name": "users"
}
```

### πŸ”— db_table_relations

Get foreign key relationships for a table.

```typescript
{
"table_name": "orders"
}
```

### πŸ’‘ db_suggest_associations

Suggest Rails associations and validations based on database schema.

```typescript
{
"table_name": "posts"
}
```

Returns:
- Rails association declarations (belongs_to, has_many, has_one)
- Validation suggestions based on constraints
- Model name inference

## Database Schema Support

The indexer automatically parses `db/schema.rb` to provide database-aware features:

### Automatic Schema Indexing
- Parses `db/schema.rb` during reindex
- Extracts tables, columns, indexes, and foreign keys
- Stores schema metadata in SQLite for fast queries

### Rails Association Generation
Based on foreign keys in your schema, the indexer suggests:
- `belongs_to` associations for foreign key columns
- `has_many` or `has_one` based on unique constraints
- Proper `dependent` options from ON DELETE rules
- `inverse_of` relationships

### Validation Suggestions
Automatically suggests validations based on:
- NOT NULL constraints β†’ `presence: true`
- Unique indexes β†’ `uniqueness: true`
- String column limits β†’ `length: { maximum: X }`
- Numeric columns β†’ `numericality` validations

## Rails File Type Recognition

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 |

## How It Works

1. **Parsing**: Hybrid approach - native Ruby AST parser when Ruby is available, regex fallback otherwise
2. **Indexing**: Stores parsed data in SQLite with FTS5 for fast search
3. **MCP Protocol**: Exposes tools via Model Context Protocol for AI assistants

### Ruby Support (Optional)

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:
1. Detects your Ruby version
2. Installs appropriate parser gems
3. Uses native AST parsing for 100% accurate symbol detection
4. Falls back to regex parsing if native parsing fails

## Architecture

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Claude/AI Agent │────▢│ MCP Protocol β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Rails MCP Serverβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β–Ό β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Ruby Parser β”‚ β”‚ Indexer β”‚ β”‚ Database β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Rails Codebase β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

## Development

### Prerequisites

- Node.js 18+
- TypeScript 5+

### Setup

```bash
# 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
```

### Testing

```bash
# Run tests
npm test

# Test with MCP Inspector
npx @modelcontextprotocol/inspector npm start
```

## Usage Examples

### Real-World Advantages in Claude Code

#### Without Rails MCP Indexer (Vanilla Claude Code)
```
User: "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]
```

#### With Rails MCP Indexer
```
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]
```

### Common Use Cases

#### 1. Finding Symbol Definitions
```bash
# 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
```

#### 2. Understanding Model Relationships
```bash
# 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
```

#### 3. Finding Related Tests
```bash
# 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
```

### Direct Tool Usage

```javascript
// 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
});
```

## Troubleshooting

### Server not connecting

1. Check Node.js version: `node --version` (should be 18+)
2. Verify paths: Ensure REPO_PATH points to valid Rails project
3. Check logs: Run with `DEBUG=* npm start`

### Index not updating

1. Run reindex: Use the `reindex` tool with `full: true`
2. Check permissions: Ensure write access to DB_PATH directory
3. Verify file patterns: Check if your Rails structure matches expected patterns

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

MIT License - see [LICENSE](LICENSE) file for details.

## Support

- Issues: [GitHub Issues](https://github.com/ganjooh/rails-ast-mcp-server/issues)
- Discussions: [GitHub Discussions](https://github.com/ganjooh/rails-ast-mcp-server/discussions)

## Acknowledgments

Built with [Model Context Protocol SDK](https://github.com/modelcontextprotocol/sdk) for seamless AI integration.