Skip to main content
Glama
tbaraniuk

arxiv-agent-mcp

by tbaraniuk

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/ — 一个 PydanticAI Agent(基于 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_API_KEY

OpenRouter 密钥——由代理和 score_paper_relevance 使用。

OPENROUTER_MODEL

模型标识,例如 openai/gpt-4o-mini

OBSIDIAN_API_KEY / OBSIDIAN_BASE_URL

Local REST API 插件凭据。

OBSIDIAN_MCP_COMMAND

用于启动你的 Obsidian MCP 服务器的空格分隔参数,例如 npx -y <obsidian-mcp-package>

RELEVANCE_PASS_THRESHOLD

通过筛选的最低相关性分数(0–1)。默认 0.5

CITATIONS_PER_YEAR_THRESHOLD

通过影响力检查的最低每年引用次数。默认 5

NEW_PAPER_AGE_EXEMPT_YEARS

比这更年轻的论文可免于影响力检查。默认 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_relevancefind_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.”

输入

query: strcategories: list[str] = [cs.LG, cs.AI, cs.CL, stat.ML]since_date: str | NoneYYYY-MM-DD),max_results: int = 10(1–50)

输出

list[{arxiv_id, title, abstract, authors: list[str], published_date, categories: list[str]}]

错误条件

无效类别代码、格式错误的 since_datemax_results 超出 [1, 50] 时引发 ValueError——在任何网络调用之前引发。上游 HTTP 失败通过 raise_for_status() 引发。零匹配是有效的空列表,不是错误。

副作用

无——只读 HTTP GET 到 export.arxiv.org

示例

search_arxiv_papers(query="transformer attention", max_results=5) → 5 篇带摘要的候选论文。

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.”

输入

concept_summary: strpaper: {arxiv_id, title, abstract}

输出

{relevance: float, novelty: float, citation_count: int, publication_year: int, citations_per_year: float, impact_pass: bool, rationale: str}

错误条件

如果 OpenAlex 没有该论文的 arXiv DOI 记录,则从 custom_server.openalex 引发 PaperNotFoundError——与找到但未被引用的论文不同,后者是有效的 citation_count: 0。如果 OpenRouter 调用的结构化输出在重试后未通过模式验证,则引发 UnexpectedModelBehavior

副作用

只读:一次 OpenAlex GET,一次 OpenRouter 聊天完成调用。

示例

score_paper_relevance(concept_summary="attention mechanisms in NLP", paper={...}){relevance: 0.92, novelty: 0.6, citation_count: 84331, impact_pass: True, ...}

find_foundational_citations(自定义)

用途

引文图谱分析:给定一篇论文,按其自身引文数量对其参考文献进行排序,以揭示其所依托的成熟工作。与 search_arxiv_papers 不同——它分析的是特定论文的参考文献列表,而非关键词搜索。

面向模型的描述

"给定一篇论文的 arXiv ID,返回其被引次数最多的参考文献——即它所依托的成熟先前工作。在选定要阅读的论文之后使用此工具,以揭示其背后的背景文献。没有记录到参考文献的论文会返回空列表——这是正常结果,而非错误。"

输入

arxiv_id: strmax_results: int = 3(1–3)

输出

list[{openalex_id, title, cited_by_count, publication_year}],按 cited_by_count 降序排序,取前 max_results

错误条件

max_results 超出 [1, 3] 范围则抛出 ValueError。若 OpenAlex 中没有该 arXiv ID 的记录则抛出 PaperNotFoundError。零参考文献的论文返回 []——有效结果,而非错误。

副作用

只读:一次 OpenAlex 论文查询 + 一次或多次批量 OpenAlex works 查询(每次请求按 50 个 ID 分块)。

示例

find_foundational_citations(arxiv_id="2005.14165", max_results=3) → GPT-3 所引用的被引次数最多的 3 篇论文。

Obsidian Local REST API MCP(现有,Part A)

通过 PydanticAI 代理的自然语言工具调用(而非固定的包装函数)在流程中用于两种操作:

引用解析

在任何 Obsidian 调用之前,parse_prompt 要求 PydanticAI 代理(纯 LLM 推理,而非 MCP 调用)识别用户自由文本提示所隐含的笔记标题。若无法识别,流程将以"信息不足"状态中止,且绝不调用 Obsidian。

读取

提示代理读取标题为 note_title(来自 parse_prompt)的笔记并返回其纯文本内容——为 concept_text 提供输入,即关键词提取和相关性评分的数据来源。

写入

提示代理创建/覆盖标题为 "{note_title} — Related Papers" 的笔记,内容为 compose_note_content 生成的 markdown——这是闭合两个 MCP 服务器之间循环的可观察效果。

错误条件

插件已停止、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.pyfilter_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,与有效的空结果相区分。

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    D
    maintenance
    This 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.
    3
    Apache 2.0
  • F
    license
    A
    quality
    D
    maintenance
    A streamlined MCP server that connects AI assistants to arXiv's vast collection of academic papers, enabling search, retrieval, and analysis of research papers.
    7
    1
  • F
    license
    Not graded
    quality
    D
    maintenance
    An 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

View all related MCP servers

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

View all MCP Connectors

Latest Blog Posts

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