Skip to main content
Glama

Tersign is the evidence layer for the agent economy — a neutral, counter-signed, hash-chained ledger for agent commerce. Sellers sign EIP-712 receipts; Tersign chains them per seller and counter-signs every entry. When the dispute comes, the transcript is already sealed.

Venues rotate. The transcript endures.


Verify a Real Entry — Right Now

No account. No API key. This is the genesis receipt, seq 1 on the production chain:

npx tersign verify 0xe5874f1ffe87f0a6dd9eb157730f67b86ee4538b125fe30fcc4e165213dd3fc4
ledger: counter-signed OK (seller tersign-first, seq 1 …) VALID

npx tersign verify <receipt.json | 0xdigest> [--ledger url] recovers the EIP-712 signature locally. A bare digest is then checked against the Tersign ledger unless --ledger names another; a receipt file verifies offline and touches no chain at all. The ledger consulted is always printed. Prefer raw HTTP? The same proof, no CLI:

curl https://tersign.ai/v1/receipts/0xe5874f1ffe87f0a6dd9eb157730f67b86ee4538b125fe30fcc4e165213dd3fc4/verify

Related MCP server: touchstone-mcp

One-Call Disclosure Evidence

Counter-signed evidence that your agent presented a disclosure — one command, no account:

npx tersign disclose "You are chatting with an AI assistant." --medium chat --agent-id my-agent

The text is digested locally (only the digest travels — data-minimization by construction). Your key signs the record; the ledger counter-signs it into a per-signer hash chain whose head is submitted for Bitcoin anchoring on a six-hourly cron. First call self-provisions a free signer-keyed account bound set-once to your key (key resolution: TERSIGN_SELLER_KEY env → macOS keychain tersign-signer~/.tersign/signer.key, created on first use). Free tier is quota- and rate-limited — limits. What this is: independently verifiable evidence the disclosure was attested at that time. What it is not: a compliance certification.

Chain of Custody

Every entry takes the same path: the seller signs the receipt (EIP-712, x402 offer-receipt extension) → Tersign computes the keccak256 canonical digest → the digest joins that seller's hash chain, each seq n bound to seq n−1 → the neutral ledger counter-signs (secp256k1) → anyone verifies, and any venue gets a serialized envelope.

Since 2026-08-28 each anchor stamps a chain commitment — an accumulator over every counter-signed link — so one anchored digest covers the whole prefix; rows anchored earlier bind the head record only and say so (subjectSchema).

graph LR
    A["agent transaction<br/>x402"] --> B["seller-signed receipt<br/>EIP-712"]
    B --> C["canonical digest<br/>keccak256"]
    C --> D["per-seller hash chain<br/>seq n binds seq n−1"]
    D --> E["neutral counter-signature<br/>secp256k1 ledger"]
    E --> F["verifiable by anyone<br/>venue-ready envelope"]

Diagram renders on GitHub. On npm, the paragraph above IS the diagram.

Refunds chain back to the original receipt via refundOf. Disputes attach to the digest with objective reason codes. Party statements are structurally segregated behind an UNVERIFIED marker — the evidence stays prompt-injection-hardened.

Enter the Record

npm i tersign

withAssure() wraps your x402 fetch handler so every paid call issues a signed, chained receipt. The full register:

Capability

In the record

Receipts

Seller-signed EIP-712 (x402 offer-receipt extension), keccak256 canonical digests

withAssure()

x402 fetch-handler adapter — a receipt per paid call

Compliance exports

EU Art-226b minimal tier · EN 16931 full tier · HK IRO s.51C retention

Action records

ActionRecordV1 — GDPR-minimized; captures the content of an Art-50 disclosure so the disclosure itself is independently attested, not self-reported

Refunds

Chained to the original receipt via refundOf

Disputes v0

Objective reason codes, evidence submission, adjudication

Venue envelopes

Internet Court (5,000-char slot) · Kleros ERC-1497 · UMA · generic

Evidence packs

format=art50 · format=safr (beta)

Idempotency

In-memory + Cloudflare D1 stores

tersign intercept

Audit capture at the MCP boundary — a signed, digest-only action record per tool call (experimental)

Capture at the MCP Boundary — tersign intercept

An agent's tool calls are usually recorded, if at all, by the party running the agent. Put a recording clamp on the wire instead:

npx tersign intercept -- npx your-mcp-server

The proxy is a pure observer: bytes reach the server and the client exactly as sent, in order, unmodified. Every tools/call it sees becomes an ActionRecordV1 signed by your key and counter-signed into a hash chain — digests only, so the record proves what happened without carrying arguments or results anywhere. Records go to a configured ledger, and fall back to a local ~/.tersign/intercepts-<date>.jsonl so evidence is never silently dropped.

