关于 crossref-mcp-server
crossref-mcp-server 面向学术研究与文献工作流,通过 Crossref REST API 解析 DOI、检索学术作品并查询参考文献、期刊、资助方和出版者信息。支持 stdio 与 Streamable HTTP。
主要功能
- 01解析 DOI 并获取学术作品元数据
- 02按文本或结构化筛选检索作品
- 03获取作品的参考文献列表
- 04按 ISSN 或标题查找期刊
- 05检索资助方及其资助作品
- 06查询出版者与 DOI 前缀
适用场景
- 01获取论文作者、摘要和出版信息
- 02按主题、作者或筛选条件搜索学术作品
- 03查看论文引用的参考文献
- 04核实期刊、资助方或出版者记录
MCP 相关
它通过 MCP 向客户端提供 7 个 Crossref 学术元数据查询工具,支持 stdio 与 Streamable HTTP,并提供公共托管实例。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://crossref.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-crossref https://crossref.caseyjhand.com/mcp{"mcpServers":{"cyanheads-crossref":{"type":"http","url":"https://crossref.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-crossref":{"type":"http","url":"https://crossref.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-crossref":{"type":"http","url":"https://crossref.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-crossref":{"serverUrl":"https://crossref.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
7| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| doi | string | 是 | DOI,格式为 "10.NNNN/suffix",例如 "10.1038/nature12373"。也接受带解析器前缀的格式——"https://doi.org/10.1038/nature12373"、"https://dx.doi.org/…"、"doi:10.1038/nature12373"——并会去除前缀。 |
| limit | integer | 否 | 单页返回的作者最大数量(1–500,默认 25)。普通记录可在单页内返回;粒子物理和基因组学领域的大型合作论文可能提交数千位作者。 |
| offset | integer | 否 | 要返回的首位作者的从零开始索引。传入上一次响应中的 nextOffset,可继续获取较长的作者列表。只有作者列表分页;记录的其他所有字段都会在每一页完整返回。 |
详细介绍
@cyanheads/crossref-mcp-server
通过 Crossref REST API 解析 DOI、搜索约 1.88 亿篇学术著作、获取参考文献,并查询出版商。支持 STDIO 或 Streamable HTTP。
概述
来自 Crossref REST API 的学术元数据。将 DOI 解析为完整元数据记录,按自由文本或结构化筛选条件搜索约 1.88 亿篇学术著作,获取外引参考文献列表,并查询期刊、资助机构和出版商。
工具
| 工具 | 描述 |
|---|---|
crossref_get_work | 将 DOI 解析为完整的 Crossref 元数据记录:标题、作者、编辑、所属机构、摘要、包含卷号/期号/页码的期刊信息、ISSN 和 ISBN、出版日期、许可证、全文链接、资助机构致谢、出版后更新,以及相关标识符 |
crossref_search_works | 按自由文本和/或结构化筛选条件搜索 Crossref 著作索引,支持限定字段的查询参数、排序、字段选择,以及基于偏移量或游标的分页 |
crossref_get_references | 返回 DOI 的外引参考文献列表——即该论文引用的著作,以及可用时的引文字符串和已解析 DOI |
crossref_search_journals | 按 ISSN 或标题查询查找 Crossref 期刊记录;也可选择获取该期刊最新著作的分页结果 |
crossref_search_funders | 按名称、注册表 ID 或资助机构 DOI,在 Crossref 资助机构注册表中查找资助机构;也可选择获取受资助著作的分页结果 |
crossref_get_member | 将 Crossref 成员 ID 解析为其出版商记录——名称、所拥有的 DOI 前缀、DOI 数量,以及各类别的元数据提交覆盖情况 |
crossref_get_prefix | 将 DOI 前缀(例如 10.1038)解析为所属出版商,并继续调用 crossref_get_member |
功能参考
crossref_get_work 工具
- 在调用上游服务前,使用
10.NNNN/suffix正则表达式验证 DOI;接受裸 DOI 或带解析器前缀的 DOI(https://doi.org/…、https://dx.doi.org/…、doi:…),并在查询前去除前缀 - 返回标题、作者及其所属机构、摘要(如有存档)、载体/期刊、出版日期、作品类型、ISSN、许可 URL、全文链接 URL 和资助方致谢
- 引文定位信息
volume、issue、page和articleNumber使用与crossref_search_works相同的名称,并显示在同一行;还包括isbn——均按存档内容返回,不存在时省略 editors使用作者条目的结构完整返回,且从不计入authorCount- 作者列表按
offset/limit分页(默认 25,每次最多 500 条;更大的limit会被限制为 500,并附带notice);authorCount报告完整的存档总数,作者尚未全部返回时可通过nextOffset继续查询——其他所有字段均会在每一页完整返回 updatedBy列出 Crossref 针对该作品记录的更正、撤稿、关注声明和新版本——逐条提供通知 DOI、类型、来源(publisher或retraction-watch,含其记录 ID)及日期;updateTo则列出该记录所对应通知的作品;存在updatedBy时,notice会列出每种更新类型及其来源。没有updatedBy并不意味着该作品从未更新relations按关系类型、标识符类型和声明方对相关标识符(预印本 ↔ 已发表版本、各版本、评论、补充材料)进行分组,并完整返回;其中只有在 Crossref 注册的 DOI 可通过此工具解析- 如果资助方或所属机构仅通过 ROR 注册表声明(未存档名称),则返回
ror代替name,不会出现空白条目 - 出版日期按顺序取本工具中第一个包含值的字段:
published、published-print、published-online和issued;Crossref 记录为未知的日期部分会被省略,其下所有精度更低的部分也一并省略 - 外引文以数量形式报告(
referencesCount)——条目来自crossref_get_references;同时包含传入引文数量(isReferencedByCount),但 Crossref 不会公开引用该作品的作品——请使用 OpenAlex 构建引文图谱 - 对于 Crossref 没有记录的 DOI,会返回
doi_not_found,并说明 DOI 注册机构指出的持有机构(registrationAgency——DataCite、JaLC、mEDRA 等);如果该 DOI 由 Crossref 注册,还会提供 Funder Registry 指针;如果没有任何机构注册,则会说明这一点
crossref_search_works 工具
- 自由文本
query,以及使用 Crossref 连字符键(from-pub-date、type、funder、issn、has-abstract、license.url等)的结构化filter对象 - 字段范围参数
queryTitle、queryAuthor、queryContainerTitle和queryBibliographic可与query及彼此组合使用 - 可按
relevance、score、is-referenced-by-count、published、deposited或其他列出的字段排序;按出版日期排序只能通过offset分页,因为 Crossref 不允许与游标一起使用。带查询词且未设置sort的游标遍历按相关性排序(发送sort=score,不带order),可能在分页边界重复或跳过记录;设置sort: "created"遍历则不会重复。仅使用筛选条件的遍历按 Crossref 注册顺序进行 fields可将负载缩减为摘要投影的 19 个可选名称中的任意名称,包括引文定位信息volume、issue、page、article-number和ISSN,以及更新链接updated-by和update-to;其他名称均不接受。始终返回DOI,记录的其余部分由crossref_get_work提供- 每篇作品都会在条目结构和
crossref_get_work使用的呈现行中包含updatedBy(针对该作品记录的更正、撤稿、关注声明、新版本)和updateTo(该作品所针对的通知),因此无需逐个 DOI 调用,就能筛查结果页中是否存在撤稿 - 空白或仅含空格的查询词或筛选值,以及空的
sort或order,均视为未提供;如果因此没有任何搜索条件,notice会说明该页面是未筛选的列表 - 每次调用中,
rows最多返回 100 篇作品,authorLimit限制每篇作品的作者数(默认 25,最多 500);超过上限的值会被限制到上限,并附带notice。在偏移分页中,notice还会指出接续已返回记录的偏移量;接近约 10K 上限时,也会指出仍可与该偏移量一同使用的较小rows值;authorCount报告完整的已提交作者总数——如需获取被截断作品的其余信息,可将其 DOI 传给crossref_get_work - 偏移分页上限为
offset + rows ≤ 10,000;低于上限但被拒绝的偏移量会附上仍可使用的rows值,而cursor="*"可通过串联nextCursor令牌启动深度分页——游标和偏移量不能同时使用 - 游标遍历会在不包含
nextCursor的页面结束——空页面不会携带该字段;每个空页面的notice都会说明适用的三种原因之一
crossref_get_references 工具
- 接受不带包装或带解析器包装的引用作品 DOI,与
crossref_get_work接受的形式相同 - 每条参考文献都会包含其已提交的引文字符串;如果 Crossref 已解析该参考文献,还会包含可供
crossref_get_work使用的 DOI,并通过doiAssertedBy说明该 DOI 是由出版商提交还是由 Crossref 匹配得到 - 按已提交内容提供结构化字段:作者、年份、文章标题、期刊标题、所引图书或卷册的标题(
volumeTitle;没有文章标题时用作标题)、丛书标题、卷、期、首页、版次和 ISSN - 引文字符串中的格式标记会被剥除,字符引用会被解码;无法识别为标签的方括号内容(例如被引 URL、Miller 指数、DOI 片段)会完全保留其提交时的原样
- 使用
offset/limit分页(默认 100,每次调用最多 500;超过 500 的limit会被限制为 500,并附带notice);referenceCount是完整的已提交总数,有更多结果时由nextOffset提供接续位置 - 覆盖情况因出版商而异——2000 年前的作品和未参与的出版商通常没有已编入索引的参考文献
- 仅支持单跳;Crossref 不提供传入引用——构建引文图请使用 OpenAlex
- 对于 Crossref 没有记录的 DOI,会以
doi_not_found返回并指出其注册机构(registrationAgency),或说明没有机构注册该 DOI,与crossref_get_work的处理方式相同
crossref_search_journals 工具
include_works: true还会返回该期刊最新作品的一个页面:使用works_offset时按最新出版时间排序,使用works_cursor遍历时按最新注册时间排序;要求期刊唯一明确——标题查询匹配多个结果时会返回ambiguous_journal,并列出候选项及 ISSN- 返回期刊标题、出版商、标明印刷版/电子版形式的 ISSN、学科领域、DOI 数量(总计/当前/回溯)以及各类别的元数据存缴覆盖情况(摘要、参考文献、ORCID、资助方、许可等),以当前/回溯分数表示;细分方式与
crossref_get_member为各出版商提供的相同 - 使用
issn查询时还会按发行年份升序返回 DOI 数量;标题查询结果不包含这些数据 - 标题查询结果按
offset分页(上限为offset + rows ≤ 100,000);作品列表单独按works_offset分页(上限为≤ 10,000)——超出任一列表末尾的偏移量都会附带一条指出该列表的notice,分页在任一上限处停滞时也会如此,同时注明偏移量及能获取上限以下最后几条记录的较小rows值 works_cursor="*"使用串联的nextWorksCursor令牌对作品列表分页,不设上限;游标遍历按 Crossref 注册日期从新到旧进行(Crossref 不支持按出版日期排序进行游标遍历),且不能与works_offset > 0组合使用(works_cursor_offset_conflict)- 匹配到的期刊若没有已注册的 ISSN,则没有可寻址的作品列表——跳过
include_works,并返回notice,而不是空列表
crossref_search_funders 工具
- 接受名称
query、纯注册 ID(100000001)或完整资助方 DOI(10.13039/100000001,可带doi:/https://doi.org/前缀) include_works: true还会返回一页受资助作品;要求资助方唯一明确——名称查询匹配多个结果时会返回ambiguous_funder,并列出候选项及注册 ID- 返回资助方名称、注册 ID、国家和别名
- 名称查询结果按
offset分页(上限为≤ 100,000);受资助作品列表单独按works_offset分页(上限为≤ 10,000),也可使用不设上限的works_cursor="*"串联nextWorksCursor;偏移分页按最新出版时间排序,游标遍历按最新注册时间排序,两者不能组合使用(works_offset > 0);超出任一列表末尾的偏移量都会附带一条指出该列表的notice,分页在任一上限处停滞时也会注明偏移量及能获取上限以下最后几条记录的较小rows值 - 受资助作品列表还会统计由该资助方的注册后代资助的作品;
crossref_search_works使用{"funder": "10.13039/<id>"}过滤时不会统计这些作品 - 已弃用的注册条目会以其后继条目的名称响应,但只统计自身的作品——响应中的
notice会通过replacedBy标明取代它的 ID;不会自动跟进到替代条目
crossref_get_member 工具
- 成员是注册 DOI 的组织——此工具用于回答“该出版商出版了什么,以及其元数据存缴情况有多完整?”
- 返回主要名称、其他印记名称、所属 DOI 前缀、DOI 数量(总计/当前/回溯)、按作品类型细分的数量,以及各类别的元数据存缴覆盖情况(参考文献、摘要、ORCID、资助方、许可等),以当前/回溯分数表示
- 先使用
crossref_get_prefix将 DOI 前缀解析为成员 ID,再与此工具配合使用
crossref_get_prefix 工具
- 接受 DOI 的注册机构前缀(例如
10.1038,不含/suffix) - 返回出版商名称和数字成员 ID — 该 ID 可直接传入
crossref_get_member,获取完整记录 - Crossref 前缀记录按设计仅包含基本信息(所有者名称和成员链接);更丰富的出版商数据位于成员记录中
- 若某个前缀没有对应的 Crossref 成员,则返回
prefix_not_found,并注明注册该前缀的机构(registrationAgency,例如10.5281对应 DataCite),或说明该前缀未由任何机构注册
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可替换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及结构化日志和可选的 OpenTelemetry 跟踪。
Crossref 专属功能:
- 每次 Crossref 请求都会注入礼貌池
User-Agent标头 — 设置CROSSREF_MAILTO即可获得优先访问权限,否则使用无需密钥的访问方式;不需要 API 令牌 - 对 429(遵循
Retry-After)、5xx、HTTP 408/504 和网络故障进行指数退避重试;响应正文格式错误,以及请求达到CROSSREF_TIMEOUT_MS时,不会重试 - 在 works 搜索和两个 works 子资源上支持基于游标的深度分页,可处理超过偏移量上限的结果集
- Crossref 拒绝请求时会返回明确的原因 —
unknown_filter(当 Crossref 列出带连字符的键时,使用该键)、invalid_parameter、sort_cursor_conflict、invalid_cursor— 并附带被拒绝的输入和恢复提示;格式错误的issn筛选值会在请求前被拒绝,任何上游错误都不会转发 Crossref 的原始响应正文 - 对所有人类可读的值进行文本规范化:解码 HTML 字符引用并合并空白;引用字符串还会剥除格式标记,使标题和摘要显示为纯文本,而不是原始 JATS XML;MathML 公式保留其结构 — 如果 deposit 中包含 TeX 注释,则使用该注释,否则采用线性形式,例如
x_i、A^{−1}、√(m)、(a+b)/c
便于 Agent 使用的输出:
- 来源可追溯 — 标识符、URL 和日期按字节原样返回,而人类可读文本经过规范化,因此调用方无需重新验证即可信任
doi、issn和日期字段 - 优雅处理部分失败 — 空页面视为成功,而不是错误:偏移量超出列表末尾,或查询无匹配结果时,会附带说明具体情况的
notice;crossref_search_works游标遍历到末页时也会附带notice;期刊或资助方 works 遍历会在缺少nextWorksCursor的页面结束 - 带判别字段的输出契约 — 列表耗尽后,不再提供
nextCursor、nextOffset、nextWorksOffset和nextWorksCursor续传字段;在偏移量上限处停止的页面会在notice中说明;游标令牌仍可能出现在最后一个部分页面中,而其后的空页面不包含令牌 - 明确处理歧义 —
ambiguous_journal和ambiguous_funder会在错误数据中列出所有候选项及其标识符,而不是静默选择第一个匹配项
开始使用
公共托管实例
公共实例位于 https://crossref.caseyjhand.com/mcp — 无需安装。通过 Streamable HTTP 将任意 MCP 客户端指向该实例:
{
"mcpServers": {
"crossref-mcp-server": {
"type": "streamable-http",
"url": "https://crossref.caseyjhand.com/mcp"
}
}
}
自托管 / 本地运行
将以下内容添加到 MCP 客户端配置文件中。CROSSREF_MAILTO 为可选项,但建议设置 — 未设置时,服务会使用 Crossref 的匿名池,速率限制更严格。
{
"mcpServers": {
"crossref-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/crossref-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"CROSSREF_MAILTO": "[email protected]"
}
}
}
}
也可使用 npx(无需 Bun):
{
"mcpServers": {
"crossref-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/crossref-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"CROSSREF_MAILTO": "[email protected]"
}
}
}
}
也可使用 Docker:
{
"mcpServers": {
"crossref-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-e", "[email protected]",
"ghcr.io/cyanheads/crossref-mcp-server:latest"
]
}
}
}
使用 Streamable HTTP 时,设置传输方式并启动服务:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 [email protected] bun run start:http
# Server listens at http://localhost:3010/mcp
前置条件
- Bun v1.4.0 或更高版本(或 Node.js v24+)。
CROSSREF_MAILTO的电子邮件地址为可选项,但建议设置 — Crossref 礼貌池会为表明身份的客户端提供优先访问权限。无需账户或令牌。
安装
- 克隆代码仓库:
git clone https://github.com/cyanheads/crossref-mcp-server.git
- 进入目录:
cd crossref-mcp-server
- 安装依赖:
bun install
- 配置环境:
cp .env.example .env
# edit .env and optionally set CROSSREF_MAILTO for polite-pool access
配置
启动时,所有配置都会通过 src/config/server-config.ts 中的 Zod 模式进行验证。
| 变量 | 说明 | 默认值 |
|---|---|---|
CROSSREF_MAILTO | 嵌入每个 Crossref 请求的礼貌池 User-Agent 标头中的电子邮件地址。可选——未设置时,服务仍会启动,但会记录警告,并使用速率限制更严格的匿名池。此地址绝不会发送给 DOI 注册机构:Crossref 未找到记录后进行的机构查询只会标识服务和版本。 | — |
CROSSREF_BASE_URL | Crossref API 基础 URL。可覆盖此值,以便通过本地代理进行测试。无论此处设置什么值,Crossref 未找到记录后进行的机构查询始终会访问 https://doi.org。 | https://api.crossref.org |
CROSSREF_TIMEOUT_MS | 每个请求的超时时间(毫秒)。这也是等待无响应上游服务的最坏情况——超时的请求不会重试。 | 10000 |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_SESSION_MODE | HTTP 会话模式:auto、stateful 或 stateless。此服务不需要多轮输入,因此 src/index.ts 声明为 stateless;Docker 和 .env.example 也固定使用相同值,设置此变量会覆盖该声明。 | stateless(在 src/ 中声明) |
MCP_HTTP_PORT | HTTP 服务的端口。 | 3010 |
MCP_AUTH_MODE | 身份验证模式:none、jwt 或 oauth。 | none |
MCP_LOG_LEVEL | 日志级别(RFC 5424)。 | info |
LOGS_DIR | 日志文件目录(仅限 Node.js)。 | <project-root>/logs |
LOG_TOOL_FAILURE_PAYLOADS | 记录每次失败的工具调用参数和结果,按键名对内容进行脱敏,并限制在 LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES 字节以内(默认值为 16384)。自由格式值中的机密不会被脱敏。 | false |
OTEL_ENABLED | 启用 OpenTelemetry 插桩。 | false |
完整的可选覆盖项列表请参阅 .env.example。
运行服务
本地开发
-
构建并运行:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:http -
运行检查和测试:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口点——注册工具并初始化服务。 |
src/config | 使用 Zod 解析并验证特定于服务的环境变量。 |
src/mcp-server/tools | 工具定义(*.tool.ts)。 |
src/services/crossref | CrossrefService——HTTP 客户端、礼貌池标头、重试和分页辅助工具。 |
tests/ | 单元测试和集成测试,结构与 src/ 对应。 |
开发指南
开发指南和架构规则请参阅 CLAUDE.md。简要说明:
- 处理器抛出错误,框架捕获错误——工具逻辑中不要使用
try/catch - 使用
ctx.log记录请求范围内的日志,使用ctx.state存储租户范围内的数据 - 通过
src/mcp-server/tools/definitions/index.ts中的汇总入口注册新工具 - 封装外部 API 调用:验证原始数据 → 规范化为领域类型 → 返回输出模式;绝不伪造缺失字段(Crossref 记录中经常缺少摘要、参考文献列表和所属机构信息)
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
许可证
Apache-2.0——详情请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。