Zenodo Mcp Server

io.github.cyanheads由 GitHub 账号 cyanheads 发布v0.2.0更新于 Oct 29, 2026

Search and resolve Zenodo datasets, software, and publications by DOI; trace versions and funding.

已验证Streamable HTTP可网页运行网页搜索与抓取知识与记忆

概览

AI 生成的概览

按关键词、DOI 或记录 ID 检索并解析 Zenodo 上的数据集、软件与论文等研究存档,含版本、文件与资助信息。

可以做什么
  • 按关键词检索存档,可按资源类型、社区、资助方、基金、ORCID、文件类型、许可证、访问状态和日期筛选,并返回分面计数
  • 用记录 ID、Zenodo DOI、概念 DOI 或网址解析单条存档,返回完整元数据、作者、资助、权利信息及可选引用格式
  • 列出某存档版本序列中的全部版本,最新在前
  • 分页查看存档的文件清单,或列出某个 .zip 压缩包内的成员
  • 读取单个文本文件或压缩包成员的 UTF-8 片段,每次有字节上限
  • 把社区、资助方、奖项、许可证和资源类型名称解析为检索筛选所需的 ID
适用场景
适合需要查找或核实可引用研究成果、确认应引用数据集或软件存档的哪个版本、追溯版本历史,或在复用数据前核对资助与许可信息的场景。
运行要求
可使用托管 HTTP 端点,或通过 npx 在本地运行(需 Node.js;源码构建需 Bun v1.4.0+ 或 Node.js v24+)。匿名读取无需账号;可选在 ZENODO_ACCESS_TOKEN 中提供 Zenodo 个人访问令牌以提高速率上限。需要能访问 Zenodo 的网络。
安装前请注意
托管实例的所有调用方共享 Zenodo 的匿名速率限制,工具可能返回 rate_limited。令牌以创建它的账号身份认证,可看到该账号拥有的受限记录,共享服务器上应使用专用账号。标题、描述和文件内容由存档者提供,应视为不可信数据。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Zenodo Mcp Server,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.github.cyanheads%2Fzenodo-mcp-server/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。

{
  "mcpServers": {
    "zenodo": {
      "type": "http",
      "url": "https://zenodo.caseyjhand.com/mcp"
    }
  }
}

README

@cyanheads/zenodo-mcp-server

Search and resolve Zenodo datasets, software, and publications by DOI; trace versions and funding, list files, and preview text files via MCP. STDIO or Streamable HTTP.

6 Tools

Public Hosted Server: https://zenodo.caseyjhand.com/mcp


Overview

Datasets, software releases, and publications from Zenodo, CERN's open research repository. Search deposits with filters for funder, grant, community, license, and file type; resolve any Zenodo DOI, concept DOI, or URL to its record; walk a deposit's versions; and list, open, and preview its files, including members of .zip archives.

Tools

The published zenodo-guide covers selecting a cited release, resolving funding identities, and checking inspection coverage. Plugin installs include it; MCP clients can discover it through the Skills extension and its skill resources.

ToolDescription
zenodo_search_recordsSearch deposits by keyword plus type, community, funder, grant, ORCID, file type, license, access, and date filters, with facet counts
zenodo_get_recordResolve one deposit from a record id, DOI, concept DOI, or URL to its full metadata, first 25 files, and an optional citation
zenodo_list_versionsList every version of a deposit's version series, newest first
zenodo_list_filesPage a deposit's file manifest, or list the members of one of its .zip files
zenodo_read_fileRead a byte-capped text excerpt of one file or .zip member
zenodo_lookup_vocabularyResolve community, funder, grant, license, and resource-type names to the ids search filters take

Capability reference

