Skip to main content
Glama

@forestrie/mcp-register

An MCP server that signs a statement and registers it on a Forestrie transparency log under a Forestrie-Grant, then waits for the seal and verifies the receipt. It can also buy the grant: as the requester, it signs a child grant under your own authority log and registers it with canopy, paying canopy's x402 charge within hard caps. It is the write path of the Forestrie MCP trio:

The statement is signed with a log key the server holds. The default backend for that key is an ES256 key file the server creates. Child grants are signed with a separate authority key, held the same way. The model never handles signature bytes: you pass the payload and the server signs it. No tool takes a signature or a key as input.

Paying is optional, and the payer is yours. The server never creates a payer key and holds no funds of its own: you choose how payment happens (see Choosing a payer). Whichever you choose, a payer key never crosses the MCP boundary, and the spending caps are configuration, not tool arguments. With no payer configured, the server spends nothing: it returns canopy's payment requirements, and you pay from your own x402 wallet (relay mode).

Status

Version 0.1.1 on npm, published with provenance from publish.yml. 0.1.0 was published by hand and has no provenance attestation; use 0.1.1 or later.

Related MCP server: @sequesign/mcp

Tools

Tool

What it does

get_log_key

Returns the log key's public half (x‖y). Your grant must name this key. The key is created on first use.

delegate_sealing

Authorises the operator's sealer for your data log. Runs canopy's prepare with the same grant first if the coordinator does not know the log's public root yet. Once per log.

register_statement

Signs a payload (inline base64 or a file path, up to 4 MiB, with an explicit content type) and registers it.

check_registration

Does one status check: pending, awaiting_seal or sealed. Once sealed, it saves the receipt.

verify_registration

Verifies the receipt over the statement with mcp-verify's verifier and returns its four answers unaltered.

issue_grant

