Back to MCP directory
publicPublicdnsLocal runtime

mcp-local-rag

一个完全在本地运行的隐私优先文档搜索服务器,通过MCP协议为AI编程工具提供语义搜索功能,无需API密钥或云端服务,所有数据处理均在用户计算机上完成。

article

README

🚀 MCP本地检索增强生成(RAG)

这是一个注重隐私的文档搜索服务器,可完全在本地机器上运行。无需API密钥,不依赖云服务,数据不会离开你的计算机。

该项目基于模型上下文协议(MCP)构建,允许你使用Cursor、Codex、Claude Code或任何MCP客户端,通过语义搜索在本地文档中进行搜索,而无需将任何内容发送到外部服务。

🚀 快速开始

将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

重启你的工具,然后就可以开始使用了:

"Ingest api-spec.pdf"
"What does this document say about authentication?"

就是这么简单,无需安装,无需使用Docker,也无需复杂的设置。

✨ 主要特性

解决痛点

你可能希望使用AI来搜索文档,这些文档可能是技术规范、研究论文、内部文档或会议记录。然而,大多数解决方案都需要将文件发送到外部API,这会带来三个问题:

  • 隐私问题:文档可能包含敏感信息,如客户数据、专有研究或个人笔记。将其发送给第三方服务意味着要将这些数据托付给他们。
  • 大规模使用成本高:外部嵌入API按使用次数收费。对于大量文档或频繁搜索,成本会迅速增加。
  • 网络依赖性:如果离线或网络连接受限,就无法搜索自己的文档。

本项目通过在本地运行所有操作来解决这些问题,文档不会离开你的机器。嵌入模型只需下载一次,之后即可离线使用,并且可以免费无限次使用。

提供的工具

服务器通过MCP提供了五个工具:

  • 文档摄入:支持处理PDF、DOCX、TXT和Markdown文件。指定一个文件后,它会提取文本,将其拆分为可搜索的块,使用本地模型生成嵌入向量,并将所有内容存储在本地向量数据库中。如果再次摄入相同的文件,它会替换旧版本,不会产生重复数据。
  • 语义搜索:允许使用自然语言进行查询。它理解语义,而不是简单的关键词匹配。例如,询问 “how does authentication work” 时,即使相关部分使用了 “login flow” 或 “credential validation” 等不同的表述,也能找到相关内容。
  • 文件管理:显示已摄入的文件及其摄入时间。你可以查看每个文件生成的块数,并验证所有内容是否已正确索引。
  • 文件删除:从向量数据库中删除已摄入的文档。删除文件时,其所有块和嵌入向量将被永久删除。这对于删除过时的文档或不再希望索引的敏感数据非常有用。
  • 系统状态:报告数据库的相关信息,如文档数量、总块数和内存使用情况。有助于监控性能或调试问题。

技术选型

所有功能都基于以下技术:

  • LanceDB:用于向量存储(基于文件,无需服务器)
  • Transformers.js:用于生成嵌入向量(在Node.js中运行,无需Python)
  • all-MiniLM-L6-v2 模型:384维,在速度和准确性之间取得了良好的平衡
  • RecursiveCharacterTextSplitter:用于智能文本分块

性能表现

在标准笔记本电脑上,即使索引了数千个文档块,查询响应通常也能在3秒内完成。

📦 安装指南

本项目无需复杂的安装过程,按照快速开始部分的步骤将MCP服务器添加到你的AI编码工具中即可。

首次运行

服务器会立即启动,但嵌入模型会在首次使用时(即首次摄入或搜索时)下载:

  • 下载大小:约90MB(模型文件)
  • 缓存后的磁盘使用量:约120MB(包括ONNX运行时缓存)
  • 下载时间:在良好的网络连接下需要1 - 2分钟
  • 首次操作延迟:首次摄入或搜索请求将等待模型下载完成

控制台会显示类似 “Initializing model (downloading ~90MB, may take 1 - 2 minutes)…” 的消息。模型会缓存在 CACHE_DIR(默认:./models/)中,以便离线使用。

