| Crates.io | project-rag |
| lib.rs | project-rag |
| version | 0.1.0 |
| created_at | 2026-01-24 14:43:32.559754+00 |
| updated_at | 2026-01-24 14:43:32.559754+00 |
| description | RAG-based codebase indexing and semantic search - dual purpose library and MCP server |
| homepage | https://github.com/Brainwires/project-rag |
| repository | https://github.com/Brainwires/project-rag |
| max_upload_size | |
| id | 2066803 |
| size | 943,536 |
A Rust-based Model Context Protocol (MCP) server that provides AI assistants with powerful RAG (Retrieval-Augmented Generation) capabilities for understanding massive codebases.
This MCP server enables AI assistants to efficiently search and understand large projects by:
The server provides 9 slash commands for quick access in Claude Code:
/project:index - Index a codebase directory (automatically performs full or incremental)/project:query - Search the indexed codebase/project:stats - Get index statistics/project:clear - Clear all indexed data/project:search - Advanced search with filters/project:git-search - Search git commit history with on-demand indexing/project:definition - Find where a symbol is defined (LSP-like)/project:references - Find all references to a symbol/project:callgraph - Get call graph for a function (callers/callees)See slash-commands.md for detailed usage.
Project RAG automatically indexes and searches 40+ file types across three categories:
Supports AST-based semantic chunking for these languages:
.rs).py).js, .mjs, .cjs), TypeScript (.ts), JSX (.jsx), TSX (.tsx).go).java).c), C++ (.cpp, .cc, .cxx), C/C++ Headers (.h, .hpp).cs).swift).kt, .kts).scala).rb).php).sh, .bash).sql).html, .htm).css), SCSS (.scss, .sass)With special handling for rich content:
.md, .markdown).pdf) - Automatically converted to Markdown with table preservation.rst).adoc, .asciidoc).org).txt).log)PDF Conversion Features:
pdf-extract libraryFor complete project understanding:
.json).yaml, .yml).toml).xml).ini).conf, .config, .cfg).properties).env)# Index documentation PDFs in your project
query_codebase("API authentication flow") # Finds content in .pdf, .md, .rst files
# Search configuration files
query_codebase("database connection string") # Finds .yaml, .toml, .env, .conf files
# Find code implementations
search_by_filters(query="JWT validation", file_extensions=["rs", "go"])
The server provides 9 tools that can be used directly:
index_codebase - Smartly index a codebase directory
query_codebase - Hybrid semantic + keyword search across the indexed code
get_statistics - Get statistics about the indexed codebase
clear_index - Clear all indexed data
search_by_filters - Advanced hybrid search with filters
search_git_history - Search git commit history using semantic search
find_definition - Find where a symbol is defined (LSP-like)
find_references - Find all references to a symbol
get_call_graph - Get call graph for a function
sudo apt-get install protobuf-compiler on Ubuntu/Debian)LanceDB (Default - Embedded, Stable)
No additional setup needed! LanceDB is an embedded vector database that runs directly in the application. It stores data in ./.lancedb directory by default.
Why LanceDB is the default:
Qdrant (Optional - Server-Based)
To use Qdrant instead of LanceDB, build with the qdrant-backend feature:
cargo build --release --no-default-features --features qdrant-backend
Then start a Qdrant instance:
Using Docker (Recommended):
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd)/qdrant_data:/qdrant/storage \
qdrant/qdrant
Using Docker Compose:
version: '3.8'
services:
qdrant:
image: qdrant/qdrant
ports:
- "6333:6333"
- "6334:6334"
volumes:
- ./qdrant_data:/qdrant/storage
Or download standalone: https://qdrant.tech/documentation/guides/installation/
# Navigate to the project
cd project-rag
# Install protobuf compiler (Ubuntu/Debian)
sudo apt-get install protobuf-compiler
# Build the release binary (with default LanceDB backend - stable and embedded!)
cargo build --release
# Or build with Qdrant backend (requires external server)
cargo build --release --no-default-features --features qdrant-backend
# The binary will be at target/release/project-rag
The server communicates over stdio following the MCP protocol:
./target/release/project-rag
Add the MCP server to Claude Code using the CLI:
# Navigate to the project directory first
cd /path/to/project-rag
# Add the MCP server to Claude Code
claude mcp add project --command "$(pwd)/target/release/project-rag"
# Or with logging enabled
claude mcp add project --command "$(pwd)/target/release/project-rag" --env RUST_LOG=info
After adding, restart Claude Code to load the server. The slash commands (/project:index, /project:query, etc.) will be available immediately.
Add to your Claude Desktop config:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"project-rag": {
"command": "/absolute/path/to/project-rag/target/release/project-rag",
"env": {
"RUST_LOG": "info"
}
}
}
}
Note: Claude Code and Claude Desktop are different products with different configuration methods.
Index a codebase:
{
"path": "/path/to/your/project",
"include_patterns": ["**/*.rs", "**/*.toml"],
"exclude_patterns": ["**/target/**", "**/node_modules/**"],
"max_file_size": 1048576
}
Query the codebase:
{
"query": "How does authentication work?",
"limit": 10,
"min_score": 0.7
}
Advanced filtered search:
{
"query": "database connection pool",
"limit": 5,
"min_score": 0.75,
"file_extensions": ["rs"],
"languages": ["Rust"],
"path_patterns": ["src/db"]
}
Index (or re-index) a codebase:
{
"path": "/path/to/your/project",
"include_patterns": [],
"exclude_patterns": []
}
Note: This automatically performs a full index for new codebases or an incremental update for previously indexed ones.
Find definition of a symbol:
{
"file_path": "/path/to/your/project/src/main.rs",
"line": 42,
"column": 10
}
Find all references to a symbol:
{
"file_path": "/path/to/your/project/src/lib.rs",
"line": 15,
"column": 8,
"include_definition": false
}
Get call graph for a function:
{
"file_path": "/path/to/your/project/src/api.rs",
"line": 100,
"column": 4,
"depth": 2
}
project-rag/
├── src/
│ ├── bm25_search.rs # Tantivy BM25 keyword search with RRF fusion
│ ├── client/ # High-level client API
│ │ ├── mod.rs # RagClient - unified interface for all operations
│ │ └── indexing/ # Indexing pipeline with progress reporting
│ ├── embedding/ # FastEmbed integration for local embeddings
│ │ ├── mod.rs # EmbeddingProvider trait
│ │ └── fastembed_manager.rs # all-MiniLM-L6-v2 implementation
│ ├── vector_db/ # Vector database implementations
│ │ ├── mod.rs # VectorDatabase trait
│ │ ├── lance_client.rs # LanceDB + Tantivy hybrid search (default)
│ │ └── qdrant_client.rs # Qdrant implementation (optional)
│ ├── indexer/ # File walking and code chunking
│ │ ├── mod.rs # Module exports
│ │ ├── file_walker.rs # Directory traversal with .gitignore + 40+ file types
│ │ ├── chunker.rs # Chunking strategies (AST-based, fixed-lines, sliding window)
│ │ ├── ast_parser.rs # Tree-sitter AST parsing for 12 languages
│ │ └── pdf_extractor.rs # PDF to Markdown converter with table support
│ ├── relations/ # Code relationship analysis (LSP-like features)
│ │ ├── mod.rs # RelationsProvider trait, HybridRelationsProvider
│ │ ├── types.rs # SymbolId, Definition, Reference, CallEdge types
│ │ ├── repomap/ # AST-based symbol extraction (fallback provider)
│ │ │ ├── mod.rs # RepoMapProvider
│ │ │ ├── symbol_extractor.rs # Extract definitions from AST
│ │ │ └── reference_finder.rs # Find references via identifier matching
│ │ ├── storage/ # Relations storage layer
│ │ │ ├── mod.rs # RelationsStore trait
│ │ │ └── lance_store.rs # LanceDB storage (placeholder)
│ │ └── stack_graphs/ # Optional: High-precision name resolution
│ │ └── mod.rs # StackGraphsProvider (feature-gated)
│ ├── mcp_server.rs # MCP server with 9 tools
│ ├── types/ # Request/Response types with JSON schema
│ │ └── mod.rs # All MCP request/response types
│ ├── main.rs # Binary entry point with stdio transport
│ └── lib.rs # Library root
├── Cargo.toml # Rust 2024 edition with dependencies
├── README.md # This file
├── CONTRIBUTING.md # Contributor guidelines
├── TESTING.md # Testing guide
└── CLAUDE.md # AI assistant instructions
RUST_LOG - Set logging level (options: error, warn, info, debug, trace)
RUST_LOG=debug cargo runhttp://localhost:6334all-MiniLM-L6-v2 (384 dimensions)Both query_codebase and search_by_filters tools implement intelligent adaptive threshold lowering:
How it works:
min_score threshold (default: 0.7)threshold_used and threshold_lowered fields for transparencyBenefits:
Example Response:
{
"results": [...],
"duration_ms": 45,
"threshold_used": 0.4,
"threshold_lowered": true
}
Project RAG provides code navigation capabilities similar to a Language Server Protocol (LSP) implementation, but optimized for semantic search use cases:
Find Definition (find_definition):
Find References (find_references):
Get Call Graph (get_call_graph):
Architecture:
RelationsProvider (trait)
├── StackGraphsProvider (high precision: ~95%)
│ └── Supports: Python, TypeScript, Java, Ruby
└── RepoMapProvider (fallback: ~70% precision)
└── Supports: All tree-sitter languages (12+)
When to Use:
Project RAG uses a two-layer locking system to prevent multiple processes from indexing the same codebase simultaneously:
Layer 1: Filesystem Locks (Cross-Process)
flock() system call for OS-level exclusive locks~/.local/share/project-rag/locks/ (or brainwires/locks/)Layer 2: In-Memory Locks (In-Process)
How It Works:
Process A (Claude Session 1) Process B (Claude Session 2)
───────────────────────────── ─────────────────────────────
index_codebase("/project") index_codebase("/project")
│ │
▼ ▼
Acquire filesystem lock Try filesystem lock
│ │
▼ ▼
ACQUIRED BLOCKED (waits)
│ │
▼ │
Do full indexing... │
│ │
▼ │
Release lock ──────────────────────────────────►│
▼
Lock acquired
│
▼
Return (index is current)
Benefits:
The BM25 (Tantivy) index uses additional file-based locks to prevent concurrent writes:
Stale Lock Detection:
Automatic Recovery:
Error Messages:
"BM25 index is currently being used by another process. Please wait and try again later."Thread Safety:
Best Practices:
ignore crate# Run all unit tests (413 tests with ~94% coverage)
cargo test --lib
# Run specific module tests
cargo test --lib types::tests
cargo test --lib chunker::tests
cargo test --lib pdf_extractor::tests # PDF to Markdown conversion tests
cargo test --lib bm25_search::tests # Includes concurrent access & lock safety tests
cargo test --lib config::tests # Includes validation & env override tests
cargo test --lib indexing::tests # Includes error path & edge case tests
# Run with output
cargo test --lib -- --nocapture
# Run with code coverage
cargo llvm-cov --lib --html
# Open target/llvm-cov/html/index.html to view coverage report
# Debug build
cargo build
# Release build (optimized)
cargo build --release
# Check without building
cargo check
# Format code
cargo fmt
# Lint with clippy
cargo clippy
# Fix clippy warnings
cargo clippy --fix
# Run with debug logging
RUST_LOG=debug cargo run
# Run with trace logging
RUST_LOG=trace cargo run
Indexing Speed: ~1000 files/minute
Search Latency: 20-30ms per query
Memory Usage:
Storage:
Qdrant API Changes
FastEmbed Mutability
Async Trait Warnings
async fn in public traitsQdrant Backend: Requires external Qdrant server when using qdrant-backend feature
Model Download: First run downloads ~50MB model
Path Filtering: Currently post-query filtering (not optimized)
No Configuration File: All settings hardcoded
Large Codebases: Projects with 100k+ files may take significant time to index
Memory: Very large indexes (1M+ chunks) may require significant RAM
Error: "BM25 index is currently being used by another process"
This means another agent or process is actively indexing. This is expected behavior to prevent index corruption.
Solutions:
rm ~/.local/share/project-rag/lancedb/lancedb_bm25/.tantivy-*.lock
Note: The system automatically detects and cleans up stale locks (>5 minutes old) from crashed processes. You should rarely need manual intervention.
# Check if Qdrant is running
curl http://localhost:6334/health
# View Qdrant logs
docker logs <container-id>
# Pre-download model
python -c "from fastembed import TextEmbedding; TextEmbedding()"
# Or set HuggingFace mirror
export HF_ENDPOINT=https://hf-mirror.com
# Reduce batch size (edit source)
# Or index in smaller chunks
# Or use smaller embedding model
# Check disk I/O
# Reduce max_file_size
# Use exclude_patterns to skip unnecessary files
MIT License - see LICENSE file for details
Contributions welcome! Please ensure:
Code Quality:
cargo fmtcargo clippy)Testing:
cargo test)Commits:
Built with ❤️ using Rust 2024 Edition