关于 arxiv-mcp-server
arxiv-mcp-server 通过 arXiv API 和 OAI-PMH 元数据源,为研究者和 Agent 提供论文搜索、元数据查询及全文阅读。支持 STDIO、Streamable HTTP 和托管端点,并可选用本地元数据镜像。
主要功能
- 01按查询、分类和日期搜索论文
- 02按 arXiv ID 获取元数据
- 03读取全文并回退多种格式
- 04列出 arXiv 分类体系
- 05可选 SQLite 元数据镜像
适用场景
- 01按主题和日期查找论文
- 02检索论文版本与结构化元数据
- 03阅读论文正文以辅助研究
- 04通过镜像减少元数据查询限流
MCP 相关
向 MCP 客户端提供论文搜索、元数据和全文阅读工具,以及论文和分类资源。支持 STDIO 与 Streamable HTTP,也提供公共托管端点。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://arxiv.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-arxiv https://arxiv.caseyjhand.com/mcp{"mcpServers":{"cyanheads-arxiv":{"type":"http","url":"https://arxiv.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-arxiv":{"type":"http","url":"https://arxiv.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-arxiv":{"type":"http","url":"https://arxiv.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-arxiv":{"serverUrl":"https://arxiv.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
4| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| query | string | 是 | 搜索查询。字段前缀:ti:(标题)、au:(作者——基于词元;多词姓名请加引号,如 au:"hinton g",或与主题子句组合以区分常见姓氏)、abs:(摘要)、cat:(类别——叶子代码精确匹配,裸存档代码如 cat:astro-ph 匹配整个子树)、co:(评论)、jr:(期刊引用)、all:(所有字段)。布尔运算符:AND、OR、ANDNOT。示例:"au:bengio AND ti:attention"、"all:transformer AND cat:cs.CL"。 |
| start | integer | 否 | 分页偏移量(0-10000)。与 max_results 配合可翻页。例如,start=10 且 max_results=10 会返回第 11–20 条结果。偏移量 10000 + max_results 之后的匹配项无法通过翻页访问——请将搜索拆分为 submitted_from/submitted_to 时间窗口,并在每个窗口内翻页。 |
| sort_by | enum | 否 | 排序标准。使用 "submitted" 按最新论文排序,使用 "relevance" 按查询匹配度排序。relevance | submitted | updated |
| category | string | 否 | 限制为某个 arXiv 类别的结果。叶子代码("cs.CL"、"math.AG")精确匹配。裸存档代码("astro-ph"、"cond-mat"、"cs"、"math")匹配整个存档,包括其学科类别以及存档细分前归入旧式平面分类的论文。请注意,"physics" 是普通物理存档(physics.*),而非更广泛的物理类别组:astro-ph、cond-mat、hep-*、quant-ph 等都是独立的存档代码。使用 arxiv_list_categories 查找学科类别。 |
| sort_order | enum | 否 | 排序方向。"descending" 会将最新或最相关的结果排在前面。ascending | descending |
| max_results | integer | 否 | 要返回的最大结果数(1-50)。默认值为 10。每条结果都包含标题、作者、摘要和元数据——请保持较低值以限制响应大小。 |
| submitted_to | string | 否 | 要包含的最晚提交日期(含),格式为 UTC YYYY-MM-DD。省略则不设上限。上下限均包含在内,因此连续时间窗口("2024-01-01".."2024-01-15",然后是 "2024-01-16".."2024-01-31")可以无间隔覆盖匹配项;但在两个窗口交界的午夜时刻恰好提交的论文会同时出现在两边,因此请按论文 ID 对收集的结果去重。要访问超出 start 上限的匹配项,应按日期范围拆分,然后在每个窗口内翻页。 |
| submitted_from | string | 否 | 要包含的最早提交日期(含),格式为 UTC YYYY-MM-DD。省略则不设下限。 |
详细介绍
@cyanheads/arxiv-mcp-server
通过 MCP 搜索 arXiv 论文、获取论文元数据并阅读全文。支持 STDIO 或 Streamable HTTP。
公共托管服务: https://arxiv.caseyjhand.com/mcp
概述
通过 arXiv API 及其 OAI-PMH 元数据源获取 arXiv 论文、元数据和全文。按查询词、类别和提交日期搜索论文;按 ID 获取结构化元数据;并通过 HTML 和 PDF 渲染版本自动回退的方式阅读论文全文。可作为 stdio 进程、本地 Streamable HTTP 服务运行,也可使用上述公共托管端点。
工具
| 工具 | 描述 |
|---|---|
arxiv_search_papers | 按查询词搜索 arXiv 论文,支持字段前缀、类别和日期筛选 |
arxiv_get_metadata | 按 arXiv ID 获取一篇或多篇论文的元数据 |
arxiv_read_paper | 通过 HTML、ar5iv 或 PDF 提取回退方式阅读论文全文 |
arxiv_list_categories | 列出 arXiv 类别体系,可按组筛选 |
资源
| 资源 | 描述 |
|---|---|
arxiv://paper/{paperId} | 按 arXiv ID 获取论文元数据 |
arxiv://categories | 完整的 arXiv 类别体系 |
功能参考
arxiv_search_papers 工具
- 查询支持字段前缀
ti:、au:、abs:、cat:、co:、jr:、all:以及AND/OR/ANDNOT,最多 1000 个字符;category接受分类代码(cs.CL)或整个归档分类(astro-ph、cs、math) - 查询语法遵循 arXiv 的规则:以空格分隔的词项会用
OR连接(如需匹配所有词项,请写AND);运算符只能使用大写形式,且三种运算符的优先级相同,并从右向左分组(a AND b OR c等同于a AND (b OR c))。多词主题请加引号("graph neural networks" AND cat:cs.LG),并在筛选条件前用括号列出备选项;在带引号的短语之外,arXiv 会忽略of和the等常见词 - 可按
sort_by(relevance/submitted/updated)和sort_order排序,并通过submitted_from/submitted_to设置包含边界的 UTC 日期范围(格式为YYYY-MM-DD);每次调用最多返回 50 条结果(将max_results设得更大仍只返回 50 条) - arXiv 对查询仅提供前 10,000 条结果;
start设为 10,000 会导致start_beyond_result_limit。如需查看更多结果,请使用日期范围 - 输出会回显实际使用的查询、匹配总数和分页偏移量;空页面会提供恢复建议,而非返回错误。如果总数是下限(本地镜像的计数上限为 50,000),则会包含
totalFoundIsLowerBound: true
arxiv_get_metadata 工具
- 最多接收 100 个 ID,并查询前 10 个;其余 ID 会放在
remaining_ids中,供下一次调用的paper_ids使用 - 接受带版本号的 ID(
2401.12345v2)、不带版本号的 ID,以及 2007 年之前的 ID(hep-th/9901001);可选带arXiv:前缀,或使用 arxiv.org 的abs/pdf/htmlURL - 返回查到的论文,以及其余 ID 对应的带类型
not_found[](not_in_arxiv/version_not_in_mirror/version_not_served/live_lookup_failed/invalid_id);version_not_served表示 arXiv API 对已被取代的 2007 年之前版本返回 HTTP 500,其detail会指出最新版本。使用本地镜像时,live_lookup_failed表示镜像中没有该 ID,且在线查询失败;镜像成功提供的论文仍会返回 - 如果所有 ID 格式都不正确,则返回
invalid_id;如果所有 ID 均未匹配,则返回no_match;如果某个版本只能通过在线 API 获取,则返回version_unavailable;如果所有 ID 都是 arXiv 不会提供的版本,则返回version_not_served
arxiv_read_paper 工具
- 依次尝试 arXiv HTML、ar5iv 和 PDF 文本提取;
source字段会报告实际提供内容的来源。PDF 文本为纯文本,因此数学公式、表格和标题会被压平 - ar5iv 每篇论文只保留一个渲染版本,因此 ar5iv 正文可能与
paper_id指定的版本不同,并会带有revision_unconfirmed: true;但如果读取时未指定版本,且 arXiv API 报告 v1 是该论文唯一的版本,则不会如此。pdf_url与paper_id指定的版本完全一致 max_characters默认为 100,000(传入null可获取整篇论文);使用start分页。第一页会包含带偏移量的章节标题outlinepaper_id接受与arxiv_get_metadata相同格式的 ID- 可能返回
invalid_id、content_unavailable(没有渲染版本或 PDF)、pdf_extraction_failed(PDF 没有文本层或无法解析)、version_unavailable(指定版本的 ID 需要通过在线 API 获取),或version_not_served(arXiv 不会提供已被取代的 2007 年之前版本;会指出最新版本以及此版本的 PDF)
arxiv_list_categories 工具
- 8 个顶级组(
cs、econ、eess、math、physics、q-bio、q-fin、stat)中约有 155 个分类 - 可选的
group筛选条件可缩小结果范围 - 静态数据——始终成功
arxiv://paper/{paperId} 资源
paperId接受与arxiv_get_metadata相同格式的 ID;旧版 ID 中的斜杠需进行百分号编码(arxiv://paper/hep-th%2F9901001)- 可能返回
empty_id、invalid_id、no_match、version_unavailable或version_not_served
arxiv://categories 资源
- 返回
{ categories: [...] },一个扁平数组,每个条目包含code/name/group - 无参数;可缓存 24 小时
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及支持可选 OpenTelemetry 跟踪的结构化日志记录。
arXiv 专属功能:
- 只读,无需身份验证
- 请求队列强制执行 arXiv 的 3 秒爬取间隔;遇到速率限制响应时会快速失败并进入冷却期
- 论文文本会按顺序从 arXiv HTML、ar5iv 回退到 PDF 提取
- 将完整的 arXiv 分类体系作为静态数据嵌入
- 可选的本地 OAI-PMH 元数据镜像(SQLite + FTS5),可消除搜索和元数据查询的速率限制风险。请参阅可选:本地镜像
便于 Agent 使用的输出:
arxiv_read_paper会标明其source;arxiv_search_papers会回显实际使用的查询arxiv_get_metadata会返回找到的论文,并针对每条未找到的论文提供带类型的not_found[]原因- 带类型的
source和not_found[].reason枚举可让调用方根据数据进行分支处理
入门
公共托管实例
可使用公共实例 https://arxiv.caseyjhand.com/mcp,无需安装。通过 Streamable HTTP 将任何 MCP 客户端指向该实例:
{
"mcpServers": {
"arxiv-mcp-server": {
"type": "streamable-http",
"url": "https://arxiv.caseyjhand.com/mcp"
}
}
}
自托管 / 本地部署
将以下内容添加到 MCP 客户端配置文件中。
{
"mcpServers": {
"arxiv-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/arxiv-mcp-server@latest"]
}
}
}
也可使用 npx(无需 Bun):
{
"mcpServers": {
"arxiv-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/arxiv-mcp-server@latest"]
}
}
}
也可使用 Docker:
{
"mcpServers": {
"arxiv-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/arxiv-mcp-server:latest"]
}
}
}
对于 Streamable HTTP,请设置传输方式并启动服务:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
前置条件
- Bun v1.4.0 或更高版本(或 Node.js v24+)。
安装
- 克隆仓库:
git clone https://github.com/cyanheads/arxiv-mcp-server.git
- 进入目录:
cd arxiv-mcp-server
- 安装依赖项:
bun install
配置
所有配置均为可选项,服务器使用合理的默认值即可开箱即用。
| 变量 | 说明 | 默认值 |
|---|---|---|
ARXIV_API_BASE_URL | arXiv API 基础 URL。 | https://export.arxiv.org/api |
ARXIV_REQUEST_DELAY_MS | arXiv API 请求之间的最短延迟(毫秒)。 | 3000 |
ARXIV_CONTENT_TIMEOUT_MS | 获取论文正文的超时时间,包括 HTML 渲染和 PDF 下载(毫秒)。 | 30000 |
ARXIV_API_TIMEOUT_MS | API 搜索/元数据请求的超时时间(毫秒)。启用镜像后,对于未指定版本的 arxiv_read_paper,这也是在镜像返回已存储论文前等待元数据查询(包括排队)的最长时间。 | 15000 |
ARXIV_READ_TIMEOUT_MS | 单次 arxiv_read_paper 调用的时间预算,包括元数据查询、每次内容请求和重试,以及 PDF 文本提取(毫秒)。请将其设为低于 MCP 客户端的请求超时时间(默认 60 秒)。 | 50000 |
ARXIV_MIRROR_ENABLED | 启用本地 OAI-PMH 元数据镜像。 | false |
ARXIV_MIRROR_PATH | 镜像的 SQLite 路径。 | ./data/arxiv-mirror.db |
ARXIV_MIRROR_REFRESH_CRON | 进程内每日刷新的 UTC cron 表达式(仅限 HTTP 模式)。 | 未设置 |
ARXIV_MIRROR_FALLBACK_LIVE | 本地 ID 查询未命中时回退到实时 API。 | true |
ARXIV_MIRROR_RECENT_DAYS_LIVE | 正值会向实时 API 发送按 sort_by=submitted 降序排列的查询;0 表示禁用。 | 2 |
ARXIV_MIRROR_OAI_BASE_URL | arXiv OAI-PMH 端点基础 URL。 | https://oaipmh.arxiv.org/oai |
ARXIV_MIRROR_OAI_REQUEST_DELAY_MS | OAI-PMH 请求之间的最短延迟(毫秒)。 | 3000 |
ARXIV_MIRROR_REFRESH_TIMEOUT_MS | 单次计划刷新任务的时间预算(毫秒)。 | 7200000 |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_HTTP_PORT | HTTP 服务器端口。 | 3010 |
MCP_SESSION_MODE | auto、stateful 或 stateless。 | stateless |
MCP_AUTH_MODE | 身份验证模式:none、jwt 或 oauth。 | none |
MCP_LOG_LEVEL | 日志级别(RFC 5424)。 | info |
OTEL_ENABLED | 启用 OpenTelemetry 插桩(跨度、指标、完成日志)。 | false |
完整的可选覆盖项列表请参阅 .env.example。
运行服务器
本地开发
-
构建并运行:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdio -
运行检查和测试:
bun run devcheck # Lint, format, typecheck, security audit bun run test # Vitest test suite
可选:本地镜像
对于通过单个出口 IP 进行自托管部署的场景,arXiv 约 3 秒的爬取间隔会让并发用户请求排队。可选的本地镜像通过 OAI-PMH 抓取数据,并存储在 SQLite + FTS5 中;它可减少 arxiv_search_papers 和 arxiv_get_metadata 的速率限制影响。arxiv_read_paper 始终实时获取正文——完整内容抓取违反 arXiv 的数据政策——仅在实时查询失败,或对于未指定版本的 ID,实时查询在 ARXIV_API_TIMEOUT_MS 后仍未完成时,才从镜像读取元数据和已存储的版本。在下次刷新前,镜像中的版本可能落后于 arXiv 的最新版本。
默认禁用。启用方法:
# 1. Cold-start harvest (~4.4h sequential). One-time per installation.
# Waits out arXiv outages; Ctrl+C stops it, and a rerun resumes from its checkpoint.
bun run mirror:init
# 2. Enable the mirror.
export ARXIV_MIRROR_ENABLED=true
# 3. Start the server — reads switch to the mirror once the harvest completes.
bun run start:http
通过 npm 安装时,mirror:* 命令属于软件包,而非你的项目:请在软件包目录中运行(bun run --cwd node_modules/@cyanheads/arxiv-mcp-server mirror:init),或在项目根目录中直接运行脚本(bun node_modules/@cyanheads/arxiv-mcp-server/scripts/arxiv-mirror-init.ts)。将 ARXIV_MIRROR_PATH 设为 node_modules 外的绝对路径,并确保该路径与服务器读取的路径一致,这样重新安装后镜像也会保留。
使用 bun run mirror:refresh(cron/systemd/launchd,或 HTTP 模式下的 ARXIV_MIRROR_REFRESH_CRON)让镜像保持最新,并使用 bun run mirror:verify 检查。如果刷新中断,下次运行会从上次记录的日期戳继续,并重新读取该日;如果进程内刷新在离开启动时所在日期之前用完 ARXIV_MIRROR_REFRESH_TIMEOUT_MS 预算,下次运行则会从停止处继续。发布版本变更镜像架构时,服务器会改为从实时 API 响应,直到写入程序原地迁移文件,不会重新采集数据:HTTP 模式下设置 ARXIV_MIRROR_REFRESH_CRON 时,服务器会自行启动刷新;否则运行 bun run mirror:refresh 或 bun run mirror:verify。同一时间只能有一个写入程序迁移文件:此时启动的镜像命令不会更改任何内容,并会以状态码 75 退出,同时指出占用迁移的进程;待其完成后重新运行即可。架构 v3 的镜像会在下一次写入程序打开时按此方式迁移到 v4:它会向类别表添加一列并填充数据,然后重建五个日期索引。完整大小的镜像需要几分钟,而不是几秒(约五分钟),并且需要预留磁盘空间:WAL 峰值约为 450 MB,文件会增大约 9%。架构 v4 的镜像会以相同方式迁移到 v5:它会重写文本中含有 ' 或 " 的每篇论文,将其替换为引号字符;此类论文约占 320 万篇论文中的 120 万篇,随后重建搜索使用的类别索引。完整大小的镜像在主机负载不同的情况下约需 4.5 到 7.5 分钟,WAL 峰值约为 160 MB,文件会增大约 10%。回滚到 1.7.1 或更早版本并刷新后,刷新重写的每篇论文中会再次存储这些引用;升级回来后,在文件上运行 UPDATE schema_version SET version = 4,然后运行 bun run mirror:verify 以再次修复。
镜像使用 FTS5 BM25 排序,因此 sort_by=relevance 返回的首批结果与实时 API 不同。不含自由文本词项的镜像搜索只有在按一个类别代码筛选时才会精确计数;跨多个代码(cat:cs、两个类别)或仅按提交日期范围筛选的搜索,计数上限为 50,000;达到该数值时会返回 totalFoundIsLowerBound: true,表示结果为 50,000 篇或更多。以下搜索会转到实时 API:按 sort_by=submitted 降序排序的搜索(当 ARXIV_MIRROR_RECENT_DAYS_LIVE 为正数时);自由文本词项匹配 50,000 篇或更多论文的搜索;含有镜像无法作为筛选条件应用的 cat: 或 submittedDate: 操作数的查询(该操作数与其余部分通过 OR 或空格连接,或位于 ANDNOT 右侧),以及移除这些操作数后只剩 ANDNOT 词项的查询;括号不平衡的查询、没有值的字段前缀(ti: x、ti:)、空引号短语或没有剩余匹配内容的查询(());含有 rn:、id: 或 lastUpdatedDate: 操作数,或 submittedDate: 格式错误的查询;包含 arXiv 索引会丢弃的词(of、the、and、……),且这些词不在更长的引号短语中的查询;类别名称不存在的 cat: 通配符(cat:zzz.*);以及指定版本的请求(镜像只保存最新版本)。
Docker
docker build -t arxiv-mcp-server .
docker run --rm -p 3010:3010 arxiv-mcp-server
Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/arxiv-mcp-server。默认安装 OpenTelemetry 对等依赖项;如需省略它们,请使用 --build-arg OTEL_ENABLED=false 构建。
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口点 — 注册工具和资源,并启动可选的镜像刷新计划任务。 |
src/config | 使用 Zod 解析并验证服务专属环境变量。 |
src/mcp-server/tools/definitions | 工具定义(*.tool.ts)。 |
src/mcp-server/resources/definitions | 资源定义(*.resource.ts)。 |
src/services/arxiv | ArxivService — 实时 arXiv API 客户端(搜索、元数据、HTML),以及通过工作线程提取 PDF 文本(pdf-text.ts)。 |
src/services/arxiv/mirror | 可选的 OAI-PMH 镜像 — 收割器、SQLite + FTS5 存储、查询转换器、运行器。 |
skills/arxiv-guide | 发布给安装此服务的 Agent 的 Agent 技能,并通过 MCP 提供:引文到 ID 的解析、搜索门槛、版本及逐节阅读工作流。 |
scripts/arxiv-mirror-*.ts | 镜像生命周期脚本(init、refresh、verify);scripts/tsconfig.json 会将它们的 @/ 导入解析到 src/,或在安装时解析到 dist/。 |
tests/ | 单元测试和集成测试。 |
docs/ | 设计文档和目录结构。 |
开发指南
开发指南和架构规则请参见 CLAUDE.md。简而言之:
- 处理器抛出异常,框架负责捕获 — 工具逻辑中不要使用
try/catch - 使用
ctx.log记录请求范围内的日志,使用ctx.state存储租户范围内的数据 - arXiv API 对所有请求都返回 HTTP 200 — 包括触发速率限制的请求 — 因此解析前要检查内容类型和响应正文
- 验证原始 arXiv 响应 → 规范化为领域类型 → 返回输出架构;绝不捏造缺失字段
贡献
欢迎提交问题。提交前请运行检查:
bun run devcheck
bun run test
许可证
Apache-2.0 — 详情请参见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。