延迟初始化的原因:这种方式允许服务器立即启动,无需预先加载模型。只有在实际需要时才进行下载,使服务器在快速状态检查或文件管理操作时更具响应性。

离线模式:首次下载后,完全支持离线使用,无需网络连接。

💻 使用示例

配置

服务器默认配置即可使用,但你可以通过环境变量进行自定义。

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"
DB_PATH = "./lancedb"
CACHE_DIR = "./models"

注意:节名称必须为 mcp_servers(使用下划线)。使用 mcp-serversmcpservers 会导致Codex忽略该配置。

Cursor

在Cursor设置中添加以下内容:

  • 全局设置(所有项目):~/.cursor/mcp.json
  • 项目特定设置:项目根目录下的 .cursor/mcp.json
{
  "mcpServers": {
    "local-rag": {
      "command": "npx",
      "args": ["-y", "mcp-local-rag"],
      "env": {
        "BASE_DIR": "/path/to/your/documents",
        "DB_PATH": "./lancedb",
        "CACHE_DIR": "./models"
      }
    }
  }
}

Claude Code

在项目目录中运行以下命令以启用该项目:

cd /path/to/your/project
claude mcp add local-rag --env BASE_DIR=/path/to/your/documents -- npx -y mcp-local-rag

或者为所有项目全局添加:

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

使用其他环境变量

claude mcp add local-rag --scope user \
  --env BASE_DIR=/path/to/your/documents \
  --env DB_PATH=./lancedb \
  --env CACHE_DIR=./models \
  -- npx -y mcp-local-rag

环境变量说明

| 变量 | 默认值 | 描述 | 有效范围 | |------|---------|-------------|-------------| | BASE_DIR | 当前目录 | 文档根目录。服务器仅访问此路径内的文件(防止意外访问系统文件) | 任何有效路径 | | DB_PATH | ./lancedb/ | 向量数据库存储位置。随着文档数量的增加,该目录可能会变得很大 | 任何有效路径 | | CACHE_DIR | ./models/ | 模型缓存目录。首次下载后,模型将保留在此处以便离线使用 | 任何有效路径 | | MODEL_NAME | Xenova/all-MiniLM-L6-v2 | HuggingFace模型标识符。必须与Transformers.js兼容。请参阅 可用模型注意:更改模型需要重新摄入所有文档,因为不同模型的嵌入向量不兼容 | HF模型ID | | MAX_FILE_SIZE | 104857600(100MB) | 文件最大字节数。为防止内存问题,较大的文件将被拒绝 | 1MB - 500MB | | CHUNK_SIZE | 512 | 每个块的字符数。值越大,上下文信息越多,但处理速度越慢 | 128 - 2048 | | CHUNK_OVERLAP | 100 | 块之间的重叠字符数。用于保留跨边界的上下文信息 | 0 - (CHUNK_SIZE/2) |

操作使用

配置后重启客户端

  • Cursor:完全退出并重新启动(在Mac上使用Cmd + Q,而不仅仅是关闭窗口)
  • Codex:重启IDE/扩展
  • Claude Code:无需重启,更改将立即生效

服务器将作为可用工具显示,供你的AI助手使用。

摄入文档

  • Cursor:Composer Agent会在需要时自动使用MCP工具:
"Ingest the document at /Users/me/docs/api-spec.pdf"
  • Codex CLI:助手会在需要时自动使用配置好的MCP工具:
codex "Ingest the document at /Users/me/docs/api-spec.pdf into the RAG system"
  • Claude Code:直接自然提问即可:
"Ingest the document at /Users/me/docs/api-spec.pdf"

路径要求:服务器要求使用文件的绝对路径。你的AI助手通常会自动将自然语言请求转换为绝对路径。BASE_DIR 设置出于安全考虑,限制了对该目录树内文件的访问,但你仍需提供完整路径。

