代码RAG MCP服务器

本地代码检索增强生成(RAG)MCP 服务器,通过混合检索、向量召回和重排序为 LLM 提供高可用的代码库问答、调试与功能开发支持。

  • by heggria
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 heggria/local-rag-mcp

使用说明

Local Code RAG MCP Server

一个高可用、零依赖的本地代码检索增强生成(RAG)MCP 服务器。专为配合大语言模型(LLM)进行代码库问答、调试和功能开发而设计。

✨ 核心特性

本项目致力于解决本地代码检索中的痛点,提供企业级的稳定性和检索精度:

  • 🚀 高可用性 (High Resilience)

    • 自动降级策略:启动时自动检测环境。如果高性能组件(如 LanceDB)初始化失败,自动无缝切换到纯内存模式(Memory Mode),保证 99.9% 的启动成功率。
    • 多级 Worker 池:Embedding 服务采用 Worker Pool 并行处理,若失败则自动降级为单 Worker 甚至主线程模式。
  • 🎯 混合检索 (Hybrid Search)

    • 精度 >85%:结合了语义向量检索 (Vector Search) 和 关键词匹配 (Keyword Matching)。
    • 智能重排序 (Reranking):先通过向量检索召回 3 倍候选集,再利用关键词覆盖率进行加权重排序(70% 语义 + 30% 关键词),有效解决了纯向量检索无法精准定位函数名、变量名的问题。
  • ⚡ 极致性能

    • 并行索引:支持多流并发读取文件和 Batch 批量 Embedding 生成,速度提升 3-5 倍。
    • 智能缓存:内置去重和 Embedding 缓存机制,增量索引极其迅速。
    • 低延迟:千级文件项目查询延迟 < 200ms。
  • 🔒 隐私与离线

    • 完全本地化:所有模型(Embeddings)和向量库均在本地运行,无需任何外网 API 调用,确保代码隐私安全。

🏗 技术架构

本项目采用了分层架构设计,确保了模块的解耦和扩展性。

graph TD
    Client[MCP Client (Claude/Cursor)] --> Transport[Stdio Transport]
    Transport --> Server[MCP Server]

    subgraph Core Logic
        Server --> SearchHandler[Code Search Handler]
        Server --> FileIndexer[File Indexer]

        SearchHandler --> HybridRanker[Hybrid Reranker]
        SearchHandler --> VectorStore[Vector Store Adapter]

        FileIndexer --> Chunker[Chunker Adapter]
        FileIndexer --> EmbeddingSvc[Embedding Service]
        FileIndexer --> VectorStore

        EmbeddingSvc --> WorkerPool[Worker Pool]
        WorkerPool -- Parallel --> Model[Local ONNX Model]
    end

    subgraph Storage Layer
        VectorStore -- Primary --> LanceDB[(LanceDB Filesystem)]
        VectorStore -- Fallback --> MemoryDB[(In-Memory Map)]
    end

关键模块说明

  1. VectorStoreAdapter (存储适配器)

    • 实现策略模式,自动选择最佳存储引擎。
    • Primary: LanceDB (C++ Native),高性能持久化存储。
    • Fallback: MemoryVectorStore (纯 JS),无本机依赖,兼容性极强。
  2. EmbeddingService (向量化服务)

    • 管理本地量化模型 (Quantized ONNX models)。
    • 实现 Worker 线程池,避免阻塞 Node.js 主线程。
    • 支持 auto | bge-small | all-minilm 多种模型选择。
  3. CodeSearchHandler (检索处理器)

    • Context Injection: 在 Chunk 中注入文件路径、AST 上下文(类名/函数名),提升语义理解。
    • 执行“向量召回 -> 关键词提取 -> 混合打分”的流水线。

📦 安装与使用

环境要求

  • Node.js >= 18.0.0
  • (可选) Python 环境(如果涉及特定构建脚本)

快速开始

  1. 安装依赖

    npm install
    # 可选:安装高性能向量库(推荐)
    npm install @lancedb/lancedb
    
  2. 构建项目

    npm run build
    
  3. 下载模型 (首次运行自动,或手动预下载)

    # 脚本会自动下载所需的 ONNX 模型到 resources/models
    npm run download-grammars
    
  4. 配置 MCP (以 Claude Desktop 为例) 在 ~/Library/Application Support/Claude/claude_desktop_config.json 中添加:

    {
      "mcpServers": {
        "local-code-rag": {
          "command": "node",
          "args": ["/绝对路径/to/rag-mcp/dist/index.js"],
          "env": {
            "EMBEDDING_WORKERS": "4"
          }
        }
      }
    }
    

🛠 配置选项

你可以通过环境变量来调整服务器行为:

环境变量 默认值 说明
EMBEDDING_WORKERS 4 向量化工作的并行 Worker 数量
EMBEDDING_WORKERS_MAX (auto) 自动分配模式下的 Worker 上限(防止过度并行)
EMBEDDING_WORKER_MEM_GB 3 自动分配模式下每个 Worker 预估占用内存(GB),用于按内存上限缩 worker
EMBEDDING_BATCH_SIZE 512 索引时单次送入 embedBatch 的外层批次大小(过大可能导致卡顿/超时)
EMBEDDING_MAX_SUB_BATCH_SIZE 128 embedBatch 内部子批次上限,用于避免超大 batch 造成 worker 卡死
EMBEDDING_MAX_SUB_BATCH_CHARS 160000 embedBatch 内部子批次字符上限(防止少量超大 chunk 撑爆内存)
EMBEDDING_TIMEOUT_PER_TEXT_MS 400 批量向量化超时系数(每条文本 ms),机器慢可调大
EMBEDDING_TIMEOUT_PER_CHAR_MS 0.1 批量向量化按字符估算超时系数(ms/char),用于超大文本场景
EMBEDDING_BATCH_TIMEOUT_MIN_MS 10000 批量向量化超时下限
EMBEDDING_BATCH_TIMEOUT_MAX_MS 300000 批量向量化超时上限
EMBEDDING_BATCH_TIMEOUT_SAFETY 3 批量向量化超时安全系数(估算值 × safety)
EMBEDDING_BATCH_RETRIES 1 子批次超时/错误后的自动重试次数(会自动二分子批次)
EMBEDDING_PROVIDER local Embedding 后端:local(内置 worker/CPU) / ollama(HTTP 调 Ollama,GPU 跑大模型)
OLLAMA_HOST http://127.0.0.1:11434 Ollama 服务地址(本机默认)
OLLAMA_EMBED_MODEL nomic-embed-text Ollama Embedding 模型名(也兼容读 OLLAMA_MODEL)
OLLAMA_BATCH_ENDPOINT auto 批量接口:auto(优先 /api/embed,不支持则退回 /api/embeddings) / embed / embeddings
OLLAMA_CONCURRENCY 1 Ollama 批量请求并发上限(GPU/显存紧张建议保持 1)
OLLAMA_TIMEOUT_MULTIPLIER 2 Ollama 请求超时倍率(把内部估算 timeout 乘以该值,避免 GPU 排队导致误超时)
OLLAMA_REQUEST_TIMEOUT_MS (unset) Ollama 请求超时硬下限(ms),最终 timeout = max(估算×倍率, 该值)
OLLAMA_BATCH_RETRIES 3 Ollama 子批次超时/错误后的最大重试次数(会持续二分子批次直到成功或到达上限)
VECTOR_DIM 384 LanceDB 向量维度初始值(一般无需设置;启动会按 Embedding 实际维度自动校验/重建)
VECTORSTORE_RESET_ON_DIM_MISMATCH false Embedding 维度与现有 LanceDB 表不一致时自动重建表(会清空旧向量)
RAG_CACHE_DIR / VECTORSTORE_PATH (unset) 覆盖默认缓存/向量库目录(默认 <workspace>/.rag-cache),便于按不同模型隔离索引或做基准测试
MAX_FILES 50000 最大索引文件数量限制
FILE_BATCH_SIZE 150 单次处理的文件批次大小
EMBEDDING_MODEL auto 指定模型 (auto, bge-small, all-minilm)
ENABLE_DEDUP_CACHE true 是否启用 Embedding 去重缓存
SEARCH_TOP_K 10 默认返回给 LLM 的片段数量(推荐设为 3-5)
RETRIEVAL_CANDIDATES 50 向量召回候选数(推荐 50),用于后续 rerank
RERANK_PROVIDER none 重排序提供方:none / transformers / jina / mixedbread
RERANK_CANDIDATES 50 送入 rerank 的候选数量(默认等于 RETRIEVAL_CANDIDATES,受召回数量影响)
RERANK_MODEL (provider default) 重排序模型名(对 transformers/jina 生效;Mixedbread 用 MIXEDBREAD_RERANK_MODEL)
RERANK_MODEL_PATH ./resources/models 本地 transformers 重排序模型目录(等价 TRANSFORMERS_RERANK_MODEL_PATH)
RERANK_BASE_URL (unset) HTTP 重排序服务 base URL(对 jina/mixedbread 生效;也可用各自专用变量)
RERANK_API_KEY (unset) HTTP 重排序服务 API Key(也可用 JINA_API_KEY/MIXEDBREAD_API_KEY)
RERANK_OFFLINE true 本地 transformers 重排序是否禁用远程下载(推荐保持 true)
RERANK_WASM_THREADS (auto) 本地 transformers 重排序 WASM 线程数(上限 8)
RERANK_MAX_DOC_CHARS 2000 单个候选最大字符数(控制上下文与性能)
MIXEDBREAD_API_KEY (unset) Mixedbread API Key(启用 RERANK_PROVIDER=mixedbread 必填)
MIXEDBREAD_RERANK_MODEL mxbai-rerank-large-v2 Mixedbread 重排序模型名
MIXEDBREAD_BASE_URL https://api.mixedbread.ai Mixedbread API Base URL
MIXEDBREAD_TIMEOUT_MS 15000 Mixedbread 请求超时(ms)
MIXEDBREAD_MAX_DOC_CHARS 2000 单个候选文本最大字符数(用于控制请求体大小)
JINA_RERANK_BASE_URL http://127.0.0.1:8000 Jina Rerank API Base URL(本地部署推荐)
JINA_API_KEY (unset) Jina API Key(本地部署可不填;云 API 需要)
JINA_RERANK_MODEL jina-reranker-v3 Jina 重排序模型名
JINA_RERANK_TIMEOUT_MS 15000 Jina 重排序请求超时(ms)
JINA_RERANK_MAX_DOC_CHARS 2000 单个候选文本最大字符数(用于控制请求体大小)
TRANSFORMERS_RERANK_MODEL Xenova/bge-reranker-base 本地 transformers 重排序模型(推荐)
TRANSFORMERS_RERANK_MODEL_PATH ./resources/models transformers.js env.localModelPath
TRANSFORMERS_RERANK_OFFLINE true 同 RERANK_OFFLINE(别名)
TRANSFORMERS_RERANK_WASM_THREADS (auto) 同 RERANK_WASM_THREADS(别名)
TRANSFORMERS_RERANK_MAX_DOC_CHARS 2000 同 RERANK_MAX_DOC_CHARS(别名)

