AHG Archives について
AHG Archives は AtoM のアーカイブカタログに検索、レコード閲覧、変更提案の機能を加えます。アーキビストや研究者向けで、提案はレビュー待ちとなり、承認されるまでレコードは変更されません。
主な機能
- 01記述と典拠レコードの検索
- 02階層と来歴を含むレコード取得
- 03画像、テキスト、IIIF マニフェストの閲覧
- 04親レコード配下の記録を順に取得
- 05記述、文字起こし、翻訳の変更提案
活用シーン
- 01カタログからアーカイブ記録を探す
- 02子レコード、画像、来歴を確認する
- 03記述の変更案をレビューに提出する
- 04ファイルの文字起こしや翻訳を提案する
MCP 対応
MCP サーバーはカタログ検索、レコードやファイル情報の取得、変更提案のツールをクライアントに提供します。提案はレビューキューに送られ、アーカイブ記録を直接変更しません。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://mcp.theahg.co.za/public/mcpclaude mcp add --transport http za-co-theahg-ahg-archives https://mcp.theahg.co.za/public/mcp{"mcpServers":{"za-co-theahg-ahg-archives":{"type":"http","url":"https://mcp.theahg.co.za/public/mcp"}}}Cursor で開く{"servers":{"za-co-theahg-ahg-archives":{"type":"http","url":"https://mcp.theahg.co.za/public/mcp"}}}VS Code で開く{"mcpServers":{"za-co-theahg-ahg-archives":{"type":"http","url":"https://mcp.theahg.co.za/public/mcp"}}}{"mcpServers":{"za-co-theahg-ahg-archives":{"serverUrl":"https://mcp.theahg.co.za/public/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
https://mcp.theahg.co.za/public/mcphttps://mcp.theahg.co.za/mcp認証が必要ツール
詳細
AHG Archives MCP サーバー
AtoM カタログ向けの MCP サーバーです。標準の AtoM と AHG Extensions を搭載した AtoM に対応しており、Heratio への対応も予定しています。アシスタントがアーキビストと同じようにカタログを扱えるようにします。記録を検索し、子記録、画像、テキスト、来歴とともに閲覧し、改善案を提案できます。アーキビストが確認して承認するまで、提案によって記録が変更されることはありません。
開発中です。AtoM での動作をご覧ください:AtoM MCP Server in Action。
お試しください
- キーなし: 任意の MCP クライアントを
https://mcp.theahg.co.za/public/mcpに接続します。PSIS デモ用カタログの公開済み記録を読み取り専用で閲覧できます。 - 個人用の読み取り専用キーあり: ご自身のエージェントでテストする場合は、[email protected] にキーをお問い合わせください(氏名、所属、試したい内容、利用期間をお知らせください)。訪問者に表示される情報を読み取り、利用終了日と1日あたりの上限が設定されています。
https://mcp.theahg.co.za/mcpで利用できます。提案にはスタッフ用キーが必要です。 - すべてのキーには1時間あたりの上限があります。1人が1時間に行える提案は最大200件です。上限に達すると、リセット時刻を平易な言葉でお知らせします。
クイックスタートガイド(docs/AHG_Archives_MCP_Quick_Start.md)では、ブラウザーおよびデスクトップクライアントの接続方法、効果的な質問、改善案の提案について説明しています。
ツール
| ツール | 機能 |
|---|---|
list_catalogues | このサービスが読み取れる目録:ホーム目録と、その他の目録やデモ用目録です。 |
search_records | テキストで記述を検索します。任意で親レコードを指定できます。catalogue="all" を指定すると、すべての目録を一度に検索します。 |
get_record | 1件の記述の全情報:日付、作成者、アクセスポイント、階層、子レコード、画像、来歴の連鎖です。 |
get_children | 記述の直下にあるレコードを取得します。 |
work_through_series | 親レコードの下にあるすべてのレコード(家族用聖書の各ページなど)を、バッチごとにたどります。各レコードについて、これまでの提案と、今の時間内にあと何件提案できるかも示します。 |
get_authority | 典拠レコード(人物、家族、組織)を取得します。 |
search_authorities | 名前とIDで、既存の人物、組織、家族、場所を検索します。 |
get_iiif_manifest | レコードの画像のIIIFマニフェストを取得します。 |
get_record_text | レコードのファイルに保持されているテキストをページ単位で取得します。抽出テキスト、OCR、書き起こしが含まれます。 |
get_record_image | アシスタントが確認するための、レコードの参照画像を取得します。 |
list_my_proposals | 自分の提案とその結果(保留中、承認済み、リンク済み、却下など)を取得します。却下された提案を繰り返さずに済みます。サインインしている場合のみ利用できます。 |
propose_access_points_and_dates | 人物、組織、場所、日付を、各項目の根拠と出典とともに提案します。人物と組織には、新しい典拠レコード用として、存続期間、略歴、場所を含めることができます。名前や場所には既存のレコード(existing_id)を指定でき、アーキビストがリンク先の第一候補として確認します。 |
propose_relationships | レコードに記載された人物間または組織間の関係(配偶者、親、子、その他のAtoMの関係タイプ)を、その関係が記された日付と一文とともに提案します。承認されると、両方の典拠レコードに表示されます。 |
propose_description_change | 記述の1つのフィールド(タイトル、内容と範囲、記録史など)の新しいテキストを提案します。 |
propose_transcription | テキストのないスキャンページなど、レコードのファイルの書き起こしを提案します。ページ画像と並べて確認され、承認されると、そのファイルのテキストとなり、検索可能になります。 |
propose_translation | フィールドの別言語への翻訳(例:オランダ語やアフリカーンス語から英語への翻訳)を提案します。 |
すべての読み取りツールは、任意で catalogue(list_catalogues で取得した名前)を指定できます。空の場合はホーム目録が使われます。提案は常にホーム目録に送られます。
失敗時は必ず、人物向けの message とプログラム向けのエラーコードを含む found: false が返されます。エラーコードは not_found、refused、rate_limited、unsupported、unavailable、needs_sign_in、unknown_catalogue、no_image のいずれかです。
呼び出し元に表示される内容は、AtoM独自の権限設定に従います。AtoMで表示できない呼び出し元には、未公開レコード、非表示の子レコード、マスターファイルは表示されません。tests/no_leak.py は、稼働中の目録を使ってこの動作を確認します。
セキュリティ
- 読み取りはカタログの API 経由のみで行い、データベースにはアクセスせず、カタログ独自の権限に従います。独自のキーを持たない呼び出し元はサービスキーを使って読み取るため、そのキーで読み取れる範囲は訪問者と同じでなければなりません。サーバーは起動時にこの点を確認し(
glam_mcp/keycheck.py)、スタッフ用キー、または訪問者が開けない記録を読み取れるキーの場合は起動を拒否します。この確認では最新の記録をサンプルとして調べます。データベースアクセスを使う完全なテストはtests/no_leak.pyです。 - アシスタントが記録に書き込むことはありません。 提案はカタログの審査キューに送られ、アーキビストがそれぞれ承認します。単体テストではコードを読み取り、検索または審査キューへの呼び出し以外を送信できる呼び出しがあれば失敗します。カタログ側では、提案エンドポイントが書き込むのは審査キューのテーブルのみで、記録の編集権限が必要です(
docs/EVIDENCE.mdを参照)。呼び出し元自身のキーはホームカタログでのみ使用され、別のカタログに送信されることはありません。 - 画像はカタログ独自のホストとポートからのみ取得します(ファイルリンクは通常のパスである必要があります)。リダイレクトには従わず、画像形式のみを受け付け、分割して読み込み、3 MB で停止します。デモカタログのホストもパブリックアドレスでなければなりません。
- 標準の AtoM は、サイトでは訪問者に非表示のフィールドも API 経由で返します(下書き状態、表示要素の設定、アーキビストのメモを確認しません)。そのため、標準の AtoM では API からフィールドを一切取得しません。すべての値は、AtoM 自身が独自のアクセス規則に従って訪問者向けにレンダリングした、記録の公開ページから取得します。API は記録の検索にのみ使用します。この方法は AtoM 2.10 のページレイアウトに依存しており、テストでそのレイアウトを固定しています。AHG Extensions、Heratio、OpenRiC を備えた AtoM では、API で表示制御が適用されます。
- デモカタログはスタッフがウェブページで追加するため、追加時と接続のたびにアドレスを検証します。パブリックでないアドレス(名前がネットワーク内部を指すようになった場合など)から返される応答は、使用前に拒否されます。
- 制限: 各カタログキーには独自の時間あたりの上限があり、カタログで設定できる日次上限と有効期限もあります。サインイン済みの各ユーザーがキューに登録できる提案アイテムは、ディスクに保存され、1 時間あたり最大
GLAM_PROPOSAL_CAP件です。 - ログにはツール、カタログ、結果が記録されますが、自由記述テキスト(検索語、名前、提案文)は文字数と短いハッシュのみが記録されます。ログファイルは所有者のみがアクセスでき、
GLAM_LOG_DAYS日(90 日)後に削除されます。サインイントークンはハッシュとして保存され、カタログキーは暗号化されます。
標準の AtoM での表示状態は、記録ごとに 5 分間記憶されます(速度を優先した意図的な選択です)。そのため、そこで非公開になった記録が検索結果に最大 5 分間表示されることがありますが、詳細な読み取りでは必ずその場で再確認されます。AHG Extensions を備えた AtoM では、このような遅延はありません。
/healthz は、サービスキーを使ってカタログから実際に読み取りができた場合に限り ok(200)を返し、それ以外の場合は unreachable、key_refused、または not_working(503)を返します。
独立した 2 件のソースレビュー(2026 年 10 月 26 日)を受けて、v0.5.0 から v0.5.2 が改良されました。単体テスト、漏えいテスト、2 つ目のカタログ経由での漏えいテストは、プッシュのたびにプロジェクトのイメージ内で実行されます。各リリースタグでは、これらのテストに合格した後にのみイメージを公開します(GitHub Actions、ワークフロー no-leak と image)。実際のブラウザーを使ったサインインには専用のテストがあります(tests/SIGNIN_TEST.md、所要時間は約 10 分。その後 tests/signin_check.py を実行します)。初回実行はまだ保留中です。未解決の点として、標準の AtoM では公開ページ上のテキスト一致によってフィールドを絞り込んでいるため、独自のキーを持つスタッフにも訪問者向けフィールドのみが表示されます。
コードの構成
| ファイル | 内容 |
|---|---|
glam_mcp/server.py | MCP レイヤー:ツール、サインインとウェブルート、起動処理。 |
glam_mcp/catalogue.py | カタログアダプター:カタログとやり取りするすべての処理(両方のバックエンドからの読み取り、標準AtoMの公開範囲とフィールド、画像、標準CSV)。Heratioなどの新しいバックエンドはここに追加します。 |
glam_mcp/calls.py | 呼び出しごとのポリシー:呼び出しで使用するキー、1時間あたりの提案上限、呼び出しログの行。 |
glam_mcp/settings.py | 設定、呼び出しログ、カタログ(ホーム、設定済み、デモ)。 |
glam_mcp/keycheck.py | バックエンドの検出、サービスキーの確認、公開アドレスの確認。 |
glam_mcp/auth.py | OAuth サインイン。 |
glam_mcp/usage.py、glam_mcp/catalogues.py | 職員向けページ /usage と /catalogues。 |
バックエンド
サーバーは起動時に、カタログが以下のどのバックエンドを使用しているかを検出します(GLAM_BACKEND=auto)。そのため、同じインストールで両方に対応できます。
atom-ahg:REST API v2(ahgAPIPlugin)を通じた、AHG Extensions搭載のAtoMです。propose_transcriptionとpropose_translationには atom-ahg-plugins v3.121.63以降、propose_relationshipsには v3.121.62、list_my_proposalsには v3.121.61、search_authoritiesとexisting_idには v3.121.60、提案での典拠の詳細には v3.121.45(その他の機能には v3.121.43)が必要です。提案はAI > NER reviewおよびAI > Suggest reviewに送られ、アーキビストが確認します。Authority Resolutionプラグインがある場合は、そのキューにも送られます。- Heratio:
atom-ahgバックエンドがそのまま対応します(heratio-dev上のHeratio v1.160.0~v1.163.0で、17種類すべてのツールと情報漏えいテストを実施。禁輸措置、分類、ICIPを含む非公開レコード60件、299項目を確認)。Heratioでは職員を含むすべてのキーで読み取り権限が閲覧者レベルとなるため、下書きへの提案は「見つかりません」と応答します。 openric:OpenRiCのRiC-O JSON-LD API(/api/ric/v1)を使用する読み取り専用バックエンドです。OpenRiC参照サービスとOpenRiC Workspaceの両方に対応します(UUIDキー、各レコード内の作成者と子レコード)。レコード、エージェント、場所、関係を扱い、タイトルで検索します(OpenRiCには全文検索がありません)。OpenRiC Workspace(v0.0.49以降)は完全なバックエンドです。/records/{uuid}/filesからファイルのテキストと参照画像を取得し(マスターは取得しません)、あらゆる種類の提案をレビューキューに送信します(Manage > Proposals to review)。また、list_my_proposalsにも対応します。関係はRiCの関係タイプとして送信され、両端とも既存の典拠レコードである必要があります。参照サービスにはファイルもレビューキューもないため、提案は担当者が適用するために返されます。OpenRiCはAHG APIのコピーも含みますが、こちらが先に検出されます。OpenRiC v0.17.26以降では公開済みレコードのみが表示されます。キーは不要です。CATALOGUE_API_KEYを空のままにするか、OpenRiC Workspace APIキー(Workspace v0.0.46以降)を指定してください。このキーで読み取れるのは公開情報のみです。Workspaceは、認識していないキーを拒否します。情報漏えいテストは、TEST_BACKEND=openricを指定したtests/no_leak.py、またはWorkspace用のHIDDEN_FILEで実行します。atom-base:AtoM独自のREST API(arRestApiPlugin)を使用する標準AtoMです。AtoM 2.10.2でテスト済みです。検索、レコード、子レコード、work_through_seriesが動作します。標準APIでは典拠レコード、IIIFマニフェスト、ファイルのテキストは提供されないため、その旨を通知します。提案は保存されません。標準の書き込みAPIは追加ではなく上書きを行うためです。代わりに、名称と場所をAtoM独自の インポート > CSV 用の1行CSVとして返します(種別は Archival description、更新動作は Update matches ignoring blank fields in CSV、Skip unmatched records にチェック)。これにより、レコードに追加され、ほかの内容はそのまま保持されます。日付はインポートするとレコードの日付が置き換わるため、手動で入力するものとして一覧表示されます。AtoMはレコードの識別子、タイトル、リポジトリでファイルを照合するため、リポジトリがないレコードはこの方法では更新できません。
Stock AtoM:セットアップ
- Admin > Plugins:arRestApiPlugin を有効にします。
- 公開サービス用にグループを割り当てないユーザーを作成し、REST API キーを生成します(ユーザーを編集します)。サインイン済みのアーキビストは、それぞれ自分のキーを使用します。
CATALOGUE_URL、CATALOGUE_API_KEY、CATALOGUE_NAMEを設定します。GLAM_BACKEND=autoにすると、標準の API が検出されます。
AtoM 2.10.2 の REST API が確認するのは「read」権限のみで、「view draft」権限は確認しません。そのため、どのキーでも REST API 経由で草稿レコードを読み取れてしまい、サイトが訪問者に非表示にしているフィールドも返されます。そこで、このサーバーは、訪問者が公開ページを開ける場合に限り、標準の AtoM 上のレコードを公開可能として扱います。これにより、そのカタログ独自のルールが適用されます(それ以外の場合は「見つかりません」となります)。また、そのページに表示されるフィールドのみを返します。API キーは、このサーバー以外の場所では使用しないでください。
独自のカタログにインストールする
サーバーはお客様のカタログと並行して、お客様独自のアドレスで実行され、API を通じてのみカタログと通信します。設定しない限り、AHG のホステッドサービスを参照することはありません。
-
カタログ上で公開エンドポイント用の読み取り専用ユーザーを作成し、API キーを発行します。変更を提案する人は、それぞれ自分のスタッフ用キーを使用します。
-
docker-compose.example.ymlをdocker-compose.ymlにコピーし、すべてのexample.orgアドレスをお客様のものに置き換えます。 -
シークレットを
.envに設定します(決してコミットしないでください)。cat > .env <<'EOF' CATALOGUE_API_KEY=<read-only service user's API key> MCP_SECRET=<Fernet key> EOFpython -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"を実行してMCP_SECRETを生成します。 -
起動します。既成のイメージを取得する場合は(
docker pull ghcr.io/archiveheritagegroup/ahg-archives-mcp:latestを実行し、docker-compose.ymlのimage:に設定します)、または独自にビルドする場合は(docker build -t ahg/glam-mcp:phase2 .を実行します)、その後docker compose up -dを実行し、curl 127.0.0.1:8031/healthzで確認します。サービスキーの読み取り権限が閲覧者より広い場合、サービスは起動を拒否し、その理由を表示します(docker compose logs)。 -
サービスユーザーのキーで閲覧者に表示される情報のみを読み取れることを確認します。
docker run --rm ghcr.io/archiveheritagegroup/ahg-archives-mcp python -m glam_mcp.keycheck https://catalogue.example.org <key>を実行します。 -
2 つのエンドポイントを、お客様独自のドメイン名で HTTPS の背後に配置します。
docs/nginx-mcp.theahg.co.za.confはコピーして名前を変更できる、動作確認済みの設定例です。 -
誰でもアクセスできるようにする前に、お客様のカタログに対して
tests/no_leak.pyを実行します。
必須の設定が不足している場合、サーバーは他者のカタログにフォールバックせず、不足している設定名を示して起動を停止します。
| 設定 | 必須 | 意味 |
|---|---|---|
CATALOGUE_URL | はい | リンクで使用する、カタログの公開アドレスです。 |
CATALOGUE_NAME | はい | 回答内でカタログをどのように表記するかを指定します。 |
CATALOGUE_API_URL | いいえ | カタログの API です。デフォルトは CATALOGUE_URL + /api/v2(atom-base の場合は /api)です。 |
CATALOGUE_API_KEY | 公開エンドポイント | 読み取り専用のサービスユーザーのキーです。 |
GLAM_BACKEND | いいえ | auto(デフォルト。起動時にカタログに問い合わせ、AHG API が導入されている場合はそれを、導入されていない場合は AtoM 独自の REST API を使用します)、atom-ahg または atom-base です。 |
GLAM_AUTH | いいえ | off(公開、読み取り専用、デフォルト)または oauth(サインイン済み)です。 |
MCP_PUBLIC_URL | oauth の場合 | サインインに使用する、このサーバー独自の公開アドレスです。 |
MCP_SECRET | oauth の場合 | 保存されたカタログキーを暗号化する Fernet キーです。 |
MCP_SIGNED_IN_URL | いいえ | 変更を提案するためにサインインするよう、公開エンドポイントが案内する先です。 |
GLAM_HTTP_PATH | いいえ | エンドポイントのパスです。例:/mcp または /public/mcp。 |
GLAM_DATA | サインイン済みサービス | サインインストア(トークンはハッシュ化され、キーは暗号化されます)、時間ごとの提案上限、デモカタログ用のフォルダーです。両方のサービスにマウントしてください。サインイン済みサービスは、この設定なしでは起動しません。 |
GLAM_CALL_LOG | いいえ | ツール呼び出しの任意の JSON Lines ログです。ツール、カタログ、結果を記録し、自由記述(検索語、名前、提案文)については長さと短いハッシュのみを記録します。サービスユーザーのみが読み取れる、1 日 1 ファイルのログです。 |
GLAM_LOG_DAYS | いいえ | 削除まで保持する呼び出しログの日数です(デフォルトは 90 日)。 |
GLAM_PROPOSAL_CAP | いいえ | サインインした 1 人が 1 時間あたりにキューへ登録できる提案項目数です(デフォルトは 200 件)。 |
GLAM_OTHER_CATALOGUES | いいえ | JSON 形式で指定する、追加の読み取り対象カタログです(「複数のカタログ」を参照)。 |
GLAM_DEMO_DAYS | いいえ | /catalogues に追加したデモカタログの有効日数です(デフォルトは 7 日)。 |
GLAM_USAGE_LOGS | いいえ | サインイン済みサービスのみ:/usage のスタッフ向け利用状況ページに表示する、カンマ区切りの呼び出しログです(デフォルトは自身のログ)。両方を表示するには、公開サービスのログを追加します。 |
以前の名前(PSIS_PUBLIC_BASE、PSIS_API_BASE、PSIS_API_KEY、GLAM_SOURCE_LABEL、GLAM_PUBLIC_BASE、GLAM_SECRET)も引き続き使用できます。
docs/AHG_Archives_MCP_Quick_Start.md は、接続方法、動作確認、良い質問の仕方、提案の確認方法を説明する、AHG のホステッドサービスを利用するアーキビスト向けガイドです。
複数のカタログ
1 つのサービスで複数のカタログを読み込めます。ホームカタログ(CATALOGUE_URL)は、提案とサインイン済みユーザーのキーを受け付けます。それ以外は読み取り専用で、それぞれ独自のサービスキーを使用します(グループに所属しないユーザー用に作成すると、訪問者に表示される内容だけが返されます)。呼び出し元のキーや提案を受け取ることはありません。
GLAM_OTHER_CATALOGUES='[{"name": "Heratio", "url": "https://heratio.example.org", "key": "..."}]'
起動時に接続できないカタログは、警告を出して対象から除外されます。各エントリでは、自動検出の代わりに "backend" を指定できます。
デモ用カタログ。 デモや説明のために、カタログの管理者と編集者は、サインイン済みサービスの /catalogues ページでクライアントのカタログを追加できます。必要なのは、名前、アドレス、読み取り専用キーです。エージェントは list_catalogues でそのカタログを見つけ、catalogue="<name>" を指定して読み取れます。GLAM_DEMO_DAYS(7)日後に期限切れになります。ホスト自身のネットワーク内のアドレスは拒否されます。両サービスは <GLAM_DATA>/demo-catalogues.json からリストを読み込むため、再起動せずに共有できます。
フェデレーション。 search_records で catalogue="all" を指定すると、すべてのカタログを一度に検索し、それぞれに独自の訪問者キーを使用して、各結果にカタログ名を付けます。カタログのフェデレーションピア(ahgFederationPlugin)を検索するには、各ピアを独立したカタログとしてここに追加し、そのピアの訪問者キーを指定します。サービスはプラグインのフェデレーション経由では検索しません。プラグインは各ピアを、設定時に指定されたキーで検索します。また、その Elasticsearch コネクターは未公開レコードを除外しないため、訪問者には見えない内容が結果に含まれる可能性があります。この方法で追加すると、各ピアは起動時のキー確認を通過し、情報漏えいテストの対象になります。
2 つ目のカタログを経由して情報漏えいテストを実行するには、TEST_CATALOGUE にその名前を設定します。
実行方法
docs/OPERATIONS.md:更新、バックアップと復元(hosting/backup.sh)、ロールバック、監視(hosting/healthcheck.sh。サービスが応答を停止したときに Workbench に通知されます)。セキュリティ上の問題の報告方法については SECURITY.md を参照してください。
カタログへのすべてのリクエストには、User-Agent AHG-GLAM-MCP/0.7 (+https://www.atom-extensions.com) が付与されます。fail2ban やボット対策ルールを回避してサービスを許可するには、バージョン間で変わらないプレフィックス AHG-GLAM-MCP/ を照合してください。ホストされているサービスからの接続元は 169.1.190.139(theahg.ddns.net)です。
ツールはワーカースレッドで実行されるため、1 つのカタログの応答が遅くても、ほかの呼び出し元を待たせません。負荷テスト(tests/load_test.py、テスト用カタログに対して 2026 年 10 月 26 日に実施):同時に 25 クライアント、毎秒 40 回の呼び出し、エラーなし、レコード読み取りの中央値 0.6 秒、メモリ使用量 60 MB 未満。
すぐに使えるイメージ
各バージョンタグ(v0.4.0 以降)では、情報漏えいテストを実行してから ghcr.io/archiveheritagegroup/ahg-archives-mcp を公開します。タグにはバージョンと latest が付与されます(.github/workflows/image.yml)。本番環境ではバージョンを固定してください。
ホストされたクライアント
hosting/client.sh は、他の機関の目録向けサービスを1台のホスト上で実行します。クライアントごとに1組のサービス(サインイン済み用と公開用)があり、それぞれ個別のアドレス、サインイン用シークレット、ログ、利用状況ページ、デモ目録を備えます。
hosting/client.sh add <client> "<Catalogue name>" <catalogue-url> [host] # クライアントのサービスキーを尋ねます
hosting/client.sh leak-test <client> "<note>" # テストがその目録に対して tests/no_leak.py を通過したことを記録します
hosting/client.sh publish <client> # DNS の解決後、リークテストの記録があれば、nginx サイトと証明書を設定します(sudo)
hosting/client.sh check <client> # ヘルスチェックと、キーの再チェックを行います
hosting/client.sh list
hosting/client.sh remove <client> # サービスを停止し、キー、シークレット、データ、ログを削除します
ホストの既定値は <client>.mcp.theahg.co.za で、ポートは8041から順に割り当てられます。各クライアントの設定は clients/<client>/.env に保存されます(モード600、Gitには含まれません)。イメージは GLAM_IMAGE で指定します。
何かを開始する前に、クライアントのキーをチェックします(glam_mcp/keycheck.py)。全員の提案を一覧表示できる可能性があるキーはスタッフキーとみなされ、拒否されます。また、そのキーで読み取る最新レコードのサンプルについて、公開サイトで訪問者が各レコードを開けることを確認します。これは抜き取りチェックです。完全なチェックは、目録のデータベースを使い、クライアントとともに実行する tests/no_leak.py です。leak-test でその結果を記録するまで、publish は実行を拒否します。同じキーのチェックはデモ目録のページでも行われます。目録は読み取り専用で、7日間一覧表示されます。
利用状況データ
サインイン済みサービスは /usage でスタッフ用ページを提供します。このページでは、過去30日間の呼び出し数を、日別、ツール別、サービス別、結果別、キー別に確認でき、提案がどうなったか(保留中、承認済み、却下済み、種類別)も確認できます。全員の提案を一覧表示できる目録キー(管理者と編集者)でアクセスできます。このキーはこのページ専用に使用されます。キーはハッシュの先頭8文字で表示されます。GLAM_USAGE_LOGS に両サービスのログを指定し、nginx で /usage をサインイン済みサービスにルーティングしてください(docs/nginx-mcp.theahg.co.za.conf を参照)。
テスト
tests/test_server.py と tests/test_auth.py(69件のテスト)は、ネットワークを使わず、偽の目録に対して実行されます。すべての読み取りツールの応答と拒否(401、403、404、429、501、500)、目録の選択とキー、画像取得(自ホストのみ、リダイレクトなし、画像形式のみ、サイズ制限)、非公開アドレスから応答するデモ目録、公開ページのみを読み取る標準 AtoM(API が返す情報だけのものは取得されないこと)、OpenRiC アダプター、キーのチェックにおける同一ホストへのリダイレクト、検索とレビューキュー以外の呼び出しを送信できないこと、ヘルス状態、データフォルダーのルール、1時間あたりの提案制限、キーのチェック、ログの内容、サインイン(ハッシュ化されたトークン、暗号化されたキー、1回限りのコード、ローテーション、失効、目録側で失効したキー)をテストします。CI ではプッシュのたびに次のテストを実行します。
docker run --rm -v "$PWD/tests:/app/tests:ro" ahg/glam-mcp:phase2 python -m unittest discover -s tests -p 'test_*.py'
tests/no_leak.py は、非表示レコード(下書き、および AHG 拡張機能を使う場合は、公開禁止、機密、ICIP によるアクセス制限のあるレコード)が、どのツールを通じても返されないことをチェックします。参照による取得、検索、子レコードへの表示、可視レコードの階層内での表示も含みます。プッシュのたびに GitHub Actions が、公開済みレコードと下書きレコードを含む使い捨ての標準 AtoM 2.10.2(tests/stock-atom)を起動し、それに対して公開サービスを実行してテストします(.github/workflows/no-leak.yml)。手動で実行するには、次のとおりです。
cd tests/stock-atom && docker compose -p stock-atom up -d --build
docker compose -p stock-atom exec -T atom sh /opt/setup.sh # READER_API_KEY と ADMIN_API_KEY を表示します
# CATALOGUE_URL=http://127.0.0.1:8097 とリーダーキーを設定してサーバーを起動し、次を実行します。
GLAM_MCP_URL=http://127.0.0.1:8000/mcp CATALOGUE_DB_CNF=db.cnf CATALOGUE_DB=atom PUBLIC_CONTROL_SLUG=published-letter python tests/no_leak.py
docker compose -p stock-atom down -v でテスト用目録を削除します。
バージョン
- v0.8.2(2026年10月26日):標準の AtoM では、children と children_count の取得元を REST API のツリー(サブツリー全体を返します)から、訪問者向けのツリービュー(直接の子項目のみ、ページ分割、下書きは除外)に変更しました。これにより、大規模な fonds でもタイムアウトやカタログの処理停止が発生しなくなりました。単体テストは69件です。
- v0.8.1(2026年10月26日):外部テスターが標準の AtoM で再テストした結果に基づき、get_children は下書きと存在しない slug のどちらにも同じ応答を返します(API の前に可視性を確認)。レコードには訪問者向けパンくずリストから取得した part_of と、可視の子項目の children_count が含まれます。単体テストは68件です。
- v0.8.0(2026年10月26日):OpenRiC Workspace を完全なバックエンドとして追加しました。ファイルのテキストと画像、レビューキューへの提案、投稿した自分の提案、RiC タイプとしての関係、UUID リンクに対応しています。レビュアーのキーはサービスキーとして拒否されます。カタログがリクエストを拒否した理由も引き継ぎます。キー確認ではレート制限が解除されるまで待機します。OpenRiC にサービスキーは不要です。単体テストは64件です。
- v0.7.1(2026年10月26日):すべてのリクエストで User-Agent を
AHG-GLAM-MCP/0.7に統一し、fail2ban とボットのルールで変わらないプレフィックスを使用します。ヘルスチェックですべてのホスト対象クライアントを確認します。漏えいテストは OpenRiC に対して実行します(Workspace は合格しました)。 - v0.7.0(2026年10月26日):エビデンスリリースの第2弾です。ツールをワーカースレッドで実行(負荷時のスループットが3倍);すべての失敗に
errorコードを付与;openric アダプター経由で OpenRiC Workspace に対応;CI に依存関係スキャンと SBOM を追加(イメージ内で pip をアップグレード);SECURITY.mdを追加;バックアップ、復元、ロールバック、ヘルスアラートを記載したdocs/OPERATIONS.mdを追加し、それぞれ1回試行;list_cataloguesをログに記録;離脱時にホスト対象クライアントを完全に削除します。単体テストは52件です。 - v0.6.1(2026年10月26日):公開済みレコードのみを表示する OpenRiC v0.17.27 用の OpenRiC アダプターを追加しました。日付は日付範囲から、子項目は階層から取得し、型付きタイトル検索と API 経由のキー確認に対応します。ric.theahg.co.za に対してローカルで確認済みです。
- v0.6.0(2026年10月26日):エビデンスリリースです。標準の AtoM のフィールドは公開ページからのみ取得(API からフィールドを取得しない);OpenRiC アダプター(読み取り専用);バックエンドの一覧表を一本化;Heratio は
atom-ahg経由で提供;キー確認は同一ホストへのリダイレクトに追従;漏えいテストで Heratio の公開制限テーブル、PUBLIC を超える分類、継承された制限を確認し、非表示レコードの各種からサンプルを取得;レビューキュー以外に書き込み経路がないことを単体テストで証明しました。単体テストは45件です。 - v0.5.2(2026年10月26日):2回目のレビューを受けて更新しました。標準の AtoM のフィールドは、それぞれの見出しの下にある完全一致の値のみを対象にします;デモカタログでは実際に接続したアドレスを確認(DNS リバインディング対策);サインイン済みサービスには書き込み可能なデータフォルダーが必要;
/healthzで到達不能、キー拒否、動作不良を個別に報告;ホスト対象クライアントは公開前に記録済みの漏えいテストが必要です。単体テストは39件です。 - v0.5.1(2026年10月26日):
server.pyを MCP レイヤー、カタログアダプター、呼び出しごとのポリシー、設定に分割しました(動作に変更はありません);実際のブラウザーを使ったサインインテスト(tests/SIGNIN_TEST.md、tests/signin_check.py)。 - v0.5.0(2026年10月26日):独立したソースレビューを受けた後の、セキュリティと信頼性のリリースです。画像取得をカタログ自身のホストに限定;起動時にサービスキーを確認;標準の AtoM のフィールドは公開ページに表示される内容のみを使用;自由記述を含まないログを記録し、ローテーションのうえ90日後に削除;提案の時間ごとの上限をディスク上で維持;偽のカタログを使った単体テストを CI に追加しました。
- v0.4.0(2026年10月26日):複数のカタログに対応(
list_catalogues、すべての読み取りツールでcatalogueを指定、全カタログ横断検索);デモカタログページ、スタッフ利用状況ページ、ホスト対象クライアント(hosting/client.sh)、すぐに使えるイメージ、キー確認を追加しました。
ライセンス
Copyright (C) 2026 Johan Pieterse, Plain Sailing Information Systems. GNU Affero General Public License バージョン3以降(AGPL-3.0-or-later)で公開されています。LICENSE を参照してください。変更したバージョンをネットワークサービスとして実行する場合、利用者に変更後のソースを提供する必要があります。
お問い合わせ
The Archive and Heritage Digital Commons Group - [email protected]
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。