Ultra-fast indexed code search engine with MCP server for AI coding tools.
Project description
xgrep
Ultra-fast indexed code search engine with MCP server for AI coding tools.
Pre-builds a trigram inverted index, then searches in milliseconds. Designed for repeated searches on large codebases — by humans and AI agents alike.
Features
- Indexed search — trigram inverted index makes repeated searches 2-46x faster than ripgrep
- File discovery —
--findmode locates files 2-15x faster than fd - MCP server — built-in Model Context Protocol server for AI coding tools (Claude Code, Cursor, etc.)
- LLM-optimized output —
--format llmproduces Markdown with language tags, context lines, and token-aware truncation - Git-aware — search only changed files (
--changed), recent commits (--since 1h), respects.gitignore - Zero config — install via cargo/npm/pip, then
xg "pattern". Index builds automatically on first search - Hybrid search — serves results from index instantly while rebuilding in the background
Why xgrep?
| ripgrep | zoekt | xgrep | |
|---|---|---|---|
| Setup | None | Server required | None (cargo/npm/pip) |
| First search | Instant | After server start | Auto-builds index |
| Repeated search (Linux kernel) | 1,687ms | 170ms (server) | 37ms |
| File discovery (next.js, 26K files) | N/A | N/A | 9ms (fd: 191ms) |
| Index size | N/A | 155% of source | 8% of source |
| AI agent integration | None | None | MCP server built-in |
| Memory (search) | 11MB | 288MB | 208MB |
xgrep is not a ripgrep replacement. Use ripgrep for one-off searches. Use xgrep when you search the same codebase repeatedly — the index pays for itself after ~2 searches.
Installation
Choose your package manager:
# Rust (recommended — native binary, no runtime)
cargo install xgrep-search # Requires Rust 1.85+
# npm (Node.js 18+)
npm install -g xgrep
# pip (Python 3.8+)
pip install xgrep-search
Prebuilt binaries are also available on the Releases page.
Quick Start
xg "pattern" # Search (auto-builds index on first run)
Build from source
git clone https://github.com/momokun7/xgrep.git
cd xgrep/rust
cargo build --release
cp target/release/xg ~/.local/bin/
Usage
xg "pattern" # Smart-case search (all-lowercase = case-insensitive)
xg "Pattern" # Mixed/upper case in pattern = case-sensitive
xg "pattern" -i # Force case-insensitive
xg "pattern" -s # Force case-sensitive (disable smart-case)
xg "pattern" /path/to/repo # Search a specific directory
xg -e "handle_\w+" # Regex search
xg "pattern" -w # Match whole words only
xg "pattern" -t rs # Filter by file type
xg "pattern" -C 3 # Context lines (symmetric)
xg "pattern" -A 2 -B 1 # 2 lines after, 1 line before
xg "pattern" -g "*.rs" # Include only paths matching glob (repeatable)
xg "pattern" -g "!*_test.rs" # Exclude paths matching glob (! prefix)
xg "pattern" --format llm # Markdown output for LLMs
xg "pattern" --changed # Only git changed files
xg "pattern" --exclude vendor # Exclude paths containing "vendor"
xg "pattern" --absolute-paths # Show absolute paths
xg "pattern" --no-hints # Suppress regex pattern hints
xg --find "*.rs" # Find files by glob pattern
xg --list-types # Show supported file types
xg status # Show index status
xg init # Explicitly rebuild index
Search is smart-case by default: an all-lowercase pattern matches case-insensitively, while any uppercase letter makes the search case-sensitive. Use -i or -s to override (priority: -i > -s > smart-case).
Environment Variables
| Variable | Description | Default |
|---|---|---|
XGREP_LLM_CONTEXT |
Default context lines for --format llm |
3 |
XGREP_ABSOLUTE_PATHS |
Set to 1 to always use absolute paths |
unset |
XGREP_NO_HINTS |
Set to 1 to suppress regex pattern hints |
unset |
Run xg --help for all options.
MCP Server
xgrep runs as an MCP server, giving AI coding tools fast indexed search.
xg serve # Start MCP server
xg serve --root /path/to/repo # Specific directory
Claude Code
{
"mcpServers": {
"xgrep": {
"command": "xg",
"args": ["serve"]
}
}
}
Available tools: search, find_definitions, read_file, index_status, build_index
See docs/agents.md for agent-oriented usage patterns.
Performance
Measurement environment (tables below): Apple M4, 32GB RAM, NVMe SSD, macOS 15. Warm filesystem cache,
hyperfine --warmup 5 --runs 20. Results on other hardware — especially shared Linux machines or HDD — will differ; see Reproducibility below.
Search: Linux kernel (92,947 files, 2.0GB)
| Query | xg | ripgrep | vs ripgrep | Pattern type |
|---|---|---|---|---|
struct file_operations |
37ms | 1,687ms | 46x faster | focused |
printk |
52ms | 1,756ms | 34x faster | focused |
EXPORT_SYMBOL |
66ms | 1,773ms | 27x faster | focused |
The queries above were selected for xgrep's sweet spot (trigram index filters well). For distributed patterns that appear across most files, xgrep approaches ripgrep speed — see the Reproducibility section for honest numbers.
File discovery: next.js (27,332 files)
| Query | xg --find | fd | vs fd |
|---|---|---|---|
*.ts (4,838 files) |
20.8ms | 187.3ms | 9x faster |
config (substring) |
12.7ms | 188.1ms | 15x faster |
Index cost
| Metric | xgrep | zoekt |
|---|---|---|
| Build time (Linux kernel) | 6s | 46s |
| Index size | 175MB (8% of source) | 3.0GB (155%) |
| Breakeven | ~2 searches | — |
First run includes a one-time index build. See docs/benchmarks.md for full results including medium/small repos.
Reproducibility
The numbers above were measured on the author's Apple M4 with a warm filesystem cache. Third-party benchmarks on shared Linux machines (different CPU, spinning disk, cold cache) show a different picture depending on pattern type:
| Query | hits | M4 result | Third-party Linux (example) |
|---|---|---|---|
CONFIG_PREEMPT_RT |
~300 | xg wins big | xg wins big (cache fits in L3) |
EXPORT_SYMBOL_GPL |
~21k | xg wins | xg faster, but gap narrows |
raw_spin_lock_irqsave |
~1.2k | xg wins | xg ≈ ripgrep (互角) |
devm_kzalloc |
~7.4k | xg wins | xg slower than ripgrep |
The pattern: when trigram intersection leaves many candidate files (widely-used symbols),
xgrep must scan nearly the whole codebase — the index overhead then outweighs the savings.
This is a known limitation being investigated. Use bench/fair-bench.sh to measure on
your own hardware; the script runs both focused and distributed queries for a complete picture.
Limitations
- Short queries (< 3 chars) bypass the index — no speed advantage over ripgrep
- Tiny files (< 3 bytes) hold no trigrams and are invisible to indexed content search — a deliberate trade-off of the trigram index
- Index staleness — background rebuild runs every ~30s. Use
--freshfor up-to-date results - find_definitions uses regex heuristics, not AST analysis — false positives expected
When to use ripgrep instead: one-off searches, very small codebases (< 100 files), or queries shorter than 3 characters.
How It Works
- Index Build: Walks the codebase, extracts 3-byte trigrams from each file, builds an inverted index with delta+varint compression
- Search: Extracts trigrams from query, intersects posting lists to find candidate files, verifies matches
- Hybrid Mode: Combines index results with direct scanning of changed files when index is stale
- MCP Server: Exposes search via JSON-RPC over stdio, with token-aware truncation
Contributing
See CONTRIBUTING.md for development setup and guidelines.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xgrep_search-0.7.0-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: xgrep_search-0.7.0-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.8.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42d4e3f9cf5a708c67f807afcfc1687af27720b860c1ae194621efc68a7d0653
|
|
| MD5 |
7d0979a39685a084fbda38b69526b304
|
|
| BLAKE2b-256 |
029bab6061873eded785a8aaa3177a2265085da393e6f8b972a2db54dd921c1d
|
File details
Details for the file xgrep_search-0.7.0-cp311-cp311-manylinux_2_39_x86_64.whl.
File metadata
- Download URL: xgrep_search-0.7.0-cp311-cp311-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 1.2 MB
- Tags: CPython 3.11, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.8.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
637f05d22af4c00b96906df47b3f57f11bbd9924f4ad736c715419ff497a9597
|
|
| MD5 |
64a185e89a34d449ef1b603a0c73e6a1
|
|
| BLAKE2b-256 |
bdf3ca9e706dea26d3c65ef4d98f31a613a4778edb043fec092ece462c7a113d
|
File details
Details for the file xgrep_search-0.7.0-cp311-cp311-manylinux_2_39_aarch64.whl.
File metadata
- Download URL: xgrep_search-0.7.0-cp311-cp311-manylinux_2_39_aarch64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.11, manylinux: glibc 2.39+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.8.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37c9b127f7987a46d06264977c6e9a95b339086f1f6771bd7157f5ce235f9d6a
|
|
| MD5 |
793fb8c0c4ea532588079c62cd149d27
|
|
| BLAKE2b-256 |
b424734598dfc0df3bff87b935d1706335c1dfc7cf9ed5e943db4b7b79fd368c
|
File details
Details for the file xgrep_search-0.7.0-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: xgrep_search-0.7.0-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.8.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6bd5a45c1dd19eb428abc7e0e39ad11b80f437ea01efa15d52bd8e2ad9ee574f
|
|
| MD5 |
c9b5c8a0d1ad38437815963e4f777179
|
|
| BLAKE2b-256 |
fedf95874ef22a55abf1b88d56540c0552e8b776c10e81d5ad70b34c08e78000
|
File details
Details for the file xgrep_search-0.7.0-cp311-cp311-macosx_10_12_x86_64.whl.
File metadata
- Download URL: xgrep_search-0.7.0-cp311-cp311-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.11, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.8.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d36dbcabdc603f87c99f734ef63daf3901f636560dc5669bd216923aa18f68a8
|
|
| MD5 |
ae3d36c215029e7f36024a6e2a21cec1
|
|
| BLAKE2b-256 |
e8e114fa222ae6ed1fec1b1864a914e0c0454b9be1ddb03eb98b7025186aa9d2
|