Verify SCITT receipts from Forestrie transparency logs, offline について
@forestrie/mcp-verify は、Forestrie の透明性ログにある SCITT レシートをオフラインで検証する MCP サーバーです。呼び出し元が指定する信頼ルートを使ってローカルで確認し、バックエンドやネットワークには接続しません。
主な機能
- 01SCITT レシートの検証
- 02許可レシートの検証
- 03パッケージ自身のリリースレシート確認
- 04CBOR レシートのデコード
- 05同梱フィクスチャリソース
活用シーン
- 01声明がログに記録されたかのオフライン確認
- 02署名者の投稿権限の確認
- 03パッケージの来歴検証
- 04同梱リソースを使ったレシート検証
MCP 対応
レシートの検証とデコードを行う読み取り専用ツール、および検証入力に使えるフィクスチャリソースを提供します。stdio トランスポートのみを使用し、ネットワーク通信は行いません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
4掲載時のツール一覧 · 1 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| trust | any | はい | 信頼するアンカー |
| entryId | string | はい | 32 文字の小文字 16 進数:idtimestamp_be8 || mmrIndex_be8 |
| payload | any | はい | SHA-256 がリーフ ContentHash となる、EXACT に登録された payload のバイト列 — {b64: <standard base64>}(base64 は別名として使用可能)、または {path: <ローカルサーバーが読み取るファイル>}。 |
| receipt | any | はい | レンダリングする COSE レシート — {b64: <standard base64>}(base64 は別名として使用可能)、または {path: <ローカルサーバーが読み取るファイル>}。 |
詳細
@forestrie/mcp-verify
Forestrie の透明性ログに記録された SCITT レシートを、手元で保持している信頼ルートに照らして検証します。オフラインで動作します。バックエンド、アカウント、鍵、ネットワークは不要です。 レシートの検証とデコードのみを行う MCP サーバーです。
{
"mcpServers": {
"forestrie-verify": {
"command": "npx",
"args": ["-y", "@forestrie/mcp-verify"]
}
}
}
npx -y @forestrie/mcp-verify demo
理由
エージェントは、自分が作成した場面に立ち会っていない発言にもとづいて動作します。たとえば、引用、承認、ツールの結果、別のエージェントの出力などです。通常、発言の記録は発言者が保管しているため、後から関わる人は「本当にその発言をしたのか、そして全員に対して同じことを言ったのか」と確認できません。
Forestrie のレシートは、発言が追記専用の透明性ログに封印されたことを証明します。このパッケージは、Forestrie に接続せず、手元のプロセス内で、保持している信頼ルートに照らしてその証明を検証します。適切な信頼ルートがあれば、さらに難しい問いにも答えられます。つまり、提示されたログが、ほかの全員に提示されたログと同じかどうかを確認できます。透明性がもたらすもの、その限界、レシートに含まれる情報については、TRANSPARENCY.md をご覧ください。
証明する内容
| ツール | 対応するコマンド | 確認できること |
|---|---|---|
verify_receipt | forestrie verify | このペイロードのバイト列は、このエントリー ID で正確に記録されていますか? |
verify_grant_receipt | forestrie verify-grant | この許可はこのログに受理されましたか? つまり、署名者には書き込む権限がありましたか? |
verify_self | forestrie verify | このパッケージ自身のリリースレシートは、配布されるバイト列を保証していますか? |
decode_receipt | forestrie decode-receipt --json | このレシートには実際に何が含まれていますか?(CBOR を表示するだけで、何も検証しません。) |
すべてのツールには readOnlyHint: true, openWorldHint: false の注釈が付いています。これは単なる飾りではありません。「このツールは何にも触れない」という機械可読な形式であり、エージェントは何も実行せずにそれを確認できます。
信頼ルート
「検証」を求めるのではありません。信頼するルートを指定すると、そのルートで何を確認できるかが結果に示されます。
| ルート | 提供するもの |
|---|---|
genesis | 登録時に取得した、フォレストの genesis ドキュメント |
known-log-key | 帲外で保持しているログ所有者の鍵(keyXy、P-256)または KS256 アドレス(ks256Address) |
known-accumulator | チェーンから読み取ったログのピークのスナップショット |
checkpoint-chain | 保持している .sth チェックポイントのチェーンと、genesis または keyXy。各リンクで委任の制限を適用します |
KS256(secp256k1)のルートもオフラインで検証できます。EOA ルートは、genesis または ks256Address を含む known-log-key から、ecrecover によって検証されます。コントラクトルート(Safe)はチェーンの読み取りなしでは確認できません。このパッケージはチェーンを読み取らないため、別の場所で取得した ERC-1271 レコードである ks256Attestation を渡してください(@forestrie/mcp-resolve の fetch_ks256_attestation ツール、または forestrie-cli の fetch-ks256-attestation)。この場合、結果は 証明対象のブロックにおけるコントラクトの署名者に基づいて 有効となり、そのブロックが示されます。20 バイトの ks256Address は、どのログを所有しているかを主張するものであり、証明するものではありません。checkpoint-chain にも ks256Attestation を指定します。その際、フォレストのチェーン ID に対応する KS256 の genesis が必要です。1 つの証明は 1 つの委任証明書に適用されるため、委任先を変更した Safe には証明書ごとに 1 つ必要です。ks256Attestations 配列として渡してください。各証明は結果で、使用済み、または未使用とその理由が報告されます。黙って無視されることはありません。checkpoint-chain は各リンクの委任制限(mmrStart、mmrEnd、expiresAt)も適用します。該当するエラーは delegation_out_of_range と delegation_expired です。0.7.0 以降、レシートに添付されたピークは信頼するのではなく、リーフと包含パスに照らして検証されます(@forestrie/receipt-verify 3.2.0)。これにより、known-accumulator と checkpoint-chain のルートにあった脆弱性が解消されています。詳細:docs/trust-roots.md。
ルートに強さの順序はありません。最初の 2 つはオペレーターの署名をローカルで確認しますが、分割ビューを検出できません。最後の 2 つは、オペレーターが制御できないアキュムレーターにピークを照合するため、分割ビューを検出できます。すべての結果は、封印、分割ビュー、追記権限、帰属の 4 つの問いに答え、それぞれの答えは ok、failed、not_answered_by_this_root のいずれかです。最後の答えも実際の回答であり、ユーザーに提示する必要があります。ok だけを表示するクライアントは、このツールを誤って使用しています。
各ルートが有効な選択肢となる場合、検証時に取得した genesis ドキュメントが登録時から保持していたものより弱い理由、署名ルートでは見分けられないもの、およびデモのトランスクリプトについては、以下を参照してください: docs/trust-roots.md。
オペレーターを信頼する必要はありません
Forestrie のオペレーターが誠実であると仮定しなくても、レシートには意味があります。
- 保管庫ではなく、パイプです。 ログに記録されるのはコンテンツハッシュだけです。声明とそのレシートはお客様の手元に残り、検証はそのバイト列だけを使って行われるため、検証時にオペレーターに何かを問い合わせる必要はありません。
- オペレーターは権限を持ちません。 ログのルートキーはログの所有者が保持し、インスタンスのブートストラップキーは forest のコントラクトをデプロイした人が保持します。オペレーターのシーラーは、キーをリースしたログに限り、各リースの MMR 範囲内でチェックポイントに署名します。
- 公開される履歴は一つです。 チェックポイントは univocity コントラクトに公開され、既存の内容と矛盾するものは拒否されます。その上にあるアキュムレーターのルートは、その内容に対して検証されます。
オペレーターが対応を拒否することはあり得ますが、それは明らかになります。登録を拒否したり、提供するデータを出し渋ったり、シーリングを停止したりできます。しかし、アンカーされた履歴を書き換えたり、分岐させたり、キーをリースしていないログのために署名したりはできません。どのキーを誰が保持し、オペレーターに何ができて何ができないかについては、 key custody と operator powers をご覧ください。
このパッケージ自体の来歴
ソフトウェアの来歴は透明性ログのよく知られたユースケースであり、このパッケージはそれを自分自身に適用しています。リリースごとに、小さな声明(パッケージ名、バージョン、git コミット)を Forestrie ログに登録し、そのレシートを tarball に同梱します。npx -y @forestrie/mcp-verify verify --self または verify_self ツールを使うと、オフラインで検証できます。これは npm の SLSA 来歴を補完するものであり、置き換えるものではありません。現在、レシートは公開開発レーン上のログにつながっています。詳細は
docs/self-registration.md
をご覧ください。
このバンドルは、実際の手順を示す例の題材にもなっています。公開レーンからこのパッケージ自身のリリースレシートを取得し、同梱のキーで検証して、ジェネシスルートのもとで文書化された delegation_invalid を確認し、チェーン読み取りで split-view ok を得るまでを、アカウントなしで数秒で実行できます。この例は、
取得処理はこのパッケージではなくそちらの役割であるため、
@forestrie/mcp-resolve's README
に掲載されています。
検証の演算処理は @forestrie/receipt-verify に由来し、正確なバージョンに固定されたうえで、個別に公開・証明されています。tarball には src と、テストに使用する凍結済みの適合性ベクトル(fixtures/PROVENANCE.md)が含まれているため、演算処理を信頼するだけでなく、再実行して確認できます。
このパッケージをインストールすると、検証に必要なもの以上が取り込まれます。@modelcontextprotocol/sdk は、express、hono、jose、cors、ajv などを含むウェブスタックを取り込みますが、これらはこのパッケージが使用しない HTTP トランスポートのためのものです。このパッケージが構築するのは stdio トランスポートのみです。検証コアは SDK をインポートせず、ブラウザー安全性ゲートもそれを強制します。そのため、パッケージの "." エクスポートをインポートすれば、それらを一切使わずに演算処理を利用できます。
バンドルされたリソースと、それらだけで実行可能になる2つの呼び出し
tarballにはフィクスチャがforestrie://fixtures/… MCP リソースとして含まれているため、独自のデータを何も持たないエージェントでも実際の検証を実行できます。
リソースだけで合格できる呼び出しは2つあり、どちらも
test/node/mcp-smoke.test.tsでアサートされています。
genesisルートでのgrantレシート — verify_grant_receiptを次の引数で呼び出します。
| 引数 | リソース |
|---|---|
receipt | golden/grant-receipt.cbor |
committedGrant | golden/committed-grant.cbor(読み込み時にgolden/manifest.jsonから導出) |
entryId | golden/entry-id.txtのテキスト |
trust | {root: "genesis", genesis: golden/grant-genesis.cbor} |
結果:verify-grant: PASS · root=genesis · sealing ok, split-view not answered at this root, append-authority ok, attribution ok。
アキュムレータールートでのペイロードレシート。オフラインで実際の
アンカーに対して検証 — lane-Aバンドル
(fixtures/lane-a/PROVENANCE.md)を使ってverify_receiptを呼び出します。公開レーンの実際のレシートと、univocityコントラクトがブロック46770471時点のログに対して公開したアキュムレーターを、独立したチェーン読み取りによって取得したものです。(このレーンのコンテンツは2026-09-20にリセットされました。バイト列は引き続き検証できますが、取得元のURLはすでに解決できません。)
| 引数 | リソース |
|---|---|
receipt | lane-a/receipt.cbor |
payload | lane-a/statement.cose |
entryId | lane-a/entry-id.txtのテキスト |
trust | {root: "known-accumulator", accumulator: lane-a/accumulator.cbor} |
結果:verify: PASS · root=known-accumulator · sealing ok, split-view ok, append-authority ok, attribution okとなり、anchor.matchedPeakが設定されます。
demoが独自に導出したスナップショットとは異なり、このアンカーはコントラクトが公開した状態であるため、split-viewの判定はそのブロック時点の証拠となります。
同じレシートは{root: "known-log-key", keyXy: {b64: <text of lane-a/log-key.xy.b64>}}でも合格し、ログがフォレストルートの孫であるため、{root: "genesis", genesis: lane-a/genesis.cbor}ではdelegation_invalidを返します(docs/self-registration.md)。
リソースのバイト列は{b64: <the blob>}として渡します。lane-a/log-key.xy.b64のようなテキストリソースはすでにbase64テキストなので、そのテキストをそのままb64に入れます。golden/burial/public-key.xy.b64も同じ方法で埋葬チェーンのルートキーを提供するため、リソースを使ってcheckpoint-chainを実行できます。ただし、埋葬バンドルにはリーフのプリイメージが含まれていないため、ドキュメントに記載された否定的な判定になります。
レジストリ
このサーバーは公式MCPレジストリにdev.forestrie/verifyとして登録されています。
開発
mise install # node 22.14.0, pnpm 10.6.5
pnpm install
pnpm test # browser-safe gate + encoding-copy gate + server.json gate + unit tests
pnpm build
規約、不変条件、リリースチェックリストについては、AGENTS.mdを参照してください。
ライセンス
MIT。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。