shinpr/mcp-local-rag
GitHub: shinpr/mcp-local-rag
本地RAG服务器为开发者提供私有化文档搜索,通过语义和关键词混合技术解决代码检索精度和数据隐私问题。
Stars: 262 | Forks: 51
# 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, 代码分析, 代码搜索, 信息检索, 凭证管理, 向量搜索, 向量数据库, 命令行界面, 威胁情报, 嵌入模型, 开发工具, 开发者工具, 技术文档, 文档检索, 文档管理, 文档结构分析, 智能分块, 本地优先, 本地服务器, 检索增强生成, 模型上下文协议, 离线工作, 结果过滤, 网络安全, 自动化攻击, 语义搜索, 隐私保护, 零设置