服务器会执行以下操作:

  1. 验证文件是否存在且大小不超过100MB
  2. 提取文本(支持PDF/DOCX/TXT/MD格式)
  3. 将文本拆分为块(每个块512个字符,重叠100个字符)
  4. 为每个块生成嵌入向量
  5. 将其存储在向量数据库中

在标准笔记本电脑上,每MB文件大约需要5 - 10秒。完成后会显示确认信息,包括生成的块数。

搜索文档

使用自然语言提问:

"What does the API documentation say about authentication?"
"Find information about rate limiting"
"Search for error handling best practices"

服务器会执行以下操作:

  1. 将查询转换为嵌入向量
  2. 在向量数据库中搜索相似的块
  3. 返回前5个匹配结果,并显示相似度得分

结果包括文本内容、文件来源和相关性得分。你的AI助手将使用这些结果回答你的问题。

你可以请求更多结果:

"Search for database optimization tips, return 10 results"

限制参数接受1 - 20个结果。

管理文件

查看已索引的文件:

"List all ingested files"

这将显示每个文件的路径、生成的块数以及摄入时间。

从数据库中删除文件:

"Delete /Users/me/docs/old-spec.pdf from the RAG system"

这将从向量数据库中永久删除该文件及其所有块。该操作是幂等的,即删除不存在的文件不会报错。

检查系统状态:

"Show the RAG server status"

这将报告总文档数、总块数、当前内存使用情况和运行时间。

重新摄入文件

如果你更新了文档,请再次摄入:

"Re-ingest api-spec.pdf with the latest changes"

服务器会在添加新块之前自动删除该文件的旧块,不会产生重复或过时的数据。

📚 详细文档

开发相关

从源代码构建

git clone https://github.com/shinpr/mcp-local-rag.git
cd mcp-local-rag
npm install

运行测试

# 运行所有测试
npm test

# 运行测试并生成覆盖率报告
npm run test:coverage

# 开发时的监视模式
npm run test:watch

测试套件包括:

  • 每个组件的单元测试
  • 完整摄入和搜索流程的集成测试
  • 路径遍历保护的安全测试
  • 验证查询速度目标的性能测试

代码质量检查

# 类型检查
npm run type-check

# 代码检查和格式化
npm run check:fix

# 检查循环依赖
npm run check:deps

# 全面质量检查(运行所有检查)
npm run check:all

项目结构

src/
  index.ts          # 入口点,启动MCP服务器
  server/           # RAGServer类,MCP工具处理程序
  parser/           # 文档解析(PDF、DOCX、TXT、MD)
  chunker/          # 文本拆分逻辑
  embedder/         # 使用Transformers.js生成嵌入向量
  vectordb/         # LanceDB操作
  __tests__/        # 测试套件

每个模块都有明确的边界:

  • Parser:验证文件路径并提取文本
  • Chunker:将文本拆分为重叠的段
  • Embedder:生成384维向量
  • VectorStore:处理所有数据库操作
  • RAGServer:协调所有操作并暴露MCP工具

性能表现

测试环境

MacBook Pro M1(16GB RAM),于2025年1月在Node.js 22上使用v0.1.3版本进行测试。

查询性能

  • 平均:对于10,000个索引块(返回5个结果),查询时间为1.2秒
  • 目标:p90 < 3秒(已达成)

摄入速度(10MB PDF)

  • 总计:约45秒
    • PDF解析:约8秒(17%)
    • 文本分块:约2秒(4%)
    • 嵌入向量生成:约30秒(67%)
    • 数据库插入:约5秒(11%)

内存使用

  • 基线:空闲时约200MB
  • 峰值:摄入50MB文件时约800MB
  • 目标:< 1GB(已达成)

并发查询

能够处理5个并行查询而不降低性能。LanceDB的异步API允许非阻塞操作。

注意:实际结果会因硬件而异,尤其是CPU速度(嵌入向量计算在CPU上运行,而非GPU)。

故障排除

"No results found" 搜索无结果

原因:搜索前必须先摄入文档。

解决方案

  1. 首先摄入文档:"Ingest /path/to/document.pdf"
  2. 验证摄入情况:"List all ingested files"
  3. 然后进行搜索:"Search for [your query]"

