AMIRA — Africa Multiple Research Data について
AMIRAは、Africa Multipleの研究データを探索する研究者向けの読み取り専用MCPサーバーです。検索可能なレコード、出版物、メディアの文字起こしに加え、出典リンク、オフラインスナップショット、研究ワークフロー用プロンプトを提供します。
主な機能
- 01研究項目と出版物の検索
- 02プロジェクト、人物、場所、機関の閲覧
- 03ポッドキャストと動画の文字起こし検索
- 04レコードのエクスポートと引用生成
- 05オフラインスナップショットと任意の更新
活用シーン
- 01主題、場所、寄稿者から研究データを検索
- 02プロジェクト、人物、出版物のつながりを追跡
- 03文字起こしと出版物の全文を検索
- 04プロジェクト資料や文献レビューを作成
MCP 対応
33個のコアツール、5つの研究ワークフロー用プロンプト、引用可能なレコードと一括エクスポート用リソースを通じて、AMIRAのデータをMCPクライアントに公開します。クライアントは同梱スナップショット、または公開Omeka S APIから更新したデータを検索できます。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://data.africamultiple.uni-bayreuth.de/mcpclaude mcp add --transport http am-digital-research-environment-amira https://data.africamultiple.uni-bayreuth.de/mcp{"mcpServers":{"am-digital-research-environment-amira":{"type":"http","url":"https://data.africamultiple.uni-bayreuth.de/mcp"}}}Cursor で開く{"servers":{"am-digital-research-environment-amira":{"type":"http","url":"https://data.africamultiple.uni-bayreuth.de/mcp"}}}VS Code で開く{"mcpServers":{"am-digital-research-environment-amira":{"type":"http","url":"https://data.africamultiple.uni-bayreuth.de/mcp"}}}{"mcpServers":{"am-digital-research-environment-amira":{"serverUrl":"https://data.africamultiple.uni-bayreuth.de/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
35このツールにパラメーターはありません。
詳細
AMIRA MCP サーバー
バイロイト大学のアフリカ・マルチプル・クラスター・オブ・エクセレンスが運営する研究データプラットフォーム、Africa Multiple Interactive Research Atlas(AMIRA)用の読み取り専用Model Context Protocolサーバーです。AMIRAは、クラスターの公開Omeka Sサイトdata.africamultiple.uni-bayreuth.deで公開されています。
AMIRAは、クラスターのデジタルインフラ部門である**Digital Research Environment(DRE)が構築・保守しています。DREは、世界各地のAfrica Multiple Research Centres(AMRCs)**およびパートナー機関の研究者をつなぐデータシステムを設計、構築、保守しています。データのキュレーションと記述は、Université Joseph Ki-Zerbo、Rhodes University、University of Lagos、Moi UniversityのAMRCに所属するパートナーとの共同作業です。バイロイトは、調整を担うDREのインフラとメタデータ層をホストしています。Federal University of Bahiaは重要なパートナーですが、AMRCではありません。
ストレージはデフォルトで分散された状態に保たれます。データはローカルリポジトリに置かれたまま、バイロイトがそのデータを参照するメタデータ層を保持します。研究データは移動させることなく検索可能になります。高品質なメタデータによって、研究者のデータが見つけやすくなり、その研究がより広い研究者コミュニティに知られるようになります。
このサーバーは、AMIRAのプロジェクト、テーマ別の研究セクション、約4,000件のデジタル化された研究資料、人物、機関、グループ、コレクション、クラスターの全文検索可能な書誌データ(オープンアクセスPDFから抽出)とその学術誌、トランスクリプト付きポッドキャストエピソード、およびトランスクリプトを検索できるクラスターのYouTube動画を公開します。これらは、LLMがクエリできる33個のコアツール、研究ワークフロー向けの5つのプロンプト、引用可能なレコードや一括エクスポート用のリソースとして利用できます。1つのMCPインターフェースから、クライアントはレコードを横断し、それらを結び付ける場所、言語、主題をたどることができます。
すべてのレコードには**amira_urlが付いています。これはOmeka Sサイト上の公開ページ(…/s/amira/item/<id>)で、情報源へのリンクとして引用**できます。AMIRAはクラスターの研究データを対象としています。Africa Multiple Cluster of Excellenceのニュース、イベント、一般情報については、africamultiple.uni-bayreuth.deをご覧ください。
**2026年10月6日時点の収録状況:**研究資料3,975件(うち1,419件にデジタル化メディアあり)、プロジェクト93件、出版物555件(うち60件に抽出済み全文あり)、学術誌87誌、ポッドキャストエピソード43件、動画140件、主題典拠3,085件(米国議会図書館件名標目646件)。件数は特定日時点のスナップショットです。実行中のサーバーに実際に含まれるデータについては、get_collection_overviewを使用してください。出版物ガイド、各リリースでの変更内容を記載した変更履歴、および今後の改善について記載したロードマップをご覧ください。
データの取得方法と、ほかに何も必要ない理由
このサーバーは自己完結型で、オフラインファーストです。次の2つのソースから読み込みます。
.mcpbに同梱された完全なデータスナップショット — ビルド時に公開されているOmeka S REST APIからクロールし、コンパクトな型付きレコードに変換しているため、セットアップ不要でサーバーを完全にオフラインで動作させられます。- (オプション。デフォルトで有効) HTTPS経由のOmeka S API。起動時と毎日、プローブがアイテムおよびアイテムセットの変更シグネチャと合計件数を比較します。変更シグナルが検出されると、完全なクロールを実行します。週次の強制クロールによって、語彙のみの編集も検出できます。書き込みロック、不変の世代データ、アトミックポインターにより、更新に失敗した場合も、以前の利用可能なスナップショットが保持されます。APIのオリジンとインストールパスによってキャッシュが分割され、レコードをそのサイトの引用URLで提供する前に、マニフェストとの一致を確認します。
エンドユーザーにAPIキーも認証情報もVPNも必要ありません。公開サイトを支えるものと同じ、一般公開されているデータです。
ツール
まずget_collection_overviewを呼び出してデータの範囲を把握し、その後、詳しく調べてください。
| ツール | 目的 |
|---|---|
get_collection_overview | コレクション全体の件数と内訳、およびスナップショットの最新状況 |
search_research_items | キーワード(すべての単語が一致する必要があります。フレーズは引用符で囲みます)、主題、場所(階層を考慮)、国(完全一致。Côte d'Ivoire = Ivory Coast などの別名にも対応)、貢献者、プロジェクト、セクション、大学、リソースタイプ、形式/ジャンル、言語、年、has_media、added_since / modified_since でアイテムを検索します。`export=csv |
get_research_item | 1 件のアイテムの完全なメタデータ(Omeka id または型付き ID で指定)。型付き日付、当時の所属先を含む役割、地域/国の階層情報を含む場所、関連機関へのリンクとしての来歴、型付き識別子、コレクション、関連アイテム、メディアファイル、IIIF マニフェストに加え、自動生成された引用と BibTeX/RIS/CSL-JSON エクスポート(citation_format)を返します |
search_projects / get_project | キーワードまたは略称、大学、セクション、PI、メンバー、資金提供者でプロジェクトを検索します。詳細には、アイテムの内訳、上位の主題、アイテムの例が含まれます |
list_research_sections / get_research_section | 助成フェーズ(AM 1.0 / AM 2.0)、PI、件数、プロジェクトを含むテーマ別セクションを一覧表示します。名前または ID で詳細を取得できます |
search_persons / get_person | 人物を検索します(姓名の順序はどちらでも構いません)。プロフィールには、GND その他の典拠識別子、プロジェクトおよび研究セクションでの役割、アイテム、出版物、ポッドキャスト、動画、主な共同研究者が含まれ、件数の読み取り方を説明する coverage_note も含まれます。該当する人物がいない名前には、近似候補の suggestions が返されます(「Rudigr Seeman」→ Seesemann, Rüdiger)。get_person は not_found エラーに候補を一覧表示します |
list_institutions / get_institution / list_cluster_partners / list_groups | 名前、略称、ID で組織(機関、Africa Multiple のパートナーカテゴリー、研究グループ)を検索し、そのプロジェクト、人物、アイテムを取得します |
list_subjects | アイテムの頻度順に主題標目を一覧表示します。各項目には、米国議会図書館の標目(id.loc.gov URI 付き)か、自由タグ(`vocabulary=lcsh |
list_locations | すべての場所を一覧表示します。国と都市を階層を統合した単一のリストにまとめ、アイテム数順に並べます。座標と Wikidata ID も含まれます。国、名前、near(半径)、bbox で絞り込めます |
list_collections | コレクション(アイテムセット)を研究アイテム数順に一覧表示し、IIIF コレクションリンクを含めます。collection フィルターと組み合わせて使用します |
list_categories | ファセット値(形式/ジャンル、言語、リソースタイプ)を返します |
list_years | 年または年代ごとの研究アイテムの日付ヒストグラムを返します。経時的な収録状況と、最も収録数の多い年/年代を確認できます |
search_publications / get_publication | 著者、主題、言語、種類、掲載媒体、年、追加日、全文の有無で文献目録を絞り込みます。すべての言語の抄録と、PDF から抽出したテキストを検索します。詳細には、すべての抄録と言語、関連する典拠、会議/ページ数/アクセス/学位論文のメタデータが含まれます。citation_format でページごとの BibTeX/RIS/CSL-JSON を選択でき、export で検索結果全体を 1 つのファイルとしてダウンロードするリンクを取得できます |
list_publication_facets | 絞り込んだ文献目録全体を対象に、種類、年、言語、主題、著者/編集者、掲載媒体ごとの件数を返します。順位付けとページネーションに対応しています |
list_journals | クラスターが出版しているジャーナルを出版件数順に一覧表示し、ISSN と国を含めます。venue フィルターと組み合わせて使用します |
find_related | エンティティを横断して探索します。主題/場所/人物/プロジェクトを起点に、同時に出現するエンティティ(出版物を含む)を探します |
search_podcasts / get_podcast | 検索可能な文字起こし付きのクラスターのポッドキャストエピソードを検索します。言語で絞り込み可能です。詳細には再生時間、音声ファイル、文字起こしを生成したモデルが含まれます。文字起こしテキストの取得はオプトインです |
search_videos / get_video | クラスターの YouTube 動画を検索します。文字起こし全文を検索でき(該当箇所の抜粋を表示)、サムネイルも利用できます。詳細での文字起こしの取得はオプトインです |
resolve_entity | 名前または型付き ID(どちらの語彙でも指定可能:item:9902 = research_item:9902)を解決し、同名の候補と未照合のリテラルを別々に返します。型なし、または type=person のクエリで解決できない場合は、近似する人物の suggestions が返されます |
get_entity_graph | 1 ホップの範囲を指定したグラフを返します。明示的なリンクと共起を区別し、引用された根拠をページネーション付きで表示します |
get_text_passages | 選択した出版物/動画/ポッドキャストのレコードから、元のテキストにおける正確なオフセット付きで該当箇所を探します |
compare_collections | 共通のフィルター、分母、欠損データを用いて、2~4 件のプロジェクトまたはコレクションを比較します |
get_data_quality | スナップショットの収録状況、欠落しているメタデータ、未解決参照の件数を確認します |
get_snapshot_changes | 同一インスタンスの保持されているスナップショット間で、追加、更新、削除されたレコードをページ単位で取得します |
プロンプトとリソース
5 つのプロンプトが、複数ステップのリサーチワークフローをパッケージ化しています。ホストではスラッシュコマンドとして表示され、引数の入力補完にはスナップショット独自の典拠名が使われます。また、それぞれで引用ルールが改めて示されます。prompts/list を通じて一覧表示されるため、各ターンのツールペイロードは増えません。
| プロンプト | 引数 | ワークフロー |
|---|---|---|
literature_review | topic, year_from?, year_to? | トピックに関するファセット、出版物、全文の抜粋、関連する研究データ |
project_dossier | project | 1 つのプロジェクトのチーム、所蔵資料、期間、場所、つながり |
person_profile | name | 1 人の人物の識別、プロフィール、グラフ、出版物リスト。人物の評価ではなく、AMIRA の記録として提示 |
place_report | place | 国、市、地域の項目、プロジェクト、主題、期間 |
transcript_evidence | query | トランスクリプトとオープンアクセス全文からの引用抜粋 |
リソースは、ツール呼び出し以外からデータを公開します。
| URI | 内容 |
|---|---|
amira://record/{kind}/{id} | 引用可能な JSON として任意のレコードを返します。get_* ツールと同じ形式です。種類は resolve_entity の ID(research_item、publication、person、location、subject など)に従います |
amira://export/{corpus}/{format}/{query} | フィルター済みのエクスポートです(研究項目は CSV/JSONL、出版物は CSV/JSONL/BibTeX/RIS/CSL-JSON)。検索ツールを export を指定して呼び出すと、これらのリンクが resource_link として返されます |
amira://dataset | 提供されるスナップショットを説明する schema.org の Dataset。件数、対象範囲、ライセンスの内訳、資金提供者、引用方法が含まれます |
プロファイルとリサーチワークフロー
デフォルトは AMIRA_TOOL_PROFILE=full で、コアツールは 33 個、HTTP では 35 個です。
research、discovery、visualization では、ドキュメント化された小規模なサブセットが公開されます(コアツールはそれぞれ 22/12/14 個、HTTP では search と fetch が追加されます)。プロファイルは起動時に固定され、アクセス権限ではなく、ツールの検出にかかるコストを削減します。プロファイルに含まれないツールは削除され、それらを表示するアプリも同様に削除されます。正確な一覧は src/toolProfiles.ts を参照してください。
どちらの表記体系でも、型付き ID はどこでも使用できます(item: / research_item:、pub: / publication:、section:、person:、organisation:、project:、video:、podcast:)。すべての get_* ツールの id も同様です。ページ付きの結果が 40,000 文字を超える場合、早めに停止し、response_limited: true と正しい next_offset を返します。Claude Code は、より大きなツール結果を会話の外に移動します。エラー結果には、エラーが JSON テキストのみで含まれます。
グラフをたどる前に resolve_entity を使い、返された型付き id を変更せずに get_entity_graph に渡してください。グラフのエッジでは、異なるソースレコードの数が集計され、各コーパスが分けられ、カタログ上のリンクと共起が区別されます。types(例:["person"])を指定すると、その型の隣接ノードだけが残り、件数上限の適用前にフィルターされます。neighbour_types は、指定の有無にかかわらず、すべての隣接ノードを型別に集計します。共起も主題の共有も、共同研究を示すものではありません。安定した根拠のページ取得には、edge_id と返された snapshot_id を使ってエッジをたどってください。グラフはノード 100 個、エッジ 200 個、JSON 42,000 バイトを上限とするため、truncated を確認してください。
get_text_passages は、1~10 個の publication:ID(または pub:ID)、video:ID、podcast:ID の識別子を受け取ります。1 ページあたり最大 20 個の抜粋、元の UTF-16 オフセット、ソースの引用情報を返します。すべての一致箇所は next_offset を通じて取得できます(scanned_matches_capped は、一致箇所が 10,000 件を超えるドキュメントを報告します)。これらは抽出テキスト内のオフセットであり、PDF のページ番号や音声のタイムスタンプではありません。get_snapshot_changes には、同じソースのローカルな世代が 2 つ必要です。差分を捏造せず、利用可能な履歴を報告します。
回答できる質問の例
| 質問… | モデルが使用するもの… |
|---|---|
| 「コレクションにはイスラムについてどのような資料がありますか?」 | list_subjects keyword=Islam → search_research_items subject=Islam |
| 「フランス語の資料をすべて表示してください」 | search_research_items language=French(コード fr/fra/旧コード fre も使用できます) |
| 「Ulli Beier はどのような貢献をしましたか?」 | get_person name="Ulli Beier"(「Beier, Ulli」として解決されます) |
| 「ナイジェリア由来の資料はどれですか?」 | search_research_items location=Nigeria(Lagos の資料も含まれます — location は場所の階層をたどります)、または country=Nigeria(完全一致:Niger は含まれません) |
| 「AMIRA にはコートジボワール由来のどのような資料がありますか?」 | search_research_items country="Côte d'Ivoire"(典拠には「Ivory Coast」として登録されています。一般的な別名も解決されます) |
| 「9月以降に追加されたものは何ですか?」 | search_research_items added_since=2026-09-01(または search_publications added_since=…) |
| 「デジタル化された画像がある Lagos の資料はどれですか?」 | search_research_items location=Lagos has_media=true → ファイルと IIIF マニフェストを取得するための get_research_item |
| 「イスラム関連の資料をすべてスプレッドシートにしてください」 | search_research_items subject=Islam export=csv → 返された amira://export/… リンクを読み込みます |
| 「ILAM コレクションにはどのような音声録音がありますか?」 | search_research_items project_id=37700 resource_type=Audio |
| 「脱植民地性について議論している講演はどれですか?」 | search_videos keyword=decolonial(トランスクリプト内も検索し、matched_in に表示されます) |
| 「クラスターの出版物のうち、移住管理について論じているものはどれですか? — 実際には何と述べていますか?」 | search_publications keyword="migration control"(抽出された全文内も検索し、matched_in に表示されます) → get_publication include_fulltext=true |
| 「フランス語の出版物は何件あり、どのような種類がありますか?」 | list_publication_facets facet=type language=fr → search_publications language=fr |
| 「文献管理ソフト用に、フランス語の書誌をエクスポートしてください」 | search_publications language=fr citation_format=ris → next_offset をたどり、完全な ris レコードを結合します |
| 「クラスターはどのジャーナルに出版していますか?」 | list_journals(出版件数順) |
| 「プロジェクト間で建築と関連するテーマは何ですか?」 | find_related entity_type=subject value=Architecture |
| 「この写真はいつ撮影されましたか?」 | get_research_item → 型付きの dates(作成/収集/発行など) |
| 「この資料の引用情報と BibTeX を教えてください」 | get_research_item → generated_citation + bibtex(文献管理ソフト用には citation_format=ris/csl-json) |
| 「コレクションが最も多くカバーしている年代はどれですか?」 | list_years bucket=decade sort=count |
関連スキル
研究ワークフロー用のスキルは .claude/skills/amira-mcp/ に含まれています:
クラスターのコンテキスト、クエリのワークフロー、タスク別のツール一覧、引用のルール、網羅性に関する注意事項が含まれています。
どちらの方法でもインストールできます:
- ダウンロード:
リリースページからamira-mcp-skill.zipをダウンロードし、Claude のスキルディレクトリ(例:~/.claude/skills/)に展開します — 展開先は~/.claude/skills/amira-mcp/です。 - またはコピー:このリポジトリの
.claude/skills/amira-mcp/フォルダーをそこにコピーします。
…またはサーバーから提供する(MCP 経由のスキル)
公式拡張機能ですが、ホストによって対応状況が異なります。 SEP-2640 は Final になりました。サーバーは、すべてのファイルの SHA-256 ダイジェストとバイトサイズを含む 公開済みの Skills 拡張機能に準拠しています。上記の zip は、拡張機能に対応していないクライアント向けに引き続き利用できます。リサーチツールと引用の仕様は、どちらの方法でも機能します。
サーバーは、SEP-2640 拡張機能
(io.modelcontextprotocol/skills)に準拠して、同じスキルを接続経由で提供します。ダウンロードも同期も不要です。この拡張機能を実装したホストは、接続時にスキルを検出します。取得されるのは、説明対象のツール構成より古い可能性のある zip ではなく、実行中のサーバーに組み込まれたコピーです。リモート HTTP インターフェースにアクセスできるのはこの方法だけです。ChatGPT、Claude.ai のコネクター、API にはローカルのスキルディレクトリがありません。
| 方法 | 返される内容 |
|---|---|
skills/list | カタログ:skill://amira-mcp/SKILL.md、そのフロントマター、およびすべてのファイルの SHA-256 ダイジェストとバイトサイズ |
skills/get | URI で指定した単一のスキル。再列挙せずにダイジェストを更新できます |
resources/read | SKILL.md または参照ファイルなど、任意の単一ファイルをオンデマンドで読み取ります |
resources/directory/read | 一度に 1 つのディレクトリ階層を読み取ります(skill://amira-mcp、skill://amira-mcp/references) |
未使用時のコスト:ゼロです。 スキルのテキストがサーバーの instructions やツールの説明に挿入されることはないため、毎ターン再送される部分である tools/list のペイロードは、ホストが拡張機能に対応しているかどうかにかかわらずバイト単位で同一です。いつ開示するかは引き続きホストが決定します。3 つの参照ファイルは、実際に読み取られる場合にのみ読み込まれます。
AMIRA_SKILLS=0 を設定すると、この機能と 3 つのメソッドが完全に無効になります。
インストール(エンドユーザー向け)
リリースページ
から amira-mcp-server.mcpb をダウンロードし、ダブルクリックします。Claude Desktop にインストールダイアログが表示されたら、インストールをクリックします。
追加の設定は不要です。最新のタグ付きリリースには最新のデータが含まれています。ローリングリリースの data-latest プレリリースは、常に最新のサイトスナップショットを反映します。
ChatGPT、API、または任意のリモートクライアントから利用する
.mcpb は Claude Desktop 用のローカルかつオフラインで使える方法です。同じサーバーはリモートの Streamable HTTP エンドポイントとしても実行できます。HTTPS URL を 1 つ貼り付けるだけで、ChatGPT、Claude(Web + デスクトップのリモートコネクター)、OpenAI および Anthropic の API、Cursor、VS Code、その他のクライアントから接続できます(ダウンロード不要で、常に最新のデータを利用できます)。リモートのインターフェースでは、同じ 33 個のツールに加え、ChatGPT のリサーチ連携用に OpenAI 互換の search / fetch ツールを提供します(合計 35 個)。アクセスに認証は不要です。データは公開されており、読み取り専用です。
search では通常のキーワードを指定します(完全一致のフレーズではなく、語句ごとに照合されます)。必要に応じて limit と types を指定して結果を絞り込むこともできます。リサーチ項目、書誌(出版物の全文も検索対象)、ポッドキャスト、動画、プロジェクト、リサーチセクションを横断して、ランキング順に結果を返します。search の結果と fetch のドキュメントの url は、常に AMIRA/Omeka の公開レコードページを指します。DOI、YouTube/watch、ポッドキャスト/listen の URL は、補助的なメタデータ/テキストリンクとして保持されます。fetch は、search が返した ID を使って 1 件のレコードの全文を返します。動画とポッドキャストについては、デフォルトでトランスクリプトを省略し(全文は数万文字に及ぶ場合があるため、メタデータと説明のみを返します)、include_transcript=true を指定すると取得できます。トランスクリプトは transcript_offset / transcript_max_chars を使ってページ分割できます(get_video / get_podcast と同じパラメーター名です)。出版物の全文も同様に取得できます(include_fulltext=true を指定し、fulltext_offset / fulltext_max_chars でページ分割します。get_publication と同じパラメーターです)。また、max_chars で本文全体の長さを制限できます。追加する範囲は、メタデータのヘッダーを除いた max_chars の残り文字数を基準に調整されるため、*_returned_chars は text に実際に含まれた文字数と正確に一致し、次のページは空白なく offset + returned_chars から始まります。
npm run build && npm run start:http # → http://localhost:8787/mcp
# or, self-contained, via Docker:
docker build -t amira-mcp . && docker run -p 8787:8787 amira-mcp
エンドポイント:POST /mcp(MCP エンドポイント)と GET /healthz。PORT / HOST でバインドします。
-
ChatGPT → Settings → Security and login で Developer mode を有効にしてから、ChatGPT Plugins でサーバー URL を追加します。リサーチ連携では
search+fetchを使用します。詳しくは現在の OpenAI セットアップガイドをご覧ください。 -
Claude(Web またはデスクトップ)→ Settings → Connectors → Add custom connector →
https://<your-host>/mcp。 -
OpenAI API(Responses)—
mcpツールの接続先にエンドポイントを指定します。{ "type": "mcp", "server_label": "amira", "server_url": "https://<your-host>/mcp", "allowed_tools": ["search", "fetch"], "require_approval": "never" }
デプロイ(セルフホスト。例:amira サイトと同じ環境)
マルチステージの Dockerfile は、ビルド時に最新のスナップショットをクロールし、自己完結型のバンドルを実行します(実行時に node_modules は不要です)。Linux ホストでは、リバースプロキシの背後で systemd を使って実行することもできます。
# /etc/systemd/system/amira-mcp.service
[Service]
ExecStart=/usr/bin/node /opt/amira-mcp/server/http.js
Environment=PORT=8787 HOST=127.0.0.1 AMIRA_LIVE_REFRESH=true
Restart=always
User=www-data
location /mcp { proxy_pass http://127.0.0.1:8787/mcp; proxy_buffering off; client_max_body_size 64k; }
proxy_buffering off によって、Streamable-HTTP/SSE のレスポンスが途切れずに送信されます。Omeka と同じ環境に配置する場合でも、更新処理では AMIRA_SITE_BASE(デフォルトでは公開 HTTPS API)を使用します。変更が検出されると全件クロールを実行するため、同じ環境に配置しても API の負荷はなくなりません。サーバーはリクエストボディを 64 KiB、レート制限の状態を 10,000 クライアントまでに制限します。公開環境では、リバースプロキシで接続数、リクエストレート、同時実行数の制限を設定してください。プロセス内のリミッターは補助的な制御です。シャットダウン時には更新処理をキャンセルし、HTTP 接続を終了するために 10 秒間の猶予を設けます。
ビルド中に Omeka を呼び出さず、事前にレビュー済みの data/ スナップショットを使用するには、次のようにします。
docker build --build-arg SNAPSHOT_STAGE=bundled -t amira-mcp .
デフォルトの SNAPSHOT_STAGE=fetch では、引き続き最新データをクロールします。どちらのステージでもスナップショットの検証を行います。イメージではベースイメージのダイジェストを固定し、npm ci ではコミット済みのロックファイルを使用します。
開発/再ビルド
npm ci
npm run fetch-data # crawl the public Omeka API -> ./data snapshot (~1 min)
npm run typecheck # tsc --noEmit
npm run build # esbuild -> server/{index,http,fetchCli,lib}.js
npm test # unit tests: transform fixtures, folding, snapshot + store lifecycle,
# and the full tool layer against a fixture snapshot via
# InMemoryTransport (offline)
npm run test:live # integration tests against the live API (network)
npm run smoke # test/smoke/stdio.mjs: spawn the stdio server, exercise every tool offline
npm run smoke:http # test/smoke/http.mjs: spawn the HTTP server on a free port: search/fetch +
# parity, CORS preflight for both protocol revisions, the rate limiter
npm run weigh # token budget report (needs ./data — run fetch-data first)
npm run benchmark # offline latency baseline against ./data (30 warm samples per query)
トークン予算
コンテキストはクライアントにとって最も希少なリソースです。そのため、このサーバーが消費する両方の要素を測定し、上限を設けています(scripts/weigh.mjs ではバイト数を4で割ってトークン数を推定します。これは自身との比較には使えますが、請求明細の数値とは比較できません)。
| 内容 | 予算 | 変動 | |
|---|---|---|---|
| サーフェス | 毎ターン再送される tools/list ペイロード | フルプロファイルのトランスポートあたり 14,000 tok | 3%超で失敗 |
| レスポンス | 各ツールを最大制限まで呼び出した場合 | 呼び出しあたり 20,000 tok、かつ 45,000 文字未満 | 10%超で警告 |
ツールの説明はスナップショットから生成されないため、サーフェスはコードだけで決まります。test/unit/budget.test.mjs はデータなしでオフライン検証し、空のストアで測定した値がフルスナップショットを基準に記録されたベースラインと一致することを確認します。レスポンスの重み付けには実データが必要なため、代わりにスモークジョブで npm run weigh -- --check を実行します。この場合の変動は警告のみです。通常の npm run fetch-data でビルドが失敗してはなりません。一方、絶対上限(Claude Code はツールの結果を 25,000 トークンで切り詰めます)は致命的なエラーとなります。また、呼び出しに失敗したプローブも同様です。構造化された拒否応答は約60トークンしかないため、そうでなければすべての上限をすり抜けてしまいます。
バージョン1.18では、6つのツールと有用な出力スキーマに対応するため、フルプロファイルの上限を推定トークン数14,000に意図的に引き上げています。より小さいプロファイルの上限は、10,100(research。resolve_entity の境界に近いフィールドに対応するため、10,000から引き上げ)、6,500(discovery)、9,500(visualization)です。評価アブレーションのガイダンスなしのサーフェスも、リリース版と同様に測定して上限を設定しています。コミット済みのベースラインには、サーフェスの正確なサイズ、テキストのバイト数、シリアライズ後のワイヤーバイト数(テキストと構造化コンテンツの両方を計上)、および測定対象のスナップショットが記録されています。すべてのレスポンスは45,000文字未満に収める必要もあります。Claude Code は50,000文字を超えるツール結果を会話内ではなくファイルに保存するためです。ページ分割された結果とグラフは、バイト数の上限に収まるよう制限されています。
どちらかの数値が妥当に増加する変更を加える場合:
npm run weigh -- --update # rewrites test/token-baseline.json
差分をコミットしてください。このファイルの目的は、新しいツールや、より充実した結果の要約によるコストを、見過ごされることなく数値としてコードレビューに反映させることです。
拡張機能をパッケージ化します。
npm run prepack-mcpb # clean + typecheck + build + test + smoke
npm run validate:manifest
npm run pack-mcpb # -> amira-mcp-server.mcpb
scripts/census.mjs は、フィールドマッピングの基礎となるプロパティ調査(scripts/census-report.json)を再実行します。インスタンスのテンプレートを変更した場合は、再実行して差分を確認してください。その背景にある設計判断は ROADMAP.md に記載されており、各リリースは CHANGELOG.md に記録されています。
継続的デリバリー
プルリクエストと配布には、3 つの GitHub Actions ワークフローを使用します(2 つの配布ワークフローは公開 API をクロールします。認証情報は不要です)。
-
CI(
.github/workflows/ci.yml)— プルリクエスト時とmainへのプッシュ時に実行します: 最初に型チェックを 1 回実行し、その後、Linux 上の Node.js 22、24、26、および Windows 上の Node.js 24 で、オフラインのユニットテスト一式(ツールのサーフェスのトークン予算を含む)を実行します。続いて、両方の MCP トランスポートをテストし、各ツールの応答を最大制限で測定して、MCPB マニフェストを検証します。依存関係の完全な監査では、重大度が「高」または「致命的」のアドバイザリが見つかると失敗します。 別のコンテナジョブでは、オフラインのフィクスチャーイメージをビルドして、ヘルスチェックを行います。 Windows CI では、フィクスチャー拡張機能もパッケージ化し、ファイルリストを確認します。 別の非ブロッキングジョブでは、公式 MCP 適合性テストスイートを HTTP サーバーに対して実行します。 Actions はコミット SHA で固定されており、すべてのジョブにタイムアウトが設定されています。 -
リリース(
.github/workflows/release.yml)—v*タグのプッシュ時に実行します:タグとpackage.jsonの内容を照合し、新しいスナップショットをクロールして、ユニットテスト、ライブテスト、スモークテストを実行し、読み取り専用ジョブで.mcpbをパッケージ化し、付属スキルをamira-mcp-skill.zipとして ZIP 化します。別の公開ジョブでは、ビルドの来歴証明とともに両方のファイルを GitHub Release に添付します。別の非ブロッキングジョブでは、server.jsonを MCP Registry に公開します。 -
データスナップショットを更新(
.github/workflows/refresh-data.yml)— 毎週および手動で実行します。変換後のスナップショットのコンテンツハッシュが変わった場合にのみ再ビルドします。対象には項目セットと語彙の変更も含まれ、ローリングプレリリースdata-latestを更新します。
Actions から公開するには、書き込み可能なトークンが必要です。 組織でデフォルトのワークフロートークンの書き込み権限が無効になっている場合は、(a)Organization → Settings → Actions → General → Workflow permissions で Read and write permissions を有効にするか、(b)リポジトリまたは組織のシークレット
RELEASE_TOKENにcontents: write権限を持つ PAT または GitHub App トークンを追加してください。ワークフローでは、secrets.RELEASE_TOKENが存在する場合はそれを使用し、存在しない場合はデフォルトのトークンを使用します。
設定(環境変数/拡張機能の設定)
| 環境変数 | 拡張機能の設定 | デフォルト | 意味 |
|---|---|---|---|
AMIRA_LIVE_REFRESH | ライブサイトからデータを更新 | true | 起動時および定期的な間隔で、公開 API を確認し、スナップショットを更新します |
AMIRA_REFRESH_INTERVAL_HOURS | — | 24 | ライブ更新が有効な場合、サーバーの実行中にこの間隔で鮮度確認を繰り返します。定期確認を無効にするには 0 を設定します |
AMIRA_FULL_REFRESH_HOURS | — | 168 | 項目の署名が変わっていなくても、スナップショットの経過時間がこの値に達したら完全なクロールを強制します。最小値は 1 時間です |
AMIRA_TOOL_PROFILE | — | full | full、research、discovery、または visualization。変更するには再起動してください |
AMIRA_CACHE_DIR | 更新データのキャッシュディレクトリ | ~/.amira-mcp/cache | 更新済みスナップショットの保存先 |
AMIRA_SITE_BASE | サイトのベース URL(詳細設定) | https://data.africamultiple.uni-bayreuth.de | 引用および更新に使用するベース URL(AMIRA_DASHBOARD_BASE も、非推奨の警告とともに有効です) |
AMIRA_SITE_SLUG | — | amira | amira_url で使用する Omeka サイトのスラッグ |
AMIRA_DATA_DIR | — | バンドルされた data/ | バンドルされたスナップショットのパスを上書きします(開発用) |
AMIRA_EXPOSURE | — | full | ベンチマーク実験専用:ツールが公開するメタデータを制限します(下記を参照) |
AMIRA_GUIDANCE | — | on | ベンチマーク実験専用:off にすると、キュレーションガイダンス(指示、説明、エラー時の助言、プロンプト、スキル)なしで同じツールを提供します(下記を参照)。変更するには再起動してください |
AMIRA_SKILLS | — | on | 最終版の SEP-2640 拡張機能を通じて付属スキルを提供します。0/false/off にすると、この機能と skills/* メソッドを無効にします |
PORT | — | 8787 | リモート HTTP トランスポート(server/http.js)のポートです。.mcpb では無視されます |
HOST | — | 127.0.0.1 | HTTP バインドアドレスです。リモートアクセスを許可するには、明示的に 0.0.0.0 を設定してください。Docker イメージではこの値が設定されます |
AMIRA_ALLOWED_ORIGINS | — | localhost, 127.0.0.1, [::1] | HTTP エンドポイントの呼び出しを許可する、ブラウザーの Origin ホスト名または URL をカンマ区切りで指定します。Origin を省略するサーバー間クライアントには影響しません。信頼できる Web クライアントの Origin を明示的に追加してください。ワイルドカードは拒否されます。 |
AMIRA_RATE_LIMIT | — | 120 | /mcp におけるクライアントごとの毎分リクエスト数(0 で無効)。便宜上の上限です。クエリはメモリ内のスナップショットを使用するため、セキュリティ対策ではありません。/healthz は対象外です |
AMIRA_TRUST_PROXY | — | false | リバースプロキシが確認したアドレス(X-Real-IP、それがない場合は右端から数えて AMIRA_PROXY_HOPS 番目の X-Forwarded-For エントリー。クライアントが指定した最左端のエントリーは使用しません)に基づいてリクエスト元を判定します。プロキシ経由で使用する場合は有効にしてください。有効にしないと、すべてのリクエストがプロキシからのものとなり、すべてのクライアントが同じ枠を共有します。また、クライアントが直接接続する場合は有効にしないでください |
AMIRA_PROXY_HOPS | — | 1 | X-Real-IP がない場合に X-Forwarded-For を読み取るための、サーバー前段にある信頼できるプロキシの数です。IPv6 クライアントは /64 単位で分類されます |
スナップショットのレイアウトと復旧
キャッシュは AMIRA_CACHE_DIR/<API identity hash>/ の下に保存されます。active.json は、現在の不変な generations/<uuid>/ ディレクトリと、2つ前までの世代を示します。参照されていない世代には、24時間のクリーンアップ猶予期間があります。既存のフラット形式のスナップショットと、同じソースの従来形式である cache/current は、引き続き読み取れます。最初の新しい公開時に、フラット形式の保存先は世代履歴に移行されます。npm run fetch-data も data/ に世代形式のレイアウトで書き込みます。スクリプトでは、data/manifest.json がアクティブだと仮定せず、loadSnapshot を使用してください。
書き込み中にクラッシュすると、writer.lock が残ることがあります。そのキャッシュを使用しているすべてのプロセスを停止し、書き込み中のプロセスがないことを確認してから、そのロックファイルだけを削除して再起動してください。サーバーは、古いロックを安全に取得できるかどうかを決して推測しません。更新に失敗しても、最後に使用可能だったデータは引き続き利用できます。/healthz、概要、データ品質レポートには、更新の試行時刻と成功時刻、進行中の状態、失敗の分類が表示されます。再試行は一時的な上流の障害に限って行われ、上限付きの Retry-After を尊重し、更新の15分間の期限またはシャットダウン後に中止します。プローブでは Omeka のスナップショットをトランザクション整合性のある形で取得できないため、定期的な完全クロールが引き続き必要です。
メタデータ公開レベル(ベンチマーク実験)
AMIRA_EXPOSURE を使うと、評価で「メタデータ仲介」条件における LLM アクセス研究と同様に、メタデータの公開範囲を段階的に変えて、同じタスクを実行できます。これはエンドユーザー向けの設定ではなく、実験用フラグです。デフォルト(full)は通常のサーバー設定です。存在フラグ(has_transcript/has_fulltext)はすべてのレベルで表示されます。制限されるのはコンテンツと関連情報だけで、拒否は構造化エラー(exposure_restricted/text_access_disabled)として返されます。そのため、モデルは幻覚を起こさず、回答できない理由を説明できます。
| レベル | モデルに表示される情報 |
|---|---|
minimal | タイトル、種類、日付、URL、メディアフラグ。キーワード検索はタイトルのみを対象とし、エンティティ/ファセット/関連情報ツールと構造化フィルターは拒否されます |
descriptive | + 説明、要約、目次(これらも検索対象) |
structured | + 主題、場所、人物、プロジェクト、セクション、コレクション、会場 — すべてのフィルターとエンティティツール |
full | + トランスクリプトと出版物の全文(デフォルト) |
ガイダンスのアブレーション(ベンチマーク実験)
AMIRA_GUIDANCE=off にすると、キュレーションのガイダンスなしで同じ操作を提供でき、そのガイダンスがもたらす効果を評価できます。AMIRA_EXPOSURE と同様に、これは実験用フラグです。デフォルト(on)では何も変わりません。ツール一覧はサーバー起動時に作成されるため、変更するには起動前に変数を設定し、再起動してください。
| チャネル | on(デフォルト) | off |
|---|---|---|
| サーバーの指示 | initialize 時に送信 | なし |
| ツール | 名前、タイトル、説明、パラメーターの説明を含むスキーマ | 同じ名前、入力・出力スキーマ(型、列挙値、範囲、必須フィールド)、アノテーション、アプリの _meta。タイトル、説明、.describe() のテキスト、anthropic/alwaysLoad のヒントはなし |
| エラー | code、メッセージ、suggested_tool、available_values | code と、何が問題だったかを示す簡潔なメッセージ。他のツールへの案内、候補値、助言(「公開されたままのメタデータから回答してください…」)はなし |
| 結果 | データに加え、*_hint ページングヒント、エクスポートの note、検索結果がない場合の hint、人物の suggestions、および search_research_items の緩和に関する suggestions と did_you_mean | これらを含まない同じデータ |
| プロンプト、コンパニオンスキル | 登録および宣言されます | どちらもなし |
| リソース | タイトルと説明 | URI と MIME タイプのみ |
ガイダンスを有効にした場合、stdio でのツール一覧の推定コストは1ターンあたり12,040トークン、無効にした場合は8,485トークンです(HTTP ではそれぞれ12,981と9,044トークン)。指示はセッションごとに一度、448トークンを追加します。npm run weigh で両方を測定でき、ベースラインにも記録されています。
アーキテクチャ
-
純粋なインメモリの型付きレコード。 Omeka JSON-LD はビルド時に一度変換され(
src/transform.ts、証拠はscripts/census-report.json)、実行時にはコンパクトなレコードを読み込み、起動時にインデックスを作成します。ネイティブバインディングはなく、esbuild のバンドルは単体で動作します。 -
オフライン優先のアトミックな更新。 バンドル済みスナップショットとロックされた世代の公開を組み合わせています。起動時には最新のマニフェストが優先されるため、古いキャッシュが新しいバンドル済みスナップショットより優先されることはありません。
-
引用の形式は統一されています。すべてのエンティティが Omeka アイテムであるため、すべてのレコードに
amira_url = <site>/s/amira/item/<o:id>が含まれます。 -
どこでもアクセント記号を区別しない照合(
src/text.ts)。このコレクションはフランス語圏のアフリカに関する資料が多く、典拠レコードでは自由記述テキストとアクセント記号の有無が一貫していません。「Côte d'Ivoire」は件名標目である一方、アイテムのタイトルには「Cote d'Ivoire」と記載されています。すべてのキーワード比較では両側を変換します(NFD、結合文字を削除、小文字化、曲線引用符・ダッシュ・合字 œ/æ/ß を通常の表記に変換)。そのため、呼び出し側がどちらの綴りを指定したかによって結果が変わることはありません。長いテキストの変換結果はメモ化され、更新によってスナップショットが置き換わると破棄されます。 -
インタラクティブな結果(MCP Apps)。 7 つのツールには
_meta.ui.resourceUriが設定されており、text/html;profile=mcp-appリソースを参照します。そのため、io.modelcontextprotocol/ui拡張に対応するホスト(Claude、Claude Desktop)では結果がインラインで表示されます。それ以外のクライアントは_metaを無視し、まったく同じ JSON を受け取ります。ツール リソース 表示内容 get_collection_overviewui://amira/overview統計タイルと、大学・セクション・リソースタイプ・言語別のランキング付き内訳 list_yearsui://amira/timeline年または年代ごとのアイテム数のヒストグラム list_research_sectionsui://amira/sectionsAM 1.0 / AM 2.0 の資金提供フェーズにおけるセクションのガントチャートと「現在」マーカー find_relatedui://amira/related放射状の共起ハブ。中央に起点となる項目を置き、関係タイプごとにラベル付きのセクターを表示 get_entity_graphui://amira/graphエンティティタイプ別のセクターグラフ、タイプチップ、根拠を表示する選択可能なスポーク、キーボード操作 list_locationsui://amira/mapオフライン地図、国のドロップダウン、場所の表、アイテムの根拠 search_publicationsui://amira/bibliography絞り込み可能な書誌(言語のドロップダウン、著者候補)と選択内容のエクスポート モジュールは
src/ui/にあります。shell.tsにはデザイントークンと共通の棒グラフプリミティブがあり、bridge.tsには公式の Apps SDK がバンドルされています。各アプリは独自の CSS とレンダー関数を使用します。テンプレートはネットワークから一切読み込みません。スクリプト、スタイル、フォント、タイルのいずれも読み込まないため、_meta.ui.cspの許可設定は不要で、最も厳格なサンドボックスでも動作します。アプリのコントロールは、ホストを通じて許可リストに登録された読み取り専用ツールを呼び出します。フィルターのドロップダウンも同じ方法で選択肢を読み込むため、選択肢のリストがモデルに渡ることはありません。引用リンクとファイルのダウンロードもホスト API を通じて行います。すべての視覚表現には、表またはテキストによる代替手段があります。アプリの開発と来歴を参照してください。 色はDREVisualizations Omeka モジュールのテーマ(--primary/Africa Multiple のブランドパレット)に基づいているため、チャット内のグラフと AMIRA サイト上の同じグラフが一つのシステムとして認識できます。また、目視で判断するのではなく、それぞれの表示面で検証しています。ライトモードでは#fdfcfa上の#007a50、ダークモードでは#1b211e上の#35a87dを使用します(テーマ独自の#3fb488はダークモードの明度帯からわずかに外れるため、アプリでは一段階暗い色を使用します)。すべてのグラフは単一系列で、カテゴリは軸ラベルに表示されるため、アクセントカラーは一色で適切であり、凡例も不要です。共起ハブでは、6種類の関係タイプに6色を割り当てるのが本来の形ですが、ブランドパレットのどの6色の組み合わせも、すべての色の組み合わせでCVDの色差基準を満たせませんでした(最良の候補でも deutan では ΔE 2.4 が下限でした)。そのため、ここでは関係タイプごとにラベル付きのセクターを配置し、空間的に区別します。これにより、グレースケール、印刷、強制カラーモードでも判別できます。
プロトコルの方針
2026年10月6日に、現在の仕様 および TypeScript SDK のドキュメントに照らして検証済みです。 サーバーは両方のトランスポートで MCP 2026-07-28 を使用し、2025年当時のクライアントにも変更なしで応答します。
このサーバーは v2 TypeScript SDK(固定された
@modelcontextprotocol/sdk v1 モノリスではなく、スコープ付きパッケージの
@modelcontextprotocol/server、/node、/client)を使用しています。エントリーポイントを扱う場合に知っておくべき点が2つあります。
- 新しい時代のプロトコルはオプトインです。
SUPPORTED_PROTOCOL_VERSIONSはレガシーなinitializeのバージョン一覧で、2025-11-25 までで終わります。SDK は意図的に2026年の文字列を内部に保持しています。createAmiraServerはsupportedProtocolVersionsでリビジョンを自ら指定し、これによってserver/discoverが登録されます。指定しない場合、このメソッドは-32601を返します。 - 時代を決めるのはトランスポートではなくエントリーです。
serveStdio(factory)とcreateMcpHandler(factory)は、接続またはリクエストごとに時代を決定し、 ファクトリーからインスタンスを固定します。StdioServerTransportまたはNodeStreamableHTTPServerTransportに直接接続すると、2025年の時代のみが提供されます。
具体的な通信内容として、server/discover は ["2026-07-28"] を通知し、結果には
resultType が含まれます。また、キャッシュ可能な結果には SDK の保守的な既定値
{ ttlMs: 0, cacheScope: "private" } ではなく、実際の ttlMs/cacheScope が設定されます(tools/list、resources/list、server/discover は1時間の public、ui:// アプリの HTML がビルドごとに不変である resources/read は24時間)。後方互換性は、ハンドラーの legacy: 'stateless' という既定値で確保されます。これにより、2025年当時のトラフィックにはリクエストごとに新しいインスタンスで応答し、このサーバーが従来から提供してきた形を維持します。
このリビジョンでの非推奨化による影響はありません。Roots、Sampling、Logging、Elicitation はいずれも使用しておらず、ログは stderr に出力され、ツールの順序は決定的です(登録順)。CORS は両世代のヘッダー(Mcp-Session-Id/MCP-Protocol-Version および Mcp-Method/Mcp-Name/X-Mcp-Header)を受け入れます。
このソフトウェアの引用
このサーバーが AMIRA の資料を見つけたり分析したりする手段の一部となった場合は、引用してください。リポジトリには CITATION.cff が含まれているため、GitHub の このリポジトリを引用 ボタンから BibTeX と APA 形式を生成できます。
@software{madore_amira_mcp_server,
author = {Madore, Frédérick},
title = {{AMIRA MCP Server}},
year = {2026},
publisher = {Africa Multiple Cluster of Excellence, University of Bayreuth},
url = {https://github.com/AM-Digital-Research-Environment/amira-mcp-server},
license = {MIT}
}
データはソフトウェアとは別に引用してください。個々のレコードは amira_url(https://data.africamultiple.uni-bayreuth.de/s/amira/item/<id>)で引用できます。このため、すべてのツールの結果にこの URL が含まれています。
クレジットと資金提供
バイロイト大学のアフリカ・マルチプル・エクセレンス・クラスターに属する**デジタル研究環境(DRE)**が構築・保守しています。DREはクラスターのデジタルインフラ部門であり、AMIRAを支えるデータシステムの設計と運用を担っています。基盤となる記録のキュレーションと説明は、アフリカ・マルチプル研究センター(ジョセフ・キ=ゼルボ大学、ローズ大学、ラゴス大学、モイ大学)およびバイーア連邦大学のパートナーと共同で行っています。
ドイツ研究振興協会(DFG)のドイツ・エクセレンス戦略のもとで資金提供を受けています — EXC 2052/1 — 390713894 (アフリカ・マルチプル:アフリカ研究の再構築)。
ライセンス
MIT — LICENSEを参照してください。CONTRIBUTING.mdおよびSECURITY.mdもご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。