Fast, local semantic code search powered by Rust.
Search your codebase using natural language queries like "where do we handle authentication?" β all running locally with no API calls.
- Semantic Search β Natural language queries that understand code meaning
- Hybrid Search β Combines vector similarity + BM25 full-text search with RRF fusion
- Neural Reranking β Optional second-pass reranking with Jina Reranker for higher accuracy
- Smart Chunking β Tree-sitter AST-aware chunking that preserves functions, classes, methods
- Context Windows β Shows surrounding code (3 lines before/after) for better understanding
- Local & Private β All processing happens locally using ONNX models, no data leaves your machine
- Fast β Sub-second search after initial model load, incremental indexing
- GPU Acceleration β Optional CUDA, TensorRT, DirectML, and Ollama (recommended) support for faster indexing
- Multiple Interfaces β CLI, HTTP server, and MCP server for Claude Code integration
- Installation
- Quick Start
- Command Reference
- Global Options
- Search Modes
- MCP Server (Claude Code & OpenCode)
- HTTP Server API
- Database Management
- Supported Languages
- Embedding Models
- GPU Acceleration
- Ollama Backend
- Configuration
- How It Works
- Troubleshooting
sudo apt-get update
sudo apt-get install -y build-essential protobuf-compiler libssl-dev pkg-configsudo dnf install -y gcc protobuf-compiler openssl-devel pkg-configbrew install protobuf openssl pkg-config# Using winget
winget install -e --id Google.Protobuf
# Or using chocolatey
choco install protoc# Clone the repository
git clone https://github.com/yxanul/demongrep.git
cd demongrep
# Build release binary
cargo build --release
# The binary is at target/release/demongrep
# Optionally, copy to your PATH:
sudo cp target/release/demongrep /usr/local/bin/demongrep --version
demongrep doctor # Check system health# 1. Navigate to your project
cd /path/to/your/project
# 2. Index the codebase (first time only, ~30-60s for medium projects)
demongrep index
# 3. Search with natural language
demongrep search "where do we handle authentication?"
# 4. Search with better accuracy (slower)
demongrep search "error handling" --rerankSearch the codebase using natural language queries.
demongrep search <QUERY> [OPTIONS]| Argument | Description |
|---|---|
<QUERY> |
Natural language search query (e.g., "where do we handle authentication?") |
| Option | Short | Default | Description |
|---|---|---|---|
--max-results |
-m |
25 | Maximum total results to return |
--per-file |
1 | Maximum matches to show per file | |
--content |
-c |
Show full chunk content instead of snippets | |
--scores |
Show relevance scores and timing information | ||
--compact |
Show file paths only (like grep -l) |
||
--sync |
-s |
Re-index changed files before searching | |
--json |
Output results as JSON (for scripting/agents) | ||
--path |
. |
Path to search in | |
--filter-path |
Only show results from files under this path (e.g., src/) |
||
--vector-only |
Disable hybrid search, use vector similarity only | ||
--rerank |
Enable neural reranking for better accuracy (~1.7s extra) | ||
--rerank-top |
50 | Number of candidates to rerank | |
--rrf-k |
20 | RRF fusion parameter (higher = more weight to rank position) |
# Basic search
demongrep search "database connection pooling"
# Show full code content with context
demongrep search "error handling" --content
# Get JSON output for scripting
demongrep search "authentication" --json -m 10
# Search only in src/api directory
demongrep search "validation" --filter-path src/api
# High-accuracy search with reranking
demongrep search "complex algorithm" --rerank
# Quick search with scores
demongrep search "config loading" --scores
# Re-index changed files, then search
demongrep search "new feature" --sync
# File paths only
demongrep search "tests" --compactIndex a codebase for semantic search.
demongrep index [PATH] [OPTIONS]| Argument | Description |
|---|---|
[PATH] |
Path to index (defaults to current directory) |
| Option | Short | Description |
|---|---|---|
--dry-run |
Preview what would be indexed without indexing | |
--global |
-g |
Index to global database in home directory |
--provider |
Execution provider: cpu, auto, cuda, tensorrt, coreml, directml |
|
--device-id |
GPU device ID for CUDA/TensorRT (default: 0) | |
--batch-size |
Override batch size for embedding |
# Index current directory
demongrep index
# Index a specific project
demongrep index /path/to/project
# Preview files to be indexed
demongrep index --dry-run
# Force complete re-index (delete and rebuild)
demongrep index --force
# Index with a specific model
demongrep index --model jina-code
# Index using GPU acceleration (CUDA)
demongrep index --provider cuda
# Index using specific GPU device
demongrep index --provider cuda --device-id 1- All text files respecting
.gitignore - Custom ignore patterns from
.demongrepignoreor.osgrepignore - Skips binary files,
node_modules/,.git/, etc.
The index is stored in .demongrep.db/ directory inside your project root.
Run an HTTP server with live file watching for continuous indexing.
demongrep serve [PATH] [OPTIONS]| Option | Short | Default | Description |
|---|---|---|---|
--port |
-p |
4444 | Port to listen on |
# Start server on default port (4444)
demongrep serve
# Start server on custom port
demongrep serve --port 3333
# Serve a specific project
demongrep serve /path/to/project --port 8080The server automatically re-indexes files when they change (with 300ms debouncing).
Start an MCP (Model Context Protocol) server for Claude Code integration.
demongrep mcp [PATH]| Argument | Description |
|---|---|
[PATH] |
Path to project (defaults to current directory) |
See MCP Server section for detailed setup.
Show statistics about the indexed database.
demongrep stats [PATH]π Database Statistics
============================================================
πΎ Database: /path/to/project/.demongrep.db
Vector Store:
Total chunks: 731
Total files: 45
Indexed: β
Yes
Dimensions: 384
Storage:
Database size: 12.34 MB
Avg per chunk: 17.28 KB
Delete the index database.
demongrep clear [PATH] [OPTIONS]| Option | Short | Description |
|---|---|---|
--yes |
-y |
Skip confirmation prompt |
# Clear with confirmation
demongrep clear
# Clear without confirmation (for scripts)
demongrep clear -y
# Clear a specific project's index
demongrep clear /path/to/project -yList all indexed repositories (searches for .demongrep.db directories).
demongrep listCheck installation health and system requirements.
demongrep doctorPre-download embedding models.
demongrep setup [OPTIONS]| Option | Description |
|---|---|
--model |
Specific model to download (defaults to default model) |
These options work with all commands:
| Option | Short | Description |
|---|---|---|
--verbose |
-v |
Enable verbose/debug output |
--quiet |
-q |
Suppress informational output (only results/errors) |
--model |
Override embedding model | |
--store |
Override store name | |
--help |
-h |
Show help |
--version |
-V |
Show version |
demongrep supports three search modes with different accuracy/speed tradeoffs:
Combines vector similarity with BM25 full-text search using Reciprocal Rank Fusion (RRF).
demongrep search "query"- Speed: ~75ms
- Best for: Most queries, balances semantic understanding with keyword matching
Pure semantic similarity search using embeddings.
demongrep search "query" --vector-only- Speed: ~72ms
- Best for: Conceptual queries where exact keywords don't matter
Two-stage search: hybrid retrieval followed by cross-encoder reranking.
demongrep search "query" --rerank- Speed: ~1.8s (adds ~1.7s for reranking)
- Best for: When accuracy matters more than speed
demongrep can act as an MCP server, allowing AI coding assistants to search your codebase semantically.
-
Build demongrep and note the binary path:
cargo build --release # Binary at: /path/to/demongrep/target/release/demongrep -
Index your project:
cd /path/to/your/project demongrep index -
Configure Claude Code
Edit
~/.config/claude-code/config.json(Linux/Mac) or the appropriate config location:{ "mcpServers": { "demongrep": { "command": "/absolute/path/to/demongrep", "args": ["mcp", "/absolute/path/to/your/project"] } } } -
Restart Claude Code
| Tool | Parameters | Description |
|---|---|---|
semantic_search |
query, limit |
Search code semantically |
get_file_chunks |
path |
Get all indexed chunks from a file |
index_status |
Check if index exists and get stats |
Once configured, Claude Code can use commands like:
- "Search for authentication handling"
- "Find all chunks in src/auth.rs"
- "Check if the index is ready"
demongrep also works with OpenCode as an MCP server.
-
Index your project:
cd /path/to/your/project demongrep index -
Configure OpenCode
Edit
~/.config/opencode/opencode.json:{ "$schema": "https://opencode.ai/config.json", "mcp": { "demongrep": { "type": "local", "command": ["/absolute/path/to/demongrep", "mcp"], "enabled": true, "timeout": 30000 } } }Without a path argument, demongrep uses the current working directory, which is typically what you want for per-project search.
-
Start OpenCode in an indexed project directory
The following tools will be available:
demongrep/semantic_search- Natural language code searchdemongrep/get_file_chunks- Get indexed chunks from a filedemongrep/index_status- Check index statistics
For project-specific config, create opencode.json in your project root:
{
"mcp": {
"demongrep": {
"type": "local",
"command": ["/absolute/path/to/demongrep", "mcp", "."],
"enabled": true
}
}
}| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check (returns {"status": "ok"}) |
| GET | /status |
Index statistics |
| POST | /search |
Search the codebase |
Request:
curl -X POST http://localhost:4444/search \
-H "Content-Type: application/json" \
-d '{
"query": "authentication",
"limit": 10
}'Response:
{
"results": [
{
"path": "src/auth/handler.rs",
"start_line": 45,
"end_line": 67,
"kind": "Function",
"content": "pub fn authenticate(...) { ... }",
"score": 0.89,
"signature": "fn authenticate(credentials: &Credentials) -> Result<User>"
}
],
"query": "authentication",
"total_results": 1
}Each project has its own index at <project_root>/.demongrep.db/
# Incremental update (only changed files)
demongrep search "query" --sync
# Or explicitly re-index
demongrep index
# Full rebuild (delete and recreate)
demongrep index --force# Interactive
demongrep clear
# Non-interactive
demongrep clear -y
# Or manually
rm -rf .demongrep.db/demongrep statsThese languages have full AST-aware chunking that extracts functions, classes, methods, etc.:
| Language | Extensions |
|---|---|
| Rust | .rs |
| Python | .py, .pyw, .pyi |
| JavaScript | .js, .mjs, .cjs |
| TypeScript | .ts, .mts, .cts, .tsx, .jsx |
These languages are indexed with fallback line-based chunking:
| Language | Extensions |
|---|---|
| Go | .go |
| Java | .java |
| C | .c, .h |
| C++ | .cpp, .cc, .cxx, .hpp |
| C# | .cs |
| Ruby | .rb, .rake |
| PHP | .php |
| Swift | .swift |
| Kotlin | .kt, .kts |
| Shell | .sh, .bash, .zsh |
| Markdown | .md, .markdown, .txt |
| JSON | .json |
| YAML | .yaml, .yml |
| TOML | .toml |
| SQL | .sql |
| HTML | .html, .htm |
| CSS | .css, .scss, .sass, .less |
Models marked with β in both columns can be used interchangeably between FastEmbed and Ollama backends.
| Name | FastEmbed ID | Ollama ID | Dims | Notes |
|---|---|---|---|---|
| All-MiniLM-L6 | minilm-l6-q |
all-minilm |
384 | Default - Fast, works on both backends |
| MiniLM-L6 | minilm-l6 |
all-minilm |
384 | Non-quantized version |
| MiniLM-L12 | minilm-l12-q |
β | 384 | Higher quality, FastEmbed only |
| BGE Small | bge-small-q |
β | 384 | FastEmbed only |
| Nomic Embed | nomic-v1.5 |
nomic-embed-text |
768 | Works on both, good quality |
| BGE Base | bge-base |
β | 768 | FastEmbed only |
| Jina Code | jina-code |
β | 768 | Code-optimized, FastEmbed only |
| MxBai Large | mxbai-large |
mxbai-embed-large |
1024 | Works on both, highest quality |
| BGE Large | bge-large |
bge-large |
1024 | Works on both |
| BGE-M3 | β | bge-m3 |
1024 | Ollama only, multilingual |
| E5 Multilingual | e5-multilingual |
β | 384 | FastEmbed only, multilingual |
Recommended models (work on both backends):
all-minilm/minilm-l6-q(384d) β Default, fastest, good for most codebasesnomic-embed-text/nomic-v1.5(768d) β Better quality, long contextmxbai-embed-large/mxbai-large(1024d) β Highest quality, slower
# FastEmbed backend
demongrep index --model minilm-l6-q
# Ollama backend
demongrep index --backend ollama --ollama-model all-minilm
# Search must use same model/backend as index
demongrep search "query"Note: The model used for indexing is saved in metadata. If you search with a different model, you may get poor results. Use --force to re-index with a new model.
demongrep supports GPU acceleration for faster embedding generation during indexing.
| Provider | Platform | Flag | Build Feature | Recommended |
|---|---|---|---|---|
| Ollama | All (with Ollama installed) | --backend ollama |
--features ollama |
β Best option |
| CPU | All (Linux, macOS, Windows*) | --provider cpu |
(default) | β Good fallback |
| CUDA | Linux/Windows* + NVIDIA GPU | --provider cuda |
--features gpu-nvidia |
|
| TensorRT | Linux/Windows* + NVIDIA GPU | --provider tensorrt |
--features tensorrt |
|
| CoreML | macOS (Intel & Apple Silicon) | --provider coreml |
--features gpu-apple |
β Not recommended |
| DirectML | Windows* (DirectX 12 GPU) | --provider directml |
--features gpu-windows |
β Untested |
*Windows support has not been tested.
| Platform | Build Command | Notes |
|---|---|---|
| All platforms (recommended) | cargo build --release --features ollama |
Use Ollama for GPU |
| macOS | cargo build --release --features gpu-apple |
Includes Ollama (CoreML not recommended) |
| Linux (NVIDIA GPU) | cargo build --release --features "gpu-nvidia,ollama" |
Ollama + CUDA fallback |
| CPU only (all platforms) | cargo build --release |
Basic, no GPU |
| Windows (DirectX 12)* | cargo build --release --features gpu-windows |
Untested |
*Windows support has not been tested.
Recommendation: Build with --features ollama and install Ollama for the best GPU acceleration on all platforms.
Basic CPU build (all platforms):
cargo build --releaseThis works on Linux, macOS (Intel & Apple Silicon), and Windows. No GPU features needed.
macOS (Intel & Apple Silicon):
# Recommended: Ollama support (uses Metal GPU via Ollama)
cargo build --release --features ollama
# Alternative: includes Ollama + CoreML (CoreML not recommended)
cargo build --release --features gpu-appleNote: On macOS, always use Ollama for GPU acceleration. CoreML is not optimized for transformers and is often slower than CPU. The gpu-apple feature includes CoreML as a fallback, but Ollama with Metal is ~10x faster.
Linux/Windows with NVIDIA GPU:
# CUDA support (requires NVIDIA drivers)
cargo build --release --features gpu-nvidia
# TensorRT support (requires TensorRT SDK installed)
cargo build --release --features tensorrtWindows with DirectX 12 GPU (untested):
cargo build --release --features gpu-windows# Auto-detect best available provider
demongrep index --provider auto
# Use CUDA explicitly
demongrep index --provider cuda
# Use specific GPU device
demongrep index --provider cuda --device-id 1
# Check available providers
demongrep doctordemongrep uses intelligent adaptive batching to maximize throughput:
- Chunks sorted by length β Similar-sized chunks are batched together to minimize padding waste
- Dynamic batch sizes β Short chunks get large batches, long chunks get small batches
- Token budget β Batches are sized to stay within optimal memory limits (10K tokens default)
This results in ~30% faster indexing compared to fixed batch sizes.
- All platforms: Install Ollama and build with
--features ollamaβ ~10x faster than other options - macOS: Use Ollama, NOT CoreML β CoreML is optimized for CNNs, not transformers, and is often slower than CPU
- NVIDIA GPUs: Ollama is still faster than CUDA/TensorRT for embeddings; use
--provider cudaonly as fallback - Check GPU memory: Use
nvidia-smi(NVIDIA) or Activity Monitor (macOS) β model uses ~500MB - Tune token budget: Set
DEMONGREP_TOKEN_BUDGETenvironment variable if needed
demongrep supports Ollama as an alternative embedding backend. This is the recommended approach for GPU acceleration as it provides significantly better performance than ONNX Runtime.
| Backend | nomic-embed-text (768d) | Notes |
|---|---|---|
| FastEmbed CPU | 5.6 chunks/sec | Slow for large models |
| FastEmbed CUDA | 6.8 chunks/sec | Minimal GPU benefit |
| Ollama CPU | 2.4 chunks/sec | Model stays warm |
| Ollama GPU | 52.2 chunks/sec | ~10x faster than FastEmbed |
With the same model, Ollama with GPU is ~10x faster for indexing and ~3x faster for search.
Why not CoreML? Apple's CoreML is optimized for CNNs (image models), not transformer-based embedding models. Many transformer operations fall back to CPU, and data transfer overhead can make it slower than pure CPU. Ollama uses Metal directly with hand-optimized shaders for transformers, which is why it's much faster on Mac.
macOS/Linux:
curl -fsSL https://ollama.ai/install.sh | shOr with Docker (recommended for servers):
# With GPU support (NVIDIA)
docker run -d --gpus all --name ollama -p 11434:11434 ollama/ollama
# CPU only
docker run -d --name ollama -p 11434:11434 ollama/ollama# Default: Jina Code (best for code search, 8k context, cross-compatible with FastEmbed)
ollama pull unclemusclez/jina-embeddings-v2-base-code
# Alternatives:
ollama pull nomic-embed-text # 768 dims, 2k context, general purpose
ollama pull all-minilm # 384 dims, fastest but short context (256 tokens)
ollama pull mxbai-embed-large # 1024 dims, highest quality# macOS (gpu-apple already includes ollama)
cargo build --release --features gpu-apple
# Linux/Windows
cargo build --release --features ollamaOllama is auto-detected! When built with --features ollama and Ollama is running, demongrep automatically uses it:
# Auto-detects Ollama if running
demongrep index
# Output:
# π‘ Auto-detected Ollama at http://localhost:11434 - using Ollama backend
# (Use --backend fastembed to override)You can also be explicit:
# Explicitly use Ollama backend
demongrep index --backend ollama
# Force FastEmbed even if Ollama is running
demongrep index --backend fastembed
# Use a different Ollama model
demongrep index --ollama-model mxbai-embed-largeModels are downloaded automatically! When you specify a model, demongrep will pull it from Ollama if not already installed.
| Model | Dims | Context | FastEmbed Equivalent | Notes |
|---|---|---|---|---|
unclemusclez/jina-embeddings-v2-base-code |
768 | 8192 tok | jina-code |
Default - trained on code, long context |
nomic-embed-text |
768 | 2048 tok | nomic-v1.5 |
Good general purpose |
all-minilm |
384 | 256 tok | minilm-l6-q |
Fastest, but very short context |
mxbai-embed-large |
1024 | 512 tok | mxbai-large |
Highest quality |
bge-large |
1024 | 512 tok | bge-large |
High quality |
bge-m3 |
1024 | 8192 tok | β | Ollama only, multilingual |
snowflake-arctic-embed |
1024 | 512 tok | β | Ollama only |
Context Length Handling:
- Context length is automatically queried from Ollama at startup
- Text exceeding the context is automatically truncated with retry logic
- First attempt uses optimistic estimate (3 chars/token), retries with conservative (1.5 chars/token)
Recommended: Use the default jina-embeddings-v2-base-code for best code search quality with 8k context.
Using a model:
# Just specify it - demongrep will auto-pull if needed
demongrep index --ollama-model all-minilm
# Or manually pull first
ollama pull all-minilm
# Set default in config (~/.demongrep/config.toml)
[embedding.ollama]
model = "all-minilm"Check available models:
# List models installed in Ollama
ollama list
# Check demongrep configuration
demongrep doctorAdd to ~/.demongrep/config.toml:
[embedding]
backend = "ollama" # Use Ollama by default
[embedding.ollama]
url = "http://localhost:11434" # Ollama server URL
model = "all-minilm" # Embedding model (384d, cross-compatible)
timeout = 30 # Request timeout (seconds)
parallelism = 8 # Parallel HTTP requestsBenchmarked on RTX A2000 8GB with 1394 code chunks:
| Metric | FastEmbed (CPU) | Ollama (GPU) | Speedup |
|---|---|---|---|
| Indexing | 5.6 c/s | 52.2 c/s | 9.3x |
| Search | 1.27s | 0.43s | 3.0x |
| Index 1394 chunks | 264s | 27s | 9.8x |
"Cannot connect to Ollama"
# Check Ollama is running
curl http://localhost:11434/api/tags
# Start Ollama
ollama serve
# or
docker start ollama"Model not found"
# Pull the model first
ollama pull nomic-embed-textDimension mismatch error
# Re-index with --force when switching backends/models
demongrep index --backend ollama --force| Variable | Description | Default |
|---|---|---|
DEMONGREP_TOKEN_BUDGET |
Token budget for adaptive batching | 10000 |
DEMONGREP_BATCH_SIZE |
Override batch size (legacy) | Auto |
RUST_LOG |
Logging level | demongrep=info |
Create .demongrepignore in your project root:
# Ignore test fixtures
**/fixtures/**
**/testdata/**
# Ignore generated code
**/generated/**
*.generated.ts
# Ignore large files
*.min.js
*.bundle.jsdemongrep also respects .gitignore and .osgrepignore files.
- Walks directory respecting
.gitignoreand custom ignore files - Detects language from file extensions
- Skips binary files automatically
- Parses code with tree-sitter (native Rust implementation)
- Extracts semantic units: functions, classes, methods, structs, traits, impls
- Preserves metadata: signatures, docstrings, context breadcrumbs
- Falls back to line-based chunking for unsupported languages
- Uses fastembed with ONNX Runtime
- GPU acceleration via CUDA, TensorRT, CoreML, or DirectML
- Adaptive token-budget batching: sorts chunks by length, dynamically sizes batches
- SHA-256 content hashing for incremental change detection
- arroy for approximate nearest neighbor search
- LMDB for ACID transactions and persistence
- Single
.demongrep.db/directory per project
- Query embedding β Vector search β BM25 search β RRF fusion β (Optional) Reranking
# Index the project first
demongrep index-
Check if index is stale:
demongrep search "query" --sync -
Try different search mode:
demongrep search "query" --rerank -
Rebuild index:
demongrep index --force
If you indexed with one model and search with another:
# Re-index with the model you want to use
demongrep index --force --model minilm-l6-q# Reduce token budget
DEMONGREP_TOKEN_BUDGET=5000 demongrep index
# Or use legacy batch size override
DEMONGREP_BATCH_SIZE=32 demongrep index# Check GPU status
demongrep doctor
# Verify CUDA is available
nvidia-smi
# Fall back to CPU
demongrep index --provider cpu# Use a different port
demongrep serve --port 5555# Debug build
cargo build
# Release build
cargo build --release
# Run tests
cargo test
# Format code
cargo fmt
# Lint
cargo clippyRUST_LOG=demongrep=debug demongrep search "query"
RUST_LOG=demongrep::embed=trace demongrep indexApache-2.0 - See NOTICE for attribution.
Contributions welcome! See TODO.md for planned features.