研究摘录pdf论文
MCP服务器,通过模型上下文协议(MCP)接口在arXiv中搜索研究论文,下载其PDF,提取结构化内容,并用语义嵌入对其进行索引。
______________________________________________________________________
目录
______________________________________________________________________
1.工程概况
研究摘录pdf论文 是基于Python的 模型上下文协议(MCP) 服务器,使AI助手和LLM管道能够:
- 搜索 arXiv适用于任何主题的研究论文。
- 下载并解析 将PDF转换为干净的Markdown文本。
- 块 将提取的文本分成准备嵌入的部分。
- 嵌入 使用可配置的嵌入模型(Google Gemini、Voyage AI或OpenAI)的块。
- 商店 在Redis中嵌入,以便以后进行语义检索。
- 检索 按纸张ID保存纸张元数据。
主要用例
| 用例 | 描述 |
|---|---|
| 研究助理 | 向法学硕士提供按主题检索的相关论文的全文。 |
| 语义纸张搜索 | 为RAG(检索增强生成)构建纸张块的矢量存储。 |
| 文献综述自动化 | 自动发现、下载和索引任何主题的论文。 |
| 引文和元数据查找 | 快速查找论文ID的作者、摘要和发表日期 |
______________________________________________________________________
2.特点
- 🔍 arXiv搜索 --按主题查询arXiv,结果计数可配置;结果以JSON格式保存在本地。
- 📄 PDF提取 --通过HTTP获取PDF,并使用PyMuPDF/pymupdf4llm将其转换为Markdown。
- ✂️ 分段感知分块 --在以下位置拆分纸张
##-分级标题以生成有意义的文本块。 - 🧮 可插拔嵌入模型 --支持Gemini(
gemini-embedding-001),航行(voyage-3),以及OpenAI(text-embedding-3-small)通过LiteLLM。 - 🗄️ Redis兼容密钥方案 --块按以下方式键入 `doc:paper:
:chunk:` 为了便于检索。
- ✅ 索引状态跟踪 --本地JSON元数据跟踪论文是否已完全嵌入。
- 🐳 Docker支持 --包括a
Dockerfile用于集装箱化部署。 - 🧪 测试套件 --基于pytest的测试,对所有网络/文件I/O进行模拟。
- 🛠️ Makefile自动化 --一个命令格式、lint、测试和覆盖工作流。
______________________________________________________________________
3.技术栈和语言组成
| 层 | 技术 |
|---|---|
| 语言 | Python 3.14 |
| MCP框架 | [mcp[fastmcp]](https://github.com/modelcontextprotocol/python-sdk) |
| arXiv API客户端 | arxiv |
| PDF解析 | PyMuPDF (fitz) + pymupdf4llm |
| HTTP客户端 | httpx |
| 嵌入模型 | litellm (双子座/航海/OpenAI) |
| 包管理器 | uv |
| 代码格式 | black |
| Linting | pylint |
| 测试 | pytest + pytest-cov |
| 容器化 | Docker(python:3.12-lim-base——见下面的注释) |
⚠️ 注:pyproject.toml声明requires-python = ">=3.14"和.python-version针3.14,但是Dockerfile目前使用python:3.12-slim。要获得完全一致的容器构建,请更新FROM排队Dockerfile到python:3.14-slim一旦稳定的图像可用。 |环境|python-dotenv|
______________________________________________________________________
4.存储库结构
research-extract-pdf-papers/
├── research_server.py # Main MCP server — all tool definitions live here
├── main.py # Minimal standalone entrypoint (prints hello message)
├── test_server.py # pytest test suite for research_server.py
├── pyproject.toml # Project metadata and dependency declarations (uv/pip)
├── uv.lock # Locked dependency versions for reproducible installs
├── Makefile # Dev automation: format / lint / test / coverage / clean
├── Dockerfile # Container build definition
├── .dockerignore # Files excluded from Docker build context
├── .gitignore # Git-ignored paths (envs, caches, PDFs, logs)
├── .python-version # Pinned Python version (3.14, used by pyenv/uv)
├── LICENSE # MIT License
└── papers/ # Auto-created at runtime; stores per-topic sub-directories
└── /
└── papers_info.json # Metadata for papers found under that topic密钥文件: research_server.py
包含五个暴露于任何连接的MCP客户端的MCP工具:
| 工具 | 目的 |
|---|---|
search_papers(topic, max_results) | 搜索arXiv并将元数据保存到 papers//papers_info.json |
extract_info(paper_id) | 返回特定纸张ID的已保存元数据JSON |
extract_chunks(paper_id, pdf_url) | 下载PDF,转换为Markdown,拆分成数字块 |
embed_chunk(text) | 为单个文本块生成嵌入向量 |
mark_paper_indexed(paper_id) | 设置 indexed: true 论文完全存储后,在本地元数据中 |
______________________________________________________________________
5.安装与设置
先决条件
| 要求 | 版本 |
|---|---|
| Python | ≥3.14 |
uv | 最新推荐 |
| Redis | 任何最新版本(运行时需要矢量存储) |
| 嵌入API密钥 | Gemini、Voyage AI或OpenAI |
逐步本地设置
# 1. Clone the repository
git clone https://github.com/Muhammadyousafrana/research-extract-pdf-papers.git
cd research-extract-pdf-papers
# 2. Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 3. Install project dependencies
uv pip install .
# 4. Copy and configure environment variables
cp .env.example .env # create .env from the example (see Configuration section)
# Edit .env and fill in at least one embedding API key
# 5. Run the MCP server (stdio transport — suitable for MCP clients)
python research_server.pyDocker设置
# Build the image
docker build -t research-mcp .
# Run (pass env vars at runtime)
docker run --rm -e GEMINI_API_KEY=your_key research-mcp______________________________________________________________________
6.使用方法
运行MCP服务器
服务器使用 stdio传输 并且被设计为连接到MCP兼容客户端(例如Claude Desktop、LLM管道或任何MCP主机)。
python research_server.py连接后,MCP客户端可以直接调用这些工具。以下是交互示例:
示例:搜索论文
# Via MCP client call
search_papers(topic="retrieval augmented generation", max_results=5)
# Returns: ["2301.07041", "2305.14283", ...]
# Side effect: saves papers/retrieval_augmented_generation/papers_info.json示例:检索纸张元数据
extract_info(paper_id="2301.07041")
# Returns JSON:
# {
# "title": "Precise Zero-Shot Dense Retrieval without Relevance Labels",
# "authors": ["Luyu Gao", "Xueguang Ma", ...],
# "summary": "...",
# "pdf_url": "https://arxiv.org/pdf/2301.07041",
# "published": "2023-01-17",
# "indexed": false
# }示例:提取PDF块(索引的第一步)
extract_chunks(
paper_id="2301.07041",
pdf_url="https://arxiv.org/pdf/2301.07041"
)
# Returns JSON:
# {
# "status": "ok",
# "paper_id": "2301.07041",
# "total_chunks": 12,
# "chunks": [
# {"index": 0, "redis_key": "doc:paper:2301.07041:chunk:0", "text": "..."},
# ...
# ]
# }示例:嵌入块(索引的第2步)
embed_chunk(text="Retrieval-augmented generation combines parametric...")
# Returns JSON:
# {"status": "ok", "vector": [0.012, -0.034, ..., 0.091]} # 3072 floats (Gemini)示例:将纸张标记为索引(索引的第3步)
mark_paper_indexed(paper_id="2301.07041")
# Returns: "Paper '2301.07041' marked as indexed."完整的索引工作流程
1. search_papers(topic) → get list of paper IDs
2. extract_info(paper_id) → get pdf_url from metadata
3. extract_chunks(paper_id, url) → get text chunks + redis_key for each
4. For each chunk:
embed_chunk(chunk.text) → get vector
RedisMCPServer:hset(...) → store text fields
RedisMCPServer:set_vector_in_hash(...) → store vector
5. mark_paper_indexed(paper_id) → flag as done______________________________________________________________________
7.配置
配置通过环境变量提供(自动加载 python-dotenv 如果a .env 文件存在)。
环境变量
| 变量 | 必填 | 描述 |
|---|---|---|
GEMINI_API_KEY | 如果使用Gemini | Google Gemini嵌入的API密钥 |
VOYAGE_API_KEY | 如果使用Voyage | API键进行Voyage AI嵌入 |
OPENAI_API_KEY | 如果使用OpenAI | API密钥进行OpenAI嵌入 |
创建一个 .env 项目根目录中的文件:
# .env — fill in whichever embedding provider you use
GEMINI_API_KEY=your_gemini_key_here
# VOYAGE_API_KEY=your_voyage_key_here
# OPENAI_API_KEY=your_openai_key_here嵌入模型选择
主动模型由以下两个常数控制 research_server.py:
# Gemini (default) — 3072 dimensions
EMBEDDING_MODEL = "gemini/gemini-embedding-001"
EMBEDDING_DIMS = 3072
# Voyage — uncomment to switch
# EMBEDDING_MODEL = "voyage/voyage-3"
# EMBEDDING_DIMS = 1024
# OpenAI — uncomment to switch
# EMBEDDING_MODEL = "openai/text-embedding-3-small"
# EMBEDDING_DIMS = 1536Redis密钥前缀
按键按模式排列 doc:paper: :chunk:.前缀 doc: 可通过配置 REDIS_PREFIX 恒常 research_server.py.
纸张存储目录
下载的纸张元数据存储在 ./papers/ 默认情况下。这是由控制 PAPER_DIR 恒常 research_server.py.
______________________________________________________________________
8.测试
该项目使用 pytest 单元测试在 test_server.py。所有网络和文件I/O都被模拟,因此测试完全脱机运行。
运行测试套件
# Using make (recommended)
make test
# Or directly with pytest
python -m pytest test_server.py -v --tb=short带覆盖率运行
make coverage
# Opens a full HTML report at htmlcov/index.html运行格式和linting检查
make format # auto-format with black
make format-check # check formatting without changes (suitable for CI)
make lint # run pylint (fails if score ` 并检查HTTP 200。
- 一些arXiv论文的访问权限受到限制。使用 `/pdf/` URL的变体,而不是抽象页面。
### 下载PDF时出现HTTP错误
**症状:** `{"status": "error", "error": "connection refused"}` 或 `httpx.HTTPStatusError`
**修复:**
- 检查您的互联网连接/公司代理设置。
- arXiv有时会限制快速下载。在通话之间添加一个短暂的延迟。
- 这 `httpx.get` 呼叫使用30秒超时。增加它 `research_server.py` 如果需要: `timeout=60`.
### 嵌入API关键错误
**症状:** `litellm.AuthenticationError` 或类似
**修复:**
- 确保设置了正确的环境变量(`GEMINI_API_KEY`, `VOYAGE_API_KEY`,或 `OPENAI_API_KEY`).
- 确认密钥已加载--添加 `from dotenv import load_dotenv; load_dotenv()` 在...的顶部 `research_server.py` 如果还没有。
- 验证密钥是否有足够的配额/信用。
### `papers_info.json` 未找到
**症状:** `extract_info` 总是回来 `"There's no saved information related to paper ."`
**修复:** 跑 `search_papers` 首先是相关话题。JSON文件是在第一次成功的搜索调用时创建的。
### Python版本不匹配
**症状:** Python\<3.14上的语法错误或导入失败
**修复:** 该项目需要Python 3.14+。使用 `pyenv install 3.14` 或者切换到使用Python 3.12的Docker镜像(调整 `pyproject.toml` `requires-python` 如果你需要以3.12为目标)。
### `uv` 命令未找到
**修复:** 安装 `uv` 与:
curl -LsSf https://astral.sh/uv/install.sh | sh
______________________________________________________________________
## 10.贡献
欢迎投稿!请遵循以下工作流程:
1. **分叉** GitHub上的存储库。
1. **创建分支** 对于您的更改:git checkout -b feat/my-new-feature
1. **进行更改**,然后运行完整的质量套件:make # format + lint + test
1. **提交** 带有清晰、描述性的信息:git commit -m "feat: add support for Semantic Scholar API"
1. **推** 你的分支机构和打开一个 **拉取请求** 反对 `main`.
### 指南
- 保持函数的焦点,并添加/更新文档字符串以匹配。
- 新工具应遵循现有的MCP `@mcp.tool()` 装饰图案。
- 所有新代码都必须包含在测试中 `test_server.py`.
- 跑 `make format-check` 和 `make lint` 在提交之前,CI将强制执行这两项。
______________________________________________________________________
## 11.许可证
该项目根据 **MIT许可证**.\
看 [许可证](LICENSE) 文件全文。
______________________________________________________________________
## 12.安全和隐私说明
### 安全处理PDF
- PDF通过HTTPS获取,并使用PyMuPDF在内存中完全解析——没有临时PDF文件写入磁盘。
- 恶意PDF可以利用PDF解析器漏洞。保持 `pymupdf` / `fitz` 更新到最新版本。
- 不要将不受信任的用户提供的URL直接传递给 `extract_chunks` 未经验证;攻击者可以使服务器向内部网络资源(SSRF)发出请求。添加URL分配(例如限制为 `arxiv.org`)如果服务器暴露于不可信的输入。
### API密钥和秘密
- 永不承诺 `.env` 文件或版本控制的API密钥。 `.env` 已在中列出 `.gitignore`.
- 旋转任何意外暴露的按键。
- 使用特定于环境的机密管理(例如Docker机密、GitHub Actions机密),而不是简单的 `.env` 生产中的文件。
### 论文中的敏感数据
- 下载的纸质文本可能包括姓名、机构隶属关系和其他个人身份信息。如果您的用例再次暴露了这些数据,请根据适用的数据保护法规(GDPR等)处理提取的内容。
- 在生产部署中,应使用身份验证和TLS保护存储在Redis中的嵌入向量。
### 依赖安全
- 依赖关系已锁定 `uv.lock` 为了可重复性。
- 定期审核依赖关系 `uv pip check` 或工具,例如 `pip-audit`.