The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the MCP Local Rag listing page.
🍴 Forked from shinpr/mcp-local-rag — original work by Shinsuke Kagawa
Local code intelligence engine for AI coding assistants. AST-level semantic chunking + keyword boost for pinpointing functions, classes, and APIs — fully private, zero setup.
📖 中文文档
useEffect, error codes, class names rank higher — not just semantically guessed.find_definition and find_references for IDE-level code navigation, powered by tree-sitter metadata captured at ingest time.huggingface.co → hf-mirror.com → modelscope.cn, zero config for users in mainland China.npx command. No Docker, Python, or servers to manage.Set BASE_DIR to the folder you want to search (BASE_DIRS for multiple roots — see Configuration).
Cursor — ~/.cursor/mcp.json:
Claude Code:
Codex — ~/.codex/config.toml:
WorkBuddy — Settings → Custom Connectors → Add:
⚠️ WorkBuddy: you MUST click "Trust" in the Custom Connectors list after adding, otherwise the server is silently blocked.
No MCP needed — run directly from the terminal:
That's it. No Docker, Python, or server setup.
Chunking strategy is chosen per file type:
CodeChunker parses source via tree-sitter AST, splits at structural boundaries (functions, classes, methods). Each chunk's contextualizedText includes its scope chain and import context for precise semantic search.SemanticChunker splits into sentences, groups by embedding similarity to find natural topic boundaries. Markdown code blocks remain intact — never split mid-block.Search = semantic similarity + keyword boost (RAG_HYBRID_WEIGHT, default 0.6):
Exact identifiers like useEffect are never buried by semantic approximations.
Only files under BASE_DIR / BASE_DIRS are accessible for ingest, list, delete, or read-neighbor operations. Symlinks resolved outside roots are rejected. Sibling-prefix paths (e.g., /foo/barista when root is /foo/bar) are also blocked — prevents path traversal attacks.
15 tools organized into 5 categories.
| # | Tool | Purpose | Example |
|---|---|---|---|
| 1 | ingest_file | Single file (PDF/DOCX/TXT/MD/code) | "Ingest ./docs/api-spec.pdf" |
| 2 | ingest_data | In-memory text/HTML | "Fetch this page and ingest the HTML" |
| 3 | ingest_directory | Bulk directory ingest | "Ingest everything under ./src" |
ingest_file supports 50+ code languages. PDFs support an optional visual mode — a local VLM generates captions for figure pages, making visual content searchable. Two profiles available:
| Profile | Model | Cache | Suited for |
|---|---|---|---|
fast (default) | SmolVLM-256M | ~250 MB | Light visual indexing |
quality | Qwen2.5-VL-3B-ONNX | ~2.9 GB | Figures with in-image text |
ingest_data runs Readability → Markdown → index. Perfect for web content fetched by your AI assistant. Re-ingesting replaces old versions automatically.
ingest_directory scans recursively, respects .gitignore, shows real-time progress via MCP notifications.
| # | Tool | Purpose | Key Parameters |
|---|---|---|---|
| 4 | query_documents | Hybrid search (semantic + keyword) | query, limit, scope, highlightContext, fromTimestamp |
| 5 | read_chunk_neighbors | Expand context around results | filePath, chunkIndex, before, after |
query_documents — scope accepts a single path prefix or list, restricting results to that subtree. highlightContext returns snippets around matched terms. fromTimestamp / untilTimestamp enable time-range filtering.
read_chunk_neighbors — defaults to 2 chunks before and after (like grep -C 2), max 50 each. Response includes the target chunk marked isTarget: true.
| # | Tool | Purpose |
|---|---|---|
| 6 | list_files | List files with ingestion status (ingested: true/false) |
| 7 | delete_file | Delete by file path or source URL |
| 8 | status | Index stats: docs, chunks, memory, search mode |
list_files supports scope filtering with the same prefix-match semantics as search. In large directories, scope accelerates the scan by skipping out-of-scope subtrees.
| # | Tool | Purpose | Input |
|---|---|---|---|
| 9 | find_definition | Locate symbol definition (file, line range, scope) | Exact symbol name |
| 10 | find_references | Find all references (import + text mention) | Symbol name |
Both tools depend on AST metadata (imports, entities, scope chains) extracted by tree-sitter at ingest time. Only works for code files ingested with CodeChunker — files ingested before v0.18.7 lack this metadata and require reindex_all to rebuild.
find_references uses a two-phase strategy: (1) exact match in codeMeta.imports → (2) FTS full-text search for the symbol name. Results are deduplicated by (filePath, chunkIndex), with import references listed first.
| # | Tool | Purpose |
|---|---|---|
| 11 | config | Runtime hot read/write config — no restart needed |
| 12 | dedup_check | SHA256 + Jaccard similarity to detect duplicate files |
| 13 | export_index | Export entire index as JSON (backup or migration) |
| 14 | reindex_all | Full re-chunk + re-embed (after model change) |
| 15 | reindex_stale | Re-ingest only files modified on disk (incremental sync) |
config hot-swaps hybridWeight, modelName, cacheDir, baseDir/baseDirs, etc. Switching models auto-disposes the old Embedder and initializes the new one — note: changing models alters the embedding space and requires reindex_all.
dedup_check is especially useful in monorepos — spot ↔ futures mirror code is typically flagged with similarity 1.0.
query, read-neighbors, list, status, delete emit JSON to stdout (pipe to jq). ingest emits progress to stderr.
Global options (--db-path, --cache-dir, --model-name) go before the subcommand:
⚠️ The CLI does NOT read your MCP client config (
mcp.json, etc.). Configure via flags or environment variables.
Flags — global options before, subcommand options after:
--base-dir is repeatable on ingest and list:
Environment variables:
For multiple roots, use BASE_DIRS (JSON array):
Precedence: CLI flags > environment variables > defaults.
huggingface.co is inaccessible from mainland China. Built-in three-tier mirror chain with automatic fallback:
At startup, each mirror is HEAD-probed (3s timeout). The first reachable mirror with a complete API is selected:
HTTPS_PROXY) → direct to huggingface.coNo manual HF_ENDPOINT required. For manual control:
| Env Var | Effect |
|---|---|
HF_AUTO_MIRROR=false | Disable auto-detection, use huggingface.co only |
HF_ENDPOINT=<url> | Force a specific mirror, skip auto-detection |
v0.18.5+ uses
setGlobalDispatcher(ProxyAgent)— all Node.js 22 network requests go through the proxy.
6 embedding models with alias resolution via model-registry:
| Model | Alias | Size | Dims |
|---|---|---|---|
Xenova/all-MiniLM-L6-v2 (default) | mini | ~90 MB | 384 |
Xenova/all-MiniLM-L12-v2 | — | ~120 MB | 384 |
Xenova/bge-small-en-v1.5 | bge-small | ~130 MB | 384 |
Xenova/all-mpnet-base-v2 | mpnet | ~420 MB | 768 |
Xenova/bge-base-en-v1.5 | — | ~420 MB | 768 |
Xenova/multi-qa-mpnet-base-dot-v1 | multi-qa | ~420 MB | 768 |
Guidance: code repos → default model + high keyword boost; multilingual → consider embeddinggemma-300m; scientific papers → consider allenai-specter.
RAG_DTYPE controls ONNX precision (fp32 / fp16 / q8). Default fp32; use q8 when memory-constrained. ⚠️ Changing models or dtype requires deleting DB_PATH and re-indexing.
Set RAG_WATCH=true — the server starts recursive fs.watch on baseDirs (500ms debounce):
ingest_filedelete_fileIdeal for actively changing projects.
| Variable | Default | Description |
|---|---|---|
RAG_HYBRID_WEIGHT | 0.6 | Keyword boost: 0 = semantic only, 1 = keyword only |
RAG_GROUPING | unset | similar = top group only, related = top 2 groups |
RAG_MAX_DISTANCE | unset | Filter low-relevance results (e.g., 0.5) |
RAG_MAX_FILES | unset | Limit results to top N files |
Code-focused tuning (recommended default):
Document-focused tuning:
Keyword boost is applied after semantic filtering — improves precision without introducing noise.
Beyond search accuracy, inference performance is also configurable. All optimizations are environment variables — no code changes required.
RAG_DTYPE)Controls ONNX model inference precision. For all-MiniLM-L6-v2, three levels are available:
| Value | Model Size | Speed | Memory | Precision Loss | Best For |
|---|---|---|---|---|---|
fp32 (default) | ~90 MB | baseline | ~80 MB | none | First use, maximum accuracy |
fp16 | ~45 MB | 20-30% faster | ~45 MB | negligible | Recommended for daily use |
q8 | ~45 MB | 30-50% faster | ~45 MB | minor | Low memory, large projects |
⚠️ Changing dtype requires index rebuild — embedding spaces are incompatible.
Verify it works: After restart, call status via MCP and check the dtype field. Should match your setting (e.g., "fp16").
If it fails: Startup throws EmbeddingError with a list of supported dtypes. Common cause: the model doesn't provide the q8 variant — switch to fp16.
RAG_DEVICE)Controls which ONNX Runtime backend to use:
| Value | Backend | Notes |
|---|---|---|
cpu (default) | CPU | Most stable, no extra dependencies |
webgpu | GPU (WebGPU) | ⚠️ Experimental: M1/M2 Mac uses Metal, NVIDIA uses Vulkan |
⚠️ Changing device changes the embedding space — requires index rebuild. Stacks with RAG_DTYPE — fp16 + webgpu gives both model-size reduction and GPU speedup.
Verify it works: MCP startup log should show Loading model on device "webgpu". status should show device: "webgpu".
If it fails:
Unsupported device at startup → WebGPU unavailable in your environment, revert to "cpu""cpu"RAG_DEVICE line to fall back — other config is untouchedCHUNK_MIN_LENGTH)Filters out chunks shorter than this value during ingest. Default 50 keeps nearly everything; 200 drops 30-40% of noise fragments.
⚠️ Blunt instrument — short but important code (e.g., config constants) may also be discarded. Requires index rebuild. Sweet spot: 100-200.
| Scenario | Config |
|---|---|
| Daily development | RAG_DTYPE=fp16 |
| Large project + M1/M2 Mac | RAG_DTYPE=fp16, RAG_DEVICE=webgpu |
| Memory-constrained | RAG_DTYPE=q8 |
All changes require reindex_all (MCP) or re-running ingest (CLI). If something breaks, delete the failing env line to revert to defaults.
MCP server: environment variables only (via your MCP client's env block).
CLI: environment variables + equivalent flags (flags take precedence).
| Env Var | CLI Flag | Default | Description |
|---|---|---|---|
BASE_DIR | --base-dir (repeatable) | cwd | Document root (security boundary) |
BASE_DIRS | — | unset | JSON array of roots, overrides BASE_DIR |
DB_PATH | --db-path | ./lancedb/ | Vector database path |
CACHE_DIR | --cache-dir | ./models/ | Model cache — recommend absolute path |
MODEL_NAME | --model-name | all-MiniLM-L6-v2 | HuggingFace model ID |
MAX_FILE_SIZE | --max-file-size | 100 MB | Max file size in bytes |
CHUNK_MIN_LENGTH | --chunk-min-length | 50 | Min chunk length (1–10000 chars) |
RAG_DEVICE | — | cpu | ONNX execution device |
RAG_DTYPE | — | fp32 | Quantization (fp32/fp16/q8) |
HTTPS_PROXY | — | unset | Model download proxy. v0.18.5+ globally effective |
HF_ENDPOINT | — | huggingface.co | Manual mirror override |
HF_AUTO_MIRROR | — | true | Auto-detection toggle |
RAG_WATCH | — | unset | File watching (true/1) |
Root resolution order: CLI --base-dir > BASE_DIRS > BASE_DIR > cwd. BASE_DIRS and BASE_DIR are never merged. Only JSON array syntax supported for BASE_DIRS — delimiter syntax is intentionally rejected.
Symptoms: fetch failed, status shows searchMode: fts instead of hybrid.
Solutions:
Network restriction (mainland China, etc.) — use proxy:
Set in your MCP client config, not the terminal. v0.18.5+ globally effective via setGlobalDispatcher.
Auto-mirror fallback (v0.18.2+, default) — three-tier probe. Usually works without any config.
Manual override — HF_ENDPOINT=https://modelscope.cn or download models manually into CACHE_DIR.
npx cached old version — clear and restart:
npx @damoqiongqiu/mcp-local-rag should run without errorsAfter switching models or when the database is corrupted:
DB_PATH directory (default ./lancedb/) — safe, doesn't affect source filesRAG_DEVICE. Support depends on your system, Node.js version, and the ONNX backend.DB_PATH directory.MIT License. Free for personal and commercial use.
Built with Model Context Protocol (Anthropic), LanceDB, and Transformers.js.