Think Cursor's codebase indexing, but for Claude Code.
How It Works ◆ Quick Start ◆ Tools ◆ Configuration ◆ Architecture
- Ruby files — Parsed with Prism into classes, modules, and methods
- ERB templates — Parsed with Herb into blocks, conditionals, and HTML elements
- Other files (JS, TS, YAML, Markdown) — Sliding window chunking
- Embeddings — Generated locally with all-MiniLM-L6-v2 (384 dimensions, zero config)
- Vector search — SQLite + sqlite-vec for cosine similarity
- Background indexing — Starts automatically, search is available immediately
gem install rails_mcp_code_search
cd your-project
rails-mcp-code-search --setupRequires Ruby 4.0+. Run --setup inside each project you want to index. It creates a version-independent wrapper script (~/.local/bin/) and a per-project .mcp.json that configures Claude Code automatically. The gem auto-updates daily. The first search downloads the embedding model (~80 MB) to ~/.cache/informers/.
Tip: Add
.mcp.jsonto your project's.gitignore— it contains local paths.
Search the codebase by concept or behavior using natural language.
query: "user authentication logic"
limit: 10
file_pattern: "app/models/**/*.rb"
Returns ranked results with file path, line range, similarity score, and code content. On each search, changed files are automatically re-indexed with a 200ms time budget.
Trigger a manual reindex. Returns immediately — runs in the background.
full: true # Rebuild entire index
full: false # Incremental (default, only changed files)
Check index health, chunk count, embedding provider, and search stats.
| Variable | Default | Description |
|---|---|---|
RAILS_MCP_CODE_SEARCH_PROVIDER |
local |
Embedding provider: local or openai |
RAILS_MCP_CODE_SEARCH_DB_PATH |
auto | Override database file path |
RAILS_MCP_CODE_SEARCH_LOG_LEVEL |
info |
Log level: debug, info, warn, error |
RAILS_MCP_CODE_SEARCH_OPENAI_API_KEY |
— | Required when provider is openai |
For faster indexing or higher-dimensional embeddings, use OpenAI's text-embedding-3-small (1536 dimensions):
export RAILS_MCP_CODE_SEARCH_PROVIDER=openai
export RAILS_MCP_CODE_SEARCH_OPENAI_API_KEY=sk-...| Local (default) | OpenAI | |
|---|---|---|
| Dimensions | 384 | 1536 |
| Speed | ~5 min / 1000 files | ~15s / 1000 files |
| Cost | Free | Per-token API cost |
| Privacy | Everything stays local | Code sent to OpenAI |
| Setup | Zero config | Requires API key |
Switching providers triggers a full reindex automatically.
Privacy notice: When using the OpenAI provider, source code chunks from your repository are sent to OpenAI's embedding API. The local provider (default) keeps everything on your machine.
*.rb *.erb *.js *.ts *.yml *.yaml *.md
Excluded: vendor/ node_modules/ tmp/ log/
┌─────────────────────────────────────────────────────────┐
│ Claude Code │
│ (MCP Client) │
└──────────────────────┬──────────────────────────────────┘
│ stdio
▼
┌─────────────────────────────────────────────────────────┐
│ MCP Server (search, reindex, status) │
└──────────────────────┬──────────────────────────────────┘
│
┌────────────┴────────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Background │ │ Embedding │
│ Worker │ │ Adapter │
│ (sole writer) │ │ (local / openai) │
└────────┬─────────┘ └────────┬─────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────┐
│ SQLite + sqlite-vec │
│ (WAL mode, per-project DB) │
│ ~/.local/share/rails-mcp-code-search/ │
└─────────────────────────────────────────────┘
| File Type | Parser | Chunk Types |
|---|---|---|
*.rb |
Prism AST | class, module, method |
*.erb |
Herb AST | erb_block, erb_conditional, html_element |
| Everything else | Sliding window | window (50 lines, 10 overlap) |
- Standalone ActiveRecord — No Rails runtime dependency, just SQLite
- Single writer thread — All DB mutations go through the background worker
- Smart reindex — Changed files (via
git diff) are re-indexed before each search - Per-project database — SHA256 of the project path, stored in
~/.local/share/ - Prism + Herb AST — Semantic chunking produces better search results than naive line splitting
MIT
Made in Tokyo with ❤️ and 🤖