Public log

@forestrie/mcp-verify

Verify a SCITT receipt under a trust root you hold — offline, no backend, no key, no network

npm · fingerprint 8b3f419fd5ce881a87a5f475 · repository · RSS

4tools
3recorded versions
24dtracked
unchanged 6d

What changed

Changed 2026-10-21 11:56 UTC

2 descriptions rewritten, 1 schema or annotation change with the description left byte-identical.

--- pinned/verify_grant_receipt
+++ observed/verify_grant_receipt
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Verify a Forestrie grant receipt against the committed grant (Forestrie-Grant COSE Sign1, or raw grant payload CBOR plus an entry id), at a trust root you choose. Mirrors `forestrie verify-grant`. This is the tool that answers the append-authority question: the leaf IS the grant. KS256 contract roots take an optional ks256Attestation (fetched elsewhere; this tool never calls the chain).",
+   "description": "Verify a Forestrie grant receipt against the committed grant (Forestrie-Grant COSE Sign1, or raw grant payload CBOR plus an entry id), at a trust root you choose. Mirrors `forestrie verify-grant`. This is the tool that answers the append-authority question: the leaf IS the grant. KS256 contract roots take an optional ks256Attestation (fetched elsewhere; this tool never calls the chain; several go in ks256Attestations).",
    "execution": {
      "taskSupport": "forbidden"
    },
-         "description": "ERC-1271 attestation artifact (encodeKs256Attestation CBOR) for a KS256 CONTRACT root. Fetched elsewhere — this server never touches the network: use mcp-resolve's `fetch_ks256_attestation` tool or forestrie-cli's `fetch-ks256-attestation`. With it a contract-rooted delegation verifies as valid under the contract's signers at the attested block. Usable with the genesis, known-log-key and checkpoint-chain roots (checkpoint-chain also needs trust.genesis for the forest chain id; one attestation binds one certificate, so links signed under a different certificate still fail). Not with known-accumulator. Trust: the attestation is unsigned and only as good as whoever fetched it; accept one only from a party you would trust to read the chain for you — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
+         "description": "ERC-1271 attestation artifact (encodeKs256Attestation CBOR) for a KS256 CONTRACT root. Fetched elsewhere — this server never touches the network: use mcp-resolve's `fetch_ks256_attestation` tool or forestrie-cli's `fetch-ks256-attestation`. With it a contract-rooted delegation verifies as valid under the contract's signers at the attested block. Usable with the genesis, known-log-key and checkpoint-chain roots (checkpoint-chain also needs trust.genesis for the forest chain id; one attestation binds one certificate, so a chain whose links were signed under several certificates needs one attestation per certificate: give them in ks256Attestations). Not with known-accumulator. Trust: the attestation is unsigned and only as good as whoever fetched it; accept one only from a party you would trust to read the chain for you — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
        },