常见错误:配置完成后未摄入任何文档就立即进行搜索。

"Model download failed" 模型下载失败

嵌入模型在首次使用时(即首次摄入或搜索时)会从HuggingFace下载。如果你使用了代理或防火墙,可能需要配置网络设置。

出现情况:首次摄入或搜索操作会触发下载。如果下载失败,你会看到详细的错误消息和故障排除指导(网络问题、磁盘空间不足、缓存损坏等)。

解决方法:错误消息会提供具体建议。常见解决方案如下:

  1. 检查网络连接并重新尝试操作
  2. 确保有足够的磁盘空间(约120MB)
  3. 如果问题仍然存在,删除缓存目录并再次尝试

或者手动下载模型:

  1. 访问 https://huggingface.co/Xenova/all-MiniLM-L6-v2
  2. 下载模型文件
  3. CACHE_DIR 设置为你保存模型的位置

"File too large" 文件过大错误

默认限制为100MB。对于较大的文件:

  • 可以将其拆分为较小的文档
  • 或者在配置中增加 MAX_FILE_SIZE(注意内存使用情况)

查询性能缓慢

如果查询时间比预期长:

  • 检查已索引的块数(使用 status 命令)
  • 考虑硬件性能(嵌入向量计算对CPU要求较高)
  • 尝试减小 CHUNK_SIZE 以减少块数

"Path outside BASE_DIR" 路径超出BASE_DIR错误

为了安全起见,服务器将文件访问限制在 BASE_DIR 内。请确保文件路径在该目录内。检查以下内容:

  • MCP配置中 BASE_DIR 设置是否正确
  • 相对路径和绝对路径的使用
  • 文件路径是否有拼写错误

MCP客户端无法识别工具

Cursor
  1. 打开设置 → 功能 → 模型上下文协议
  2. 验证服务器配置是否已保存
  3. 完全重启Cursor
  4. 检查状态栏中的MCP连接状态
Codex CLI
  1. 检查 ~/.codex/config.toml 文件以验证配置
  2. 确保节名称为 [mcp_servers.local-rag](使用下划线)
  3. 直接测试服务器:npx mcp-local-rag 应能正常运行且无错误
  4. 重启Codex CLI或IDE扩展
  5. 检查Codex启动时的错误消息
Claude Code
  1. 运行 claude mcp list 查看已配置的服务器
  2. 验证服务器是否在列表中
  3. 检查 ~/.config/claude/mcp_config.json 文件是否有语法错误
  4. 直接测试服务器:npx mcp-local-rag 应能正常运行且无错误

