
A Ruby implementation of a Model Context Protocol (MCP) server for Rails projects. Let LLMs interact with your Rails codebase through code analysis, exploration, and development assistance.

**Current Version:** 1.5.0

---

## What is MCP?

The Model Context Protocol (MCP) is a standardized way for AI models to interact with their environment. It defines a structured method for models to request and use tools, access resources, and maintain context during interactions.

Rails MCP Server implements the MCP specification to give AI models access to Rails projects for code analysis, exploration, and assistance.

---

## Features

- Manage multiple Rails projects with auto-detection
- Browse project files and structures
- View Rails routes with filtering
- Inspect model information and relationships (Prism static analysis)
- Get database schema information
- Analyze controller-view relationships
- Analyze environment configurations
- Execute sandboxed Ruby code for custom queries
- Access Rails, Turbo, Stimulus, and Kamal documentation
- Context-efficient architecture with progressive tool discovery
- **GitHub Copilot Agent support** (v1.5.0+)
- **Rails 8.1+ compatibility** (v1.5.0+)

---

## Quick Start

### 1. Install the Gem

```bash
gem install rails-mcp-server
```

### 2. Configure Projects

**Option A: Interactive configuration**

```bash
rails-mcp-config
```

This provides a TUI for managing projects, downloading guides, and configuring Claude Desktop.

**Option B: Single-project mode** (v1.5.0+)

For quick usage with the current directory:

```bash
cd /path/to/your/rails/app
rails-mcp-server --single-project
```

**Option C: Environment variable** (v1.5.0+)

```bash
export RAILS_MCP_PROJECT_PATH=/path/to/your/rails/app
rails-mcp-server
```

### 3. Configure Your AI Client

#### Claude Desktop

Select "Claude Desktop integration" in the configuration tool, or manually add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "railsMcpServer": {
      "command": "ruby",
      "args": ["/path/to/rails-mcp-server/exe/rails-mcp-server"]
    }
  }
}
```

#### GitHub Copilot Agent (v1.5.0+)

See the [Copilot Agent Setup Guide](https://github.com/maquina-app/rails-mcp-server/blob/main/docs/COPILOT_AGENT.md) for detailed instructions.

---

## Project Detection (v1.5.0+)

The server uses priority-based project detection:

| Priority | Method | Description |
|----------|--------|-------------|
| 1 (Highest) | `RAILS_MCP_PROJECT_PATH` env var | Explicit path to project |
| 2 | `--single-project` flag | Uses current working directory |
| 3 | Auto-detection | Detects Rails apps (Gemfile) or engines (gemspec) |
| 4 (Lowest) | `projects.yml` | Traditional multi-project configuration |

When only one project is configured, the server auto-switches to it.

---

## Available Tools

The server provides 4 registered tools plus internal analyzers accessible via `execute_tool`.

### Registered Tools

| Tool | Description |
|------|-------------|
| `switch_project` | Change the active Rails project |
| `search_tools` | Discover available tools by category or keyword |
| `execute_tool` | Invoke internal analyzers by name |
| `execute_ruby` | Execute sandboxed Ruby code in project context |

### Internal Analyzers

| Analyzer | Description |
|----------|-------------|
| `project_info` | Project information, Rails version, directory structure |
| `list_files` | List files matching a pattern |
| `get_file` | Retrieve file content |
| `get_routes` | Rails routes with filtering |
| `analyze_models` | Active Record models with associations and validations |
| `get_schema` | Database schema information |
| `analyze_controller_views` | Controller-view relationships |
| `analyze_environment_config` | Environment configuration analysis |
| `load_guide` | Load documentation guides |

---

## Usage Examples

### Switch Project

```
switch_project(project_name: "my_rails_app")
```

### Get Routes

```
execute_tool(tool_name: "get_routes")
execute_tool(tool_name: "get_routes", params: { controller: "users" })
execute_tool(tool_name: "get_routes", params: { verb: "POST" })
```

### Analyze Models

```
execute_tool(tool_name: "analyze_models")
execute_tool(tool_name: "analyze_models", params: { model_name: "User" })
execute_tool(tool_name: "analyze_models", params: { model_name: "User", analysis_type: "full" })
```

**Tips:**
- Use CamelCase singular: `User`, `BlogPost`, `OrderItem`
- Use `analysis_type: "full"` to include Prism static analysis (callbacks, scopes, methods)

### Get Schema

```
execute_tool(tool_name: "get_schema")
execute_tool(tool_name: "get_schema", params: { table_name: "users" })
execute_tool(tool_name: "get_schema", params: { detail_level: "tables" })
```

**Tips:**
- Use snake_case plural: `users`, `blog_posts`, `order_items`
- Use `detail_level: "tables"` for a quick table list

### Execute Ruby

```
execute_ruby(code: "puts read_file('Gemfile')")
execute_ruby(code: "list_files('app/models/**/*.rb').each { |f| puts f }")
```

**Available helpers in execute_ruby:**

| Helper | Description |
|--------|-------------|
| `read_file(path)` | Read a file safely |
| `file_exists?(path)` | Check if a file exists |
| `list_files(pattern)` | Glob files matching pattern |
| `project_root` | Get the project root path |

**Important:** Always use `puts` to see output from `execute_ruby`.

---

## Server Modes

### STDIO Mode (Default)

For direct integration with Claude Desktop:

```bash
rails-mcp-server
```

### Single-Project Mode (v1.5.0+)

For working with the current directory only:

```bash
cd /path/to/rails/app
rails-mcp-server --single-project
```

### HTTP Mode

For HTTP endpoints with JSON-RPC and SSE:

```bash
rails-mcp-server --mode http
rails-mcp-server --mode http -p 8080
rails-mcp-server --mode http --bind-all  # Allow LAN access
```

**Endpoints:**
- JSON-RPC: `http://localhost:6029/mcp/messages`
- SSE: `http://localhost:6029/mcp/sse`