本地 Jina Reranker v3(/v1/rerank)

本项目的 RERANK_PROVIDER=jina 通过 HTTP 调用 POST /v1/rerank(可对接你自己在本机/内网部署的服务),因此可以做到“权重本地、请求不出网”(首次下载模型权重除外)。

最小配置示例(假设你的本地服务跑在 http://127.0.0.1:8000):

export RERANK_PROVIDER=jina
export JINA_RERANK_BASE_URL=http://127.0.0.1:8000
export JINA_RERANK_MODEL=jina-reranker-v3

本地 Transformers Reranker(Xenova/bge-reranker-base)

启用方式:

export SEARCH_TOP_K=5
export RETRIEVAL_CANDIDATES=50
export RERANK_PROVIDER=transformers
export RERANK_MODEL=Xenova/bge-reranker-base
export RERANK_MODEL_PATH=./resources/models
export RERANK_OFFLINE=true

注意:当 RERANK_OFFLINE=true 时,模型必须已存在于 RERANK_MODEL_PATH(也可用 TRANSFORMERS_RERANK_MODEL_PATH)。

Ollama Embedding (GPU 模式)

如果你希望用 GPU 跑更大的 Embedding 模型(Node 进程只做索引/搜索逻辑),确保本机已启动 Ollama 服务,然后设置:

export EMBEDDING_PROVIDER=ollama
export OLLAMA_EMBED_MODEL=nomic-embed-text   # 或你本地已有的 embedding 模型
# 可选:export OLLAMA_HOST=http://127.0.0.1:11434

# 如果从 384 维模型切换到 1024 维(如 BGE-M3),请先清理旧库或启用自动重建:
# npm run clean
# 或:export VECTORSTORE_RESET_ON_DIM_MISMATCH=1

📂 项目结构

src/
├── embeddings/     # Embedding 生成服务与 Worker 线程管理
├── handlers/       # MCP 请求处理器 (Search Logic)
├── indexing/       # 文件扫描、分块 (Chunking)、AST 解析
├── storage/        # 向量数据库适配器 (LanceDB/Memory)
├── utils/          # 通用工具 (Logger, Performance Monitor)
└── index.ts        # 程序入口与 MCP Server 定义

📊 性能基准

在 M1 Macbook Pro 上对 1000 个 TypeScript 文件的测试数据:

  • 索引速度: ~50 files/sec
  • 查询延迟: < 150ms (P95)
  • 内存占用: ~300MB (Memory Mode) / ~150MB (LanceDB Mode)

🤝 贡献

欢迎提交 Pull Request 或 Issue!

  1. Fork 本仓库
  2. 创建特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 开启 Pull Request

📄 许可证

MIT License