zenodo_search_records tool

  • Keyword query (terms OR-ed unless joined with AND, quoted phrases, field syntax such as metadata.title:"…") plus resource_type, community, funder, award, creator_orcid, file_type, license, access_status, and published_from / published_to
  • Up to 25 hits per page; only the first 10,000 matches are reachable (result_window_exceeded past that); latest versions only unless all_versions is true
  • sort: bestmatch, newest, oldest, mostviewed, mostdownloaded, updated-desc, updated-asc (default bestmatch with a query, newest without)
  • Each hit carries record and concept ids and DOIs, type, version, creators, license ids, access, file totals, and unique views and downloads; facets count resource types, access statuses, file types, subjects, and years over the full match set
  • A bare DOI or record URL as query fails as query_is_identifier; a community or funder Zenodo doesn't know fails as unknown_community / unknown_funder
  • Invalid search syntax fails as query_syntax, naming the offending token:
    • With a filter other than community or all_versions set, any invalid syntax fails (climate AND AND model, metadata.title: with no value, 'single quotes', an unclosed [a TO b]), because Zenodo would search it as plain text and drop the filters. Without such a filter it runs as plain text and the notice says so
    • Constructs Zenodo cannot run fail with or without a filter, unless the query already runs as plain text: an unclosed / (escape a literal one as \/), a trailing ! (climate\!), a range bound ending in a backslash (double-quote a bound holding a space, ], or }: [a TO "b]"]), and a boost, fuzziness, or proximity value Zenodo cannot convert (climate^1.2.3, "x y"~0.5; write ^2, ~0.5, "x y"~2)
    • An unclosed " inside a word (12" vinyl; escape it as 12\") fails without a filter; with one, the phrase is closed at the end of the query and the closed query is checked instead

zenodo_get_record tool

  • id takes a record id, a Zenodo DOI, a concept DOI or concept record id (resolves to the latest version), another DOI registered to a Zenodo record, or a zenodo.org / doi.org URL; input_kind and resolved_from report how it resolved
  • Returns the description as plain text (up to 4,000 characters), creators and contributors with ORCIDs and ROR affiliations, rights, access and embargo, funding, related identifiers, communities, version position with latest_recid, usage counts, and the first 25 files
  • Every capped field reports its total, and each cut except the file list (paged with zenodo_list_files) is listed in continuations with a cursor and the record id it is bound to; pass both back to get that field's next window (8,000 characters of text, or the next page of entries)
  • citation_style: bibtex, csl-json, apa, chicago-author-date, harvard-cite-them-right, ieee, modern-language-association, or nature
  • A miss returns found: false with miss_kind (not_found, deleted, restricted, not_on_zenodo) and guidance; a deleted record adds its removal tombstone

zenodo_list_versions tool

  • Takes the same id forms as zenodo_get_record; a concept DOI and any version's DOI list the same series
  • Newest first, up to 25 per page; reports total_versions, latest_recid, and the concept record id and DOI
  • Each version carries its record id, DOI, version label, publication date, index, is_latest, file totals, and unique views and downloads
  • Misses return found: false with the same miss_kind, guidance, and tombstone as zenodo_get_record

zenodo_list_files tool

  • Manifest entries carry key, size, MIME type, MD5, download URL, previewable, and listable (a .zip); up to 200 per page via offset / limit
  • archive_key lists the members of one .zip; Zenodo lists at most 1,000 files and directories per archive, flagged by upstream_truncated
  • key_contains filters keys or member paths case-insensitively before paging
  • Restricted and embargoed files return the access status and embargo date with no entries; unknown and deleted records fail as record_not_found / record_deleted

zenodo_read_file tool

  • key from zenodo_list_files, plus archive_member to read inside a .zip without downloading it
  • max_bytes from 256 (default 16,384), at most 65,536 per call (larger values return 65,536); continue a top-level file from next_offset; .zip members read from byte 0 only
  • status is text, not_text, restricted, or empty; excerpts end on a line or character boundary
  • Extensionless files typed application/octet-stream (LICENSE, Makefile) are returned only when their content is UTF-8 text
  • Every result carries the deposit's rights and the download_url

zenodo_lookup_vocabulary tool

  • vocabulary: communities, funders, awards, licenses, or resource_types; query by name, acronym, or keyword, or omit it to browse
  • Each entry's filter_param and filter_value name the zenodo_search_records filter and the id to pass it
  • funder scopes awards to one funder, as a ROR id, ROR URL, or Crossref Funder DOI
  • Up to 25 entries per page; only the first 10,000 entries of a list are reachable, reported as reachable beside total

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

Zenodo-specific:

  • Accepts a record id, Zenodo DOI, concept DOI, external DOI, or zenodo.org / doi.org URL in every tool that takes id; URLs are parsed locally and never fetched
  • Search filters compose into Zenodo's query, so facet counts agree with total; community and funder values are checked before the search runs
  • Separate request pacers for Zenodo's search and general rate-limit buckets, backed by its X-RateLimit-* headers, plus a process-local cache (records 5 min, searches 60 s, vocabularies 1 h)
  • Byte-range file reads and .zip member reads, with binary detection before any text is returned

