Fetch SCITT receipts and on-chain anchors for offline verification

dev.forestrie由 forestrie.dev 發布v0.5.0更新於 Nov 3, 2026

取得 SCITT 收據、其創世記錄和鏈上累加器,供 @forestrie/mcp-verify 進行驗證

AI 翻譯由 AI 模型根據下方的原文描述翻譯,可能有誤。

原文描述

Fetch a SCITT receipt, its genesis and on-chain accumulator for @forestrie/mcp-verify to verify

發布方自己的服務:Resolve

已驗證STDIO僅桌面開發者工具安全與監控

概覽

Fetch SCITT receipts and on-chain anchors for offline verification 的本機 MCP 服務,由 forestrie.dev 發布;無需登入;STDIO。

暫無 AI 概覽:以下資訊來自註冊中心條目和服務本身。

發布者
forestrie.dev

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Fetch SCITT receipts and on-chain anchors for offline verification,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

@forestrie/mcp-resolve

Fetch a SCITT receipt, its log's genesis document and its on-chain accumulator, and hand them to @forestrie/mcp-verify to verify — including the split-view answer, from a chain read. An MCP server that fetches the material the verifier verifies: a receipt, a genesis document, an accumulator snapshot, a registration status, a service configuration. Every result says where its bytes came from and which of the four questions of the trust model they can support. Listed in the MCP registry as dev.forestrie/resolve.

The verifier runs entirely in your process with no network, no account, no key and no backend, and its own rule is that installing it can never imply a network dependency. So anything that fetches lives here.

Use

json
{  "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>"      }    }  }}

Both environment variables are optional and both are yours. baseUrl is any SCRAPI base URL and rpcUrl is your own chain access; a call may pass either explicitly, and the environment values are used only when a call omits them. The package ships no default operator and no default chain provider, and names none.

Two public lanes exist and are examples, not defaults:

LaneBase URLService id
Ahttps://api-a.forest-2.forestrie.devcanopy-dev-1
Bhttps://api-b.forest-2.forestrie.devcanopy-prod-1

Requires Node 20.11 or later.

A worked example: one receipt, end to end

Every value below is public, and the ones that change per release come from the verifier's own tarball. @forestrie/mcp-verify registers each release in a Forestrie log and ships the receipt under fixtures/self/ (docs/self-registration.md there), so the published package is a statement, a receipt, a genesis document and a log owner key that this package can fetch and verify against the live lane. The run below takes about four seconds and ends in split-view ok from a public RPC endpoint, with no key and no account.

CoordinateValueWhere it comes from
base URLhttps://api-a.forest-2.forestrie.devlane A above (an example, not a default)
bootstrap loge22c8d55-3f88-b2b5-f225-5d2c2441bcddthe forest root; also decoded from the genesis document
publications logda6f297c-4a0c-4c9a-b2ae-e701e558721dthe log the verifier registers releases on
content hashsha256(fixtures/self/statement.cose)the tarball; fixtures/self/manifest.json lists the same digest
entry idfixtures/self/entry-id.txtthe tarball; query_registration returns it too
massif heightnever typedinside the receiptUrl that query_registration returns
log owner keyfixtures/self/log-key.xy.b64 (base64 text)the tarball
chainid 84532 (Base Sepolia), univocity 0xe22c8d553f88b2b5f2255d2c2441bcdd0d50cd58bound in the genesis document; fetch_genesis decodes it

To have the tarball at hand in an empty directory:

npm i @forestrie/mcp-verifyls node_modules/@forestrie/mcp-verify/fixtures/self/shasum -a 256 node_modules/@forestrie/mcp-verify/fixtures/self/statement.cose