As the requester, signs a child data-log grant with the authority key, naming a log key (by default this server's), sized with maxHeight. Sends nothing.

register_grant

Registers the child grant with canopy, pays its 402 within the caps or relays the requirements, and follows it to its receipt. Resumable by child log id; never pays twice.

The prompts walk an agent through the work:

  • register covers the key and the grant, sealing, registering, waiting, verifying and keeping the receipt.

  • audit explains which trust questions a receipt answers under which trust root.

  • issue-and-pay covers buying a grant as the requester: sizing it, issuing it, paying within the caps or relaying the payment, and handing the completed grant to the performer.

Configuration

Every value can be overridden per call.

Variable

Meaning

FORESTRIE_BASE_URL

the canopy SCRAPI base URL

FORESTRIE_ROOT_LOG_ID

the forest's root log id (R in /register/{R}/entries)

FORESTRIE_GRANT

your Forestrie-Grant, as base64 or a file path

FORESTRIE_COORDINATOR_URL

the delegation coordinator, for delegate_sealing

FORESTRIE_KNOWN_SEALER_KEY

the registrar's voucher key, base64 x‖y, for delegate_sealing

FORESTRIE_AUTHORITY_GRANT

your authority log's grant, for issue_grant and register_grant

MCP_REGISTER_HOME

key files, grants, registrations and the spend ledger, default ~/.config/forestrie/mcp-register

MCP_REGISTER_KEY_FILE

the log key file, default $MCP_REGISTER_HOME/log-key.jwk

MCP_REGISTER_AUTHORITY_KEY_FILE

the authority key file, default $MCP_REGISTER_HOME/authority-key.jwk

Choosing a payer

Whoever wants the work done pays for it: the requester, paying canopy directly. The server supports three ways to do that and prefers none of them.

Setup

What you configure

Who holds the key

Relay

nothing

your own x402 wallet: register_grant returns canopy's payment requirements and resumes on a call that carries your X-PAYMENT

Key file

MCP_REGISTER_PAYER_KEY_FILE and the caps below

a file on the machine that runs the server

Your own backend

createServer({ payer }) from @forestrie/mcp-register/server, when you embed the server

whatever your PayerBackend uses: a hosted wallet, a KMS, a remote signer

A backend of your own must sign an EIP-3009 authorisation with the nonce it is given. That nonce is what stops one grant being paid for twice (see Payment settings).

Example: a dedicated key file

This is one way to set up the key-file payer, not the way. Any EVM account works; what matters is that it pays for this and nothing else.

  1. Create a private key in a file only you can read. Any wallet tool that exports a raw private key will do. With no extra tools:

    ( umask 077; printf '0x%s\n' "$(openssl rand -hex 32)" > payer.key )

    The server accepts one line, 0x and 64 hex digits, in a regular file (not a symlink) that no other user can read.

  2. Find the account's address with a tool you already trust to derive one from a private key, or by importing the key into a wallet you use.

  3. Fund the address with the asset canopy charges in. On the default network, Base Sepolia, that is testnet USDC, from Circle's faucet. The account needs no ETH: it only signs an authorisation, and the x402 facilitator submits the transfer and pays its gas.

  4. Point the server at the file and set the caps:

    MCP_REGISTER_PAYER_KEY_FILE=/path/to/payer.key
    MCP_REGISTER_PAY_MAX_PER_CALL=100000   # $0.10
    MCP_REGISTER_PAY_MAX_PER_DAY=1000000   # $1.00

Keep one account per requester. Payments settle on chain, so anyone can link a payer address to the grants it paid for. To rotate the key, create a new one, move what is left to it, and point MCP_REGISTER_PAYER_KEY_FILE at the new file.

Payment settings

These are read from the environment only. No tool argument can set or raise them.

Variable

Meaning

MCP_REGISTER_PAYER_KEY_FILE

an EVM private key (0x + 64 hex, mode 600) that pays; unset means relay mode

MCP_REGISTER_PAY_MAX_PER_CALL

the most one payment may be, in the asset's atomic units (required with a payer)

MCP_REGISTER_PAY_MAX_PER_DAY

the most all payments in one UTC day may total (required with a payer)

MCP_REGISTER_PAY_NETWORK

the one network it pays on, default eip155:84532 (Base Sepolia)

MCP_REGISTER_PAY_ASSET

the one asset it pays in, default USDC on Base Sepolia

MCP_REGISTER_PAY_TO

optional: the only payee

MCP_REGISTER_PAY_ALLOW_MAINNET

1 to pay on a network that is not a testnet; off by default

The server pays only the canopy named in FORESTRIE_BASE_URL, and only for the request it made. Every payment it signs for a grant uses a nonce derived from that grant, so the token contract can settle at most one of them: a retry or two overlapping calls never pay for one grant twice. Each signed payment is written to the spend ledger before it is sent and counts toward the daily cap whether or not it settles. The daily cap is approximate when calls overlap. USDC has 6 decimals, so 10000 is $0.01.

Where grants come from

Forestrie runs no grant issuer. Whoever owns the authority log above yours issues your grant, naming the key that get_log_key returns. Canopy sequences grants; it does not issue them.

That owner can be you. If the owner of the root above you creates an authority log for your authority key (get_log_key with which: "authority" returns it as a PEM for forestrie-cli's create-log --auth-log --signer-pem), issue_grant and register_grant let you issue and register your own child grants. If that authority log carries the child-payment-required flag, each registration is paid for over x402, straight to the transparency operator.

Install

npx -y @forestrie/mcp-register

Layers

  • src/core is browser-safe and works on bytes only.

  • src/net is the only place fetch is called, always through an injected fetchImpl.

  • src/node holds the MCP SDK, stdio, the filesystem, the key files and the payer.

See AGENTS.md.

Licence

MIT.

Available Tools

7 tools
check_registrationCheck a registrationA
Idempotent

One status check for a registration, by its content hash: pending (not yet sequenced; retry after the given seconds), awaiting_seal (sequenced, entry id known, receipt not yet sealed — sealing takes minutes, and never happens until delegate_sealing has run for the log), or sealed (the receipt is saved and its path returned). Any other answer from canopy is reported as a problem with its reason. canopy answers a statement it never received exactly like a pending one, so after ten minutes of pending this says so. Does not sleep; pace the retries yourself.

NameRequiredDescriptionDefault
contentHashYesthe content hash register_statement returned (64 lowercase hex)

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations being present, the description adds substantial behavior the annotations cannot convey: the three status states and their timing (sealing takes minutes), the prerequisite dependency on delegate_sealing, the quirk that a never-received statement is answered like a pending one, the ten-minute escalation, and the explicit non-sleeping retry contract. The only unreconciled point is that readOnlyHint=false is not explained for what is nominally a status check.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded, followed by the state definitions and then the caveats, and each sentence carries real information (state semantics, sealing timing, the never-received quirk, retry pacing). It is dense as a single paragraph, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the full return-value burden and does so: it enumerates every expected answer, describes what each means, and covers the unexpected-answer path and the false-pending staleness case. Combined with the retry-pacing guidance, an agent has everything needed to call and interpret it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single parameter already documents both its origin ('the content hash register_statement returned') and its format (64 lowercase hex). The description's 'by its content hash' restates that provenance without adding syntax or format detail, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('One status check for a registration, by its content hash') and then defines the exact result space (pending / awaiting_seal / sealed / problem). This lets an agent distinguish it from siblings like register_statement and verify_registration without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear operating context: it is a single poll ('Does not sleep; pace the retries yourself'), it names the prerequisite that must run before sealing can occur ('never happens until delegate_sealing has run for the log'), and it sets a ten-minute escalation heuristic. It never names an alternative tool or an explicit when-not-to-use case, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delegate_sealingDelegate sealing for your logA

Authorise the operator's sealer to publish checkpoints for your data log, signed with the log key. Without it entries sequence but are never sealed. If the coordinator has not learned the log's public root, this calls canopy's prepare with the same grant first. Run once per log; the delegation lasts until the returned expiresAt. With as: "authority" it does the same for your authority log, signed with the authority key, so the child grants you register there get sealed.

NameRequiredDescriptionDefault
asNowhich key owns the log: "log" (default) for your data log, under the grant you register statements with; "authority" for your authority log, under its creation grant (FORESTRIE_AUTHORITY_GRANT), so the child grants register_grant sequences there get sealed
grantNothe Forestrie-Grant: base64 (standard or URL-safe) of the completed grant, or a path to a file holding it as raw bytes or base64 text; falls back to FORESTRIE_GRANT
baseUrlNothe canopy SCRAPI base URL; falls back to FORESTRIE_BASE_URL — never defaulted by the package itself
ttlSecondsNohow long the delegation lasts; defaults to the coordinator's suggestion
coordinatorUrlNothe delegation coordinator base URL; falls back to FORESTRIE_COORDINATOR_URL
knownSealerKeyNothe registrar's voucher key, base64 of 64 bytes x‖y, as the operator publishes it; falls back to FORESTRIE_KNOWN_SEALER_KEY

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly=false, openWorld=true, idempotent=false, destructive=false, so the safety profile is covered. The description adds real behavioral value beyond that: the conditional chained call to canopy's prepare when the coordinator hasn't learned the public root, the one-time-per-log nature, and that the delegation expires at the returned expiresAt. Auth/grant context is largely left to the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded, then consequences, then the chained prepare step, then the authority variant. Dense but every sentence carries information for a six-parameter tool. Slightly run-on phrasing but no wasted filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, the description covers the effect, the conditional prerequisite call, the lifetime of the result, and the key/variant distinction. Combined with 100% schema coverage, an agent has what it needs; minor gaps remain around failure modes and permission requirements.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters thoroughly, including the as enum and env-var fallbacks. The description restates the 'as: authority' semantics but adds no syntax or format detail beyond what the schema provides; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Authorise the operator's sealer to publish checkpoints for your data log, signed with the log key.' The scope and effect are unambiguous, and the authority variant is distinguished from the default data-log behavior. No sibling tool is named for contrast, so it stops just short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context: 'Without it entries sequence but are never sealed' explains why the tool is needed, and 'Run once per log' sets a usage constraint. It does not name alternatives or explicit when-not conditions relative to siblings like register_grant or issue_grant.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_log_keyGet the log keyA
Idempotent

Return the public half of one of this server's keys (ES256, 64 bytes x‖y, as hex, base64 and an SPKI PEM) and where it lives, creating it on first use. which: "log" (the default) is the key that owns your data log: a grant issuer names it in the grant's grantData, and a grant naming any other key cannot carry statements this server signs. which: "authority" is the requester's key that owns your authority log and signs the grants issue_grant makes. Never returns private key material.

NameRequiredDescriptionDefault
whichNowhich key: "log" (default), the key that owns your data log and signs statements; or "authority", the requester's key that owns an authority log and signs the child grants issue_grant makes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds real behavioral context beyond the annotations: creation on first use (which explains readOnlyHint=false), the idempotent nature of re-fetching, output formats (ES256, 64 bytes x‖y, hex/base64/SPKI PEM), and the security property "Never returns private key material." That is genuinely non-obvious disclosure, though it does not touch auth requirements or error modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and return shape before drilling into the variants, with no filler sentences. The prose is dense and slightly run-on with nested clauses, but every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single optional enum parameter with full schema coverage, present annotations, and no output schema, the description supplies everything needed: what is returned, in what encodings, the side effect, and the security guarantee. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns above baseline by explaining downstream implications of the choice (a grant naming another key cannot carry statements this server signs; "authority" signs grants that issue_grant makes). This adds meaning the enum label alone does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb and resource ("Return the public half of one of this server's keys") and immediately disambiguates the two variants ("log" vs "authority") with concrete operational meaning. An agent can distinguish this key-fetch tool from siblings like issue_grant or register_statement without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains clearly what each "which" value selects and notes the default, giving solid context for choice. It stops short of explicit when-to-use/when-not framing (e.g., prerequisites relative to issuing or registering grants), but the variant guidance is unusually rich.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

issue_grantIssue a child grant as the requesterA

As the requester, sign a child grant with this server's authority key: a data-log creation grant under your authority log (named by your authority grant, FORESTRIE_AUTHORITY_GRANT), naming the performer's log key (by default this server's own) and sized with maxHeight, the batch ceiling canopy prices it by. Saves the grant under a fresh child log id; nothing is sent. Call register_grant next.

NameRequiredDescriptionDefault
logIdNothe child data log to create; a fresh random UUID by default
granteeNobase64 of the 64-byte x‖y the grant names (the performer's log key); defaults to this server's own log key, for a self-purchase
maxHeightYesthe grant's batch ceiling. canopy prices a payment-gated child grant as its unit price × maxHeight, so size it to the work it is for
parentGrantNoyour authority grant: the completed grant that created your authority log and names this server's authority key, as base64 or a file path; falls back to FORESTRIE_AUTHORITY_GRANT

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare a non-readonly, non-destructive, non-idempotent local mutation; the description adds real value beyond them by disclosing that the grant is 'saved under a fresh child log id' and that 'nothing is sent', which is critical for understanding this is a local signing step rather than a network publish.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The action is front-loaded, but the opening sentence is a dense run-on packing parentheticals ('sized with maxHeight, the batch ceiling canopy prices it by') that is hard to parse. The closing next-step sentence is efficient, offsetting some of the bloat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a cryptographic grant-issuance mutation with no output schema, the description explains persistence and the follow-up step but never says what the call returns (e.g., the fresh child log id or the signed grant), which an agent needs to proceed to register_grant.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters including defaults and the UUID pattern. The description restates grantee default ('this server's own') and the pricing role of maxHeight, adding only marginal meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: it signs a child data-log creation grant using the server's authority key. It also distinguishes the step from the sibling register_grant by declaring 'Call register_grant next', so an agent can tell issuing apart from registering.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Guidance is largely implied through workflow sequencing: 'Call register_grant next' tells the agent the ordering but never states when this tool is the right choice versus siblings like delegate_sealing or register_statement, and gives no when-not conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

register_grantRegister a child grant, paying if canopy asksA

Register a child grant with canopy (POST /register/{R}/grants, your authority grant as the parent) and follow it to its receipt; call it again with the same logId to resume until it reports complete. If canopy answers 402 and a payer is configured, it pays within the server's hard caps (per call, per UTC day, one network and asset, testnet only by default) and reports any cap that refuses. With no payer it returns the payment requirements: pay them from your own x402 wallet and call again with payment set to the X-PAYMENT value. Every payment for a grant carries a nonce derived from that grant, so retries and overlapping calls can never pay for it twice. When complete it returns the completed grant for delegate_sealing and register_statement.

NameRequiredDescriptionDefault
grantNoa child grant signed elsewhere (base64 or a file path), instead of logId
logIdNothe child log id issue_grant returned: register_grant resumes that grant from wherever the last call reached
baseUrlNothe canopy SCRAPI base URL; falls back to FORESTRIE_BASE_URL — never defaulted by the package itself
paymentNorelay mode: the X-PAYMENT header value your own x402 wallet produced for the payment requirements register_grant returned
rootLogIdNothe forest's root log id (R in /register/{R}/grants); falls back to FORESTRIE_ROOT_LOG_ID
parentGrantNoyour authority grant: the completed grant that created your authority log and names this server's authority key, as base64 or a file path; falls back to FORESTRIE_AUTHORITY_GRANT

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds substantial behavioral context beyond the annotations: it explains the 402 payment flow, payer hard caps, testnet-by-default behavior, no-payer requirement response, relay payment via X-PAYMENT, and nonce-derived anti-double-pay protection. Annotations already disclose open-world and non-idempotent behavior, and the description enriches that with concrete operational details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense paragraph, but it is front-loaded with the primary action and then follows the important payment/resume branches. It is long for a tool description, yet the complexity of the registration and payment lifecycle justifies most of the detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex, multi-call, payment-aware registration tool with no output schema, the description covers the lifecycle, resume behavior, payment paths, caps, anti-double-pay guarantees, and handoff to delegate_sealing/register_statement. An agent has enough information to call and retry it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters well. The description adds some workflow meaning for logId and payment, but does not meaningfully extend baseUrl, rootLogId, or parentGrant beyond what the schema provides, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: register a child grant with canopy via POST /register/{R}/grants, using the authority grant as parent, and follow it to receipt. It also distinguishes the workflow from sibling tools by naming delegate_sealing and register_statement as downstream consumers of the completed grant.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage instructions for the multi-step lifecycle: call again with the same logId to resume, handle 402 with or without a configured payer, and use payment mode when paying from your own x402 wallet. It does not explicitly say when not to use this tool or compare it directly to issue_grant, but the context is actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

register_statementSign and register a statementA

Sign a payload with the log key and register it under your Forestrie-Grant. Takes the payload bytes (inline base64 or a file path, up to canopy's 4 MiB statement limit) and its content type. The signed statement is saved before it is sent, so the returned content hash always names it, even if the request fails. A payload path may not point at the log key or inside this server's home. Registration is accepted, not yet sequenced: call check_registration next.

NameRequiredDescriptionDefault
grantNothe Forestrie-Grant: base64 (standard or URL-safe) of the completed grant, or a path to a file holding it as raw bytes or base64 text; falls back to FORESTRIE_GRANT
issuerNoCWT iss; defaults to the hex of the key id
baseUrlNothe canopy SCRAPI base URL; falls back to FORESTRIE_BASE_URL — never defaulted by the package itself
payloadYesthe payload to sign and register, up to 4 MiB — { b64 } | { base64 } | { path }
subjectNoCWT sub; defaults to sha-256:<hex of the payload>
rootLogIdNothe forest's root log id (R in /register/{R}/entries); falls back to FORESTRIE_ROOT_LOG_ID
contentTypeYesthe payload's media type, e.g. application/json

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover safety (readOnly=false, idempotent=false, openWorld=true), and the description adds real beyond-schema behavior: the 4 MiB canopy limit, that the signed statement is persisted before sending so the content hash remains valid on failure, and that a payload path may not target the log key or the server home. It stops short of stating auth/permission requirements for the grant, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four dense sentences with the core action front-loaded, followed by input limits, side-effect semantics, and the next step. Every sentence carries information an agent would otherwise have to guess.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description explains the return value (content hash that always names the saved statement), the size limit, the persistence/async semantics, and the follow-up call — everything needed to invoke and act on the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description adds one genuinely non-schema constraint on the payload parameter (a path may not point at the log key or inside the server's home) and notes the 4 MiB ceiling. The remaining five parameters (grant, issuer, baseUrl, subject, rootLogId) get no description-level clarification.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource pair ("Sign a payload with the log key and register it") and names the scoping credential (your Forestrie-Grant), which separates it from siblings like issue_grant or register_grant. An agent can identify the operation without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit workflow handoff: "Registration is accepted, not yet sequenced: call check_registration next." That routes the agent correctly post-call, but it never states when to prefer this over verify_registration, delegate_sealing, or other siblings, so it is clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_registrationVerify a registration's receiptA
Read-onlyIdempotent

Verify a sealed registration's receipt over the statement you registered, with @forestrie/mcp-verify's verifier, and return its four-question answers unaltered. By default the trust root is this server's own log key, the root of your data log; verifying never creates a key. Pass a known accumulator (from @forestrie/mcp-resolve's fetch_accumulator) to use a root that can also answer split-view.

NameRequiredDescriptionDefault
contentHashYesthe content hash register_statement returned (64 lowercase hex)
knownAccumulatorNooptional: a known accumulator (e.g. from @forestrie/mcp-resolve's fetch_accumulator) to verify against instead of this server's own log key — { b64 } | { base64 } | { path }

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds context beyond the annotations: it states verifying never creates a key (a meaningful side-effect clarification given the sibling key/register tools), and explains the default trust root and the split-view capability tradeoff. Annotations already cover readOnly/idempotent/destructive, so this is supplementary value rather than essential disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences with no filler, and the default case is stated before the optional override. Package names and 'four-question answers' jargon cost a little readability but nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must carry the return-value burden; 'return its four-question answers unaltered' hints at a structured verification result but never defines what those four answers are. For a verification tool whose output shape matters, that is a notable gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3, but the description adds real meaning the schema cannot: why knownAccumulator exists, where to get it, and what capability it unlocks (split-view answers) versus the server-key default. contentHash is not elaborated but is well documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (verify) and resource (a sealed registration's receipt over a registered statement), and names the verifier used. It does not contrast itself with the sibling check_registration, so the agent must infer the distinction, but the core action is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives conditional guidance: default is the server's own log key, and pass a knownAccumulator (sourced from fetch_accumulator) only when you need a root that can also answer split-view. It lacks explicit when-not rules or a comparison against check_registration, but the parameter choice is well motivated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 7 tool updatesv0.1.1
    • First observedcheck_registration
    • First observeddelegate_sealing
    • First observedget_log_key
    • First observedissue_grant
    • First observedregister_grant
    • First observedregister_statement
    • First observedverify_registration

TDQS

A4.1/5.0

Scored across 7 tools

Disambiguation4/5

Most tools have clearly distinct purposes (key retrieval, signing, delegation, grant issuance). However, check_registration and verify_registration both operate on a registration's validity/status, and register_statement vs register_grant both 'register' an object, so a few pairs require careful reading of the descriptions to distinguish.

Naming Consistency5/5

All seven tools follow a consistent verb_noun snake_case convention (check_registration, register_statement, issue_grant, register_grant, etc.). No camelCase or stylistic mixing.

Tool Count5/5

Seven tools is well-scoped for a registration/grant lifecycle server, with each tool earning its place across key, statement, grant, and sealing operations. No padding or redundancy.

Completeness4/5

The core lifecycle (sign/register -> check -> verify, plus grant issue/register and sealing delegation) is well covered with no obvious dead ends. Minor gaps exist: no listing of pending registrations or grants, and no delete/revoke operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides cryptographic governance receipts for AI agents, enabling pre-execution evaluation and signed verdicts (EXECUTE/BLOCK/REVIEW/SHADOW) with offline-verifiable audit trails.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to create cryptographically verifiable receipts of their delegated work, with capabilities for multi-party approval and offline verification.
    11
    29 npm
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Issue and verify signed receipts for agent actions, enabling durable, independently checkable proof of policy decisions. Supports offline verification via get_keyset and verify_receipt tools without an account.
    0
    Inno Setup