---

## Configuration

### Environment Variable (v1.5.0+)

Set the project path explicitly:

```bash
export RAILS_MCP_PROJECT_PATH=~/projects/my-rails-app
rails-mcp-server
```

### Manual Project Configuration

Edit `~/.config/rails-mcp/projects.yml`:

```yaml
store: "~/projects/store"
blog: "~/projects/rails-blog"
ecommerce: "/full/path/to/ecommerce-app"
```

### Ruby Version Manager Users

Claude Desktop bypasses version manager initialization. Use the Ruby shim path:

```json
{
  "mcpServers": {
    "railsMcpServer": {
      "command": "/home/your_user/.rbenv/shims/ruby",
      "args": ["/path/to/rails-mcp-server/exe/rails-mcp-server"]
    }
  }
}
```

The `rails-mcp-config` tool detects this automatically.

---

## Documentation Resources

Access comprehensive documentation through `load_guide`:

```
execute_tool(tool_name: "load_guide", params: { library: "rails" })
execute_tool(tool_name: "load_guide", params: { library: "rails", guide: "getting_started" })
execute_tool(tool_name: "load_guide", params: { library: "rails", guide: "active_record_basics" })
execute_tool(tool_name: "load_guide", params: { library: "turbo" })
execute_tool(tool_name: "load_guide", params: { library: "stimulus" })
execute_tool(tool_name: "load_guide", params: { library: "kamal" })
execute_tool(tool_name: "load_guide", params: { library: "custom" })
```

**Available libraries:**

| Library | Content |
|---------|---------|
| `rails` | Official Rails Guides |
| `turbo` | Hotwire Turbo handbook and reference |
| `stimulus` | Stimulus handbook and reference |
| `kamal` | Kamal deployment documentation |
| `custom` | User-added custom guides |

Download guides using the configuration tool:

```bash
rails-mcp-config
# Select "Download guides"
```

> **Breaking Change in v1.5.0:** The `guides` parameter was renamed to `library`.
> - Old: `params: { guides: "rails" }`
> - New: `params: { library: "rails" }`

---

## Analyzer Parameter Reference

| Analyzer | Required | Optional Parameters |
|----------|----------|---------------------|
| `project_info` | - | `max_depth`, `include_files`, `detail_level` |
| `list_files` | - | `directory`, `pattern` |
| `get_file` | `path` | - |
| `get_routes` | - | `controller`, `verb`, `path_contains`, `named_only`, `detail_level` |
| `analyze_models` | - | `model_name`, `model_names`, `detail_level`, `analysis_type` |
| `get_schema` | - | `table_name`, `table_names`, `detail_level` |
| `analyze_controller_views` | - | `controller_name`, `detail_level`, `analysis_type` |
| `analyze_environment_config` | - | (none) |
| `load_guide` | `library` | `guide` |

### Common Parameter Values

**detail_level:**
- `names` - Minimal output (just names/paths)
- `summary` - Compact overview
- `full` - Complete details (default)

**analysis_type** (for models and controllers):
- `introspection` - Uses Rails runtime APIs (default)
- `static` - Uses Prism AST parsing
- `full` - Both introspection and static analysis

---

## Using with MCP Proxy

For STDIO-only clients that need HTTP/SSE capabilities:

```bash
# Start server in HTTP mode
rails-mcp-server --mode http

# Install and run MCP proxy
npm install -g mcp-remote
npx mcp-remote http://localhost:6029/mcp/sse
```