Experimental, and deliberately unopinionated about where the protocol lands: it implements the observation semantics of the audit-mode validator described in MCP SEP-2624 (Draft) as a transport-level proxy today, and is structured to move onto the interceptor primitive if and when that stabilizes. It makes no conformance claim to that draft.

For Agents — the MCP Server

npx tersign starts the MCP server (stdio). Official registry entry: io.github.tersignhq/evidence (active).

{
  "mcpServers": {
    "tersign": {
      "command": "npx",
      "args": ["tersign"],
      "env": { "TERSIGN_SELLER_KEY": "0x<your-seller-key>" }
    }
  }
}

Toolsissue_receipt · verify_receipt · verify_compliance_record · record_disclosure · record_refund · open_dispute · submit_dispute_evidence · adjudicate_dispute · get_dispute

Env var

Required

Purpose

TERSIGN_SELLER_KEY

yes

0x-prefixed private key that signs your receipts and records

TERSIGN_LEDGER_URL

no

hosted ledger for counter-signing + chain checks

TERSIGN_LEDGER_API_KEY

no

your seller API key on that ledger

TERSIGN_LEDGER_SELLER_ID

no

your seller id on that ledger

TERSIGN_ISSUER_NAME

no

issuer name stamped on action records

TERSIGN_ISSUER_JURISDICTION

no

issuer jurisdiction stamped on action records

Cold to counter-signed in one session: call issue_receipt, then check the issued receipt's digest with npx tersign verify <digest> --ledger <url>.

The agent skill tersign-evidence ships at tersignhq/skills.