The sequence, with the arguments as JSON and the one-line result each call returned when run on 2026-09-22 against the published 0.5.0 bundle (its entry id is a0caa672b7030b000000000000000001; yours is whatever entry-id.txt says):

  1. fetch_scitt_configuration {"baseUrl": "https://api-a.forest-2.forestrie.dev"} → fetched SCITT configuration (serviceId canopy-dev-1) from …/.well-known/scitt-configuration
  2. query_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", the receiptUrl (with the massif height, 14, inside it) and entryId.
  3. fetch_receipt {"receiptUrl": "<from step 2>"} → fetched receipt (438 B) from …/receipt — receipt.sha256 equals the digest of the tarball's receipt.cbor; receiptLogId names the publications log.
  4. fetch_genesis {"baseUrl": …, "logId": "e22c8d55-3f88-b2b5-f225-5d2c2441bcdd"} → fetched genesis (160 B) from …/api/forest/e22c8d55-…/genesis: univocity 0xe22c8d553f88b2b5f2255d2c2441bcdd0d50cd58 on chain 84532 — byte-identical to the tarball's genesis.cbor. Keep it: the calls below pass it back as bytes, never fetched in the same call.
  5. 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
  6. The same call with "trust": {"root": "genesis", "genesis": {"path": "…/fixtures/self/genesis.cbor"}} → verify: FAILED at signature (delegation_invalid) · root=genesis · … This is expected, not tampering: the genesis root's offline walk resolves one delegation hop from the forest root, and the publications log is a grandchild. The result carries genesis_root_reaches_direct_delegates_only saying exactly that. Verify this receipt under a key or an accumulator, as in 5 and 7.
  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 and provenance.root.from.rpcUrl say which chain state answered. If the log has grown past the receipt's peak since, the same call looks back through published checkpoints and adds root_read_from_chain_history.
  8. Optional: fetch_accumulator {"chain": {…as in 7…}, "forReceipt": {"receipt": …, "payload": …, "entryId": …}} returns the snapshot as bytes to keep; later, @forestrie/mcp-verify's verify_receipt under {"root": "known-accumulator", "accumulator": <those bytes>} answers split-view again, offline.

The chain, and where to read it. Step 7 needs JSON-RPC access to chain 84532 (Base Sepolia). This package ships no provider and names none as a default; rpcUrl (or FORESTRIE_RPC_URL) is yours. The endpoints below are third-party public services, listed only as examples of what answered unauthenticated when this example was written; use your own provider for anything beyond a first try.

EndpointOn 2026-09-22
https://sepolia.base.organswered
https://base-sepolia-rpc.publicnode.comanswered
https://base-sepolia.drpc.organswered
https://base-sepolia.gateway.tenderly.coanswered
https://1rpc.io/base-sepoliaHTTP 400
https://rpc.ankr.com/base_sepoliaHTTP 403
https://base-sepolia.g.alchemy.com/v2/demoHTTP 429

Two traps. keyXy: {"path": "log-key.xy.b64"} fails: that file is base64 text, and path inputs are read as raw bytes — pass its contents as b64. And the byte-field name is b64 in both servers (base64 is accepted here as an alias), so the shapes you learn from the verifier work here unchanged.

test/core/readme-example.test.ts asserts the coordinates in this section against the recorded lane-A fixtures, so a fixture re-capture cannot silently invalidate the example.

The eight tools

ToolProvenanceWhat it doesSupports
fetch_scitt_configurationfetchedGET {baseUrl}/.well-known/scitt-configurationnone
query_registrationfetchedone registration-status request for a statement; never pollsnone
fetch_receiptfetchedfetches a receipt, decodes it, and reports the log its certificate namesnone on its own
fetch_genesisfetchedfetches the forest's genesis document, with its chain binding and bootstrap keysealing, only for a copy you keep
fetch_accumulatorchain-readreads the log's published accumulator; looks back through history for a buried peaksplit-view, sealing, append-authority
fetch_checkpoint_historychain-readreads published checkpoints back, newest first, within your block budgetas fetch_accumulator
fetch_ks256_attestationchain-readasks a contract KS256 root, at one block, whether it accepts a receipt's certificatenone on its own; mcp-verify consumes it
verify_fetched_receiptfetched, plus supplied or chain-readfetches a receipt and verifies it under a root you supply or read from the chainthe verifier's own answers, unaltered

fetch_ks256_attestation is for a forest whose root is a contract (a Safe). Such a root cannot be checked by ecrecover, so the verifier needs the contract's own answer, and getting it needs a chain read, which the verifier never makes. Give the tool the receipt and either the root address or a genesis you hold; it reads isValidSignature(digest, signature) at one block (default the latest, then pinned) and returns the answer as a canonical-CBOR attestation:

fetch_ks256_attestation  {receipt: {b64: …}, genesis: {b64: …}, rpcUrl: …, block?: 123}  -> attestation {base64, byteLength, sha256}, fields {chainId, address, digest,     signatureHash, blockNumber, blockHash, magic}, provenance, supportsverify_receipt           {receipt: …, …, ks256Attestation: {b64: <attestation.base64>}}