Agent-friendly output:

  • Misses as data: zenodo_get_record and zenodo_list_versions return found: false with a typed miss_kind, next-step guidance, and a deleted record's tombstone
  • Depositor-supplied text is labeled untrusted: descriptions render as quoted blocks, file content in a code fence, and HTML descriptions are converted to plain text
  • Search responses echo the effectiveQuery sent to Zenodo and the appliedSort, and every paged tool reports totals with a next page or offset
  • Fields Zenodo omits stay absent rather than defaulting to 0, '', or false

Getting started

Connect to the hosted instance, no install:

sh
claude mcp add --transport http zenodo-mcp-server https://zenodo.caseyjhand.com/mcp

Or run it locally:

sh
claude mcp add zenodo-mcp-server -- npx -y @cyanheads/zenodo-mcp-server

For other clients, add this to the MCP config file:

json
{  "mcpServers": {    "zenodo-mcp-server": {      "command": "npx",      "args": ["-y", "@cyanheads/zenodo-mcp-server"]    }  }}

The hosted instance shares Zenodo's anonymous rate limit across callers. An optional Zenodo personal access token in ZENODO_ACCESS_TOKEN raises the rate limit of your own instance (-e ZENODO_ACCESS_TOKEN=your-token after the Claude Code server name, or an env entry). For Docker or a source build, see Running the server.

Configuration

VariableDescriptionDefault
ZENODO_ACCESS_TOKENZenodo personal access token, created with no scopes. Raises Zenodo's rate limit; tool behavior and page sizes are unchanged.none
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTHTTP server port.3010
MCP_SESSION_MODEHTTP session mode: stateless, stateful, or auto.stateless
MCP_AUTH_MODEAuthentication: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (debug, info, warning, error, etc.).info
LOGS_DIRDirectory for log files (Node.js only).<app-root>/logs
STORAGE_PROVIDER_TYPEStorage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1.in-memory
OTEL_ENABLEDEnable OpenTelemetry.false

See .env.example for the full list of optional overrides.

Rate limits

Zenodo rate-limits anonymous clients per IP address: 60 requests per minute and 2,000 per hour overall, and 30 per minute on record search. The server paces its own requests below those limits: 25 searches per minute, and 55 other requests per minute and 1,900 per hour. Every caller of one server process shares that budget. When it runs out, tools fail with rate_limited and a retryAfter in seconds.

With ZENODO_ACCESS_TOKEN set, Zenodo allows 100 requests per minute and 5,000 per hour, and the server paces other requests at 90 per minute and 4,800 per hour. Search stays at 25 per minute.

The token authenticates as the account that created it, so reads can see what that account can see, including restricted records it owns. On a shared or hosted server, create the token on a dedicated account that owns no restricted records.

Running the server

Local development

Requires Bun v1.4.0 or higher (or Node.js v24+).

  • Clone and install:

    sh
    git clone https://github.com/cyanheads/zenodo-mcp-server.gitcd zenodo-mcp-server && bun installcp .env.example .env   # optionally set ZENODO_ACCESS_TOKEN
  • Build and run the production version:

    sh
    # One-time buildbun run rebuild
    # Run the built serverbun run start:http# orbun run start:stdio
  • Run checks and tests:

    sh
    bun run devcheck  # Lints, formats, type-checks, and morebun run test      # Runs the test suite

Docker

sh
docker run --rm -p 3010:3010 ghcr.io/cyanheads/zenodo-mcp-server:latest

The image defaults to HTTP transport, stateless session mode, and logs to /var/log/zenodo-mcp-server. To run it over stdio from an MCP client, use "command": "docker" with "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/zenodo-mcp-server:latest"]. To build locally, docker build -t zenodo-mcp-server .; OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point: server instructions, tool registration, service setup and teardown.
src/configServer-specific environment variable parsing and validation with Zod.
src/mcp-server/toolsTool definitions (*.tool.ts) plus shared render, schema, and record-miss helpers.
src/services/zenodoZenodo service: HTTP boundary and pacers, cache, identifier parsing, query building, normalization, text previews.
tests/Unit, service, tool, and fuzz tests against recorded Zenodo fixtures.
docs/design.mdTool surface design, verified upstream behavior, and decisions log.
skills/zenodo-guide/Published research workflow guide and query reference, also served over MCP.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for logging; Zenodo responses are cached process-wide in the service, not in ctx.state
  • Register new tools in src/mcp-server/tools/definitions/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Contributing

