zenodo-mcp-server について
zenodo-mcp-serverは、研究者やデータ利用者がZenodoのデータセット、ソフトウェア、出版物を検索・確認するためのサーバーです。識別子の解決やバージョン追跡に加え、ファイルやアーカイブ内の内容をプレビューできます。
主な機能
- 01研究メタデータによる検索絞り込み
- 02DOI・コンセプトDOI・URLの解決
- 03レコードのメタデータと引用の確認
- 04登録レコードのバージョン履歴追跡
- 05ファイル一覧とテキスト抜粋の読み取り
活用シーン
- 01助成元やライセンスで研究レコードを検索
- 02DOIからZenodoレコードを特定
- 03登録レコードの各バージョンを比較
- 04テキストファイルやアーカイブ内の項目をプレビュー
MCP 対応
Zenodoの検索、レコード解決、バージョン・ファイル閲覧、テキスト抜粋の読み取りを行う6つのツールをMCPクライアントに公開します。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 ページあたりの結果数(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 | いいえ | キーワードクエリ。AND で結合しない限り、検索語は OR で結合されます。"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に対応しています。
公開ホストサーバー: https://zenodo.caseyjhand.com/mcp
概要
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(ANDで結合されていない限り、各語は OR で検索されます。引用符で囲まれたフレーズや、metadata.title:"…"のようなフィールド構文も使用できます)、およびresource_type、community、funder、award、creator_orcid、file_type、license、access_status、published_from/published_to - 1 ページあたり最大 25 件の結果を返します。取得できるのは最初の 10,000 件までです(それを超えると
result_window_exceeded)。all_versionsが true でない限り、最新バージョンのみが対象です sort:bestmatch、newest、oldest、mostviewed、mostdownloaded、updated-desc、updated-asc(デフォルトは、queryがある場合は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 文字分、または次のページの項目)を取得できます。ファイルリストはzenodo_list_filesでページを指定して取得します 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 は、同じシリーズを一覧表示します- 新しい順に、1 ページあたり最大 25 件を返します。
total_versions、latest_recid、およびコンセプトレコードの ID と DOI が報告されます - 各バージョンには、レコード ID、DOI、バージョンラベル、公開日、
index、is_latest、ファイル総数、ユニークビュー数およびダウンロード数が含まれます - 見つからない場合は、
zenodo_get_recordと同じmiss_kind、guidance、tombstoneを伴ってfound: falseが返されます
zenodo_list_files ツール
- マニフェストの各エントリーには、キー、サイズ、MIME タイプ、MD5、ダウンロード URL、
previewable、およびlistable(.zip)が含まれます。offset/limitでページあたり最大 200 件を取得できます archive_keyを指定すると、1 つの.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)で、1 回の呼び出しにつき最大 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 によって、助成金を 1 つの資金提供者に絞り込みます- ページあたり最大 25 件を取得できます。一覧の最初の 10,000 件のみアクセス可能で、その件数は
totalとともにreachableとして報告されます
特長
@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メンバーの読み取りに対応し、テキストを返す前にバイナリかどうかを判定します
エージェントに適した出力:
- 見つからない場合もデータとして返します。
zenodo_get_recordとzenodo_list_versionsは、型付きのmiss_kind、次の手順を示すguidance、および削除済みレコードの墓標とともにfound: falseを返します - 登録者が提供したテキストは信頼できないものとして表示します。説明文は引用ブロックに、ファイル内容はコードフェンスに表示し、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 では、「設定」→「コネクタ」からリモートサーバーを追加します。
ホストインスタンスはトークンなしで動作するため、すべての呼び出し元で 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=… を指定します)。Configurationを参照してください。
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回です。1つのサーバープロセスを利用するすべての呼び出し元が、この枠を共有します。枠を使い切ると、ツールは 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呼び出しをラップします。生データを検証し、ドメイン型に正規化してから、出力スキーマを返してください。不足しているフィールドを捏造しないでください
コントリビューション
Issueを歓迎します。提出前にチェックとテストを実行してください。
bun run devcheck
bun run test
ライセンス
このプロジェクトはApache 2.0 Licenseの下でライセンスされています。詳細はLICENSEファイルを参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。