shinpr/mcp-local-rag

GitHub: shinpr/mcp-local-rag

本地RAG服务器为开发者提供私有化文档搜索,通过语义和关键词混合技术解决代码检索精度和数据隐私问题。

Stars: 262 | Forks: 51

MCP Local RAG — Search below the surface.

# MCP 本地 RAG 面向开发者的本地 RAG,可通过 MCP 或 CLI 使用。 基于关键词增强的语义搜索,精确匹配技术术语——完全私有化,零配置。 ## 功能特性 - **基于关键词增强的语义搜索** 优先进行向量搜索,然后通过关键词匹配提升精确匹配项的排名。类似 `useEffect`、错误代码和类名等术语将获得更高权重——而不仅仅是基于语义的推测。 - **智能语义分块** 按语义而非字符数对文档进行分块。利用嵌入相似度寻找自然的主题边界——将相关内容聚合在一起,在主题转换处进行分割。 - **质量优先的结果筛选** 根据相关性差异对结果进行分组,而非简单地采用前 K 个。获得数量更少但更可信的片段。 - **完全本地运行** 无需 API 密钥,无需云服务,数据不会离开您的设备。首次模型下载后,可完全离线工作。 - **零摩擦设置** 一条 `npx` 命令。无需 Docker,无需 Python,无需管理服务器。 可通过 MCP、CLI 或两者结合使用。可选的 [Agent Skills](#agent-skills) 帮助 AI 助手构建更有效的查询并解读结果。 ## 快速开始 将 `BASE_DIR` 设置为您想要搜索的文件夹。文档必须存放在此目录下。 将 MCP 服务器添加到您的 AI 编码工具: **适用于 Cursor** — 添加到 `~/.cursor/mcp.json`: ``` { "mcpServers": { "local-rag": { "command": "npx", "args": ["-y", "mcp-local-rag"], "env": { "BASE_DIR": "/path/to/your/documents" } } } } ``` **适用于 Codex** — 添加到 `~/.codex/config.toml`: ``` [mcp_servers.local-rag] command = "npx" args = ["-y", "mcp-local-rag"] [mcp_servers.local-rag.env] BASE_DIR = "/path/to/your/documents" ``` **适用于 Claude Code** — 运行以下命令: ``` claude mcp add local-rag --scope user --env BASE_DIR=/path/to/your/documents -- npx -y mcp-local-rag ``` 重启您的工具,然后开始使用: ``` You: "Ingest api-spec.pdf" Assistant: Successfully ingested api-spec.pdf (47 chunks created) You: "What does the API documentation say about authentication?" Assistant: Based on the documentation, authentication uses OAuth 2.0 with JWT tokens. The flow is described in section 3.2... ``` **或直接作为 CLI 使用** — 无需 MCP 服务器: ``` npx mcp-local-rag ingest ./docs/ npx mcp-local-rag query "authentication API" ``` 就这样。无需 Docker,无需 Python,无需服务器设置。 ## 为什么选择此方案 您希望 AI 能够搜索您的文档——技术规范、研究论文、内部文档。但大多数解决方案会将您的文件发送到外部 API。 **隐私性。** 您的文档可能包含敏感数据。此方案完全在本地运行。 **成本。** 外部嵌入 API 按使用收费。首次模型下载后,此方案免费使用。 **离线性。** 设置完成后无需联网即可工作。 **代码搜索。** 纯语义搜索会错过像 `useEffect` 或 `ERR_CONNECTION_REFUSED` 这样的精确术语。关键词增强可以同时捕获语义和精确匹配。 **代理现实。** 实践中,许多 AI 环境主要使用工具调用。CLI 支持和 Agent Skills 使得即使没有完全集成 MCP,相同的工作流也能得以实现。 ## 使用方法 mcp-local-rag 提供两个接口:一个用于 AI 编码工具的 **MCP 服务器**,一个用于终端直接使用的 **CLI**。 ### 与 MCP 配合使用 MCP 服务器提供 7 个工具:`ingest_file`、`ingest_data`、`query_documents`、`read_chunk_neighbors`、`list_files`、`delete_file`、`status`。 #### 导入文档 ``` "Ingest the document at /Users/me/docs/api-spec.pdf" ``` 支持 PDF、DOCX、TXT 和 Markdown。服务器提取文本,将其分割成块,在本地生成嵌入向量,并将所有内容存储在本地向量数据库中。 重新导入同一文件会自动替换旧版本。 ##### 导入带图表的 PDF(视觉模式) 包含图表、表格或图表的 PDF 可选择添加本地 VLM 生成的描述到文档索引中,使视觉内容在同一个向量 + FTS 管道中获得某种可搜索的表示。描述是辅助文本——不是图像搜索,不是 OCR,也不是对图表的忠实转录。 **通过 MCP**: ``` "Ingest /Users/me/docs/api-spec.pdf with visual: true" ``` **通过 CLI**: ``` npx mcp-local-rag ingest ./docs/spec.pdf --visual ``` 每个描述作为其独立的块输出,带有信封 `[Visual content on page N: …]`,与页面正文块并列。它流经现有的嵌入器和 FTS 索引——没有模式差异,没有单独的索引。 视觉模式是可选的;常规导入不会加载 VLM。每页的 VLM 故障会被容忍——该页面仅使用文本继续处理。 ###### 选择视觉质量配置文件 视觉模式提供两种配置文件,在每次导入时选择: | 配置文件 | 模型 | 磁盘 (缓存) | 每页推理 | 适用场景 | |---|---|---|---|---| | `fast` (默认) | `HuggingFaceTB/SmolVLM-256M-Instruct` | ~250 MB | 基准 | 轻量级视觉索引,快速首次运行设置。 | | `quality` | `onnx-community/Qwen2.5-VL-3B-Instruct-ONNX` | ~2.9 GB | ~2倍 `fast` | 包含图像内文本(轴标签、面板子标签、注释)的图表,其中描述的保真度比推理时间更重要。 | 上述数字是在项目探测 PDF 上于开发期间在 CPU 上测量的;它们可能随模型更新而变化,或在您的硬件上有所不同。 **通过 MCP** — `ingest_file` 接受一个可选的 `visualQuality` 参数(枚举:`'fast' | 'quality'`,默认 `'fast'`;当 `visual` 为 false 时被忽略): ``` "Ingest /Users/me/docs/research-paper.pdf with visual: true and visualQuality: 'quality'" ``` **通过 CLI** — `--visual-quality fast|quality`(默认 `fast`;当未提供 `--visual` 时被静默忽略): ``` npx mcp-local-rag ingest ./docs/research-paper.pdf --visual --visual-quality quality ``` 配置文件模型标识符和量化变体在每个版本中是固定的。两种配置文件共享相同的 `CACHE_DIR`(默认:`./models/`);首次运行每个配置文件时会下载其模型。 #### 导入 HTML 内容 使用 `ingest_data` 导入您的 AI 助助通过 Web 抓取、curl、浏览器工具等获取的 HTML 内容: ``` "Fetch https://example.com/docs and ingest the HTML" ``` 服务器使用 Readability 提取主要内容(移除导航、广告等),转换为 Markdown 并进行索引。非常适合: - Web 文档 - AI 助手获取的 HTML - 剪贴板内容 HTML 会被自动清理——您获取的是文章内容,而非样板文件。 #### 搜索文档 ``` "What does the API documentation say about authentication?" "Find information about rate limiting" "Search for error handling best practices" ``` 搜索使用带关键词增强的语义相似度。这意味着 `useEffect` 会找到包含该确切术语的文档,而不仅仅是语义上相似的 React 概念。 结果包括文本内容、源文件、文档标题和相关性分数。文档标题为每个块提供上下文,有助于识别结果属于哪个文档。使用 `limit`(1-20,默认 10)调整结果数量。 #### 展开结果的上下文 当搜索结果需要更多周围上下文时,使用 `read_chunk_neighbors` 读取其前后的块: ``` "That result about authentication looks relevant — read the surrounding chunks for the full explanation" ``` 从搜索结果中传递 `filePath` 和 `chunkIndex`。响应包括目标块(标记为 `isTarget: true`)及其邻居,按块索引排序。默认前后各 2 个块(均可调整至最多 50 个)。 #### 管理文件 ``` "List all files in BASE_DIR and their ingested status" # See what's indexed "Delete old-spec.pdf from RAG" # Remove a file "Show RAG server status" # Check system health ``` ### 作为 CLI 使用 所有 MCP 工具也可作为 CLI 命令使用——无需 MCP 服务器: ``` npx mcp-local-rag ingest ./docs/ # Bulk ingest files npx mcp-local-rag query "authentication API" # Search documents npx mcp-local-rag read-neighbors --file-path /abs/path.md --chunk-index 5 # Expand context npx mcp-local-rag list # Show ingestion status npx mcp-local-rag status # Database stats npx mcp-local-rag delete ./docs/old.pdf # Remove content npx mcp-local-rag delete --source "https://..." # Remove by source URL ``` `query`、`read-neighbors`、`list`、`status` 和 `delete` 输出 JSON 到 stdout 以便管道操作(例如 `| jq`)。`ingest` 将进度输出到 stderr。全局选项(`--db-path`、`--cache-dir`、`--model-name`)放在子命令之前。运行 `npx mcp-local-rag --help` 查看详情。 #### 配置 **CLI 标志** — 全局选项放在子命令之前,子命令选项放在之后: ``` npx mcp-local-rag --db-path ./my-db query "auth" --base-dir ./docs ``` **环境变量** — 在您的 shell 中设置: ``` export DB_PATH=./my-db export BASE_DIR=./docs npx mcp-local-rag query "auth" ``` **在 MCP 和 CLI 之间共享配置** — 如果您的 MCP 客户端继承 shell 环境变量,您可以在 shell 配置文件(例如 `~/.zshrc`)中设置它们,以便两者使用相同的值。否则,也需要在您的 MCP 配置中显式设置它们。 ``` export BASE_DIR=/path/to/your/documents export DB_PATH=/path/to/lancedb ``` 配置按以下顺序解析: 1. CLI 标志(最高优先级) 2. 环境变量 3. 默认值 有关 CLI 标志、环境变量和默认值的完整列表,请参见[配置](#configuration)。 对于仅 CLI 的设置(无 MCP 服务器),请安装 [Agent Skills](#agent-skills),以便您的 AI 助手能够一致地构建更好的查询并解释结果。 ## 搜索调优 根据您的用例调整以下变量: | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `RAG_HYBRID_WEIGHT` | `0.6` | 关键词增强因子。0 = 仅语义,值越高,关键词增强越强。 | | `RAG_GROUPING` | (未设置) | `similar` 仅取最相关的组,`related` 取最相关的 2 个组。 | | `RAG_MAX_DISTANCE` | (未设置) | 过滤掉相关性低的结果(例如 `0.5`)。 | | `RAG_MAX_FILES` | (未设置) | 将结果限制在前 N 个文件中(例如 `1` 表示单个最佳文件)。 | ### 面向代码的调优 对于代码库和 API 规范,增加关键词增强,使精确标识符(`useEffect`、`ERR_*`、类名)在排名中占主导地位: ``` "env": { "RAG_HYBRID_WEIGHT": "0.7", "RAG_GROUPING": "similar" } ``` - `0.7` — 平衡语义 + 关键词 - `1.0` — 激进;精确匹配会强烈重新排序结果 关键词增强在语义过滤*之后*应用,因此它在不引入不相关匹配的情况下提高了精确度。 ## 工作原理 **简而言之:** - 文档按语义相似性分块,而非固定字符数 - 每个块使用 Transformers.js 在本地生成嵌入向量 - 搜索使用带关键词增强的语义相似度进行精确匹配 - 结果基于相关性差异进行过滤,而非原始分数 ### 详细说明 当您导入文档时,解析器根据文件类型提取文本(PDF 通过 `mupdf`,DOCX 通过 `mammoth`,文本文件直接读取)。 语义分块器将文本分割成句子,然后使用嵌入相似度将它们分组。它在语义变化的地方找到自然的主题边界——将相关内容聚合在一起,而不是在任意的字符限制处进行切割。这会产生语义连贯的块,通常为 500-1000 个字符。Markdown 代码块会被完整保留——绝不会在块中间分割——从而在搜索结果中保留可复制的代码。 每个块通过一个 Transformers.js 嵌入模型(默认:`all-MiniLM-L6-v2`,可通过 `MODEL_NAME` 配置),将文本转换为向量。向量存储在 LanceDB 中,这是一个基于文件的向量数据库,无需服务器进程。 当您搜索时: 1. 您的查询使用相同的模型转换为向量 2. 语义(向量)搜索找到最相关的块 3. 应用质量过滤器(距离阈值、分组) 4. 关键词匹配提升精确术语匹配的排名 关键词增强确保当精确术语(如 `useEffect` 或错误代码)匹配时获得更高的排名。 ## Agent 技能 [Agent Skills](https://agentskills.io/) 提供优化的提示,帮助 AI 助手更有效地使用 RAG 工具。安装技能以获得更好的查询构建、结果解释和导入工作流: ``` # Claude Code(项目级别) npx mcp-local-rag skills install --claude-code # Claude Code(用户级别) npx mcp-local-rag skills install --claude-code --global # Codex npx mcp-local-rag skills install --codex ``` 技能包括: - **查询优化**:更好的搜索查询构建 - **结果解释**:分数阈值和过滤指南 - **HTML 导入**:格式选择和来源命名 ### 确保技能激活 在大多数情况下,技能会自动加载——AI 助手会扫描技能元数据并在需要时加载相关指令。为了保持一致的行为: **选项 1:显式请求(自然语言)** 在 RAG 操作之前,用自然语言请求: - “对本次搜索使用 mcp-local-rag 技能” - “应用来自技能的 RAG 最佳实践” **选项 2:添加到代理指令文件** 将以下内容添加到您的 `AGENTS.md`、`CLAUDE.md` 或其他代理指令文件中: ``` When using query_documents, ingest_file, or ingest_data tools, apply the mcp-local-rag skill for better query formulation and result interpretation. ``` ## 配置 ### 环境变量和 CLI 标志 MCP 服务器仅通过环境变量配置——通过 MCP 客户端的 `env` 块传递它们。CLI 接受相同的环境变量以及等效的标志(优先级:CLI 标志 > 环境变量 > 默认值)。在裸 `mcp-local-rag`(MCP 服务器)启动时不接受 CLI 标志。 | 环境变量 | CLI 标志 | 默认值 | 描述 | |---------------------|----------|---------|-------------| | `BASE_DIR` | `--base-dir` | 当前目录 | 文档根目录(安全边界) | | `DB_PATH` | `--db-path` | `./lancedb/` | 向量数据库位置 | | `CACHE_DIR` | `--cache-dir` | `./models/` | 模型缓存目录 | | `MODEL_NAME` | `--model-name` | `Xenova/all-MiniLM-L6-v2` | HuggingFace 模型 ID([可用模型](https://huggingface.co/models?library=transformers.js&pipeline_tag=feature-extraction)) | | `MAX_FILE_SIZE` | `--max-file-size` | `104857600` (100MB) | 最大文件大小(字节) | | `CHUNK_MIN_LENGTH` | `--chunk-min-length` | `50` | 最小块长度(字符数)(1–10000) | | `RAG_DEVICE` | — | `cpu` | 执行设备。直接传递给 ONNX Runtime。有关支持的后端名称的实时列表,请参见 [Transformers.js 设备源代码](https://github.com/huggingface/transformers.js/blob/main/packages/transformers/src/utils/devices.js)。如果初始化失败,服务器会抛出错误。 | **模型选择提示:** - 多语言文档 → 例如 `onnx-community/embeddinggemma-300m-ONNX`(100+ 种语言) - 科学论文 → 例如 `sentence-transformers/allenai-specter`(引用感知) - 代码仓库 → 默认值通常足够;关键词增强更重要(或 `jinaai/jina-embeddings-v2-base-code`) ⚠️ 更改 `MODEL_NAME` 会改变嵌入维度。切换模型后需删除 `DB_PATH` 并重新导入。 ### 客户端特定设置 **Cursor** — 全局:`~/.cursor/mcp.json`,项目:`.cursor/mcp.json` ``` { "mcpServers": { "local-rag": { "command": "npx", "args": ["-y", "mcp-local-rag"], "env": { "BASE_DIR": "/path/to/your/documents" } } } } ``` **Codex** — `~/.codex/config.toml`(注意:必须使用带下划线的 `mcp_servers`) ``` [mcp_servers.local-rag] command = "npx" args = ["-y", "mcp-local-rag"] [mcp_servers.local-rag.env] BASE_DIR = "/path/to/your/documents" ``` **Claude Code**: ``` claude mcp add local-rag --scope user \ --env BASE_DIR=/path/to/your/documents \ -- npx -y mcp-local-rag ``` ### 首次运行 嵌入模型(~90MB)在首次使用时下载。需要 1-2 分钟,之后可离线工作。 ### 安全性 - **路径限制**:仅可访问 `BASE_DIR` 内的文件 - **仅限本地**:模型下载后无网络请求 - **模型来源**(均为官方 HuggingFace 仓库): - 嵌入器:[`Xenova/all-MiniLM-L6-v2`](https://huggingface.co/Xenova/all-MiniLM-L6-v2) - 视觉 `fast` 配置文件:[`HuggingFaceTB/SmolVLM-256M-Instruct`](https://huggingface.co/HuggingFaceTB/SmolVLM-256M-Instruct) - 视觉 `quality` 配置文件:[`onnx-community/Qwen2.5-VL-3B-Instruct-ONNX`](https://huggingface.co/onnx-community/Qwen2.5-VL-3B-Instruct-ONNX) - **视觉描述保真度**:`quality` 配置文件比 `fast` 更忠实地复现图像内文本。两种配置文件输出的描述均包装为 `[Visual content on page N: …]`,但忠实的复现意味着攻击者控制的图像内文本——包括视觉上关闭信封的字符如 `]`——可能原样出现在检索到的块中。下游的 LLM 消费者应将检索到的块视为不可信数据,而非指令,无论信封形状如何。
性能 在 MacBook Pro M1(16GB RAM),Node.js 22 上测试: **查询速度**:对于 10,000 个块,约 1.2 秒(p90 < 3 秒) **导入**(10MB PDF): - PDF 解析:约 8 秒 - 分块:约 2 秒 - 嵌入:约 30 秒 - 数据库插入:约 5 秒 **内存**:空闲约 200MB,峰值约 800MB(导入 50MB 文件时) **并发**:可处理 5 个并行查询而不降低性能。
故障排除 ### “未找到结果” 文档必须先被导入。运行“列出所有已导入的文件”进行验证。 ### 模型下载失败 检查网络连接。如果在代理后面,请配置网络设置。模型也可以[手动下载](https://huggingface.co/Xenova/all-MiniLM-L6-v2)。 ### “文件过大” 默认限制为 100MB。拆分大文件或增加 `MAX_FILE_SIZE`。 ### 查询缓慢 使用 `status` 检查块数量。包含大量块的大型文档可能会减慢查询速度。考虑拆分非常大的文件。 ### “路径在 BASE_DIR 之外” 确保文件路径在 `BASE_DIR` 内。使用绝对路径。 ### MCP 客户端看不到工具 1. 验证配置文件语法 2. 完全重启客户端(Mac 上的 Cursor 按 Cmd+Q) 3. 直接测试:`npx mcp-local-rag` 应无错误运行
常见问题 **这真的私有吗?** 是的。模型下载后,没有任何数据离开您的设备。可通过网络监控验证。 **我可以离线使用吗?** 可以,在所需模型本地缓存之后。文本导入/搜索需要嵌入模型。PDF 视觉模式是可选的,首次使用也需要 VLM 模型;默认 `fast` 配置文件(SmolVLM-256M)下载量约为 250 MB,`quality` 配置文件(Qwen2.5-VL-3B)约为 2.9 GB,缓存在 `CACHE_DIR`(默认:`./models/`)下。 **这与云端 RAG 相比如何?** 云服务在大规模下提供更好的准确性,但需要将数据发送到外部。此方案在准确性上做出一些权衡,以换取完全的隐私性和零运行时成本。 **支持哪些文件格式?** PDF、DOCX、TXT、Markdown 和 HTML(通过 `ingest_data`)。尚不支持:Excel、PowerPoint、图像。 **我可以更改嵌入模型吗?** 可以,但您必须删除数据库并重新导入所有文档。不同的模型会产生不兼容的向量维度。 **GPU 加速?** 通过 `RAG_DEVICE` 可选启用。设备直接传递给 ONNX Runtime。GPU 支持高度依赖于您的系统、Node.js 版本和底层的 ONNX 后端。有关支持的后端名称的实时列表,请参见 [Transformers.js 设备源代码](https://github.com/huggingface/transformers.js/blob/main/packages/transformers/src/utils/devices.js)。如果请求的设备初始化失败,服务器会抛出错误——设置 `RAG_DEVICE=cpu` 以恢复。 **多用户支持?** 不支持。设计为单用户本地访问。多用户需要身份验证/访问控制。 **如何备份?** 复制 `DB_PATH` 目录(默认:`./lancedb/`)。
开发 ### 从源码构建 ``` git clone https://github.com/shinpr/mcp-local-rag.git cd mcp-local-rag pnpm install ``` ### 测试 ``` pnpm test # Run all tests pnpm run test:watch # Watch mode ``` ### 代码质量 ``` pnpm run type-check # TypeScript check pnpm run check:fix # Lint and format pnpm run check:deps # Circular dependency check pnpm run check:all # Full quality check ``` ### 项目结构 ``` src/ index.ts # Entry point server/ # MCP tool handlers cli/ # CLI subcommands (ingest, query, list, delete, read-neighbors, etc.) parser/ # PDF, DOCX, TXT, MD parsing chunker/ # Text splitting embedder/ # Transformers.js embeddings vectordb/ # LanceDB operations __tests__/ # Test suites ```
## 贡献 欢迎贡献!有关设置和指南,请参见 [CONTRIBUTING.md](CONTRIBUTING.md)。 ## 许可证 MIT 许可证。个人和商业使用均免费。 ## 博客文章 - [为代理编码构建本地 RAG](https://www.norsica.jp/blog/local-rag-agentic-coding) — 语义分块和混合搜索设计的技术深入探讨。 ## 致谢 基于 Anthropic 的 [Model Context Protocol](https://modelcontextprotocol.io/)、[LanceDB](https://lancedb.com/) 和 [Transformers.js](https://huggingface.co/docs/transformers.js) 构建。
标签:MITM代理, SOC Prime, 代码分析, 代码搜索, 信息检索, 凭证管理, 向量搜索, 向量数据库, 命令行界面, 威胁情报, 嵌入模型, 开发工具, 开发者工具, 技术文档, 文档检索, 文档管理, 文档结构分析, 智能分块, 本地优先, 本地服务器, 检索增强生成, 模型上下文协议, 离线工作, 结果过滤, 网络安全, 自动化攻击, 语义搜索, 隐私保护, 零设置