Skip to main content
Glama

Server-side ed25519 receipt verifier

emem_verify_receipt
Read-onlyIdempotent

Verify a signed receipt byte-for-byte to confirm its Ed25519 signature and Merkle proof, detect changes or fact mismatches, and audit third-party receipts.

Instructions

Verify a signed receipt on the server. The tool builds the canonical preimage again, under the rule that the receipt's preimage_version names. It checks the ed25519 signature with the embedded key. It returns {valid, reason, failure_detail, signature_valid, merkle_proof_valid, signer_pubkey_b32, preimage_blake3_hex}. A receipt verifies BYTE FOR BYTE OR NOT AT ALL. Version 2 binds the inclusion proof, so a change of any kind makes the signature fail: a dropped field, a renamed field, a summary. Use this tool when the browser page /verify is not available. Also use it to audit a receipt from a third party.

When to use: Send the receipt EXACTLY as the read tool returned it, complete and unchanged. Two omissions cause a false forgery, not a 400. Do not drop merkle_proof. Do not drop preimage_version. Without it the value is 0, which selects the v0 rule, and the signature reads as invalid. The signature and the key can be byte arrays, or sig_b32 and responder_pubkey_b32. The tool accepts no other names. When a field changed after signing, the answer is reason: receipt_reshaped_after_signing and names the field. To require a specific signer, set pubkey_b32. A bad signature returns 200 with valid: false, never a 4xx. The example (from emem_tools) is a real receipt over two Trafalgar Square facts. Unchanged, it is valid. Change one byte, and it is not.

Example arguments: 1602 bytes, too long to inline in a listing. Call emem_tools with {"name": "emem_verify_receipt"} for it whole and runnable; it is not shortened here because a truncated example is not one.

Input Schema

NameRequiredDescriptionDefault
factsNoThe fact value(s) you intend to rely on. Each is content-addressed and checked for membership in the receipt's `fact_cids`, so a genuine receipt presented beside a tampered fact answers `valid:false` / `fact_mismatch`. Omit it and only the signature is checked, which a doctored fact survives.
receiptYesThe signed receipt envelope, the object under `receipt` in any read primitive's result. Must carry primitive/served_at/request_id/cells/fact_cids and either `signature` byte[] + `responder_pubkey` byte[] or their b32 string forms. IF ALL YOU HOLD IS AN `emem:fact:` TOKEN, this is not the tool to call first: a token is not a receipt and passing one here is a shape error. Call `emem_memory_token_resolve` on the token, then pass THAT result's `receipt` object here. Resolving proves the token points at the bytes it claims; verifying proves this responder signed them.
pubkey_b32NoOptional explicit responder pubkey (base32). When omitted, uses the receipt's embedded pubkey/responder fields.
current_responder_epochNoThe responder key epoch you currently trust, from `/v1/manifests`. Produces an advisory `key_epoch_advisory` comparison against the receipt's epoch; a mismatch is reported, never rejected.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv2.4.4
    • changedInput schema / properties / receipt / description
      Previous value: -"The signed receipt envelope (as returned by any read primitive). Must carry primitive/served_at/request_id/cells/fact_cids and either `signature` byte[] + `responder_pubkey` byte[] or their b32 string forms."New value: +"The signed receipt envelope, the object under `receipt` in any read primitive's result. Must carry primitive/served_at/request_id/cells/fact_cids and either `signature` byte[] + `responder_pubkey` byte[] or their b32 string forms. IF ALL YOU HOLD IS AN `emem:fact:` TOKEN, this is not the tool to call first: a token is not a receipt and passing one here is a shape error. Call `emem_memory_token_resolve` on the token, then pass THAT result's `receipt` object here. Resolving proves the token points at the bytes it claims; verifying proves this responder signed them."
  2. Addedv1.3.9
  3. Removedv1.3.8
  4. First observedv0.1.0

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint/idempotentHint/destructiveHint/openWorldHint, yet the description adds substantial behavior: byte-for-byte verification, false forgery rather than a 400 for omissions, bad signatures returning 200 with valid:false (never 4xx), version-2 binding of the inclusion proof, and advisory-only epoch mismatch. This is rich context well beyond the annotations.

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?

It is front-loaded with purpose and critical warnings, and every warning about omissions earns its place. It is somewhat long and slightly repetitive (byte-for-byte stated twice) and the closing paragraph about the oversized example meanders, so not a 5.

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, nested, multi-param tool with no output schema, the description enumerates the return object fields and semantics ({valid, reason, failure_detail, signature_valid, merkle_proof_valid, ...}), explains failure reasons and edge cases, and covers input shape pitfalls. Nothing critical to correct invocation appears 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 schema already documents all four parameters, setting a 3 baseline. The description nonetheless adds meaning: signature/key may be byte arrays or the b32 fields and 'accepts no other names', dropping merkle_proof/preimage_version causes false forgery, and pubkey_b32 pins a signer — real value on top of the schema.

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 a signed receipt on the server' — and the title reinforces it with 'ed25519 receipt verifier'. It distinguishes itself from siblings by naming the browser /verify page, emem_memory_token_resolve, and third-party audit scenarios, so an agent can route correctly.

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?

Provides an explicit 'When to use' section: when the browser /verify page is unavailable and to audit a third-party receipt. It names the alternative path (resolve an emem:fact: token via emem_memory_token_resolve first, then pass the resulting receipt), covering both when to use and what to do instead.

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