+       "ks256Attestations": {
+         "description": "Several ERC-1271 attestations (each encodeKs256Attestation CBOR, {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}) for a KS256 CONTRACT root that signed more than one delegation certificate (a Safe that rotated its delegate). Each certificate takes the attestation whose digest and signature hash are its own. Combined with ks256Attestation when both are given. Every attestation is reported in the result as used or unused with a reason (ks256Attestations): none is silently ignored. Same roots and trust caveats as ks256Attestation.",
+         "items": {
+           "anyOf": [
+             {
+               "properties": {
+                 "b64": {
+                   "description": "standard base64",
+                   "minLength": 1,
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "b64"
+               ],
+               "type": "object"
+             },
+             {
+               "properties": {
+                 "base64": {
+                   "description": "standard base64 (alias of b64)",
+                   "minLength": 1,
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "base64"
+               ],
+               "type": "object"
+             },
+             {
+               "properties": {
+                 "path": {
+                   "description": "filesystem path, read by the stdio adapter",
+                   "minLength": 1,
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "path"
+               ],
+               "type": "object"
+             }
+           ],
+           "description": "Bytes as {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
+         },
+         "minItems": 1,
+         "type": "array"
+       },
        "receipt": {
          "anyOf": [
            {
-             "description": "Trust an on-chain accumulator snapshot you hold. The only root that answers split-view. Checks no signature locally — the anchor is the authority.",
+             "description": "Trust an on-chain accumulator snapshot you hold. The only root that answers split-view. Checks no signature locally — the anchor is the authority. The peak is recomputed from leaf + inclusion path; a peak attached to the receipt is checked against it, never trusted.",
              "properties": {
                "accumulator": {
                  "anyOf": [
-             "description": "Fold a retained checkpoint chain and match any authenticated link. Answers split-view. Needs genesis or keyXy to root the first link. Each link's delegation certificate limits are enforced: a link signed beyond the certificate's mmrEnd fails delegation_out_of_range, and a link covering the receipt's leaf signed under a certificate that had expired when the leaf was sequenced fails delegation_expired (never wall-clock). A KS256 contract (Safe) genesis root takes ks256Attestation on the tool call.",
+             "description": "Fold a retained checkpoint chain and match any authenticated link. Answers split-view. Needs genesis or keyXy to root the first link. Each link's delegation certificate limits are enforced: a link signed beyond the certificate's mmrEnd, or below its mmrStart, fails delegation_out_of_range, and a link covering the receipt's leaf signed under a certificate that had expired when the leaf was sequenced fails delegation_expired (never wall-clock). A KS256 contract (Safe) genesis root takes ks256Attestation on the tool call (one per delegation certificate: several in ks256Attestations). Failures carry the typed reason, with stage/detail/failedLink naming the link.",
              "properties": {
                "checkpoints": {
                  "description": "retained .sth objects in ascending massif order, each {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}",
+       "detail": {
+         "description": "checkpoint-chain: which link failed and why, in words",
+         "type": "string"
+       },
        "diagnostics": {
          "description": "named notes about what the arithmetic could not separate",
          "items": {
+       "failedLink": {
+         "description": "checkpoint-chain: index of the link a failure names",
+         "type": "number"
+       },
        "ks256Attestation": {
          "additionalProperties": false,
-         "description": "present only when a supplied ERC-1271 attestation was needed for the run to pass: a contract root is valid under its signers at THIS block only",
+         "description": "present only when a supplied ERC-1271 attestation was needed for the run to pass (the first one, when several were): a contract root is valid under its signers at THIS block only",
          "properties": {
            "address": {
              "type": "string"
+       "ks256Attestations": {
+         "additionalProperties": false,
+         "description": "every supplied attestation, accounted for: used ones carried the run (valid under the contract's signers at each named block only); unused ones say why (not_needed, no_matching_certificate, duplicate); rejected ones were tried for a link's certificate and refused. Index is the position in the supplied list (ks256Attestation first, then ks256Attestations)",
+         "properties": {
+           "rejected": {
+             "items": {
+               "additionalProperties": false,
+               "properties": {
+                 "digest": {
+                   "type": "string"
+                 },
+                 "index": {
+                   "type": "number"
+                 },
+                 "links": {
+                   "items": {
+                     "type": "number"
+                   },
+                   "type": "array"
+                 }
+               },
+               "required": [
+                 "index",
+                 "digest",
+                 "links"
+               ],
+               "type": "object"
+             },
+             "type": "array"
+           },
+           "unused": {
+             "items": {
+               "additionalProperties": false,
+               "properties": {
+                 "digest": {
+                   "type": "string"
+                 },
+                 "index": {
+                   "type": "number"
+                 },
+                 "reason": {
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "index",
+                 "digest",
+                 "reason"
+               ],
+               "type": "object"
+             },
+             "type": "array"
+           },
+           "used": {
+             "items": {
+               "additionalProperties": false,
+               "properties": {
+                 "address": {
+                   "type": "string"
+                 },
+                 "blockHash": {
+                   "type": "string"
+                 },
+                 "blockNumber": {
+                   "type": "string"
+                 },
+                 "chainId": {
+                   "type": "string"
+                 },
+                 "digest": {
+                   "type": "string"
+                 },
+                 "index": {
+                   "type": "number"
+                 },
+                 "links": {
+                   "items": {
+                     "type": "number"
+                   },
+                   "type": "array"
+                 }
+               },
+               "required": [
+                 "index",
+                 "digest",
+                 "chainId",
+                 "blockNumber",
+                 "blockHash",
+                 "address"
+               ],
+               "type": "object"
+             },
+             "type": "array"
+           }
+         },
+         "required": [
+           "used",
+           "rejected",
+           "unused"
+         ],
+         "type": "object"
+       },
        "ok": {
          "type": "boolean"
        },
--- pinned/verify_receipt
+++ observed/verify_receipt
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Verify a Forestrie receipt against the EXACT registered payload bytes and an entry id, at a trust root you choose. Mirrors `forestrie verify`. Offline: no network, no key, no account. Returns both the mechanical stages and the four trust questions. KS256 contract roots take an optional ks256Attestation (fetched elsewhere; this tool never calls the chain).",
+   "description": "Verify a Forestrie receipt against the EXACT registered payload bytes and an entry id, at a trust root you choose. Mirrors `forestrie verify`. Offline: no network, no key, no account. Returns both the mechanical stages and the four trust questions. KS256 contract roots take an optional ks256Attestation (fetched elsewhere; this tool never calls the chain; several go in ks256Attestations).",
    "execution": {
      "taskSupport": "forbidden"
    },
-         "description": "ERC-1271 attestation artifact (encodeKs256Attestation CBOR) for a KS256 CONTRACT root. Fetched elsewhere — this server never touches the network: use mcp-resolve's `fetch_ks256_attestation` tool or forestrie-cli's `fetch-ks256-attestation`. With it a contract-rooted delegation verifies as valid under the contract's signers at the attested block. Usable with the genesis, known-log-key and checkpoint-chain roots (checkpoint-chain also needs trust.genesis for the forest chain id; one attestation binds one certificate, so links signed under a different certificate still fail). Not with known-accumulator. Trust: the attestation is unsigned and only as good as whoever fetched it; accept one only from a party you would trust to read the chain for you — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
+         "description": "ERC-1271 attestation artifact (encodeKs256Attestation CBOR) for a KS256 CONTRACT root. Fetched elsewhere — this server never touches the network: use mcp-resolve's `fetch_ks256_attestation` tool or forestrie-cli's `fetch-ks256-attestation`. With it a contract-rooted delegation verifies as valid under the contract's signers at the attested block. Usable with the genesis, known-log-key and checkpoint-chain roots (checkpoint-chain also needs trust.genesis for the forest chain id; one attestation binds one certificate, so a chain whose links were signed under several certificates needs one attestation per certificate: give them in ks256Attestations). Not with known-accumulator. Trust: the attestation is unsigned and only as good as whoever fetched it; accept one only from a party you would trust to read the chain for you — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
        },
+       "ks256Attestations": {
+         "description": "Several ERC-1271 attestations (each encodeKs256Attestation CBOR, {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}) for a KS256 CONTRACT root that signed more than one delegation certificate (a Safe that rotated its delegate). Each certificate takes the attestation whose digest and signature hash are its own. Combined with ks256Attestation when both are given. Every attestation is reported in the result as used or unused with a reason (ks256Attestations): none is silently ignored. Same roots and trust caveats as ks256Attestation.",
+         "items": {
+           "anyOf": [
+             {
+               "properties": {
+                 "b64": {
+                   "description": "standard base64",
+                   "minLength": 1,
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "b64"
+               ],
+               "type": "object"
+             },
+             {
+               "properties": {
+                 "base64": {
+                   "description": "standard base64 (alias of b64)",
+                   "minLength": 1,
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "base64"
+               ],
+               "type": "object"
+             },
+             {
+               "properties": {
+                 "path": {
+                   "description": "filesystem path, read by the stdio adapter",
+                   "minLength": 1,
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "path"
+               ],
+               "type": "object"
+             }
+           ],
+           "description": "Bytes as {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
+         },
+         "minItems": 1,
+         "type": "array"
+       },
        "payload": {
          "anyOf": [
            {
-             "description": "Trust an on-chain accumulator snapshot you hold. The only root that answers split-view. Checks no signature locally — the anchor is the authority.",
+             "description": "Trust an on-chain accumulator snapshot you hold. The only root that answers split-view. Checks no signature locally — the anchor is the authority. The peak is recomputed from leaf + inclusion path; a peak attached to the receipt is checked against it, never trusted.",
              "properties": {
                "accumulator": {
                  "anyOf": [
-             "description": "Fold a retained checkpoint chain and match any authenticated link. Answers split-view. Needs genesis or keyXy to root the first link. Each link's delegation certificate limits are enforced: a link signed beyond the certificate's mmrEnd fails delegation_out_of_range, and a link covering the receipt's leaf signed under a certificate that had expired when the leaf was sequenced fails delegation_expired (never wall-clock). A KS256 contract (Safe) genesis root takes ks256Attestation on the tool call.",
+             "description": "Fold a retained checkpoint chain and match any authenticated link. Answers split-view. Needs genesis or keyXy to root the first link. Each link's delegation certificate limits are enforced: a link signed beyond the certificate's mmrEnd, or below its mmrStart, fails delegation_out_of_range, and a link covering the receipt's leaf signed under a certificate that had expired when the leaf was sequenced fails delegation_expired (never wall-clock). A KS256 contract (Safe) genesis root takes ks256Attestation on the tool call (one per delegation certificate: several in ks256Attestations). Failures carry the typed reason, with stage/detail/failedLink naming the link.",
              "properties": {
                "checkpoints": {
                  "description": "retained .sth objects in ascending massif order, each {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}",
+       "detail": {
+         "description": "checkpoint-chain: which link failed and why, in words",
+         "type": "string"
+       },
        "diagnostics": {
          "description": "named notes about what the arithmetic could not separate",
          "items": {
+       "failedLink": {
+         "description": "checkpoint-chain: index of the link a failure names",
+         "type": "number"
+       },
        "ks256Attestation": {
          "additionalProperties": false,
-         "description": "present only when a supplied ERC-1271 attestation was needed for the run to pass: a contract root is valid under its signers at THIS block only",
+         "description": "present only when a supplied ERC-1271 attestation was needed for the run to pass (the first one, when several were): a contract root is valid under its signers at THIS block only",
          "properties": {
            "address": {
              "type": "string"
+       "ks256Attestations": {
+         "additionalProperties": false,
+         "description": "every supplied attestation, accounted for: used ones carried the run (valid under the contract's signers at each named block only); unused ones say why (not_needed, no_matching_certificate, duplicate); rejected ones were tried for a link's certificate and refused. Index is the position in the supplied list (ks256Attestation first, then ks256Attestations)",
+         "properties": {
+           "rejected": {
+             "items": {
+               "additionalProperties": false,
+               "properties": {
+                 "digest": {
+                   "type": "string"
+                 },
+                 "index": {
+                   "type": "number"
+                 },
+                 "links": {
+                   "items": {
+                     "type": "number"
+                   },
+                   "type": "array"
+                 }
+               },
+               "required": [
+                 "index",
+                 "digest",
+                 "links"
+               ],
+               "type": "object"
+             },
+             "type": "array"
+           },
+           "unused": {
+             "items": {
+               "additionalProperties": false,
+               "properties": {
+                 "digest": {
+                   "type": "string"
+                 },
+                 "index": {
+                   "type": "number"
+                 },
+                 "reason": {
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "index",
+                 "digest",
+                 "reason"
+               ],
+               "type": "object"
+             },
+             "type": "array"
+           },
+           "used": {
+             "items": {
+               "additionalProperties": false,
+               "properties": {
+                 "address": {
+                   "type": "string"
+                 },
+                 "blockHash": {
+                   "type": "string"
+                 },
+                 "blockNumber": {
+                   "type": "string"
+                 },
+                 "chainId": {
+                   "type": "string"
+                 },
+                 "digest": {
+                   "type": "string"
+                 },
+                 "index": {
+                   "type": "number"
+                 },
+                 "links": {
+                   "items": {
+                     "type": "number"
+                   },
+                   "type": "array"
+                 }
+               },
+               "required": [
+                 "index",
+                 "digest",
+                 "chainId",
+                 "blockNumber",
+                 "blockHash",
+                 "address"
+               ],
+               "type": "object"
+             },
+             "type": "array"
+           }
+         },
+         "required": [
+           "used",
+           "rejected",
+           "unused"
+         ],
+         "type": "object"
+       },
        "ok": {
          "type": "boolean"
        },
--- pinned/verify_self
+++ observed/verify_self
  {
    "annotations": {
      "destructiveHint": false,
+       "detail": {
+         "description": "checkpoint-chain: which link failed and why, in words",
+         "type": "string"
+       },
        "diagnostics": {
          "description": "named notes about what the arithmetic could not separate",
          "items": {
+       "failedLink": {
+         "description": "checkpoint-chain: index of the link a failure names",
+         "type": "number"
+       },
        "ks256Attestation": {
          "additionalProperties": false,
-         "description": "present only when a supplied ERC-1271 attestation was needed for the run to pass: a contract root is valid under its signers at THIS block only",
+         "description": "present only when a supplied ERC-1271 attestation was needed for the run to pass (the first one, when several were): a contract root is valid under its signers at THIS block only",
          "properties": {
            "address": {
              "type": "string"
+       "ks256Attestations": {
+         "additionalProperties": false,
+         "description": "every supplied attestation, accounted for: used ones carried the run (valid under the contract's signers at each named block only); unused ones say why (not_needed, no_matching_certificate, duplicate); rejected ones were tried for a link's certificate and refused. Index is the position in the supplied list (ks256Attestation first, then ks256Attestations)",
+         "properties": {
+           "rejected": {
+             "items": {
+               "additionalProperties": false,
+               "properties": {
+                 "digest": {
+                   "type": "string"
+                 },
+                 "index": {
+                   "type": "number"
+                 },
+                 "links": {
+                   "items": {
+                     "type": "number"
+                   },
+                   "type": "array"
+                 }
+               },
+               "required": [
+                 "index",
+                 "digest",
+                 "links"
+               ],
+               "type": "object"
+             },
+             "type": "array"
+           },
+           "unused": {
+             "items": {
+               "additionalProperties": false,
+               "properties": {
+                 "digest": {
+                   "type": "string"
+                 },
+                 "index": {
+                   "type": "number"
+                 },
+                 "reason": {
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "index",
+                 "digest",
+                 "reason"
+               ],
+               "type": "object"
+             },
+             "type": "array"
+           },
+           "used": {
+             "items": {
+               "additionalProperties": false,
+               "properties": {
+                 "address": {
+                   "type": "string"
+                 },
+                 "blockHash": {
+                   "type": "string"
+                 },
+                 "blockNumber": {
+                   "type": "string"
+                 },
+                 "chainId": {
+                   "type": "string"
+                 },
+                 "digest": {
+                   "type": "string"
+                 },
+                 "index": {
+                   "type": "number"
+                 },
+                 "links": {
+                   "items": {
+                     "type": "number"
+                   },
+                   "type": "array"
+                 }
+               },
+               "required": [
+                 "index",
+                 "digest",
+                 "chainId",
+                 "blockNumber",
+                 "blockHash",
+                 "address"
+               ],
+               "type": "object"
+             },
+             "type": "array"
+           }
+         },
+         "required": [
+           "used",
+           "rejected",
+           "unused"
+         ],
+         "type": "object"
+       },
        "ok": {
          "type": "boolean"
        },

Changed 2026-10-19 13:09 UTC

2 descriptions rewritten, 1 schema or annotation change with the description left byte-identical.

--- pinned/verify_grant_receipt
+++ observed/verify_grant_receipt
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Verify a Forestrie grant receipt against the committed grant (Forestrie-Grant COSE Sign1, or raw grant payload CBOR plus an entry id), at a trust root you choose. Mirrors `forestrie verify-grant`. This is the tool that answers the append-authority question: the leaf IS the grant.",
+   "description": "Verify a Forestrie grant receipt against the committed grant (Forestrie-Grant COSE Sign1, or raw grant payload CBOR plus an entry id), at a trust root you choose. Mirrors `forestrie verify-grant`. This is the tool that answers the append-authority question: the leaf IS the grant. KS256 contract roots take an optional ks256Attestation (fetched elsewhere; this tool never calls the chain).",
    "execution": {
      "taskSupport": "forbidden"
    },
+       "ks256Attestation": {
+         "anyOf": [
+           {
+             "properties": {
+               "b64": {
+                 "description": "standard base64",
+                 "minLength": 1,
+                 "type": "string"
+               }
+             },
+             "required": [
+               "b64"
+             ],
+             "type": "object"
+           },
+           {
+             "properties": {
+               "base64": {
+                 "description": "standard base64 (alias of b64)",
+                 "minLength": 1,
+                 "type": "string"
+               }
+             },
+             "required": [
+               "base64"
+             ],
+             "type": "object"
+           },
+           {
+             "properties": {
+               "path": {
+                 "description": "filesystem path, read by the stdio adapter",
+                 "minLength": 1,
+                 "type": "string"
+               }
+             },
+             "required": [
+               "path"
+             ],
+             "type": "object"
+           }
+         ],
+         "description": "ERC-1271 attestation artifact (encodeKs256Attestation CBOR) for a KS256 CONTRACT root. Fetched elsewhere — this server never touches the network: use mcp-resolve's `fetch_ks256_attestation` tool or forestrie-cli's `fetch-ks256-attestation`. With it a contract-rooted delegation verifies as valid under the contract's signers at the attested block. Usable with the genesis, known-log-key and checkpoint-chain roots (checkpoint-chain also needs trust.genesis for the forest chain id; one attestation binds one certificate, so links signed under a different certificate still fail). Not with known-accumulator. Trust: the attestation is unsigned and only as good as whoever fetched it; accept one only from a party you would trust to read the chain for you — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
+       },
        "receipt": {
          "anyOf": [
            {
-             "description": "Trust a log owner key you obtained out of band. Same questions as genesis; the key-to-log binding is asserted, not proven.",
+             "description": "Trust a log owner key you obtained out of band: a 64-byte P-256 key (keyXy) or a 20-byte KS256 address (ks256Address). Same questions as genesis; the key-to-log binding is ASSERTED by you, not proven — an address in particular proves nothing about which log it owns. A contract (Safe) address needs ks256Attestation on the tool call to verify offline.",
              "properties": {
+               "forestGenesis": {
+                 "anyOf": [
+                   {
+                     "properties": {
+                       "b64": {
+                         "description": "standard base64",
+                         "minLength": 1,
+                         "type": "string"
+                       }
+                     },
+                     "required": [
+                       "b64"
+                     ],
+                     "type": "object"
+                   },
+                   {
+                     "properties": {
+                       "base64": {
+                         "description": "standard base64 (alias of b64)",
+                         "minLength": 1,
+                         "type": "string"
+                       }
+                     },
+                     "required": [
+                       "base64"
+                     ],
+                     "type": "object"
+                   },
+                   {
+                     "properties": {
+                       "path": {
+                         "description": "filesystem path, read by the stdio adapter",
+                         "minLength": 1,
+                         "type": "string"
+                       }
+                     },
+                     "required": [
+                       "path"
+                     ],
+                     "type": "object"
+                   }
+                 ],
+                 "description": "the forest's genesis document, same encoding as the genesis root's `genesis` field. Read ONLY for the chain id a ks256Attestation must match; it supplies no trust keys — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
+               },
                "keyXy": {
                  "anyOf": [
                    {
-                 "description": "raw 64-byte P-256 x||y — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
+                 "description": "raw 64-byte P-256 x||y (ES256 owner key) — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
                },
+               "ks256Address": {
+                 "description": "KS256 (secp256k1/keccak) owner address, 0x + 40 hex: an EOA or a contract (Safe). Give exactly one of keyXy or ks256Address.",
+                 "pattern": "^0x[0-9a-fA-F]{40}$",
+                 "type": "string"
+               },
                "root": {
                  "const": "known-log-key",
                  "type": "string"
-               "root",
-               "keyXy"
+               "root"
              ],
              "type": "object"
            },
-             "description": "Fold a retained checkpoint chain and match any authenticated link. Answers split-view. Needs genesis or keyXy to root the first link.",
+             "description": "Fold a retained checkpoint chain and match any authenticated link. Answers split-view. Needs genesis or keyXy to root the first link. Each link's delegation certificate limits are enforced: a link signed beyond the certificate's mmrEnd fails delegation_out_of_range, and a link covering the receipt's leaf signed under a certificate that had expired when the leaf was sequenced fails delegation_expired (never wall-clock). A KS256 contract (Safe) genesis root takes ks256Attestation on the tool call.",
              "properties": {
                "checkpoints": {
                  "description": "retained .sth objects in ascending massif order, each {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}",
+       "ks256Attestation": {
+         "additionalProperties": false,
+         "description": "present only when a supplied ERC-1271 attestation was needed for the run to pass: a contract root is valid under its signers at THIS block only",
+         "properties": {
+           "address": {
+             "type": "string"
+           },
+           "blockHash": {
+             "type": "string"
+           },
+           "blockNumber": {
+             "type": "string"
+           },
+           "chainId": {
+             "type": "string"
+           }
+         },
+         "required": [
+           "chainId",
+           "blockNumber",
+           "blockHash",
+           "address"
+         ],
+         "type": "object"
+       },
        "ok": {
          "type": "boolean"
        },
--- pinned/verify_receipt
+++ observed/verify_receipt
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Verify a Forestrie receipt against the EXACT registered payload bytes and an entry id, at a trust root you choose. Mirrors `forestrie verify`. Offline: no network, no key, no account. Returns both the mechanical stages and the four trust questions.",
+   "description": "Verify a Forestrie receipt against the EXACT registered payload bytes and an entry id, at a trust root you choose. Mirrors `forestrie verify`. Offline: no network, no key, no account. Returns both the mechanical stages and the four trust questions. KS256 contract roots take an optional ks256Attestation (fetched elsewhere; this tool never calls the chain).",
    "execution": {
      "taskSupport": "forbidden"
    },
+       "ks256Attestation": {
+         "anyOf": [
+           {
+             "properties": {
+               "b64": {
+                 "description": "standard base64",
+                 "minLength": 1,
+                 "type": "string"
+               }
+             },
+             "required": [
+               "b64"
+             ],
+             "type": "object"
+           },
+           {
+             "properties": {
+               "base64": {
+                 "description": "standard base64 (alias of b64)",
+                 "minLength": 1,
+                 "type": "string"
+               }
+             },
+             "required": [
+               "base64"
+             ],
+             "type": "object"
+           },
+           {
+             "properties": {
+               "path": {
+                 "description": "filesystem path, read by the stdio adapter",
+                 "minLength": 1,
+                 "type": "string"
+               }
+             },
+             "required": [
+               "path"
+             ],
+             "type": "object"
+           }
+         ],
+         "description": "ERC-1271 attestation artifact (encodeKs256Attestation CBOR) for a KS256 CONTRACT root. Fetched elsewhere — this server never touches the network: use mcp-resolve's `fetch_ks256_attestation` tool or forestrie-cli's `fetch-ks256-attestation`. With it a contract-rooted delegation verifies as valid under the contract's signers at the attested block. Usable with the genesis, known-log-key and checkpoint-chain roots (checkpoint-chain also needs trust.genesis for the forest chain id; one attestation binds one certificate, so links signed under a different certificate still fail). Not with known-accumulator. Trust: the attestation is unsigned and only as good as whoever fetched it; accept one only from a party you would trust to read the chain for you — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
+       },
        "payload": {
          "anyOf": [
            {
-             "description": "Trust a log owner key you obtained out of band. Same questions as genesis; the key-to-log binding is asserted, not proven.",
+             "description": "Trust a log owner key you obtained out of band: a 64-byte P-256 key (keyXy) or a 20-byte KS256 address (ks256Address). Same questions as genesis; the key-to-log binding is ASSERTED by you, not proven — an address in particular proves nothing about which log it owns. A contract (Safe) address needs ks256Attestation on the tool call to verify offline.",
              "properties": {
+               "forestGenesis": {
+                 "anyOf": [
+                   {
+                     "properties": {
+                       "b64": {
+                         "description": "standard base64",
+                         "minLength": 1,
+                         "type": "string"
+                       }
+                     },
+                     "required": [
+                       "b64"
+                     ],
+                     "type": "object"
+                   },
+                   {
+                     "properties": {
+                       "base64": {
+                         "description": "standard base64 (alias of b64)",
+                         "minLength": 1,
+                         "type": "string"
+                       }
+                     },
+                     "required": [
+                       "base64"
+                     ],
+                     "type": "object"
+                   },
+                   {
+                     "properties": {
+                       "path": {
+                         "description": "filesystem path, read by the stdio adapter",
+                         "minLength": 1,
+                         "type": "string"
+                       }
+                     },
+                     "required": [
+                       "path"
+                     ],
+                     "type": "object"
+                   }
+                 ],
+                 "description": "the forest's genesis document, same encoding as the genesis root's `genesis` field. Read ONLY for the chain id a ks256Attestation must match; it supplies no trust keys — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
+               },
                "keyXy": {
                  "anyOf": [
                    {
-                 "description": "raw 64-byte P-256 x||y — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
+                 "description": "raw 64-byte P-256 x||y (ES256 owner key) — {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}"
                },
+               "ks256Address": {
+                 "description": "KS256 (secp256k1/keccak) owner address, 0x + 40 hex: an EOA or a contract (Safe). Give exactly one of keyXy or ks256Address.",
+                 "pattern": "^0x[0-9a-fA-F]{40}$",
+                 "type": "string"
+               },
                "root": {
                  "const": "known-log-key",
                  "type": "string"
-               "root",
-               "keyXy"
+               "root"
              ],
              "type": "object"
            },
-             "description": "Fold a retained checkpoint chain and match any authenticated link. Answers split-view. Needs genesis or keyXy to root the first link.",
+             "description": "Fold a retained checkpoint chain and match any authenticated link. Answers split-view. Needs genesis or keyXy to root the first link. Each link's delegation certificate limits are enforced: a link signed beyond the certificate's mmrEnd fails delegation_out_of_range, and a link covering the receipt's leaf signed under a certificate that had expired when the leaf was sequenced fails delegation_expired (never wall-clock). A KS256 contract (Safe) genesis root takes ks256Attestation on the tool call.",
              "properties": {
                "checkpoints": {
                  "description": "retained .sth objects in ascending massif order, each {b64: <standard base64>} (base64 is accepted as an alias), or {path: <a file the local server reads>}",
+       "ks256Attestation": {
+         "additionalProperties": false,
+         "description": "present only when a supplied ERC-1271 attestation was needed for the run to pass: a contract root is valid under its signers at THIS block only",
+         "properties": {
+           "address": {
+             "type": "string"
+           },
+           "blockHash": {
+             "type": "string"
+           },
+           "blockNumber": {
+             "type": "string"
+           },
+           "chainId": {
+             "type": "string"
+           }
+         },
+         "required": [
+           "chainId",
+           "blockNumber",
+           "blockHash",
+           "address"
+         ],
+         "type": "object"
+       },
        "ok": {
          "type": "boolean"
        },
--- pinned/verify_self
+++ observed/verify_self
  {
    "annotations": {
      "destructiveHint": false,
+       "ks256Attestation": {
+         "additionalProperties": false,
+         "description": "present only when a supplied ERC-1271 attestation was needed for the run to pass: a contract root is valid under its signers at THIS block only",
+         "properties": {
+           "address": {
+             "type": "string"
+           },
+           "blockHash": {
+             "type": "string"
+           },
+           "blockNumber": {
+             "type": "string"
+           },
+           "chainId": {
+             "type": "string"
+           }
+         },
+         "required": [
+           "chainId",
+           "blockNumber",
+           "blockHash",
+           "address"
+         ],
+         "type": "object"
+       },
        "ok": {
          "type": "boolean"
        },

Current tools

Show all 4 tool fingerprints
decode_receipt
9972d06bfd40bc75
verify_grant_receipt
b3482b831325dcaf
verify_receipt
ad730909b7a8f602
verify_self
66dadd5071459135

Watch this server yourself

If you run this server, put the proxy in front of it. It pins these exact fingerprints on first connect and stops the session if they move.

npx -y mcp-pin@0.2.3 -- <your @forestrie/mcp-verify command>

Or subscribe to this page's RSS feed to be told when it changes.

Badge

mcp-pin status badge for @forestrie/mcp-verify

The badge states one fact about time and nothing else. It never claims a server is safe.

[![mcp-pin](https://mcp-pin.gautamkhosla.com/badge/2561a5aefb698049.svg)](https://mcp-pin.gautamkhosla.com/servers/2561a5aefb698049.html)