🚀 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-servers 或 mcpservers 會導致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"
"Ingest the document at /Users/me/docs/api-spec.pdf"
路徑要求:服務器要求使用文件的絕對路徑。你的AI助手通常會自動將自然語言請求轉換為絕對路徑。BASE_DIR 設置出於安全考慮,限制了對該目錄樹內文件的訪問,但你仍需提供完整路徑。
服務器會執行以下操作:
- 驗證文件是否存在且大小不超過100MB
- 提取文本(支持PDF/DOCX/TXT/MD格式)
- 將文本拆分為塊(每個塊512個字符,重疊100個字符)
- 為每個塊生成嵌入向量
- 將其存儲在向量數據庫中
在標準筆記本電腦上,每MB文件大約需要5 - 10秒。完成後會顯示確認信息,包括生成的塊數。
搜索文檔
使用自然語言提問:
"What does the API documentation say about authentication?"
"Find information about rate limiting"
"Search for error handling best practices"
服務器會執行以下操作:
- 將查詢轉換為嵌入向量
- 在向量數據庫中搜索相似的塊
- 返回前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" 搜索無結果
原因:搜索前必須先攝入文檔。
解決方案:
- 首先攝入文檔:
"Ingest /path/to/document.pdf"
- 驗證攝入情況:
"List all ingested files"
- 然後進行搜索:
"Search for [your query]"
常見錯誤:配置完成後未攝入任何文檔就立即進行搜索。
"Model download failed" 模型下載失敗
嵌入模型在首次使用時(即首次攝入或搜索時)會從HuggingFace下載。如果你使用了代理或防火牆,可能需要配置網絡設置。
出現情況:首次攝入或搜索操作會觸發下載。如果下載失敗,你會看到詳細的錯誤消息和故障排除指導(網絡問題、磁盤空間不足、緩存損壞等)。
解決方法:錯誤消息會提供具體建議。常見解決方案如下:
- 檢查網絡連接並重新嘗試操作
- 確保有足夠的磁盤空間(約120MB)
- 如果問題仍然存在,刪除緩存目錄並再次嘗試
或者手動下載模型:
- 訪問 https://huggingface.co/Xenova/all-MiniLM-L6-v2
- 下載模型文件
- 將
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
- 打開設置 → 功能 → 模型上下文協議
- 驗證服務器配置是否已保存
- 完全重啟Cursor
- 檢查狀態欄中的MCP連接狀態
Codex CLI
- 檢查
~/.codex/config.toml 文件以驗證配置
- 確保節名稱為
[mcp_servers.local-rag](使用下劃線)
- 直接測試服務器:
npx mcp-local-rag 應能正常運行且無錯誤
- 重啟Codex CLI或IDE擴展
- 檢查Codex啟動時的錯誤消息
Claude Code
- 運行
claude mcp list 查看已配置的服務器
- 驗證服務器是否在列表中
- 檢查
~/.config/claude/mcp_config.json 文件是否有語法錯誤
- 直接測試服務器:
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 目錄以備份原始文檔。兩者都是普通文件,無需特殊導出操作。
🔧 技術細節
文檔處理流程
- 解析:根據文件類型使用不同的解析器提取文本。
- 分塊:使用
RecursiveCharacterTextSplitter 將文本拆分為合適大小的塊,並設置重疊部分以保留上下文。
- 嵌入:使用
Transformers.js 和 all-MiniLM-L6-v2 模型將每個塊轉換為384維向量。
- 存儲:將向量存儲在
LanceDB 中。
搜索流程
- 查詢轉換:將查詢文本轉換為向量。
- 相似度搜索:在
LanceDB 中使用餘弦相似度算法查找最相似的向量。
- 結果返回:返回匹配結果及其相關信息。
性能優化
- 批量處理:在生成嵌入向量時,每次處理8個塊以提高效率。
- 異步操作:
LanceDB 的異步API允許非阻塞操作,提高併發處理能力。
📄 許可證
本項目採用MIT許可證,詳情請參閱 LICENSE 文件。
本項目可免費用於個人和商業用途,無需註明出處,但我們對此表示感謝。
致謝
本項目基於以下技術構建:
本項目是為那些希望在不犧牲隱私的前提下使用AI進行文檔搜索的開發者而創建的實用工具。