常见问题

  • 配置文件中的JSON语法错误
  • BASE_DIR 设置中的文件路径错误
  • 找不到服务器二进制文件(尝试全局安装:npm install -g mcp-local-rag
  • 防火墙阻止本地通信

工作原理

当你摄入文档时,解析器会根据文件类型提取文本。PDF使用 pdf-parse,DOCX使用 mammoth,文本文件则直接读取。

分块器使用LangChain的RecursiveCharacterTextSplitter将文本拆分。它会尝试在自然边界(段落、句子)处进行拆分,同时保持每个块约512个字符。相邻块重叠100个字符以保留上下文信息。

每个块会通过Transformers.js嵌入模型,将文本转换为384维向量,以表示其语义含义。为了提高效率,每次处理8个块。

向量存储在LanceDB中,这是一个基于本地文件的列式向量数据库,无需服务器进程,也无需复杂的设置,只是一个包含数据文件的目录。

当你进行搜索时,查询会使用相同的模型转换为向量。LanceDB会使用余弦相似度算法找到与查询向量最相似的块。前几个匹配结果会返回给MCP客户端,并包含原始文本和元数据。

这种方法的优点在于:语义相似的文本即使使用不同的词汇,其向量也会相似。例如,“authentication process” 和 “how users log in” 会相互匹配,这与关键词搜索不同。

常见问题解答

这真的能保证隐私吗?

是的。首次下载模型后,没有任何数据会离开你的机器。你可以使用网络监控工具进行验证,摄入或搜索过程中不会有出站请求。

可以离线使用吗?

可以,模型缓存后即可离线使用。首次运行需要联网下载模型(约90MB),之后所有操作都可以离线进行。

与云RAG服务相比如何?

云服务(如OpenAI、Pinecone等)通常提供更高的准确性和可扩展性。但它们需要将文档发送到外部,有持续的成本,并且依赖网络连接。本项目在一定程度上牺牲了准确性,但保证了完全的隐私和零运行成本。

支持哪些文件格式?

目前支持的文件格式有:

  • PDF.pdf(使用 pdf-parse
  • Microsoft Word.docx(使用 mammoth,不支持 .doc
  • 纯文本.txt
  • Markdown.md, .markdown

目前不支持的文件格式有:

  • Excel/CSV:.xlsx, .csv
  • PowerPoint:.pptx
  • 带OCR的图像:.jpg, .png
  • HTML:.html
  • 旧版Word文档:.doc

如果你需要支持其他格式,请 提交问题 并说明使用场景。

可以自定义嵌入模型吗?

可以,将 MODEL_NAME 设置为HuggingFace上任何与Transformers.js兼容的模型。请注意,不同模型的向量维度不同,因此切换模型后需要重建数据库。

准确性在多大程度上依赖于模型?

all-MiniLM-L6-v2 针对英语进行了优化,对于技术文档表现良好。对于其他语言,可以考虑使用多语言模型,如 multilingual-e5-small。如果需要更高的准确性,可以尝试使用更大的模型,但处理速度会变慢。

支持GPU加速吗?

Transformers.js默认在CPU上运行。GPU支持处于实验阶段,且因平台而异。对于大多数使用场景,CPU性能已经足够(即使没有GPU,嵌入向量计算也相当快)。

多人可以共享数据库吗?

当前设计假设为单用户本地访问。对于多用户场景,需要实现身份验证和访问控制,这超出了本项目注重隐私设计的范围。

如何备份数据?

复制 DB_PATH 目录(默认:./lancedb/),这就是整个向量数据库。复制 BASE_DIR 目录以备份原始文档。两者都是普通文件,无需特殊导出操作。

🔧 技术细节

文档处理流程

  1. 解析:根据文件类型使用不同的解析器提取文本。
  2. 分块:使用 RecursiveCharacterTextSplitter 将文本拆分为合适大小的块,并设置重叠部分以保留上下文。
  3. 嵌入:使用 Transformers.jsall-MiniLM-L6-v2 模型将每个块转换为384维向量。
  4. 存储:将向量存储在 LanceDB 中。

搜索流程

  1. 查询转换:将查询文本转换为向量。
  2. 相似度搜索:在 LanceDB 中使用余弦相似度算法查找最相似的向量。
  3. 结果返回:返回匹配结果及其相关信息。

性能优化

  • 批量处理:在生成嵌入向量时,每次处理8个块以提高效率。
  • 异步操作LanceDB 的异步API允许非阻塞操作,提高并发处理能力。

📄 许可证

本项目采用MIT许可证,详情请参阅 LICENSE 文件。

本项目可免费用于个人和商业用途,无需注明出处,但我们对此表示感谢。

致谢

本项目基于以下技术构建:

本项目是为那些希望在不牺牲隐私的前提下使用AI进行文档搜索的开发者而创建的实用工具。

help

Runtime guide

cloud

Hosted runtime

Hosted servers run from a provider-managed environment. You usually connect the MCP client to the hosted endpoint or follow the provider's authorization flow, without keeping a local process alive

  1. Open provider connection page
  2. Authorize or copy endpoint
  3. Connect from your MCP client
terminal

Local runtime / other methods

Local servers run on your own machine or infrastructure. You normally copy the server_config into your MCP client, install the required package, and provide env variables from env_schema when needed

  1. Copy server_config
  2. Install required package
  3. Fill env variables and restart client