qgrep-mcp
Indexed code search for large codebases. Available as a CLI tool, MCP server, and REST API. Built for Claude Code, ports to Codex CLI, Cursor, Copilot, and any MCP-compatible client.
An amortized cost estimator decides at query time whether building a qgrep index is worth it, based on file count (which correlates r=0.96 with ripgrep latency). Works fully without qgrep installed. It's a pure enhancement over ripgrep.
Motivation
AI coding tools ship with ripgrep or similar linear-scan search. This works fine on small repos, but breaks down on large codebases:
Each search blocks the agent's reasoning until it returns. Even with async execution, ripgrep saturates disk I/O scanning the same files repeatedly. An indexed search returns in milliseconds regardless of repo size.
Why not just fix it upstream? The models behind these coding tools are post-trained to use specific built-in tools like Grep and file search. Tool preferences get baked into the model weights during post-training, and system prompts reinforce them further by defining the available tool set. Users can't modify either. We tested this directly with Claude Opus 4.6: even with the search_code MCP tool registered alongside built-in Grep, the model ignores it 100% of the time when no steering mechanism is present. This behavior may improve in future model generations, but as long as system prompts instruct the model to use a specific built-in search tool, the model will comply.
This project bridges that gap by working at the layer users can control: hooks intercept tool calls before they execute, skills inject context that nudges model behavior at inference time, and agents constrain tool access so indexed search is the only option. No post-training needed, no system prompt changes, no waiting for upstream fixes.
Benchmarks
Tested on three real-world repos with cold disk cache (OS file cache cleared between runs, simulating a fresh session where the AI agent hasn't touched these files yet). This reflects real-world conditions since agents start fresh sessions and the OS evicts cached file data over time:
Detailed results
rust-lang/rust (58,547 files):
| Query | ripgrep | qgrep | Speedup |
|---|
TODO|FIXME | 59.65s | 0.055s | 1,085x |
fn main | 59.66s | 0.027s | 2,210x |
unsafe impl | 59.40s | 0.018s | 3,300x |
fn\s+\w+\(.*Result< | 36.85s | 0.037s | 990x |
pub\s+(unsafe\s+)?fn\s+\w+ | 34.89s | 0.041s | 861x |
#\[derive\(.*Clone.*\)\] | 33.83s | 0.027s | 1,242x |
Linux kernel (92,920 files):
| Query | ripgrep | qgrep | Speedup |
|---|
TODO|FIXME | 65.04s | 0.312s | 208x |
int main | 107.97s | 0.074s | 1,459x |
static void | 104.30s | 0.098s | 1,064x |
static\s+const\s+struct\s+file_operations | 49.85s | 0.258s | 193x |
pr_err\(|pr_warn\(|pr_info\( | 47.66s | 0.225s | 212x |
MODULE_LICENSE\( | 51.55s | 0.215s | 240x |
home-assistant/core (24,718 files):
| Query | ripgrep | qgrep | Speedup |
|---|
TODO|FIXME | 36.53s | 0.043s | 850x |
async def | 22.96s | 0.036s | 638x |
class.*: | 23.30s | 0.024s | 971x |
async\s+def\s+async_setup_entry | 23.19s | 0.027s | 867x |
raise\s+HomeAssistantError | 3.43s | 0.026s | 132x |
CONF_\w+\s*=\s*" | 1.27s | 0.017s | 74x |
What determines search speed?
File count is the dominant factor. Across our three benchmark repos (25k, 58k, 93k files), ripgrep latency scales nearly linearly with file count.
Installation
Five options, from most to least automated. Pick the one that fits your workflow:
Option 1: Hook + MCP Server (hard redirect)
The fully automatic route. The hook intercepts every Grep call and redirects to search_code when it detects a large codebase. Claude doesn't need to be nudged or told anything; the hook handles it transparently.
git clone https://github.com/sumisingh10/qgrep-mcp.git
claude --plugin-dir ./qgrep-mcp