mcp-local-rag

mcp-local-rag

A fully local RAG MCP server for semantic code search and code intelligence, using AST-level chunking and hybrid search to pinpoint functions, classes, and APIs. No cloud, no API keys, zero setup.

Category
访问服务器

README

<p align="center"> <img src="assets/banner.jpg" alt="MCP Local RAG — Search below the surface." width="600" /> </p>

MCP Local RAG

GitHub stars npm version License: MIT TypeScript MCP Registry

🍴 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.

📖 中文文档


Table of Contents

  1. Features
  2. Quick Start
  3. Core Concepts
  4. MCP Tool Reference
  5. CLI
  6. Network & Models
  7. Search Tuning
  8. Performance Tuning
  9. Configuration Reference
  10. Troubleshooting
  11. Development

1. Features

  • Smart dual-strategy chunking — AST-level code chunking via tree-sitter (splits at function/class/method boundaries, injects scope chain + imports). Semantic chunking for documents (splits by meaning, not character count).
  • Semantic search + keyword boost — Vector search first, then keyword matching boosts exact terms. useEffect, error codes, class names rank higher — not just semantically guessed.
  • 15 MCP tools — Ingest, search, manage, code intelligence, and system ops in one server.
  • AST code intelligencefind_definition and find_references for IDE-level code navigation, powered by tree-sitter metadata captured at ingest time.
  • Three-tier mirror auto-fallbackhuggingface.co → hf-mirror.com → modelscope.cn, zero config for users in mainland China.
  • Runs entirely locally — No API keys, no cloud, no data leaving your machine. Works offline after the first model download.
  • Zero-friction setup — One npx command. No Docker, Python, or servers to manage.

2. Quick Start

Set BASE_DIR to the folder you want to search (BASE_DIRS for multiple roots — see Configuration).

2.1 Configure Your AI Coding Tool

Cursor~/.cursor/mcp.json:

{
  "mcpServers": {
    "local-rag": {
      "command": "npx",
      "args": ["-y", "@damoqiongqiu/mcp-local-rag"],
      "env": { "BASE_DIR": "/path/to/your/project" }
    }
  }
}

Claude Code:

claude mcp add local-rag --scope user --env BASE_DIR=/path/to/your/project -- npx -y @damoqiongqiu/mcp-local-rag

Codex~/.codex/config.toml:

[mcp_servers.local-rag]
command = "npx"
args = ["-y", "@damoqiongqiu/mcp-local-rag"]

[mcp_servers.local-rag.env]
BASE_DIR = "/path/to/your/project"

WorkBuddy — Settings → Custom Connectors → Add:

{
  "mcpServers": {
    "local-rag": {
      "command": "npx",
      "args": ["-y", "@damoqiongqiu/mcp-local-rag"],
      "env": { "BASE_DIR": "/path/to/your/project" }
    }
  }
}

⚠️ WorkBuddy: you MUST click "Trust" in the Custom Connectors list after adding, otherwise the server is silently blocked.

2.2 CLI Quick Start

No MCP needed — run directly from the terminal:

npx @damoqiongqiu/mcp-local-rag ingest ./src/
npx @damoqiongqiu/mcp-local-rag query "auth middleware"
npx @damoqiongqiu/mcp-local-rag status

That's it. No Docker, Python, or server setup.

2.3 First-Time Project Indexing

You: "Index the src directory of this project"
Assistant: Successfully ingested 156 files (2,847 chunks created)

You: "Where's the middleware that handles API rate limiting?"
Assistant: src/middleware/rateLimiter.ts — useRateLimiter(), lines 42–89

You: "How is the database connection pool configured?"
Assistant: src/config/database.ts — createPool() default max: 20, idle: 5

3. Core Concepts

3.1 Dual-Strategy Chunking

Chunking strategy is chosen per file type:

  • Code files (50+ languages) — 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.
  • Documents (PDF/DOCX/TXT/MD/HTML) — SemanticChunker splits into sentences, groups by embedding similarity to find natural topic boundaries. Markdown code blocks remain intact — never split mid-block.

