arxiv-agent-mcp
arXiv Research-Concept Companion
一个 AI/ML 学习伴侣代理(KSE Agentic Lab 作业)。它从你的 Obsidian 库中读取概念摘要笔记,查找相关的 arXiv 论文,根据主题相关性和按年龄调整的引用影响力对每篇论文进行评分,找出幸存候选者所依赖的成熟论文,并将结果写回库中。
现有 MCP 服务器(A 部分): Obsidian Local REST API MCP。
自定义 MCP 服务器(B 部分):
custom_server/— FastMCP 应用,通过公共 arXiv 和 OpenAlex API 提供 3 个工具(无需认证)。代理:
agent/— 一个 PydanticAIAgent(基于 OpenRouter),将两个 MCP 连接作为工具集持有,由 LangGraph 状态机编排。
先决条件
Python 3.12+,
uv。一个 OpenRouter API 密钥。
安装了 Local REST API 社区插件并正在运行的 Obsidian,以及一个与之通信的 MCP 服务器(任何 Obsidian Local REST API MCP 实现——启动命令可配置,见下文)。
Related MCP server: arxiv-mcp
安装
uv sync
cp .env.example .env填写 .env:
变量 | 含义 |
| OpenRouter 密钥——由代理和 |
| 模型标识,例如 |
| Local REST API 插件凭据。 |
| 用于启动你的 Obsidian MCP 服务器的空格分隔参数,例如 |
| 通过筛选的最低相关性分数(0–1)。默认 |
| 通过影响力检查的最低每年引用次数。默认 |
| 比这更年轻的论文可免于影响力检查。默认 |
运行
两个独立进程,共享一个 uv 项目:
# process 1 — the custom MCP server (arXiv + OpenAlex)
uv run python -m custom_server.server
# process 2 — the agent (connects to both MCP servers), driven by a free-text prompt
uv run python -m agent.graph "Find papers related to my 'Transformers Concept Note'"agent/graph.py 自行将 custom_server/server.py 作为 stdio 子进程启动,因此进程 2 不需要进程 1 已经运行——上面的两个命令只是演示每个进程都可以独立启动。
提示不是字面上的笔记标题——代理的第一步(parse_prompt)使用 LLM 调用来识别提示所指的 Obsidian 笔记。如果无法识别,运行会立即停止并打印“Not enough information: no Obsidian note or page was named in the prompt.”,而不会触碰 Obsidian。如果找到的笔记没有产生足够的概念关键词(少于 min_keywords,默认 2),运行会在读取后停止,并打印类似的“not enough information”消息,而不是搜索 arXiv。
离线 / 重放模式
自定义服务器调用三个实时网络 API(arXiv、OpenAlex、OpenRouter)。设置 CUSTOM_SERVER_OFFLINE=1 后,其工具将从 custom_server/fixtures/ 中的录制夹具提供——无需网络访问或 OPENROUTER_API_KEY。适用于没有可靠网络的演示/答辩,或快速迭代。
CUSTOM_SERVER_OFFLINE=1 uv run python -m custom_server.server覆盖范围:search_arxiv_papers(一个录制的搜索源,为任何查询提供——见下面的限制),以及 score_paper_relevance / find_foundational_citations 对两篇录制的论文:GPT-3(2005.14165)和 ResNet(1512.03385)。
已知限制:
search_arxiv_papers在离线模式下与查询无关——无论查询文本如何,它总是返回相同的录制源。score_paper_relevance和find_foundational_citations只识别上面两篇录制的论文。未录制的 arxiv_id 会引发PaperNotFoundError(与真实 OpenAlex 未命中产生的错误相同);传递给score_paper_relevance的未录制论文标题会引发FixtureNotFoundError——可区分,而不是静默的错误答案。
要重新生成或扩展夹具:uv run python -m custom_server.fixtures.record 会重新获取录制的 arXiv/OpenAlex 响应(两者都是公共、无需认证的 API),并覆盖 custom_server/fixtures/ 中的 JSON/XML 文件。要添加新论文,请将其两个 httpx.get 调用添加到 record.py,并在 relevance_scores.json 中添加匹配条目(手工编写——不是真实的 OpenRouter 输出,因为录制其原始聊天完成响应不值得线格式的脆弱性;结构化的 {relevance, novelty, rationale} 字段直接通过 PydanticAI FunctionModel 重放)。
测试
uv run pytest custom_server/tests agent/tests所有网络调用(arXiv、OpenAlex、OpenRouter)都被模拟;测试期间没有实时流量。
工具契约(C 部分)
search_arxiv_papers(自定义)
目的 | 主要数据源工具:搜索 arXiv 以查找某个主题的候选论文。 |
面向模型的描述 | “Search arXiv for papers on a topic, optionally restricted to categories and a minimum submission date. Use this to find candidate papers before evaluating them individually with score_paper_relevance. A valid query that matches nothing returns an empty list — that is a normal result, not an error.” |
输入 |
|
输出 |
|
错误条件 | 无效类别代码、格式错误的 |
副作用 | 无——只读 HTTP GET 到 |
示例 |
|
score_paper_relevance(自定义)
目的 | 评估工具:判断一个候选者的主题契合度,并检查其引用记录是否通过年龄调整的基准。 |
面向模型的描述 | “Score how relevant and novel a paper is to a concept summary, and check whether its citation impact clears a minimum bar (citations per year, exempting papers younger than one year). Use this on each candidate from search_arxiv_papers to decide whether it belongs in a reading list. Raises if the paper has no OpenAlex record, or if the underlying relevance-scoring model call fails.” |
输入 |
|
输出 |
|
错误条件 | 如果 OpenAlex 没有该论文的 arXiv DOI 记录,则从 |
副作用 | 只读:一次 OpenAlex GET,一次 OpenRouter 聊天完成调用。 |
示例 |
|
find_foundational_citations(自定义)
用途 | 引文图谱分析:给定一篇论文,按其自身引文数量对其参考文献进行排序,以揭示其所依托的成熟工作。与 |
面向模型的描述 | "给定一篇论文的 arXiv ID,返回其被引次数最多的参考文献——即它所依托的成熟先前工作。在选定要阅读的论文之后使用此工具,以揭示其背后的背景文献。没有记录到参考文献的论文会返回空列表——这是正常结果,而非错误。" |
输入 |
|
输出 |
|
错误条件 | 若 |
副作用 | 只读:一次 OpenAlex 论文查询 + 一次或多次批量 OpenAlex works 查询(每次请求按 50 个 ID 分块)。 |
示例 |
|
Obsidian Local REST API MCP(现有,Part A)
通过 PydanticAI 代理的自然语言工具调用(而非固定的包装函数)在流程中用于两种操作:
引用解析 | 在任何 Obsidian 调用之前, |
读取 | 提示代理读取标题为 |
写入 | 提示代理创建/覆盖标题为 |
错误条件 | 插件已停止、API 密钥无效或笔记缺失,会以 MCP 服务器可区分的工具调用失败形式呈现,而非静默的空结果。 |
设计理由
为何选择 Obsidian: 作业需要一个现有的 MCP 服务器,代理既能从中读取也能向其写入。学生自己的概念笔记是自然的"我已知道什么"输入,而将幸存论文写回可在 vault 中直观地闭合循环。
为何选择 arXiv + OpenAlex 而非需要登录的网站: 最初考虑的 KSE 课程表/Moodle 数据源均需个人登录,这被作业的公共 API 规则所排除。arXiv 和 OpenAlex 是公开的、无需认证的,且直接支持"相关性 + 影响力"这一领域。
为何相关性由 LLM 判定而非嵌入: OpenRouter 没有嵌入端点(已对照其实时模型目录验证),因此
score_paper_relevance使用 PydanticAI 结构化输出调用而非向量相似度——复用项目本已需要的同一个模型凭据。为何
find_foundational_citations不是"再用 OpenAlex 搜索一次": 它取一篇特定论文的参考文献列表并按引文影响力排序,与作业自身示例所用的受控指标比较属于同一类型——与关键词驱动的search_arxiv_papers具有不同的职责和处理逻辑。过滤是纯 Python,而非第 4 个工具:
agent/graph.py中filter_candidates_node的相关性阈值 +impact_pass过滤是对已评分数据的确定性后处理,而非新的领域逻辑——工具只是对if的间接包装。权衡 / 局限: 自定义服务器的离线/回放模式(见上文"离线 / 回放模式")覆盖两篇已记录的论文和一次与查询无关的 arXiv 搜索——并非对任意查询的通用记录/回放。
agent/自身的 Obsidian 和 OpenRouter 调用不受其影响,仍需要实时访问。影响力/相关性阈值是.env值,而非每次请求可运行时调整。
已推迟(已标记,未放弃)
将硬编码阈值暴露为超越
.env的更丰富的运行时配置。
演示 / 答辩检查清单
uv run python -m custom_server.server可独立启动;原始 MCP 客户端的list_tools显示全部 3 个工具。uv run pytest custom_server/tests agent/tests— 全部通过,网络已模拟。CUSTOM_SERVER_OFFLINE=1 uv run python -m custom_server.server可启动并在无实时网络或 API 密钥的情况下提供全部 3 个工具调用(见"离线 / 回放模式")。在演示 vault 笔记中植入概念摘要(例如"attention mechanisms"),标题例如"Transformers Concept Note"。
uv run python -m agent.graph "Find papers related to my 'Transformers Concept Note'"— 完整实时运行:解析笔记引用、读取笔记、搜索 arXiv、对候选论文评分、过滤、查找基础引文、将"<note> — Related Papers"写回 vault。展示两个 MCP 连接如何共同支撑最终输出:写回笔记同时引用 arXiv/OpenAlex 数据(自定义服务器)和原始概念笔记内容(Obsidian)。
信息不足演示:使用未指明任何笔记的提示运行(例如
"What's a transformer?")— 展示代理中止并打印"Not enough information..."而不调用 Obsidian。然后针对内容近乎为空的笔记运行 — 展示其在读取笔记之后、调用 arXiv 之前中止。失败演示,Obsidian:停止 Local REST API 插件(或使用错误的
OBSIDIAN_API_KEY/ 不存在的笔记标题)— 展示代理呈现可区分的错误,而非静默的空结果。失败演示,自定义服务器:使用无效类别调用
search_arxiv_papers,或使用 OpenAlex 中不存在的 arXiv ID 调用find_foundational_citations— 分别展示ValueError/PaperNotFoundError,与有效的空结果相区分。
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceThis MCP server enables users to search for scientific papers on arXiv and retrieve detailed metadata for specific papers. It provides tools to perform search queries and fetch in-depth information using paper IDs.3Apache 2.0
- FlicenseAqualityDmaintenanceA streamlined MCP server that connects AI assistants to arXiv's vast collection of academic papers, enabling search, retrieval, and analysis of research papers.71
- FlicenseNot gradedqualityDmaintenanceAn advanced scholarly research MCP server that enables AI assistants to discover, fetch, process, and manage academic papers across multiple sources like arXiv, PubMed, and Semantic Scholar, with capabilities for summarization, citation analysis, and concept relationship extraction.1
- FlicenseNot gradedqualityCmaintenanceAn MCP server that enables AI assistants to search arXiv papers, retrieve metadata, and access PDFs.
Related MCP Connectors
Academic research MCP server for paper search, citation checks, graphs, and deep research.
Driflyte MCP server which lets AI assistants query topic-specific knowledge from web and GitHub.
An MCP server for deep research or task groups
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/tbaraniuk/arxiv-agent-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server