Issues are welcome. Run checks and tests before submitting:

sh
bun run devcheckbun run test

License

This project is licensed under the Apache 2.0 License. See the LICENSE file for details.

来源:README.md,提交 0ae79d9

工具

6

zenodo_search_records

Search Zenodo records

Search Zenodo's open research repository — datasets, software releases, publications, and other deposits — by keyword query plus filters for resource type, community, funder, grant, creator ORCID, file type, license, access status, and publication date. Returns one summary per deposit (ids, DOIs, title, type, version, creators, license, access, file totals, usage counts) plus facet counts over the full match set, every filter applied. Query terms are OR-ed unless joined with AND, quoted phrases match exactly, and field syntax works on record fields (metadata.title:"…", metadata.subjects.subject:"…"). Only the latest version of each deposit is searched unless all_versions is true, and only the first 10,000 matches are reachable by paging. Resolve community, funder, and grant names to ids with zenodo_lookup_vocabulary first; open one deposit in full with zenodo_get_record.

输入参数pagesizesortawardqueryfunderlicensecommunityfile_typeall_versionspublished_toaccess_status另有 3 个

zenodo_get_record

Get a Zenodo record

Resolve one Zenodo deposit from a record id, a Zenodo DOI (10.5281/zenodo.N), a concept DOI or concept record id (resolves to the latest version), another DOI deposited on Zenodo, or a zenodo.org or doi.org URL, and return its full metadata: description, creators with ORCIDs and ROR affiliations, license, access and embargo, funding and grants, related identifiers, communities, version position, usage counts, and the first 25 files. Optionally includes a formatted citation. Long text and lists are cut at display caps with their totals reported; every cut except the file list (paged with zenodo_list_files) is listed in continuations with a cursor and the record id it is bound to, and passing both back returns the next window of that field (8,000 characters of text, or the next page of entries) in place of the record. A miss (an unknown id, a deleted record with its removal tombstone, restricted metadata, or a DOI not registered on Zenodo) returns found: false with guidance instead of an error.

输入参数id必填cursorcitation_style

zenodo_list_versions

List Zenodo record versions

List every version of a Zenodo deposit's version series, newest first, with each version's record id, DOI, version label, publication date, file totals, and usage counts. Accepts any identifier zenodo_get_record accepts; a concept DOI and any single version's DOI list the same series. Use it to find the version a paper cited or the current release. A miss (an unknown id, a deleted record with its removal tombstone, restricted metadata, or a DOI not registered on Zenodo) returns found: false with guidance instead of an error.

输入参数id必填pagesize

zenodo_list_files

List Zenodo record files

Page through a Zenodo deposit's file manifest (key, size, MIME type, MD5, download URL, previewability), optionally filtered by a substring of the file key, or list the members inside one of its .zip files by setting archive_key. Restricted and embargoed files return the access status and embargo date with no entries. Read a small text file or ZIP member with zenodo_read_file.

输入参数id必填limitoffsetarchive_keykey_contains

zenodo_read_file

Read a Zenodo file excerpt

Read a bounded UTF-8 excerpt (up to 64 KiB per call) of one text file in a Zenodo deposit — a README, CITATION.cff, CSV head, notebook, or script — or of one member inside a .zip file, without downloading the archive. Continue a top-level file from next_offset. A file with a text MIME type or extension is read directly; an extensionless file Zenodo types application/octet-stream (LICENSE, COPYING, Makefile) is read and returned only when its content is UTF-8 text. Binary files, restricted files, and other types return metadata and the download URL without content. File content is depositor-supplied and carries the deposit’s license.

输入参数id必填key必填max_bytesoffset_bytesarchive_member

zenodo_lookup_vocabulary

Look up Zenodo filter ids

Resolve names to the ids zenodo_search_records filters on, and browse Zenodo's reference vocabularies: communities (slug), funders (ROR id), awards and grants (award id), licenses (license id), and resource types (type id). Search by name, acronym, or keyword; awards can be scoped to one funder. Each entry names the zenodo_search_records parameter its id feeds.

输入参数pagesizequeryfundervocabulary必填

版本历史

5
  1. v0.2.0最新Oct 29, 2026
  2. v0.1.4Oct 25, 2026
  3. v0.1.3Oct 18, 2026
  4. v0.1.2Oct 9, 2026
  5. v0.1.1Sep 24, 2026

评分

已满足适用检查项的 100%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分