3.2 Hybrid Search

Search = semantic similarity + keyword boost (RAG_HYBRID_WEIGHT, default 0.6):

  1. Query vectorization → semantic search finds most relevant chunks
  2. Quality filters apply (distance threshold, grouping)
  3. Keyword matching boosts exact-term rankings

Exact identifiers like useEffect are never buried by semantic approximations.

3.3 Security Boundary

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.


4. MCP Tool Reference

15 tools organized into 5 categories.

4.1 Ingest Tools

# 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
# CLI
npx @damoqiongqiu/mcp-local-rag ingest ./spec.pdf --visual --visual-quality quality
# MCP
"Ingest ./spec.pdf with visual: true, visualQuality: 'quality'"

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.

4.2 Search Tools

# 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_documentsscope 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.

4.3 Management Tools

# 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.

4.4 Code Intelligence

# 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.

4.5 System Tools

# 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 — spotfutures mirror code is typically flagged with similarity 1.0.


5. CLI

5.1 Basic Commands

# Ingest
npx @damoqiongqiu/mcp-local-rag ingest ./src/

# Search (with scope)
npx @damoqiongqiu/mcp-local-rag query "auth middleware"
npx @damoqiongqiu/mcp-local-rag query "auth" --scope /docs/api

# Context expansion
npx @damoqiongqiu/mcp-local-rag read-neighbors --file-path /abs/path.md --chunk-index 5

# Management
npx @damoqiongqiu/mcp-local-rag list --scope /docs/api
npx @damoqiongqiu/mcp-local-rag status
npx @damoqiongqiu/mcp-local-rag delete ./docs/old.pdf
npx @damoqiongqiu/mcp-local-rag delete --source "https://..."

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:

npx @damoqiongqiu/mcp-local-rag --help

⚠️ The CLI does NOT read your MCP client config (mcp.json, etc.). Configure via flags or environment variables.

5.2 CLI Configuration

Flags — global options before, subcommand options after:

npx @damoqiongqiu/mcp-local-rag --db-path ./my-db query "auth" --base-dir ./docs

--base-dir is repeatable on ingest and list:

npx @damoqiongqiu/mcp-local-rag ingest --base-dir ./docs --base-dir ./specs ./docs/readme.md

Environment variables:

export DB_PATH=./my-db
export BASE_DIR=./docs
npx @damoqiongqiu/mcp-local-rag query "auth"

For multiple roots, use BASE_DIRS (JSON array):

export BASE_DIRS='["/Users/me/work","/Users/me/specs"]'

Precedence: CLI flags > environment variables > defaults.


6. Network & Models

6.1 Mirror Auto-Detection

huggingface.co is inaccessible from mainland China. Built-in three-tier mirror chain with automatic fallback:

huggingface.co → hf-mirror.com → modelscope.cn

At startup, each mirror is HEAD-probed (3s timeout). The first reachable mirror with a complete API is selected:

  • With proxy (HTTPS_PROXY) → direct to huggingface.co
  • No proxy → auto-switch to hf-mirror.com
  • hf-mirror API unavailable → fallback to modelscope.cn

No 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.2 Model Selection

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.

6.3 File Watching

Set RAG_WATCH=true — the server starts recursive fs.watch on baseDirs (500ms debounce):

  • File creation/modification → auto ingest_file
  • File deletion → auto delete_file

Ideal for actively changing projects.


7. Search Tuning

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):

{ "RAG_HYBRID_WEIGHT": "0.7", "RAG_GROUPING": "similar" }

Document-focused tuning:

{ "RAG_HYBRID_WEIGHT": "0.4", "RAG_GROUPING": "related" }

Keyword boost is applied after semantic filtering — improves precision without introducing noise.


8. Performance Tuning

Beyond search accuracy, inference performance is also configurable. All optimizations are environment variables — no code changes required.

