Fetch SCITT receipts and on-chain anchors for offline verification について
@forestrie/mcp-resolve は、@forestrie/mcp-verify と組み合わせて使う SCITT レシートと検証資料を取得する MCP サーバーです。SCITT サービスやブロックチェーンからデータを読み、取得元と各結果が裏付ける信頼上の問いを示します。
主な機能
- 01レシートの登録状態を照会
- 02SCITT レシートの取得とデコード
- 03ログのジェネシス文書と設定の取得
- 04アキュムレーターとチェックポイント履歴の読み取り
- 05コントラクト KS256 アテステーションの取得
活用シーン
- 01オフライン検証に必要な資料を収集
- 02チェーン読み取りでログのアキュムレーターを確認
- 03レシートの登録状態と取得元を調査
- 04コントラクトルート向け署名アテステーションを取得
MCP 対応
SCITT 設定、登録状態、レシート、ジェネシス文書、チェーンデータを取得するツールを MCP クライアントに公開します。@forestrie/mcp-verify に検証資料を渡し、検証自体は同パッケージがローカルで行います。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @forestrie/mcp-resolveFORESTRIE_BASE_URLSCRAPI base URL used when a call omits baseUrl. Optional; the package ships no default and names no operator.FORESTRIE_RPC_URLJSON-RPC endpoint used when a call omits rpcUrl: your own chain access. Optional; the package ships no default and names no provider.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
7掲載時のツール一覧 · 1 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| baseUrl | string | いいえ | 任意の SCRAPI ベース URL。省略した場合は FORESTRIE_BASE_URL にフォールバックします。パッケージ自体によるデフォルト値の設定はありません |
詳細
@forestrie/mcp-resolve
SCITT レシート、そのログのジェネシスドキュメント、オンチェーンのアキュムレーターを取得し、それらを
@forestrie/mcp-verify
に渡して検証します。チェーン読み取りによるスプリットビューの回答も含みます。検証ツールが検証するデータ、すなわちレシート、ジェネシスドキュメント、アキュムレーターのスナップショット、登録ステータス、サービス設定を取得する MCP
サーバーです。すべての結果には、バイトデータの取得元と、信頼モデルにおける4つの問いのうち、どの問いの裏付けに使えるかが示されます。MCP レジストリには dev.forestrie/resolve として掲載されています。
検証ツールはネットワーク、アカウント、キー、バックエンドを必要とせず、完全にお使いのプロセス内で動作します。また、検証ツール自体のルールとして、インストールによってネットワーク依存関係が生じることはありません。したがって、データを取得する機能はすべてこのパッケージにあります。
使い方
{
"mcpServers": {
"forestrie-resolve": {
"command": "npx",
"args": ["-y", "@forestrie/mcp-resolve"],
"env": {
"FORESTRIE_BASE_URL": "https://api-a.forest-2.forestrie.dev",
"FORESTRIE_RPC_URL": "https://<your-chain-rpc-endpoint>"
}
}
}
}
両方の環境変数は任意で、どちらもご自身で指定するものです。baseUrl には任意の SCRAPI ベース URL を、rpcUrl にはご自身のチェーンアクセス先を指定します。呼び出し時にどちらかを明示的に渡すこともでき、環境変数の値は呼び出しで省略された場合にのみ使われます。このパッケージにはデフォルトのオペレーターもデフォルトのチェーンプロバイダーも含まれておらず、どちらも指定していません。
公開レーンは2つあります。どちらも例であり、デフォルトではありません。
| レーン | ベース URL | サービス ID |
|---|---|---|
| A | https://api-a.forest-2.forestrie.dev | canopy-dev-1 |
| B | https://api-b.forest-2.forestrie.dev | canopy-prod-1 |
Node 20.11 以降が必要です。
実例:1つのレシートを最初から最後まで
以下の値はすべて公開情報です。リリースごとに変わる値は、検証ツール自身の tarball から取得します。@forestrie/mcp-verify は各リリースを Forestrie ログに登録し、レシートを fixtures/self/ に同梱しています(その中の docs/self-registration.md)。そのため、公開されたパッケージは、ステートメント、レシート、ジェネシスドキュメント、ログ所有者キーを備えており、このパッケージが取得してライブレーンに対して検証できます。以下の実行は約4秒で完了し、キーもアカウントも使わず、公開 RPC エンドポイントから split-view ok で終了します。
| 座標 | 値 | 取得元 |
|---|---|---|
| ベース URL | https://api-a.forest-2.forestrie.dev | 上記のレーン A(例であり、デフォルトではありません) |
| ブートストラップログ | e22c8d55-3f88-b2b5-f225-5d2c2441bcdd | forest root。ジェネシスドキュメントからもデコードされます |
| パブリケーションログ | da6f297c-4a0c-4c9a-b2ae-e701e558721d | 検証ツールがリリースを登録するログ |
| コンテンツハッシュ | sha256(fixtures/self/statement.cose) | tarball。fixtures/self/manifest.json にも同じダイジェストが記載されています |
| エントリー ID | fixtures/self/entry-id.txt | tarball。query_registration からも取得できます |
| massif 高さ | 入力不要 | query_registration が返す receiptUrl の中にあります |
| ログ所有者キー | fixtures/self/log-key.xy.b64(base64 テキスト) | tarball |
| チェーン | id 84532(Base Sepolia)、univocity 0xe22c8d553f88b2b5f2255d2c2441bcdd0d50cd58 | ジェネシスドキュメントにバインドされています。fetch_genesis がデコードします |
空のディレクトリで tarball を用意するには:
npm i @forestrie/mcp-verify
ls node_modules/@forestrie/mcp-verify/fixtures/self/
shasum -a 256 node_modules/@forestrie/mcp-verify/fixtures/self/statement.cose
2026-09-22 に公開済みの 0.5.0 バンドルを使って実行したときの一連の呼び出しです。引数は JSON 形式で、それぞれの呼び出しが返した 1 行の結果を示します
(そのバンドルのエントリー ID は a0caa672b7030b000000000000000001 です。お使いの環境では entry-id.txt に記載されています)。
fetch_scitt_configuration {"baseUrl": "https://api-a.forest-2.forestrie.dev"}→fetched SCITT configuration (serviceId canopy-dev-1) from …/.well-known/scitt-configurationquery_registration {"baseUrl": …, "bootstrapLogId": "e22c8d55-3f88-b2b5-f225-5d2c2441bcdd", "logId": "da6f297c-4a0c-4c9a-b2ae-e701e558721d", "contentHash": "<sha256 of statement.cose>"}→registration complete; receipt at https://api-a.forest-2.forestrie.dev/logs/e22c8d55-…/da6f297c-…/14/entries/a0caa672b7030b000000000000000001/receipt—status: "receipt-available"、receiptUrl(その中に massif の高さ 14 が含まれています)、およびentryIdが返されます。fetch_receipt {"receiptUrl": "<from step 2>"}→fetched receipt (438 B) from …/receipt—receipt.sha256は tarball 内のreceipt.cborのダイジェストと一致し、receiptLogIdは publications ログを示します。fetch_genesis {"baseUrl": …, "logId": "e22c8d55-3f88-b2b5-f225-5d2c2441bcdd"}→fetched genesis (160 B) from …/api/forest/e22c8d55-…/genesis: univocity 0xe22c8d553f88b2b5f2255d2c2441bcdd0d50cd58 on chain 84532— tarball 内のgenesis.cborとバイト単位で一致します。保持してください。以下の呼び出しではこれをバイト列として渡し、同じ呼び出し内で取得することはありません。verify_fetched_receipt {"receiptUrl": …, "entryId": "<entry-id.txt>", "payload": {"path": "…/fixtures/self/statement.cose"}, "trust": {"root": "known-log-key", "keyXy": {"b64": "<contents of log-key.xy.b64>"}}}→verify: PASS · root=known-log-key · sealing ok, split-view not answered at this root, append-authority not answered at this root, attribution ok"trust": {"root": "genesis", "genesis": {"path": "…/fixtures/self/genesis.cbor"}}を指定した同じ呼び出し →verify: FAILED at signature (delegation_invalid) · root=genesis · …これは想定どおりの結果であり、改ざんを示すものではありません。genesis ルートのオフライン探索でたどれる委任は forest ルートから 1 ホップまでで、publications ログは孫にあたります。結果には、そのことを正確に示すgenesis_root_reaches_direct_delegates_onlyが含まれます。このレシートは、5 および 7 のように、キーまたはアキュムレーターを使って検証してください。verify_fetched_receipt {"receiptUrl": …, "entryId": …, "payload": …, "trust": {"root": "known-accumulator", "chain": {"genesis": {"path": "…/fixtures/self/genesis.cbor"}, "rpcUrl": "https://sepolia.base.org", "logId": "da6f297c-4a0c-4c9a-b2ae-e701e558721d"}}}→verify: PASS · root=known-accumulator · sealing ok, split-view ok, append-authority not answered at this root, attribution ok—anchor.blockNumber、anchor.matchedPeak、およびprovenance.root.from.rpcUrlから、どのチェーン状態に基づいて回答されたかがわかります。その後ログが成長し、レシートのピークを超えている場合、同じ呼び出しで公開済みチェックポイントをさかのぼって調べ、root_read_from_chain_historyが追加されます。- 任意:
fetch_accumulator {"chain": {…as in 7…}, "forReceipt": {"receipt": …, "payload": …, "entryId": …}}スナップショットを保持用のバイト列として返します。その後、@forestrie/mcp-verifyのverify_receiptに{"root": "known-accumulator", "accumulator":}` を指定すると、オフラインで再び split-view を検証できます。
チェーンと参照先。 ステップ 7 では、チェーン 84532(Base Sepolia)への JSON-RPC アクセスが必要です。このパッケージにはプロバイダーは同梱されておらず、デフォルトのプロバイダーも指定されていません。rpcUrl(または FORESTRIE_RPC_URL)はご自身で用意してください。以下のエンドポイントは、この記事の執筆時に認証なしで応答したサードパーティーの公開サービスの例としてのみ記載しています。最初に試す場合を除き、ご自身のプロバイダーを使用してください。
| エンドポイント | 2026-09-22 時点 |
|---|---|
https://sepolia.base.org | 応答あり |
https://base-sepolia-rpc.publicnode.com | 応答あり |
https://base-sepolia.drpc.org | 応答あり |
https://base-sepolia.gateway.tenderly.co | 応答あり |
https://1rpc.io/base-sepolia | HTTP 400 |
https://rpc.ankr.com/base_sepolia | HTTP 403 |
https://base-sepolia.g.alchemy.com/v2/demo | HTTP 429 |
2 つの落とし穴があります。 keyXy: {"path": "log-key.xy.b64"} は失敗します。このファイルは
base64 テキスト であり、path の入力は生のバイトとして読み取られるためです。その内容を
b64 として渡してください。また、両方のサーバーでバイトフィールドの名前は b64 です
(ここでは base64 も別名として使えます)。そのため、検証ツールで学んだ形式をそのまま使えます。
test/core/readme-example.test.ts は、このセクションの座標が記録済みの lane-A フィクスチャと一致することを検証します。そのため、フィクスチャを再取得しても、この例が気付かないうちに無効になることはありません。
8 つのツール
| ツール | 取得元 | 内容 | 対応する機能 |
|---|---|---|---|
fetch_scitt_configuration | 取得 | GET {baseUrl}/.well-known/scitt-configuration | なし |
query_registration | 取得 | ステートメントの登録ステータスを 1 回だけリクエストします。ポーリングは行いません | なし |
fetch_receipt | 取得 | レシートを取得してデコードし、その証明書が示すログを報告します | 単独ではなし |
fetch_genesis | 取得 | フォレストのジェネシス文書を、チェーンのバインディングおよびブートストラップキーとともに取得します | sealing。保持するコピーに限ります |
fetch_accumulator | チェーン読み取り | ログの公開済みアキュムレーターを読み取り、履歴をさかのぼって埋もれたピークを探します | split-view、sealing、append-authority |
fetch_checkpoint_history | チェーン読み取り | ブロック予算の範囲内で、公開済みチェックポイントを新しい順に読み取ります | fetch_accumulator と同じ |
fetch_ks256_attestation | チェーン読み取り | あるブロック時点で、コントラクトの KS256 ルートにレシートの証明書が受け入れられるか問い合わせます | 単独ではなし。mcp-verify が利用します |
verify_fetched_receipt | 取得、および指定またはチェーン読み取り | レシートを取得し、指定したルートまたはチェーンから読み取ったルートを使って検証します | 検証者自身の回答を変更せずに保持します |
fetch_ks256_attestation は、ルートがコントラクト(Safe)であるフォレスト用です。
このようなルートは ecrecover では検証できないため、検証者にはコントラクト自身の回答が必要です。その回答を得るにはチェーン読み取りが必要ですが、検証者はそれを行いません。レシートと、ルートアドレスまたは手元に保持しているジェネシスをツールに渡してください。ツールは 1 つのブロック(既定では最新のブロックを使用し、その後固定)で isValidSignature(digest, signature) を読み取り、回答を canonical-CBOR アテステーションとして返します。
fetch_ks256_attestation {receipt: {b64: …}, genesis: {b64: …}, rpcUrl: …, block?: 123}
-> attestation {base64, byteLength, sha256}, fields {chainId, address, digest,
signatureHash, blockNumber, blockHash, magic}, provenance, supports
verify_receipt {receipt: …, …, ks256Attestation: {b64: <attestation.base64>}}
結果は、そのブロック時点でのコントラクトの署名者のもとで証明書が有効であることを示します。RPC を利用できる人は誰でも、呼び出しを再実行して確認できます。ルートにコントラクトコードがない場合(外部所有のルートには必要ありません)、呼び出しがリバートした場合、回答が正確に 1 ワード(32 バイト)ではなく、0x1626ba7e の後に 28 個のゼロバイトが続く形式でない場合(短い戻り値、不正なパディング、余分なワード、呼び出しデータ自体のエコーは拒否されます)、また RPC のチェーンがジェネシスと異なる場合は、処理を拒否し、アテステーションを返しません。どちらの状態読み取りもブロックのハッシュで固定される(EIP-1898)ため、アテステーション内のハッシュが読み取られた状態を示します。ジェネシスとともに root を指定した場合、問い合わせ対象は root のコントラクトであり、ジェネシスは想定するチェーンだけを指定します。
すべてのツールは、プロセスの外部にあるものと通信するため、読み取り専用、冪等、オープンワールドとして注釈されています。各 supports 項目の意味とその理由については、
docs/what-fetching-proves.md を参照してください。
フェッチしたものが証明すること
運営者からフェッチしたレシートは、あなたが保持する信頼の起点のもとで検証されるまでは、運営者の主張です。forestrie/protocol にある公開の信頼モデル、
spec/receipt-trust-model.md
では、レシートが答えられる4つの問い(封印、分割ビュー、追記権限、帰属)と、呼び出し元が検証に使える4つの信頼の起点(genesis、known-log-key、known-accumulator、checkpoint-chain)が示されています。起点に優先順位はありません。どれが適切かは、何を保持しているかによって決まり、フェッチすると保持しているものが変わります。
そのため、ここにある各結果には provenance(各成果物がURLからフェッチされたものか、チェーンから読み取られたものか、あなたが提供したものか、およびその時刻)と、supports(どの起点のもとで、その資料をどの問いの証拠として利用できるかを示す1行の注記)が含まれます。注記はテストが完全一致で検証する固定文字列です。一覧と説明は
docs/what-fetching-proves.md
に記載されています。
以下の3つの点は、ドキュメントに任せるのではなく、ツールのインターフェースに組み込まれています。
- フェッチした
genesisが信頼の起点になることはありません。verify_fetched_receiptでは、あなたがバイト列として提供するルート、またはチェーンから読み取るアキュムレーターを指定します。スキーマには、同じ呼び出し内でgenesisをフェッチし、それを使って検証する形式はありません。確認時に運営者から取得したgenesisを使うと、レシートとルートの両方を運営者が提供することになり、今日運営者が提供することを選んだ文書との整合性が証明されるだけで、それ以上のことは証明されません。fetch_genesisは、文書を一度取得して保持し、その後はバイト列として渡せるように用意されています。 - チェーンとの紐付けに使うのは常にフォレストの情報であり、運営者の情報ではありません。 ユニボシティのコントラクトアドレスとチェーン ID は、フォレストの
genesis文書に紐付けられています。fetch_accumulatorとverify_fetched_receiptのチェーン経由の処理では、それらをあなたが保持するgenesisから取得するか、明示的に指定します。デフォルトから取得することはなく、呼び出し内でフェッチしたgenesisから取得することも、環境変数から取得することもありません。 genesisをルートとする検証で到達できるのは直接の委任先だけであり、結果にもそのことが示されます。 指定されたgenesisを使った検証器のオフライン探索では、フォレストのルートから委任を1段階たどります。付与チェーンのさらに下にあるログからのレシート(検証器自身の公開ログは孫にあたります)は、このルートではdelegation_invalidとなり、verify_fetched_receiptはgenesis_root_reaches_direct_delegates_onlyを追加します。これは探索の限界を示すものであり、レシートに関する判定ではありません。そのようなレシートはknown-log-keyまたはknown-accumulatorをルートとして検証してください。- 埋もれたピークは、同じルートのもとで公開済みの履歴から検証されます。 後から成長したことでレシートのピークがより大きなピークに折り込まれた場合、チェーン経由の処理では、設定したブロック予算の範囲内で公開済みチェックポイントをさかのぼり、その旨を示します(
root_read_from_chain_history)。上限なく走査することはありません。
検証器自身のTRANSPARENCY.md(tarball に同梱)では、透明性ログとは何か、レシートに何が含まれるかを説明しています。このパッケージではその説明を繰り返しません。検証器のdocs/trust-roots.mdでは、信頼の起点について詳しく説明しています。
このパッケージが決して行わないこと
- 書き込みません。登録、付与、キーの設定は行いません。
- ポーリングしません。
query_registrationは1回のリクエストであり、再度呼び出すかどうかはお客様が決めます。HTTP 429 はエラーではなく、retryAfterMsを含む構造化されたproblemとして返されます。 - オペレーターやチェーンプロバイダーをお客様に代わって選ぶことはありません。
- 取得したジェネシスやアキュムレーターを呼び出し間でキャッシュしません。すべての結果には新しい
atが含まれます。 - ベリファイアの回答を編集しません。
verify_fetched_receiptはベリファイアのstages、questions、diagnosticsを変更せずに返し、バイトデータの取得元を示す診断を2つ追加します。not_answered_by_this_rootは正式な回答であり、変更されずにお客様に届きます。
レイアウトとゲート
src/core/ pure over bytes: URL construction, response classification,
provenance and supports labelling, the compose logic.
No node:*, no fetch, no fs. Exported as ".".
src/net/ the ONLY place fetch is called; every function takes fetchImpl.
Exported as "./net".
src/node/ the MCP adapter: SDK, stdio, {path}/base64 inputs, env defaults.
Exported as "./server".
CI は、AGENTS.md に記載されている純粋性とパッケージングのゲートで処理をブロックします。ユニットテストは、例外をスローする fetch のもとで実行され、test/fixtures/ に記録された通信の再生を使用します。実際のレーンを使うライブプロジェクトもありますが、オプトイン方式であり、必須のチェックではありません。
pnpm test # purity gates + unit tests
pnpm typecheck
pnpm build
pnpm test:live # FORESTRIE_LIVE=1 plus FORESTRIE_BASE_URL, FORESTRIE_RPC_URL, UNIVOCITY_ADDRESS, CHAIN_ID and GENESIS_CBOR_B64
規約、不変条件、リリース手順については、AGENTS.md をご覧ください。
依存関係
package.json ではバージョンを厳密に固定し、意図的に更新します。@forestrie/mcp-verify から使用するのは "." のコアエクスポートのみです。チェーンの読み取りを含むすべてのリクエストは、注入された fetchImpl を経由します。
ライセンス
MIT.
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。