The result says the certificate is valid under the contract's signers at that block, and anyone with RPC can re-run the call to confirm it. It refuses, and returns no attestation, for a root with no contract code (an externally owned root needs none), a reverting call, or any answer but exactly one 32-byte word, 0x1626ba7e followed by 28 zero bytes (a short return, dirty padding, extra words or an echo of the call's own data are refused), and for an RPC on a different chain from your genesis. Both state reads are pinned by the block's hash (EIP-1898), so the hash in the attestation is the state that was read. With root given beside a genesis, root is the contract asked and the genesis supplies only the expected chain.

Every tool is annotated read-only, idempotent and open-world, because every one of them talks to something outside your process. What each supports entry means, and why, is in docs/what-fetching-proves.md.

What a fetched thing proves

A receipt fetched from the operator is the operator's claim until it is verified under a trust root you hold. The public trust model, spec/receipt-trust-model.md in forestrie/protocol, names four questions a receipt can answer (sealing, split-view, append-authority, attribution) and four trust roots a caller can verify under (genesis, known-log-key, known-accumulator, checkpoint-chain). The roots are not ordered. Which one is right depends on what you hold, and fetching changes what you hold.

That is why every result here carries provenance (for each artefact: fetched from a URL, read from a chain, or supplied by you, and when) and supports (which questions the material can serve as evidence for, under which root, with a one-line note). The notes are fixed strings the tests assert verbatim; they are listed and explained in docs/what-fetching-proves.md.

Three consequences are built into the tool surface rather than left to documentation:

  • A fetched genesis is never a root. verify_fetched_receipt takes its root as bytes you supply or as an accumulator read from the chain; its schema has no form that fetches a genesis and verifies under it in the same call. A genesis obtained from the operator at check time makes the operator the supplier of both the receipt and the root, which proves consistency with a document the operator chose to serve today and nothing more. fetch_genesis exists so you can obtain the document once, keep it, and pass it as bytes from then on.
  • The chain binding is the forest's, never the operator's. The univocity contract address and chain id are bound in a forest's genesis document. fetch_accumulator and the chain path of verify_fetched_receipt take them from a genesis you hold, or explicitly, never from a default, never from a genesis fetched inside the call, and never from an environment variable.
  • A genesis root reaches direct delegates only, and the result says so. The verifier's offline walk under a supplied genesis resolves one delegation hop from the forest root. A receipt from a log further down the grant chain — the verifier's own publications log is a grandchild — fails under that root with delegation_invalid, and verify_fetched_receipt appends genesis_root_reaches_direct_delegates_only to say that this is the walk's limit, not a finding about the receipt. Verify such a receipt under known-log-key or known-accumulator.
  • Buried peaks are answered from published history, under the same root. When later growth has folded a receipt's peak into a bigger one, the chain path looks back through published checkpoints, within the block budget you set, and says so (root_read_from_chain_history). It never scans without a bound.

The verifier's own TRANSPARENCY.md (shipped in its tarball) explains what a transparency log is and what a receipt contains; this package does not repeat it. Its docs/trust-roots.md explains the roots in depth.

What this package never does

  • Never writes: no registration, no grants, no keys.
  • Never polls: query_registration is one request, and you decide whether to call it again. An HTTP 429 comes back as a structured problem with retryAfterMs, not as an error.
  • Never chooses an operator or a chain provider for you.
  • Never caches a fetched genesis or accumulator across calls: every result carries a fresh at.
  • Never edits the verifier's answers. verify_fetched_receipt returns the verifier's stages, questions and diagnostics unaltered and appends two diagnostics of its own that say where the bytes came from. not_answered_by_this_root is a real answer and reaches you unchanged.

Layout and gates

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 blocks on the purity and packaging gates described in AGENTS.md. Unit tests run under a fetch that throws and replay exchanges recorded under test/fixtures/. A live project against a real lane exists, is opt-in, and is never a required check.

pnpm test        # purity gates + unit testspnpm typecheckpnpm buildpnpm test:live   # FORESTRIE_LIVE=1 plus FORESTRIE_BASE_URL, FORESTRIE_RPC_URL, UNIVOCITY_ADDRESS, CHAIN_ID and GENESIS_CBOR_B64

Conventions, invariants and the release path are in AGENTS.md.

Dependencies

Exact pins in package.json, bumped deliberately. Of @forestrie/mcp-verify, only the "." core export is used. Every request, the chain reads included, goes through an injected fetchImpl.

License

MIT.

來源:README.md,提交 2a50000

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

5
  1. v0.5.0最新Nov 3, 2026
  2. v0.4.1Oct 20, 2026
  3. v0.4.0Oct 18, 2026
  4. v0.3.1Oct 11, 2026
  5. v0.2.0Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

其他 Resolve 整合