8.1 Quantization Precision (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
"env": { "RAG_DTYPE": "fp16", "BASE_DIR": "..." }

⚠️ 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.

8.2 Execution Device (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
"env": { "RAG_DEVICE": "webgpu", "RAG_DTYPE": "fp16", "BASE_DIR": "..." }

⚠️ Changing device changes the embedding space — requires index rebuild. Stacks with RAG_DTYPEfp16 + 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"
  • Starts successfully but inference crashes → likely an ONNX WebGPU backend bug, revert to "cpu"
  • Just delete the RAG_DEVICE line to fall back — other config is untouched

8.3 Minimum Chunk Length (CHUNK_MIN_LENGTH)

Filters out chunks shorter than this value during ingest. Default 50 keeps nearly everything; 200 drops 30-40% of noise fragments.

"env": { "CHUNK_MIN_LENGTH": "200", "BASE_DIR": "..." }

⚠️ Blunt instrument — short but important code (e.g., config constants) may also be discarded. Requires index rebuild. Sweet spot: 100-200.

8.4 Recommended Configurations

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.


9. Configuration Reference

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.


10. Troubleshooting

<details open> <summary><strong>Model download failed</strong></summary>

Symptoms: fetch failed, status shows searchMode: fts instead of hybrid.

Solutions:

  1. Network restriction (mainland China, etc.) — use proxy:

    "env": { "HTTPS_PROXY": "http://127.0.0.1:7890" }
    

    Set in your MCP client config, not the terminal. v0.18.5+ globally effective via setGlobalDispatcher.

  2. Auto-mirror fallback (v0.18.2+, default) — three-tier probe. Usually works without any config.

  3. Manual overrideHF_ENDPOINT=https://modelscope.cn or download models manually into CACHE_DIR.

  4. npx cached old version — clear and restart:

    rm -rf ~/.npm/_npx/
    

</details>

<details> <summary><strong>MCP client doesn't see tools</strong></summary>

  1. Verify config file syntax
  2. WorkBuddy users: confirm "Trust" button clicked
  3. Restart client completely (Cmd+Q on macOS)
  4. Test directly: npx @damoqiongqiu/mcp-local-rag should run without errors

</details>

<details> <summary><strong>Rebuilding the index</strong></summary>

After switching models or when the database is corrupted:

  1. Stop the MCP service
  2. Delete DB_PATH directory (default ./lancedb/) — safe, doesn't affect source files
  3. Restart MCP → fresh database auto-created
  4. Bulk re-ingest:
    npx @damoqiongqiu/mcp-local-rag ingest ./src/
    

</details>

<details> <summary><strong>FAQ</strong></summary>

  • Private? Yes. After model download, nothing leaves your machine.
  • Offline? Yes, once models are cached.
  • Supported formats? 50+ code languages + PDF/DOCX/TXT/MD/HTML. No Excel, PPT, or images.
  • GPU acceleration? Opt-in via RAG_DEVICE. Support depends on your system, Node.js version, and the ONNX backend.
  • Backup? Copy the DB_PATH directory.

</details>


11. Development

git clone https://github.com/damoqiongqiu/mcp-local-rag.git
cd mcp-local-rag
pnpm install
pnpm test              # All tests
pnpm run type-check    # TypeScript check
pnpm run check:fix     # Lint + format
pnpm run check:all     # Full CI pipeline
src/
  index.ts      # Entry point
  server/       # MCP tool handlers
  cli/          # CLI subcommands
  parser/       # PDF/DOCX/TXT/MD/code parsing
  chunker/      # SemanticChunker + CodeChunker
  embedder/     # Transformers.js embeddings
  vectordb/     # LanceDB operations
  utils/        # Shared utilities (security, scan, scope)
  __tests__/    # Test suites

License

MIT License. Free for personal and commercial use.

Acknowledgments

Built with Model Context Protocol (Anthropic), LanceDB, and Transformers.js.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选