PDF索引器MCP服务器
A. 模型上下文协议(MCP)服务器 它使AI代理能够下载、索引和语义搜索PDF研究论文。该服务器提供8个工具,人工智能代理可以自主发现和使用这些工具来构建研究论文知识库和回答问题。
什么是MCP?
模型上下文协议(MCP) 是一种标准化的协议,允许AI代理发现和使用工具。代理不再局限于文本生成,而是成为 行动能力系统 这可以:
- 发现工具:代理自动从连接的MCP服务器中发现可用工具
- 了解能力:代理阅读工具描述和参数,以了解每个工具的功能
- 执行任务:代理调用具有适当参数的工具来实现目标
- 编写工作流:代理可以组合来自不同服务器的多个工具来解决复杂的问题
MCP的工作原理
AI Agent → MCP Protocol → Tool Server → Execution → Results → Agent当您将此MCP服务器连接到AI代理(如Cursor、Claude Desktop或通过OpenAI代理框架)时,代理会自动:
- 发现此服务器上可用的所有8个工具
- 从描述中了解每个工具的功能
- 在需要完成任务时使用工具
- 可以在复杂的工作流程中组合工具
特性
- 📥 PDF下载:从URL下载研究论文
- 📄 智能分块:两种组块策略:
- 基于标头:保留文档结构(非常适合学术论文) - S2分块:用于优化语义块的空间语义混合方法
- 🗄️ 数据库索引:使用导航索引将纸张和块存储在SQLite中
- 🔍 语义搜索:使用MLX优化嵌入(Qwen3-Embedded-0.6B)搜索论文
- ⚡ FAISS矢量索引:快速相似性搜索,甚至可以搜索数千个块
- 🧠 上下文感知:检索周围的块以获得更好的上下文
快速入门:建议提示
配置MCP服务器后,您可以使用以下提示:
"I have this research paper URL: [URL]. Please download it, index it,
make it searchable, and then search for information about [topic]."或者更简单地说:
"Download and index this paper: [URL], then search it for information about [topic]."代理将自动:
- 下载PDF
- 将其编入数据库
- 生成语义搜索的嵌入
- 搜索相关内容
- 展示结果
安装
选项1:从GitHub安装(推荐)
# Clone the repository
git clone https://github.com/lizTheDeveloper/pdf-indexer-mcp.git
cd pdf-indexer-mcp
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt选项2:通过pip安装(发布后)
pip install pdf-indexer-mcpMCP服务器设置
用于游标IDE
- 查找MCP配置文件:
- macOS: ~/Library/Application Support/Cursor/User/globalStorage/mcp.json - 视窗: %APPDATA%\Cursor\User\globalStorage\mcp.json - Linux: ~/.config/Cursor/User/globalStorage/mcp.json
- 添加配置 (如果文件不存在,则创建文件):
{
"mcpServers": {
"pdf-indexer": {
"command": "/absolute/path/to/pdf_indexer_mcp/venv/bin/python3",
"args": [
"/absolute/path/to/pdf_indexer_mcp/semantic_chunked_pdf_rag.py"
],
"env": {}
}
}
}- 重新启动游标 完全(而不仅仅是重新加载)
- 验证:重新启动后,您应该看到8个可用工具:
- mcp_pdf-indexer_download_pdf - mcp_pdf-indexer_chunk_pdf - mcp_pdf-indexer_index_pdf - mcp_pdf-indexer_list_indexed_papers - mcp_pdf-indexer_get_document_structure - mcp_pdf-indexer_get_document_section - mcp_pdf-indexer_generate_embeddings - mcp_pdf-indexer_search_research_papers
适用于克劳德桌面
- 查找MCP配置文件:
- macOS: ~/Library/Application Support/Claude/claude_desktop_config.json - 视窗: %APPDATA%\Claude\claude_desktop_config.json - Linux: ~/.config/Claude/claude_desktop_config.json
- 添加相同的配置 同上
- 重新启动克劳德桌面 完全
OpenAI代理框架
from agents import Agent, Runner
from agents.mcp import MCPServerStdio
async with MCPServerStdio(
name="PDF Indexer",
params={
"command": "/path/to/pdf_indexer_mcp/venv/bin/python3",
"args": ["/path/to/pdf_indexer_mcp/semantic_chunked_pdf_rag.py"],
},
) as pdf_indexer_server:
agent = Agent(
name="Research Assistant",
instructions="Help users search and analyze research papers",
mcp_servers=[pdf_indexer_server],
model="gpt-4"
)
result = await Runner.run(
agent,
"Download and index this paper: https://arxiv.org/pdf/1706.03762.pdf"
)可用的MCP工具
该服务器公开了AI代理可以使用的8个工具。当服务器连接时,代理会自动发现工具。
1. download_pdf(url: str)
它做什么:从URL下载PDF研究论文并将其保存在本地。
当代理人使用它时:当您要求下载论文时,代理会自动发现并使用此工具。
代理工作流程示例:
User: "Download the attention paper from arxiv"
Agent:
1. Discovers download_pdf tool
2. Calls: download_pdf("https://arxiv.org/pdf/1706.03762.pdf")
3. Returns: Downloaded paper saved as "1706.03762.pdf"退货:
success: 布尔filename:str(例如,“1706.03762.pdf”)filepath:str(绝对路径)message:str
2. chunk_pdf(filename: str, method: str = "header")
它做什么:从PDF中提取文本,并使用基于页眉或S2分块对其进行分块。
参数:
filename:PDF文件名(必须在papers/目录)method:"header"(默认)或"s2"空间语义分块
当代理人使用它时:当被要求分析或处理PDF的结构时。
退货:
success: 布尔num_chunks:intchunks:带有预览文本的块字典列表method:str(使用分块方法)
3. index_pdf(filename: str, url: str = "", method: str = "header")
它做什么:完成索引工作流程-下载(如果需要)、块和存储在数据库中。
当代理人使用它时:代理使用的最常见的工具-它处理整个管道。
代理工作流程示例:
User: "Index this paper and make it searchable"
Agent:
1. Discovers index_pdf tool
2. Calls: index_pdf("paper.pdf", url="https://...", method="header")
3. Paper is now in database and searchable退货:
success: 布尔paper_id:int(数据库ID)num_chunks:intnum_sections:int(用于头方法)message:str
4. list_indexed_papers()
它做什么:列出数据库中当前索引的所有论文。
当代理人使用它时当被问及“你有什么文件?”或“给我看看所有文件”时。
退货:
success: 布尔count:intpapers:纸张元数据列表
5. get_document_structure(filename: str)
它做什么:获取论文的完整结构(节、标题、块范围)。
当代理人使用它时当你询问一篇论文的结构或章节时。
退货:
success: 布尔structure:带纸张元数据和章节列表的字典
6. get_document_section(filename: str, ...)
它做什么:检索文档的特定部分。
参数 (使用其中之一):
chunk_index:int-按索引获取特定块header_path:str-按标题路径获取节(例如“Introduction”)page_start/page_end:int-获取页面范围内的块
当代理人使用它时:当被问到“给我看介绍部分”或“获取第5-10页”时。
退货:
success: 布尔paper_id:intnum_chunks:intchunks:完整块内容列表
7. generate_embeddings(filename: str, model_name: str = "mlx-community/Qwen3-Embedding-0.6B")
它做什么:为论文中的所有块生成语义嵌入,并将其添加到FAISS向量索引中。
当代理人使用它时:代理在语义搜索之前自动使用此功能。
代理工作流程示例:
User: "Make this paper searchable"
Agent:
1. Calls index_pdf() - indexes the paper
2. Calls generate_embeddings() - makes it searchable
3. Paper is now ready for semantic search退货:
success: 布尔paper_id:intnum_embeddings:intembedding_dim:int(1024表示Qwen3-Embedded-0.6B)model_name:str
8. search_research_papers(query: str, k: int = 5, context_window: int = 1, model_name: str = "mlx-community/Qwen3-Embedding-0.6B")
它做什么:使用嵌入从语义上搜索所有索引论文,并返回最相关的块。
参数:
query:搜索查询文本k:顶部结果数(默认值:5)context_window:要包含的相邻块数(默认值:1)model_name:嵌入模型(默认:Qwen3-Embedded-0.6B)
当代理人使用它时当被问及“查找关于变压器的论文”或“寻找注意力机制”等问题时。
代理工作流程示例:
User: "What papers discuss attention mechanisms?"
Agent:
1. Discovers search_research_papers tool
2. Calls: search_research_papers("attention mechanisms", k=5)
3. Gets relevant chunks with context
4. Synthesizes answer from results退货:
success: 布尔query:str(原始查询)num_results:intresults:结果字典列表,包括:
- chunk_id, paper_id, filename, title - text:整段文本 - header_path:截面位置 - page_start, page_end:页码 - distance:相似性得分(较低=更相似) - is_context:bool(如果上下文块为true,则不直接匹配)
代理如何使用这些工具
自主工具发现
当您连接此MCP服务器时,代理会自动发现所有8个工具。每个工具都有:
- 名字:这个工具叫什么
- 描述:该工具的功能是什么(代理商阅读此内容!)
- 参数:工具需要哪些输入
- 传回型别:工具返回什么
代理使用这些描述来了解何时使用每个工具。
典型代理工作流程
User: "Find papers about transformers and summarize the key findings"
Agent workflow:
1. Discovers list_indexed_papers() → checks what's available
2. Discovers search_research_papers() → searches for "transformers"
3. Discovers get_document_section() → gets more context for top results
4. Synthesizes findings into summary
All tool calls happen autonomously!多工具组合
代理可以以复杂的方式组合工具:
# Example: Agent decides to do a complete research workflow
1. download_pdf("https://arxiv.org/pdf/...")
→ Downloads paper
2. index_pdf("paper.pdf", url="...", method="header")
→ Indexes paper in database
3. generate_embeddings("paper.pdf")
→ Makes it searchable
4. search_research_papers("related topic", k=5)
→ Finds related papers
5. get_document_section(filename, header_path="Introduction")
→ Gets specific sections for context完整使用示例
通过光标/克劳德桌面
配置并重新启动MCP服务器后,您只需询问:
You: "Download and index this paper about transformers"
Agent: [Automatically uses download_pdf and index_pdf tools]
You: "Search for papers about attention mechanisms"
Agent: [Automatically uses search_research_papers tool]
You: "Show me the Introduction section of the transformer paper"
Agent: [Automatically uses get_document_section tool]通过OpenAI代理框架
from agents import Agent, Runner
from agents.mcp import MCPServerStdio
async with MCPServerStdio(
name="PDF Indexer",
params={
"command": "/path/to/venv/bin/python3",
"args": ["/path/to/semantic_chunked_pdf_rag.py"],
},
) as pdf_server:
agent = Agent(
name="Research Assistant",
instructions="""
You help users manage and search research papers.
You can download, index, and search papers using the available tools.
""",
mcp_servers=[pdf_server],
model="gpt-4"
)
# Agent autonomously uses tools
result = await Runner.run(
agent,
"Download this paper, index it, make it searchable, and then search for related work on attention"
)
print(result.final_output)封装结构
pdf_indexer_mcp/
├── semantic_chunked_pdf_rag.py # Main MCP server (exposes tools)
├── utils/ # Logging utilities
├── pdf_processing/ # PDF text extraction
├── chunking/ # Chunking algorithms
├── database/ # Database models and operations
├── embeddings/ # MLX embedding generation and FAISS
├── papers/ # Downloaded PDFs (created automatically)
├── indexes/ # Database and FAISS indices (created automatically)
├── logs/ # Log files (created automatically)
├── requirements.txt # Python dependencies
├── pyproject.toml # Package metadata for pip
├── LICENSE # GPL-3.0 copyleft license
└── README.md # This file学习RAG(检索增强生成)
此MCP服务器演示了一个完整的 RAG(检索增强生成) 研究论文的管道。理解RAG对于构建能够访问和使用外部知识的有效AI系统至关重要。
什么是RAG?
检索增强生成 将信息检索与语言生成相结合,使LLM能够:
- 检索 外部来源的相关信息(此处:研究论文)
- 增强 LLM的上下文与检索到的信息
- 生成 基于检索内容的响应
RAG使系统能够使用最新的、特定于领域的信息来回答问题,而不是仅仅依赖预先训练的知识。
此服务器如何实现RAG
此MCP服务器提供完整的RAG实现:
1. 文件摄入 (检索设置)
download_pdf():从URL获取论文index_pdf():提取和分块文本,存储在数据库中- 创建可搜索的知识库
2. 语义索引 (矢量搜索)
generate_embeddings():将文本块转换为语义向量- 使用MLX优化的嵌入(Qwen3-Embedded-0.6B,1024维)
- 在FAISS中存储向量以进行快速相似性搜索
3. 检索 (查找相关内容)
search_research_papers():在所有论文中进行语义搜索- 根据含义而不仅仅是关键字查找相关块
- 返回带有上下文的排名结果
4. 增强 (上下文增强)
get_document_section():从特定部分检索完整上下文- 包括周围的块,以便更好地理解
- 提供元数据(节、页、标题)
5. 生成 (LLM回应)
- 代理接收检索到的块
- 将它们用作背景,以生成有根据的响应
- 答案基于实际的论文内容,而不仅仅是训练数据
RAG管道流量
User Query
↓
Semantic Search (search_research_papers)
↓
Find Relevant Chunks (FAISS vector search)
↓
Retrieve Context (get_document_section if needed)
↓
Augment LLM Context (pass chunks to LLM)
↓
Generate Response (grounded in retrieved content)展示关键RAG概念
- 分块策略:显示了两种方法:
- 基于标头:保留结构,是学术论文的理想选择 - S2分块:非结构化文档的空间语义混合
- 语义搜索:使用嵌入来寻找意义,而不仅仅是关键字
- “注意力机制”即使没有确切的单词,也能找到相关的概念 - 优于传统关键字搜索
- 向量数据库:快速相似性搜索失败
- 扩展到数千个块 - 亚毫秒搜索时间
- 增量索引:添加论文而不重建整个索引
- 每篇论文都可以独立索引 - 逐步添加嵌入
- 上下文窗口:检索周围的块以获得更好的上下文
- 有助于保持叙述流畅 - 为理解提供背景
为什么RAG很重要
没有RAG:法学硕士只能使用预先培训的知识,可能是:
- 过时(培训数据截止)
- 通用(非特定域)
- 有限(无法访问私人/出版物)
与RAG:LLM可以:
- 获取最新信息(新发表的论文)
- 使用特定领域的知识(研究论文)
- 可核查来源的地面反应
- 回答有关不在培训数据中的文件的问题
RAG最佳实践(本实施)
- 有效分组:平衡块大小-太小会失去上下文,太大会削弱相关性
- 语义嵌入:使用针对您的领域优化的模型(此处:研究论文)
- 矢量搜索:快速检索至关重要(FAISS提供亚毫秒级搜索)
- 元数据保存:保留标题、页面、部分以供导航
- 上下文检索:包括周围的块,以便更好地理解
进一步学习
为了更好地理解RAG:
- 尝试不同的组块方法(header vs S2)
- 尝试不同的嵌入模型
- 调整search_research_paper()中的context_window
- 探索数据库结构,了解块是如何存储的
- 检查日志以查看性能指标
此实现提供了一个可用于生产的RAG系统,您可以研究和扩展。
需求
- python:3.9+(numpy 2.2.6等依赖项要求)
- 平台:macOS(用于MLX优化),Linux/Windows(带CPU回退)
- 随机存取存储器:约500MB用于嵌入
- 磁盘:~1GB用于模型下载(首次运行)
技术细节
嵌入模型
- 模型:
mlx-community/Qwen3-Embedding-0.6B - 维度: 1024
- 框架:MLX(针对Apple Silicon进行了优化)
- 速度:Apple Silicon上每秒约35次嵌入
分块方法
基于标头 (method="header"):
- 最适合结构清晰的学术论文
- 保留文档层次结构
- 将内容分组到标题下
S2堵塞 (method="s2"):
- 混合空间语义方法
- 将布局分析与语义相似性相结合
- 最适合非结构化文档
存储
- 数据库:SQLite(
indexes/research_papers.db) - 向量索引:FAISS(
indexes/research_papers.faiss) - 映射:NumPy数组(
indexes/research_papers_mapping.npy)
故障排除
MCP服务器未启动
- 验证虚拟环境:
which python3 # Should show path in venv/bin/python3- 检查相关性:
pip list | grep fastmcp- 手动测试服务器:
python semantic_chunked_pdf_rag.py如果启动时没有错误,请按Ctrl+C停止。
- 检查日志:
tail -f logs/pdf_indexer_*.log代理中未显示工具
- 完全重新启动 (不仅仅是重新加载)
- 检查配置路径 是绝对的(不是相对的)
- 验证Python路径 指向虚拟环境
- 检查MCP日志 连接错误
嵌入生成失败
- 验证MLX是否已安装:
python -c "import mlx.core as mx; print('OK')"- 检查可用RAM (需要~500MB)
- 首次运行 自动下载模型(可能需要时间)
搜索未返回任何结果
- 验证索引文件:
# Agents should discover list_indexed_papers() tool- 生成嵌入:
# Agents should discover generate_embeddings() tool- 检查FAISS指数是否存在 在
indexes/目录
贡献
欢迎投稿!该项目使用GPL-3.0 copyleft许可。
许可证
GNU通用公共许可证v3.0(GPL-3.0)-Copyleft许可证
版权所有(C)2025 Liz Howard(@lizTheDeveloper)
看 许可证 文件以获取完整的许可证文本。
链接
- 仓库: https://github.com/lizTheDeveloper/pdf-indexer-mcp
- 问题: https://github.com/lizTheDeveloper/pdf-indexer-mcp/issues
- 作者:利兹·霍华德(@lizTheDeveloper)