The Live Record

  • Ledger + dashboard — public verify page: https://tersign.ai/verify

  • Census — hash-chained observations across the live x402 seller catalog, probed autonomously; the numbers are served live, never quoted stale: https://prober.tersign.ai/v1/prober/stats

  • Conformance — RFC 8785 (JCS) canonical serialization, keccak256 digests, and the public two-sided vector suite (canonical bytes, number domain, content address, chain continuity, completeness, anchored existence, phase separation, offer binding, independence — every criterion carrying both an accepting and an adversarial vector): tersignhq/evidence-record-conformance. Reproduce the bytes and your implementation is conformant — in any language.

  • Standards — the compliance-fields extension — a typed compliance-record schema plus four evaluator-side disqualifications (independence, completeness/existence, economic-phase separation, and commitment scope — an independence claim reaches exactly as far as the record's own commitments), each executable as a two-sided conformance vector — is under review upstream (x402-foundation/x402#2853) and referenced in the x402 TSC's evidence-record charter agenda (tsc#4). The merged offer-receipt spec already carries post-session verification guidance — signer authorization evaluated as of issuedAt, with mutable-source rotation handled explicitly (#2811, merged); the completeness, independence, existence and phase disqualifications are the open extension's normative core.

Machine Surfaces

Full URLs, readable without auth. If you are an agent, start here.

Surface

Address

npm package

tersignhttps://www.npmjs.com/package/tersign

MCP registry

io.github.tersignhq/evidencenpx tersign needs no configuration; the first call self-provisions a signer-keyed account

ARD catalog (Agentic Resource Discovery)

https://tersign.ai/.well-known/ai-catalog.json

Verify API

GET https://tersign.ai/v1/receipts/{digest}/verify

Envelope API

GET https://tersign.ai/v1/receipts/{digest}/envelope?venue={internet-court|kleros|uma|generic}

Ledger stats

GET https://tersign.ai/v1/stats

Ledger signer

GET https://tersign.ai/v1/ledger

Bundle verifier, out-of-band

https://tersign.ai/verify/v1/verify_bundle.py · keccak.py · secp256k1.py · SHA256SUMS. A bundle ships its own checker; for evidence from an interested party fetch this copy and diff the two.

llms.txt

https://raw.githubusercontent.com/tersignhq/tersign-js/main/llms.txt

Conformance vectors (RFC 8785 + keccak256)

https://github.com/tersignhq/tersign-js/blob/main/test/fixtures/canonical-vectors.json

Sample action record + digests

https://github.com/tersignhq/tersign-js/blob/main/test/fixtures/compliance-record.json

Genesis verify

npx tersign verify 0xe5874f1ffe87f0a6dd9eb157730f67b86ee4538b125fe30fcc4e165213dd3fc4


Contributing — read this before opening a pull request

tersignhq/tersign-js is a publish snapshot, not the development repository. Each release overwrites src/, test/ and the packaged manifests wholesale from an upstream working tree, so a pull request opened here cannot be merged in any durable way — the next release would silently erase it. That is a property of the pipeline, not a judgement on the change.

Contributions are wanted; the mechanics just have to route around that:

  • Bugs, questions, spec disagreements — open an issue here. Issues are read, and they are the right surface for anything that does not need to touch this tree.

  • Code changes — open the issue first with the diff or a description. The change is applied upstream preserving your authorship, released, and the issue closed with a link to the version that carries your work. Credit follows commit authorship, not a merge badge.

  • Conformance disagreements — the two-sided vector suite at tersignhq/evidence-record-conformance takes pull requests normally, and is the better venue for "this criterion is wrong" or "here is the case it misses." External vectors have been merged there.

If a maintainer ever asks you to reopen work elsewhere because of this, that is why.


Available Tools

9 tools
adjudicate_disputeAdjudicate disputeA

Trigger deterministic adjudication of an open dispute. The v0 rulebook is public and the verdict is recomputable by anyone from the chain — no discretion, no model in the loop. Side effects: writes a verdict entry, and a refund verdict automatically creates the corresponding refund record. Adjudicating twice is not meaningful; the first verdict stands. Returns the verdict, the rationale naming the rule applied, and the ledger signature over both.

ParametersJSON Schema
NameRequiredDescriptionDefault
disputeDigestYes0x-prefixed digest of the open dispute to adjudicate, as returned by open_dispute

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description fully carries the behavioral disclosure burden. It explicitly lists side effects—writes a verdict, may create a refund record—and additional traits like deterministic outcome, public recomputability, first-verdict-wins semantics, and the ledger signature in the return value.

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?

Three dense sentences front-load the core action, then cover side effects and return values. Every sentence adds necessary information with no redundant or filler wording.

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?

Given one parameter, no output schema, and no annotations, the description is remarkably complete: it covers preconditions, side effects, idempotency, determinism, and return shape. An agent has enough context to invoke the tool correctly and anticipate consequences.

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% with a single well-documented parameter including format and provenance ('as returned by open_dispute'). The tool description doesn't add further parameter-level semantics, 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?

The description states a specific verb and resource: 'Trigger deterministic adjudication of an open dispute.' It also distinguishes the tool through deterministic rulebook language and 'no discretion, no model in the loop,' clearly separating it from related dispute workflow tools like open_dispute and get_dispute.

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?

The description gives clear context: it applies to an 'open dispute' and warns that 'adjudicating twice is not meaningful; the first verdict stands.' It does not explicitly name alternatives or when-not-to-use relative to sibling tools, but the precondition and idempotency warning provide solid usage guidance.

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

get_disputeGet dispute recordA

Fetch a dispute in full: its state, both sides' evidence references, the verdict and rationale once adjudicated, and the ledger signature over the record. Read-only — one network read, no key required, and safe to poll while a dispute is open.

ParametersJSON Schema
NameRequiredDescriptionDefault
disputeDigestYes0x-prefixed digest of the dispute to fetch, as returned by open_dispute

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations provided, the description carries the full behavioral disclosure burden and does so well. It explicitly states 'Read-only — one network read, no key required, and safe to poll while a dispute is open', giving agents clear expectations about side effects, authentication, cost, and polling safety.

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?

The description is two sentences with zero filler. The first sentence front-loads the purpose and return contents; the second delivers the behavioral caveats. Every sentence earns its place.

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 simple single-parameter fetch tool with no output schema, the description is complete: it explains what the response contains, that the call is read-only and cheap, and that polling is safe. No critical operational detail is missing.

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 parameter disputeDigest is already fully documented in the schema, including format and provenance ('as returned by open_dispute'). The tool description adds no additional parameter-level meaning, so the baseline of 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 ('Fetch') and resource ('a dispute in full'), and enumerates what is returned: state, both sides' evidence references, verdict and rationale, and ledger signature. It clearly distinguishes itself from the dispute-mutation siblings by emphasizing read-only access.

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?

The description gives clear context for when the tool is appropriate: it is a read-only fetch, requires no key, and is safe to poll while a dispute is open. It does not explicitly say 'use this instead of X', but the read-only framing makes the correct use case obvious relative to sibling tools like open_dispute and adjudicate_dispute.

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

issue_receiptIssue signed receiptA

Issue an x402 offer-receipt (EIP-712) plus a Tersign action record for a payment that has ALREADY settled, and counter-sign both into your hash chain when a ledger is configured. Use this for money that moved; use record_disclosure for a non-payment agent action. Side effects: signs with TERSIGN_SELLER_KEY, and performs ONE network write to the ledger when TERSIGN_LEDGER_URL/_API_KEY/_SELLER_ID are set (without them it signs locally and returns an unchained artifact). Returns the signed receipt artifact, its keccak256 canonical digest, and — when chained — the ledger counter-signature and sequence number.

ParametersJSON Schema
NameRequiredDescriptionDefault
payerYes0x address that paid — the party who can later open a dispute against this receipt
txHashNoon-chain settlement transaction hash, when one exists; omit for off-chain or fiat settlement
networkYessettlement network as CAIP-2, e.g. "eip155:8453" for Base mainnet
currencyNosettlement currency code, e.g. "USDC" or "USD"
principalNothe party on whose authority the paying agent acted (x402 sense: the buyer who delegated). Omit when a human paid directly
settledAtNounix seconds when settlement occurred; defaults to now. Set it explicitly when back-filling
taxSchemeNotax regime the seller is accounting under; recorded, never computed — Tersign does not calculate tax
resourceUrlYesabsolute URL of the resource that was paid for; appears verbatim in the receipt
supplyDescriptionYeswhat was supplied, in the seller's own words; the human-readable line an auditor or venue reads

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations at all, the description carries full responsibility. It clearly discloses signing side effects (TERSIGN_SELLER_KEY), conditional network writes, local-signing fallback, and the returned artifact's unchained state. It does not disclose whether the 'ONE network write' is idempotent or reversible, but it covers the major side effects well for a signing/ledger tool.

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 dense but well-structured: purpose, usage rule, side effects, and return value are presented in a logical order. Every sentence contributes value, though the first sentence is long and packs several distinct facts. It is appropriately sized for a complex tool with nine parameters and no annotations.

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 nine-parameter tool with no output schema and no annotations, the description covers the core distinction, side effects, and return values. It lacks explicit return value structure or error cases, but the description does list the returned digest and ledger signature. Minor gaps remain around error behavior and exact configuration requirements, but it is stronger than typical tool descriptions.

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 every parameter already has a schema description. The tool description adds marginal semantics by explaining why settledAt should be set explicitly for back-filling and by clarifying that taxScheme is recorded but never computed. These are useful but not extensive, so a 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 opens with a specific verb ('Issue') and a precise resource ('an x402 offer-receipt (EIP-712) plus a Tersign action record'), then immediately scopes it to already-settled payments. It distinguishes itself from record_disclosure by naming it and stating the alternative use case, so an agent can disambiguate 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 Guidelines5/5

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

The description explicitly states when to use this tool ('Use this for money that moved') and explicitly names the alternative ('use record_disclosure for a non-payment agent action'). It also describes configuration-dependent behavior for ledger wiring, which tells the agent under what conditions chaining occurs.

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

open_disputeOpen disputeA

Open an objective dispute against a counter-signed receipt as the PAYER (the configured key must be the receipt payer). Reasons: not_delivered, wrong_content, duplicate_charge. Contested non-mechanical claims escalate to the arbiter; duplicate_charge is decided instantly from ledger arithmetic.

ParametersJSON Schema
NameRequiredDescriptionDefault
reasonYesgrounds: 'not_delivered' nothing arrived · 'wrong_content' delivered but not what was bought · 'duplicate_charge' the same supply was billed twice (decided mechanically from the chain, no arbiter)
statementNofor humans reading the record — never an adjudication input
claimAmountYesamount claimed back, as a decimal STRING in the receipt's settlement currency, e.g. "12.50"; must not exceed the receipt amount
receiptDigestYes0x-prefixed keccak256 digest of the counter-signed receipt being disputed

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the full behavioral disclosure burden. It usefully discloses the payer-key prerequisite, the three grounds, and the different adjudication paths (arbiter vs. instant ledger arithmetic). It does not mention post-submission effects or reversibility, but the core behavioral traits are well covered.

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?

Three sentences with no filler. The purpose and role are front-loaded, followed by reasons and behavioral outcome. Every sentence contributes information an agent needs before invoking the tool.

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?

The description adequately covers who can call the tool (payer), the permitted reasons, and what happens after submission (arbiter or instant decision). With no output schema and no annotations, it would benefit from a note on side effects or dispute lifecycle, but the core calling context is present and sufficient for correct invocation.

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 baseline is 3. The description repeats the reason enum values but adds no new parameter-specific meaning; the schema already documents receiptDigest, claimAmount, statement, and each reason in detail.

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 ('Open'), a specific resource ('dispute against a counter-signed receipt'), and the required role ('as the PAYER'). The enumeration of reasons and escalation behavior clearly distinguishes it from sibling tools like submit_dispute_evidence and adjudicate_dispute.

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?

Provides clear context: only the receipt payer can open, and the three allowed reasons are enumerated. It also clarifies that non-mechanical claims escalate to the arbiter while duplicate_charge is instant, which helps an agent decide when this tool is appropriate. It does not explicitly state when to use alternatives like submit_dispute_evidence or adjudicate_dispute, so it falls 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.

record_disclosureRecord counter-signed disclosureA

One-call disclosure evidence (EU AI Act Art 50 dialect): digests the disclosure text LOCALLY, signs an action record with your key, and the public ledger counter-signs it into your per-signer hash chain. No API key needed — first call self-provisions a free signer-keyed account.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNowhat was disclosed: 'ai-interaction' = the user was told they are talking to an AI; 'synthetic-content' = output was marked machine-generated. Defaults to 'ai-interaction'
textNothe disclosure text as presented — digested locally, never transmitted
mediumNochannel: 'chat' | 'api' | 'voice' | 'ui' …
agentIdYesstable identifier for the disclosing agent — keep it constant across calls so one chain accumulates per agent
textDigestNopre-computed digest (wins over text)
resourceUrlNoabsolute URL of the surface the disclosure was presented on, when there is one

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses local digesting, signing with the caller's key, public-ledger counter-signing, per-signer hash chains, and free self-provisioning. It does not explicitly state irreversibility or post-record behavior, but the public-ledger and hash-chain wording makes the durable write intent clear.

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?

Two sentences with no filler: the first states purpose and mechanism, the second adds the key onboarding fact. Important details such as local processing and no API key are front-loaded.

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?

Given six parameters, no output schema, and no annotations, the description plus schema cover the workflow, onboarding, and key parameter semantics. The main gap is an explicit return/result description, though the schema's chainId note partially covers what the first call produces.

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?

The schema already documents most parameters, so the baseline is 3; the description adds useful cross-cutting meaning by mapping 'digests the disclosure text LOCALLY' to text/textDigest, 'signs an action record with your key' to signingKey, and 'per-signer hash chain' to agentId/chainId. It does not enumerate every parameter, but the schema fills those details.

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 names a concrete action and resource: recording one-call disclosure evidence under the EU AI Act Art 50, with a clear mechanism (local digest, signing, public-ledger counter-signing). This is distinct from sibling tools like record_refund and verify_compliance_record, so an agent can identify the tool's purpose without ambiguity.

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 provides a clear when-to-use context: when EU AI Act Art 50 disclosure evidence is needed, and it stresses a one-call, no-API-key flow. It does not explicitly enumerate when not to use it or name sibling alternatives, but the regulatory use case is specific enough to route the agent.

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

record_refundRecord refundA

Record a refund against an already-chained receipt, as the SELLER. The refund becomes its own counter-signed entry that references the original — nothing is edited or deleted, so the chain stays append-only and both the charge and the refund remain visible. Requires ledger configuration (TERSIGN_LEDGER_URL/_API_KEY/_SELLER_ID) and performs one network write; errors if the original digest is not on your chain. This RECORDS a refund you have already made — it moves no money. Returns the refund record, its digest, the ledger counter-signature and sequence number.

ParametersJSON Schema
NameRequiredDescriptionDefault
amountYesrefunded amount as a decimal STRING in the original settlement currency, e.g. "12.50". A string, not a number, so no precision is lost. Partial refunds are allowed
reasonYeswhy the refund was issued, in your own words; recorded verbatim for whoever reads the chain later
originalDigestYes0x-prefixed keccak256 digest of the receipt being refunded — the digest returned by issue_receipt, and it must already exist on your chain

TDQS

A4.4/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden, and it delivers: it discloses append-only immutability ('nothing is edited or deleted'), the network write side effect, environment prerequisites, the error condition for a missing original digest, and the semantic limitation that it moves no money. This is exemplary behavioral 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?

Four sentences, each carrying distinct value: role/purpose, chain semantics, requirements/error behavior, and semantic boundary/return values. There is no filler, though the description is slightly longer than strictly necessary; it remains well-structured and front-loaded.

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?

Given no output schema and no annotations, the description is unusually complete: it states prerequisites (ledger config), side effect (one network write), error condition (digest not on chain), role constraint, and return values (record, digest, counter-signature, sequence number). An agent has what it needs to invoke the tool correctly without digging elsewhere.

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?

The input schema already documents all three parameters with 100% coverage, including amount as a precision-preserving decimal string, reason as verbatim text, and originalDigest with regex pattern and existence requirement. The description adds essentially no new parameter-level meaning beyond what the schema states (e.g., original digest must exist), so a 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 opens with 'Record a refund against an already-chained receipt, as the SELLER', stating a specific action, target resource, and role. It clearly distinguishes this from issue_receipt and other tools by focusing on refunds of already-chained receipts and explicitly noting it records an already-made refund rather than creating the original charge.

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?

The description gives clear context: use this when you are the seller and have already made a refund, and you need to record it against an existing receipt. It also clarifies a boundary ('moves no money') and a prerequisite (ledger configuration). It does not explicitly name alternative tools or list when-not-to-use conditions, so it falls just 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.

submit_dispute_evidenceSubmit dispute evidenceA

Submit signed evidence to an open dispute. Claimant evidence must be signed by the payer key; respondent evidence additionally requires the seller API key (TERSIGN_LEDGER_API_KEY).

ParametersJSON Schema
NameRequiredDescriptionDefault
roleYeswhich side you are filing as: 'claimant' = the payer who opened it (payer key) · 'respondent' = the seller answering it (also needs TERSIGN_LEDGER_API_KEY)
artifactsYesat least one evidence reference; submit every artifact you want considered in a single call
disputeDigestYes0x-prefixed digest of the open dispute, as returned by open_dispute

TDQS

A4.1/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral disclosure burden. It usefully reveals signing requirements and the respondent's additional TERSIGN_LEDGER_API_KEY need, but it does not mention side effects, whether submissions can be amended, idempotency, or what happens once evidence is accepted.

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?

Two tight sentences with no fluff. The core action is front-loaded, and the additional key-requirement detail is compact but essential.

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?

The input schema is rich and covers parameters thoroughly, but there is no output schema and no description of the response, submission lifecycle, or whether multiple submissions are allowed. For a write-style tool with no annotations, an agent still lacks closure on what happens after the call.

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 description coverage is 100%, so the schema already documents parameters, but the description still adds value beyond it. It ties the 'role' enum to concrete key requirements and clarifies what 'signed evidence' means operationally, which directly informs correct parameter selection.

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 starts with a specific verb and object — 'Submit signed evidence' — and qualifies it with 'to an open dispute,' making the tool's role unmistakable. This clearly distinguishes it from sibling tools like open_dispute, get_dispute, and adjudicate_dispute.

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?

The phrase 'open dispute' provides clear context for when this tool is appropriate, and the role distinction explains the two filing sides. However, it does not explicitly name alternatives or state when not to use it, such as before a dispute is opened or after adjudication.

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

verify_compliance_recordVerify compliance recordA

Verify a Tersign action record against its attestation: recompute the record's canonical digest, confirm the attestation commits to that exact digest, and recover the signature. Fully OFFLINE — no network, no API key, no account. Use this for an action record (a disclosure or other non-payment agent action); use verify_receipt for a payment receipt. PASS proves integrity and internal consistency only. Authorship needs an out-of-band signer address: pass expectedSigner, or the identity is whatever the artifact claims about itself. Returns { valid, signer, digest }; on mismatch, valid:false plus the recovered signer and the recomputed digest.

ParametersJSON Schema
NameRequiredDescriptionDefault
recordYesthe action record object as issued (ComplianceRecordV1 shape). Pass the object, not a JSON string; any field edit changes the digest and fails verification — which is the point
attestationYesthe attestation that accompanies the record: the signature over the record digest, as returned alongside it at issuance
expectedSignerNo0x address the record MUST be signed by, obtained out-of-band (for the public ledger: https://tersign.ai/v1/ledger). Omit to recover the signer without enforcing it

TDQS

A5/5.0
Behavior5/5

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

With no annotations available, the description carries the full burden and does so thoroughly. It discloses that the operation is fully offline with no network/API key/account, that PASS proves only integrity and internal consistency, and that authorship requires an out-of-band signer. It also specifies the return shape and mismatch behavior.

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?

Every sentence earns its place. The description front-loads the core purpose, then adds offline behavior, sibling routing, an important limitation, and the return format. It is dense but not bloated, with no redundant phrases.

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?

Despite having nested object parameters, no output schema, and no annotations, the description fully equips an agent to call the tool correctly. It covers parameter handling, return values, failure behavior, offline constraints, and the distinction from the similarly named sibling tool verify_receipt.

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

Parameters5/5

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

Although schema coverage is already 100%, the description adds meaningful parameter semantics: record must be passed as an object not a string, any field edit changes the digest, attestation is the signature returned at issuance, and expectedSigner is optional but enforces authorship. This goes well beyond the schema property descriptions.

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 opens with a specific verb and resource: 'Verify a Tersign action record against its attestation', and details the mechanism (recompute canonical digest, confirm attestation commits, recover signature). It also distinguishes itself from verify_receipt, making its scope unmistakable.

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

Usage Guidelines5/5

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

Explicit guidance is provided: 'Use this for an action record... use verify_receipt for a payment receipt.' It also tells the caller when to pass expectedSigner versus omit it, and warns that PASS only proves integrity, not authorship without an out-of-band signer address.

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

verify_receiptVerify signed receiptA

Verify an offer-receipt artifact: recover the EIP-712 signature and confirm the payload digest binds to it. Fully OFFLINE — no network, no API key, no account; verifying someone else's receipt is the intended use. Use this for a receipt (money); use verify_compliance_record for an action record (a non-payment action). Returns { valid, signer, digest } and, when expectedSigner is supplied and does not match, valid:false with the recovered signer so you can see who actually signed.

ParametersJSON Schema
NameRequiredDescriptionDefault
artifactYesthe receipt artifact exactly as issued: { format, payload, signature }. Pass the object, not a JSON string
expectedSignerNo0x address the receipt MUST be signed by — obtain it out-of-band, never from the artifact. Omit to recover the signer without enforcing it

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations, the description carries full behavioral burden and does so thoroughly: it discloses fully OFFLINE operation, no network/API key/account requirement, the return shape { valid, signer, digest }, and the specific behavior when expectedSigner mismatches. This exceeds what an agent could infer from the schema alone.

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?

Three tightly packed sentences: the first states the core operation, the second adds offline constraints and the intended user, and the third covers routing and return behavior. No filler or repetition of schema content, and the most critical details are front-loaded.

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?

Given no output schema and no annotations, the description provides all essential context: purpose, offline behavior, sibling differentiation, expectedSigner guidance, and return values. The nested artifact parameter is sufficiently described in the schema, and description-schema combined coverage leaves no critical gap for correct invocation.

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 meaningful semantic detail beyond the schema. It clarifies the expectedSigner behavior in the mismatch case and reinforces the artifact as an object, not a string, which helps avoid common invocation errors.

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: 'Verify an offer-receipt artifact' with a clear mechanism ('recover the EIP-712 signature and confirm the payload digest binds to it'). It also distinguishes itself from the sibling verify_compliance_record by domain, leaving no ambiguity about which tool handles receipts.

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

Usage Guidelines5/5

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

Explicitly says when to use this tool versus the alternative: 'Use this for a receipt (money); use verify_compliance_record for an action record (a non-payment action).' It also emphasizes the offline, no-account nature and that verifying someone else's receipt is the intended use, which guides selection.

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. 9 tool updatesv0.4.7
    • Changedadjudicate_dispute1 field changed
      • addedInput schema / properties / disputeDigest / description
        Added value: +"0x-prefixed digest of the open dispute to adjudicate, as returned by open_dispute"
    • Changedget_dispute1 field changed
      • addedInput schema / properties / disputeDigest / description
        Added value: +"0x-prefixed digest of the dispute to fetch, as returned by open_dispute"
    • Changedissue_receipt9 fields changed
      • addedInput schema / properties / currency / description
        Added value: +"settlement currency code, e.g. \"USDC\" or \"USD\""
      • changedInput schema / properties / network / description
        Previous value: -"CAIP-2, e.g. eip155:8453"New value: +"settlement network as CAIP-2, e.g. \"eip155:8453\" for Base mainnet"
      • addedInput schema / properties / payer / description
        Added value: +"0x address that paid — the party who can later open a dispute against this receipt"
      • changedInput schema / properties / principal / description
        Previous value: -"signed principal behind the paying agent"New value: +"the party on whose authority the paying agent acted (x402 sense: the buyer who delegated). Omit when a human paid directly"
      • addedInput schema / properties / resourceUrl / description
        Added value: +"absolute URL of the resource that was paid for; appears verbatim in the receipt"
      • addedInput schema / properties / settledAt / description
        Added value: +"unix seconds when settlement occurred; defaults to now. Set it explicitly when back-filling"
      • addedInput schema / properties / supplyDescription / description
        Added value: +"what was supplied, in the seller's own words; the human-readable line an auditor or venue reads"
      • addedInput schema / properties / taxScheme / description
        Added value: +"tax regime the seller is accounting under; recorded, never computed — Tersign does not calculate tax"
      • addedInput schema / properties / txHash / description
        Added value: +"on-chain settlement transaction hash, when one exists; omit for off-chain or fiat settlement"
    • Changedopen_dispute3 fields changed
      • changedInput schema / properties / claimAmount / description
        Previous value: -"claimed refund in the settlement currency"New value: +"amount claimed back, as a decimal STRING in the receipt's settlement currency, e.g. \"12.50\"; must not exceed the receipt amount"
      • addedInput schema / properties / reason / description
        Added value: +"grounds: 'not_delivered' nothing arrived · 'wrong_content' delivered but not what was bought · 'duplicate_charge' the same supply was billed twice (decided mechanically from the chain, no arbiter)"
      • addedInput schema / properties / receiptDigest / description
        Added value: +"0x-prefixed keccak256 digest of the counter-signed receipt being disputed"
    • Changedrecord_disclosure3 fields changed
      • changedInput schema / properties / agentId / description
        Previous value: -"stable identifier for the disclosing agent"New value: +"stable identifier for the disclosing agent — keep it constant across calls so one chain accumulates per agent"
      • addedInput schema / properties / kind / description
        Added value: +"what was disclosed: 'ai-interaction' = the user was told they are talking to an AI; 'synthetic-content' = output was marked machine-generated. Defaults to 'ai-interaction'"
      • addedInput schema / properties / resourceUrl / description
        Added value: +"absolute URL of the surface the disclosure was presented on, when there is one"
    • Changedrecord_refund3 fields changed
      • addedInput schema / properties / amount / description
        Added value: +"refunded amount as a decimal STRING in the original settlement currency, e.g. \"12.50\". A string, not a number, so no precision is lost. Partial refunds are allowed"
      • addedInput schema / properties / originalDigest / description
        Added value: +"0x-prefixed keccak256 digest of the receipt being refunded — the digest returned by issue_receipt, and it must already exist on your chain"
      • addedInput schema / properties / reason / description
        Added value: +"why the refund was issued, in your own words; recorded verbatim for whoever reads the chain later"
    • Changedsubmit_dispute_evidence10 fields changed
      • addedInput schema / properties / artifacts / description
        Added value: +"at least one evidence reference; submit every artifact you want considered in a single call"
      • addedInput schema / properties / artifacts / items / properties / at / description
        Added value: +"unix seconds the artifact was produced; supply it when timing is part of your argument"
      • removedInput schema / properties / artifacts / items / properties / digest / $ref
        Removed value: -"#/properties/disputeDigest"
      • addedInput schema / properties / artifacts / items / properties / digest / description
        Added value: +"0x-prefixed keccak256 digest of the artifact. Only the DIGEST is submitted — the content itself never leaves your side"
      • addedInput schema / properties / artifacts / items / properties / digest / pattern
        Added value: +"^0x[0-9a-fA-F]{64}$"
      • addedInput schema / properties / artifacts / items / properties / digest / type
        Added value: +"string"
      • addedInput schema / properties / artifacts / items / properties / kind / description
        Added value: +"what this artifact is; the adjudicator treats each kind differently"
      • addedInput schema / properties / artifacts / items / properties / note / description
        Added value: +"short human-readable label for whoever reads the record; never an adjudication input"
      • addedInput schema / properties / disputeDigest / description
        Added value: +"0x-prefixed digest of the open dispute, as returned by open_dispute"
      • addedInput schema / properties / role / description
        Added value: +"which side you are filing as: 'claimant' = the payer who opened it (payer key) · 'respondent' = the seller answering it (also needs TERSIGN_LEDGER_API_KEY)"
    • Changedverify_compliance_record3 fields changed
      • addedInput schema / properties / attestation / description
        Added value: +"the attestation that accompanies the record: the signature over the record digest, as returned alongside it at issuance"
      • addedInput schema / properties / expectedSigner / description
        Added value: +"0x address the record MUST be signed by, obtained out-of-band (for the public ledger: https://tersign.ai/v1/ledger). Omit to recover the signer without enforcing it"
      • addedInput schema / properties / record / description
        Added value: +"the action record object as issued (ComplianceRecordV1 shape). Pass the object, not a JSON string; any field edit changes the digest and fails verification — which is the point"
    • Changedverify_receipt2 fields changed
      • changedInput schema / properties / artifact / description
        Previous value: -"the receipt artifact object {format, payload, signature}"New value: +"the receipt artifact exactly as issued: { format, payload, signature }. Pass the object, not a JSON string"
      • addedInput schema / properties / expectedSigner / description
        Added value: +"0x address the receipt MUST be signed by — obtain it out-of-band, never from the artifact. Omit to recover the signer without enforcing it"
  2. 9 tool updatesv0.2.0
    • First observedadjudicate_dispute
    • First observedget_dispute
    • First observedissue_receipt
    • First observedopen_dispute
    • First observedrecord_disclosure
    • First observedrecord_refund
    • First observedsubmit_dispute_evidence
    • First observedverify_compliance_record
    • First observedverify_receipt

TDQS

A4.5/5.0

Scored across 9 tools

Disambiguation5/5

Each tool has a clear operational boundary: payment receipt issuance and refunds are distinct from disclosure recording, and verification tools are split by artifact type. The dispute tools form a separate, well-defined lifecycle, and the descriptions actively cross-reference the correct counterpart tool.

Naming Consistency5/5

All tool names follow a consistent verb_noun snake_case convention. Verification, recording, and dispute actions use predictable verbs, and the multiword nouns are consistently descriptive.

Tool Count5/5

Nine tools is well-scoped for the stated domain. Each tool corresponds to a necessary step in the receipt, compliance, refund, or dispute workflow with no redundant helpers or superficial wrappers.

Completeness5/5

The surface covers the full intended lifecycle: issue and verify payment receipts, record and verify disclosures, handle refunds, and open, evidence, adjudicate, and fetch disputes. The append-only design makes updates/deleties unnecessary, and the returned artifacts avoid dead ends.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    D
    quality
    C
    maintenance
    MCP server for the Recite API, enabling receipt scanning, transaction management, batch processing, and local ledger workflows for agents.
    57
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Local MCP server that signs and records agent actions into a tamper-evident log using Ed25519 keys for frictionless integration with Touchstone.
    29
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server providing an append-only, hash-chained evidence ledger for agent actions, where every record is a tamper-evident receipt cryptographically bound to all prior records and persisted as human-readable JSONL local state. It exposes tools to append records, verify chain integrity (pinpointing tampering), query records by actor/action/target/time, and fetch ledger stats—with no update or delete capabilities by design.
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that provides append-only, tamper-evident local receipts for AI agent actions, capturing command executions, outputs, and handoff evidence.
    MIT