关于 zenodo-mcp-server
zenodo-mcp-server 面向研究人员和数据使用者,帮助检索 Zenodo 中的数据集、软件和出版物。它可解析标识符、追踪版本,并预览文件及压缩包内容。
主要功能
- 01按研究元数据筛选检索
- 02解析 DOI、概念 DOI 和网址
- 03查看记录元数据与引用
- 04追踪存储记录的版本历史
- 05列出文件并读取文本摘录
适用场景
- 01按资助方或许可证查找研究记录
- 02通过 DOI 定位 Zenodo 记录
- 03比较存储记录的不同版本
- 04预览文本文件或压缩包成员
MCP 相关
向 MCP 客户端提供 6 个工具,用于检索 Zenodo、解析记录、浏览版本与文件并读取文本摘录。支持 STDIO 与 Streamable HTTP。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://zenodo.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-zenodo https://zenodo.caseyjhand.com/mcp{"mcpServers":{"cyanheads-zenodo":{"type":"http","url":"https://zenodo.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-zenodo":{"type":"http","url":"https://zenodo.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-zenodo":{"type":"http","url":"https://zenodo.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-zenodo":{"serverUrl":"https://zenodo.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
6| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | integer | 否 | 结果页码,从 1 开始。page × size 不得超过 10,000。 |
| size | integer | 否 | 每页结果数(1–25)。 |
| sort | enum | 否 | 排序顺序:bestmatch、newest、oldest、mostviewed、mostdownloaded、updated-desc、updated-asc。匹配时忽略大小写、空格、连字符和下划线(MostViewed 会按 mostviewed 处理)。有查询词时默认 bestmatch,无查询词时默认 newest。bestmatch | newest | oldest | mostviewed | mostdownloaded | updated-desc | updated-asc |
| award | string | 否 | 单个资助项目:award id <funder-ror>::<number>(00k4n6c32::101135562)、纯资助项目编号,或 CORDIS award DOI(10.3030/101135562)。使用 zenodo_lookup_vocabulary 查找 ID(vocabulary: awards)。 |
| query | string | 否 | 关键词查询。查询词之间默认使用 OR 连接,除非用 AND 连接;"quoted phrases" 须精确匹配;可使用 metadata.title:"…" 或 doi:"10.5281/zenodo.N" 等字段语法。将字面量 / 转义为 \/。不接受单独的 DOI 或记录 URL;请改用 zenodo_get_record 打开。省略则仅按筛选条件浏览。 |
| funder | string | 否 | 单个资助方:ROR ID(01cwqze88)、ROR URL 或 Crossref Funder DOI(10.13039/100000002)。使用 zenodo_lookup_vocabulary 解析资助方名称(vocabulary: funders)。 |
| license | string | 否 | 许可证 ID,例如 cc-by-4.0、cc0-1.0、mit(转为小写)。使用 zenodo_lookup_vocabulary 查找 ID(vocabulary: licenses)。 |
| community | string | 否 | 单个社区:其 slug、UUID 或 zenodo.org/communities/<slug> URL。使用 zenodo_lookup_vocabulary 查找 slug(vocabulary: communities)。 |
| file_type | array | 否 | 文件扩展名,以 OR 连接(也接受单个字符串):csv、zip、pdf、……转为小写并去除开头的点号。 |
| all_versions | boolean | 否 | 包含已被取代的版本;默认仅搜索最新版本。 |
| published_to | string | 否 | 最晚发布日期,格式为 YYYY、YYYY-MM 或 YYYY-MM-DD;不完整日期的截止时间为该日期范围的最后一天。 |
| access_status | enum | 否 | 访问状态:open、restricted、embargoed 或 metadata-only。匹配时忽略大小写、空格、连字符和下划线(Metadata Only 会匹配为 metadata-only)。open | restricted | embargoed | metadata-only |
| creator_orcid | string | 否 | 创建者 ORCID iD,例如 0000-0002-1825-0097;会去除 https://orcid.org/ 前缀,并将末尾的 x 转为大写。 |
| resource_type | array | 否 | 资源类型 ID,使用 OR 连接(也接受单个字符串):dataset、software、publication、publication-article、image-photo、……任何大小写均可;子类型也可使用 zenodo_lookup_vocabulary 显示为其搜索值的 <type>::<id> 格式(publication::publication-article)。顶级类型包含其子类型。使用 zenodo_lookup_vocabulary 查询 ID(词表:resource_types)。 |
| published_from | string | 否 | 最早发布日期,格式为 YYYY、YYYY-MM 或 YYYY-MM-DD;不完整日期从该日期的第一天开始。 |
详细介绍
@cyanheads/zenodo-mcp-server
通过 DOI 搜索和解析 Zenodo 数据集、软件和出版物;追踪版本和资助信息,列出文件,并通过 MCP 预览文本文件。支持 STDIO 或 Streamable HTTP。
概述
来自 CERN 开源研究知识库 Zenodo 的数据集、软件发行版和出版物。可使用资助方、项目、社区、许可证和文件类型筛选记录;解析任意 Zenodo DOI、概念 DOI 或 URL 以获取对应记录;查看记录的各个版本;并列出、打开和预览文件,包括 .zip 压缩包中的文件。
工具
| 工具 | 描述 |
|---|---|
zenodo_search_records | 按关键词搜索记录,并可按类型、社区、资助方、项目、ORCID、文件类型、许可证、访问权限和日期筛选,同时显示分面计数 |
zenodo_get_record | 根据记录 ID、DOI、概念 DOI 或 URL 解析一条记录,获取完整元数据、前 25 个文件以及可选的引用信息 |
zenodo_list_versions | 列出某条记录版本系列中的所有版本,按从新到旧排序 |
zenodo_list_files | 分页列出记录的文件清单,或列出其中一个 .zip 文件的成员 |
zenodo_read_file | 读取单个文件或 .zip 成员中受字节数限制的文本摘录 |
zenodo_lookup_vocabulary | 将社区、资助方、项目、许可证和资源类型名称解析为搜索筛选条件所需的 ID |
功能参考
zenodo_search_records 工具
- 关键词
query(各词之间默认按 OR 连接,除非用AND连接;支持带引号的短语、metadata.title:"…"等字段语法),以及resource_type、community、funder、award、creator_orcid、file_type、license、access_status和published_from/published_to - 每页最多返回 25 条结果;只能访问最前面的 10,000 条匹配项(超出时返回
result_window_exceeded);除非all_versions为 true,否则仅返回最新版本 sort:bestmatch、newest、oldest、mostviewed、mostdownloaded、updated-desc、updated-asc(有查询时默认bestmatch,无查询时默认newest)- 每条结果包含记录 ID、概念 ID 和 DOI、类型、版本、创建者、许可证 ID、访问权限、文件总数,以及独立浏览量和下载量;
facets统计完整匹配集中的资源类型、访问状态、文件类型、主题和年份 - 若
query是裸 DOI 或记录 URL,则会以query_is_identifier失败;若 Zenodo 不认识某个community或funder,则会以unknown_community/unknown_funder失败 - 如果
query不是有效的搜索语法(climate AND AND model、没有值的metadata.title:、'single quotes'、未闭合的[a TO b]),且设置了community或all_versions以外的筛选条件,则会以query_syntax失败,并指出有问题的标记,因为 Zenodo 会将其作为纯文本搜索并丢弃筛选条件;没有此类筛选条件时,则会按纯文本运行,并在notice中说明。无论是否设置筛选条件,Zenodo 无法执行的部分都会以query_syntax失败,但查询已经按纯文本运行的情况除外:没有闭合/的/(字面量斜杠可写作\/)、后面没有内容的!(climate!;可写作climate\!)、以反斜杠结尾的范围边界([a TO b\]];若边界包含空格、]或},则用双引号括起,例如[a TO "b]"]),以及 Zenodo 无法转换的提升、模糊或邻近值(climate^1.2.3、"x y"~0.5;应写作^2、~0.5、"x y"~2)。单词内部未闭合的"(12" vinyl;可写作12\")在没有筛选条件时也会以相同方式失败;有筛选条件时,短语会在查询末尾闭合,并改为检查闭合后的查询
zenodo_get_record 工具
id可接受记录 ID、Zenodo DOI、概念 DOI 或概念记录 ID(解析为最新版本)、注册到 Zenodo 记录的其他 DOI,或 zenodo.org / doi.org URL;input_kind和resolved_from会报告解析方式- 返回纯文本描述(最多 4,000 个字符)、带 ORCID 和 ROR 隶属机构的创建者与贡献者、权利、访问权限和禁运信息、资助信息、相关标识符、社群、带
latest_recid的版本位置、使用次数,以及前 25 个文件 - 每个受上限限制的字段都会报告总数;除文件列表外,每个被截断的字段都会列在
continuations中,并附带一个cursor和与之绑定的记录id;传回这两项即可获取该字段的下一个window(8,000 个字符的文本,或下一页条目) citation_style:bibtex、csl-json、apa、chicago-author-date、harvard-cite-them-right、ieee、modern-language-association或nature- 未命中时返回
found: false,并包含miss_kind(not_found、deleted、restricted、not_on_zenodo)和guidance;已删除的记录还会附带其移除墓碑信息tombstone
zenodo_list_versions 工具
- 接受与
zenodo_get_record相同形式的id;概念 DOI 和任一版本的 DOI 都会列出同一系列 - 按时间从新到旧排列,每页最多 25 条;报告
total_versions、latest_recid,以及概念记录 ID 和 DOI - 每个版本包含其记录 ID、DOI、版本标签、发布日期、
index、is_latest、文件总数,以及独立浏览量和下载量 - 未命中时返回与
zenodo_get_record相同的found: false、miss_kind、guidance和tombstone
zenodo_list_files 工具
- 清单条目包含键、大小、MIME 类型、MD5、下载 URL、
previewable和listable(.zip);每页最多返回 200 个条目,可通过offset/limit分页 archive_key用于列出一个.zip中的成员;Zenodo 每个归档最多列出 1,000 个文件和目录,并通过upstream_truncated标记是否截断key_contains会在分页前按不区分大小写的方式筛选键或成员路径- 对受限和处于禁运期的文件,会返回访问状态和禁运日期,不返回条目;未知和已删除的记录会分别以
record_not_found/record_deleted报错
zenodo_read_file 工具
- 使用
zenodo_list_files返回的key;另可使用archive_member,无需下载.zip即可读取其中的内容 max_bytes最小为 256(默认值为 16,384),每次调用最多为 65,536(更大的值会返回 65,536);顶层文件可从next_offset继续读取;.zip成员只能从字节 0 开始读取status的值为text、not_text、restricted或empty;摘录会在行或字符边界处结束- 类型为
application/octet-stream的无扩展名文件(LICENSE、Makefile)仅在内容为 UTF-8 文本时返回 - 每个结果都包含存储记录的
rights和download_url
zenodo_lookup_vocabulary 工具
vocabulary:communities、funders、awards、licenses或resource_types;可按名称、缩写或关键词使用query搜索,也可省略以浏览- 每个条目的
filter_param和filter_value分别指定zenodo_search_records的筛选参数和要传入的 ID funder将奖项限定为某个资助方,值可以是 ROR ID、ROR URL 或 Crossref Funder DOI- 每页最多 25 个条目;列表中只有前 10,000 个条目可访问,
reachable会与total一同返回
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及带可选 OpenTelemetry 跟踪的结构化日志记录。
Zenodo 专属功能:
- 所有接受
id的工具均支持记录 ID、Zenodo DOI、概念 DOI、外部 DOI 或 zenodo.org / doi.org URL;URL 会在本地解析,不会发起请求 - 搜索筛选条件会组合到 Zenodo 查询中,因此分面计数与
total一致;搜索运行前会检查社区和资助方的值 - 为 Zenodo 搜索和通用速率限制分别设置请求节流器,并依据其
X-RateLimit-*标头运行;另有进程本地缓存(记录 5 分钟、搜索 60 秒、词汇表 1 小时) - 支持字节范围文件读取和
.zip成员读取;返回任何文本之前都会先检测二进制内容
便于 Agent 使用的输出:
- 未命中会作为数据返回:
zenodo_get_record和zenodo_list_versions会返回found: false、类型化的miss_kind、后续步骤guidance,以及已删除记录的墓碑信息 - 存储者提供的文本会标记为不可信:描述以引用块呈现,文件内容置于代码围栏中,HTML 描述会转换为纯文本
- 搜索响应会回显发送给 Zenodo 的
effectiveQuery和appliedSort;所有分页工具都会报告总数以及下一页或偏移量 - Zenodo 未提供的字段会保持缺省,而不会默认设为
0、''或false
入门
公共托管实例
公共实例可通过 https://zenodo.caseyjhand.com/mcp 使用,无需安装。该实例提供 Streamable HTTP;每个客户端的配置格式各不相同。
对于 Claude Code:
claude mcp add --transport http zenodo-mcp-server https://zenodo.caseyjhand.com/mcp
对于 Cline(cline_mcp_settings.json):
{
"mcpServers": {
"zenodo-mcp-server": {
"type": "streamableHttp",
"url": "https://zenodo.caseyjhand.com/mcp"
}
}
}
对于 Cursor(mcp.json):
{
"mcpServers": {
"zenodo-mcp-server": {
"url": "https://zenodo.caseyjhand.com/mcp"
}
}
}
Claude Desktop 可在 Settings → Connectors 下添加远程服务。
托管实例无需令牌即可运行,因此所有调用方共享 Zenodo 的匿名速率限制。如需持续使用,请设置 ZENODO_ACCESS_TOKEN 并运行自己的实例。
自托管 / 本地
将以下内容添加到 MCP 客户端配置文件中。
{
"mcpServers": {
"zenodo-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/zenodo-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
也可以使用 npx(无需 Bun):
{
"mcpServers": {
"zenodo-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/zenodo-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
也可以使用 Docker:
{
"mcpServers": {
"zenodo-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/zenodo-mcp-server:latest"]
}
}
}
如需提高速率限制,请在 env 中添加 "ZENODO_ACCESS_TOKEN": "your-token"(Docker 则添加 -e ZENODO_ACCESS_TOKEN=…)。请参阅配置。
如需使用 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+)。
- 可选:Zenodo 个人访问令牌,用于提高速率限制。
安装
- 克隆仓库:
git clone https://github.com/cyanheads/zenodo-mcp-server.git
- 进入目录:
cd zenodo-mcp-server
- 安装依赖项:
bun install
- 配置环境:
cp .env.example .env
# optionally set ZENODO_ACCESS_TOKEN
配置
| 变量 | 描述 | 默认值 |
|---|---|---|
ZENODO_ACCESS_TOKEN | Zenodo 个人访问令牌,创建时不选择任何作用域。提高 Zenodo 的速率限制;工具行为和页面大小不变。 | 无 |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_HTTP_PORT | HTTP 服务端口。 | 3010 |
MCP_SESSION_MODE | HTTP 会话模式:stateless、stateful 或 auto。 | stateless |
MCP_AUTH_MODE | 身份验证:none、jwt 或 oauth。 | none |
MCP_LOG_LEVEL | 日志级别(debug、info、warning、error 等)。 | info |
LOGS_DIR | 日志文件目录(仅限 Node.js)。 | <app-root>/logs |
STORAGE_PROVIDER_TYPE | 存储后端:in-memory、filesystem、supabase、cloudflare-kv/r2/d1。 | in-memory |
OTEL_ENABLED | 启用 OpenTelemetry。 | false |
完整的可选覆盖项列表,请参阅 .env.example。
速率限制
Zenodo 按 IP 地址对匿名客户端实施速率限制:整体每分钟 60 次请求、每小时 2,000 次请求,记录搜索每分钟 30 次请求。服务会将自身请求的速率控制在限制以内:搜索每分钟 25 次,其他请求每分钟 55 次、每小时 1,900 次。一个服务进程的所有调用方共用此额度。额度用尽时,工具会返回 rate_limited 错误,并提供以秒为单位的 retryAfter。
设置 ZENODO_ACCESS_TOKEN 后,Zenodo 允许每分钟 100 次请求、每小时 5,000 次请求;服务会将其他请求的速率控制在每分钟 90 次、每小时 4,800 次。搜索仍为每分钟 25 次。
该令牌以创建它的账户进行身份验证,因此读取操作可查看该账户有权查看的内容,包括该账户拥有的受限记录。在共享或托管服务上,请使用不拥有任何受限记录的专用账户创建令牌。
运行服务
本地开发
-
构建并运行生产版本:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdio -
运行检查和测试:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
Docker
docker build -t zenodo-mcp-server .
docker run --rm -p 3010:3010 zenodo-mcp-server
Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/zenodo-mcp-server。默认会安装 OpenTelemetry 对等依赖项;构建时添加 --build-arg OTEL_ENABLED=false 可省略这些依赖项。
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口:服务说明、工具注册、服务设置和清理。 |
src/config | 使用 Zod 解析和验证服务专属环境变量。 |
src/mcp-server/tools | 工具定义(*.tool.ts),以及共享的渲染、架构和记录未命中辅助函数。 |
src/services/zenodo | Zenodo 服务:HTTP 边界和速率控制器、缓存、标识符解析、查询构建、规范化、文本预览。 |
tests/ | 基于已记录 Zenodo 固定数据的单元、服务、工具和模糊测试。 |
docs/design.md | 工具界面设计、已验证的上游行为和决策日志。 |
开发指南
请参阅 CLAUDE.md,了解开发指南和架构规则。简而言之:
- 处理程序抛出异常,框架负责捕获——工具逻辑中不要使用
try/catch - 使用
ctx.log记录日志;Zenodo 响应在服务中按进程范围缓存,而不是存储在ctx.state中 - 在
src/mcp-server/tools/definitions/index.ts中注册新工具 - 包装外部 API 调用:验证原始数据 → 规范化为领域类型 → 返回输出架构;绝不伪造缺失字段
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
许可证
本项目采用 Apache 2.0 许可证。详情请参阅 LICENSE 文件。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。