Configure Claude Desktop to use the proxy:

```json
{
  "mcpServers": {
    "railsMcpServer": {
      "command": "npx",
      "args": ["mcp-remote", "http://localhost:6029/mcp/sse"]
    }
  }
}
```

---

## Testing and Debugging

Use MCP Inspector to test the server:

```bash
npm -g install @modelcontextprotocol/inspector
npx @modelcontextprotocol/inspector /path/to/rails-mcp-server
```

The Inspector UI lets you:
- See all available tools
- Execute tool calls interactively
- View request and response details
- Debug issues in real-time

---

## Security

### Sandbox Protections

The `execute_ruby` sandbox prevents:

- File writes and modifications
- System calls and shell commands
- Network access
- Reading sensitive files (.env, credentials, master.key, etc.)

### Input Validation (v1.5.0+)

All file-accessing analyzers use centralized input validation:

- **Path traversal prevention** - Blocks `../` and absolute paths
- **Sensitive file protection** - Filters master.key, credentials.yml.enc, .env files
- **Shell injection prevention** - Uses safe argument passing
- **SQL injection prevention** - Validates table names in schema queries

---

## Compatibility

| Component | Supported Versions |
|-----------|-------------------|
| Ruby | 3.2+ |
| Rails (target projects) | 6.0+ |
| Rails 8.1.1+ | Full support (v1.5.0+) |
| Claude Desktop | Supported |
| GitHub Copilot Agent | Supported (v1.5.0+) |
| Other MCP Clients | Via STDIO or HTTP mode |

---

## Changelog Highlights (v1.5.0)

**New Features:**
- GitHub Copilot Agent support
- `--single-project` flag for single-project mode
- `RAILS_MCP_PROJECT_PATH` environment variable
- Auto-detection of Rails apps and engines
- Auto-switch when only one project configured

**Bug Fixes:**
- Fixed Rails 8.1.1 callback introspection compatibility
- Fixed `execute_tool` params schema for MCP clients
- Improved error messages with helpful tips

**Security:**
- Added PathValidator for centralized input sanitization
- Added CI security infrastructure (Dependabot, CodeQL, OpenSSF Scorecard)

**Breaking Changes:**
- `load_guide` parameter renamed: `guides` → `library`

---

## Next Steps

<div class="not-prose mt-8 grid grid-cols-1 gap-4 sm:grid-cols-2">
  <a href="https://github.com/maquina-app/rails-mcp-server" target="_blank" rel="noopener" class="group relative rounded-2xl border border-zinc-200 p-6 hover:border-[#50B1FD]/50 dark:border-zinc-800 dark:hover:border-[#50B1FD]/50 transition">
    <h3 class="font-sora font-semibold text-zinc-900 dark:text-white group-hover:text-[#50B1FD] transition">
      GitHub Repository
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      Source code, issues, and contribution guidelines.
    </p>
  </a>

  <a href="https://github.com/maquina-app/rails-mcp-server/blob/main/docs/AGENT.md" target="_blank" rel="noopener" class="group relative rounded-2xl border border-zinc-200 p-6 hover:border-[#50B1FD]/50 dark:border-zinc-800 dark:hover:border-[#50B1FD]/50 transition">
    <h3 class="font-sora font-semibold text-zinc-900 dark:text-white group-hover:text-[#50B1FD] transition">
      AI Agent Guide
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      Comprehensive guide for AI agents using this server.
    </p>
  </a>

  <a href="https://github.com/maquina-app/rails-mcp-server/blob/main/docs/COPILOT_AGENT.md" target="_blank" rel="noopener" class="group relative rounded-2xl border border-zinc-200 p-6 hover:border-[#50B1FD]/50 dark:border-zinc-800 dark:hover:border-[#50B1FD]/50 transition">
    <h3 class="font-sora font-semibold text-zinc-900 dark:text-white group-hover:text-[#50B1FD] transition">
      GitHub Copilot Setup
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      Configure Rails MCP Server with GitHub Copilot Agent.
    </p>
  </a>

  <a href="https://rubygems.org/gems/rails-mcp-server" target="_blank" rel="noopener" class="group relative rounded-2xl border border-zinc-200 p-6 hover:border-[#50B1FD]/50 dark:border-zinc-800 dark:hover:border-[#50B1FD]/50 transition">
    <h3 class="font-sora font-semibold text-zinc-900 dark:text-white group-hover:text-[#50B1FD] transition">
      RubyGems
    </h3>
    <p class="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
      Install the latest version from RubyGems.
    </p>
  </a>
</div>
