MCP signed records

When an MCP tool runs, what proof leaves the server?

MCP connects agents to tools. The server sees everything; the transcript stays inside it. Originary uses PEAC to issue signed records for tool calls, gateway decisions, and result digests, so a client, auditor, or partner can verify the run without your logs.

mcp-tool-runverified offline
Issuer
https://mcp.vendor.example
Tool
tools.call search_docs
Result
ok sha256:9a3c1d...
Signature
Ed25519 7d40e2c9...
sample record - demo signature
MCP tool callsResult digestsDeny as evidenceVerifies offline
The problem

A transcript is not portable proof.

An MCP server log can help you debug a tool run. It cannot be handed to another party as something they can independently check. A signed record answers the questions that cross the boundary:

  • Which tool was called, with which parameter digest?
  • Which policy or tool definition applied at that moment?
  • Was the call allowed, denied, or modified?
  • What result digest came back?
  • Who issued the record, and can it be verified without the server?
The specimen

One tool run. One signed record.

mcp-tool-runverified offline
Issuer
https://mcp.vendor.example
Tool
tools.call search_docs
Params
sha256:c41b09...
Policy
tool-policy:v2 sha256:4e21b8...
Result
ok sha256:9a3c1d...
Time
2026-06-12T14:08:11Z
Signature
Ed25519 7d40e2c9... kid 2026-06-key1
sample record - demo signature
How it travels
"_meta": {
  "org.peacprotocol/receipt_ref": "sha256:f04d11...",
  "org.peacprotocol/receipt_jws": "eyJhbGciOiJFZERTQSIs..."
}

Records ride existing MCP response metadata or export as bundles. They travel separately from the server that created them.

Paid MCP tool records compose the same way: the record binds the tool name, an args digest, and the observed payment receipt digest, and travels in the tool result metadata.

Verify on any machine, later
$ npx -y @peac/cli verify ./mcp-tool-run.jws --public-key ./jwks.json
Signature valid (offline)
issuer https://mcp.vendor.example
tool search_docs - allowed
$ # now edit one byte of the record and retry
$ npx -y @peac/cli verify ./mcp-tool-run.tampered.jws --public-key ./jwks.json
E_INVALID_SIGNATURE
Two ways tampering shows up
  • Edited record: any change after signing breaks the Ed25519 signature. Verification fails loudly.
  • Swapped content: the record binds a content digest. If the content you were handed does not hash to the digest in a validly signed record, the mismatch is caught at extraction.
Deny as evidence

A refused tool call is still an event.

When a gateway or server refuses a tool call, the refusal can be signed too: the requested tool, the policy that denied it, the reason class, the time, the issuer. Reviewers get evidence of what was refused without reading server logs.

The signature is valid. The answer was no. Both facts travel together.

org.peacprotocol/access-decisiondecision: denied
Issuer
https://gateway.vendor.example
Request
tools.call export_billing
Policy
tool-policy:v2 sha256:4e21b8...
Result
denied - policy_violation
Time
2026-06-12T14:10:40Z
Signature
Ed25519 e02d7f15... valid
deny-as-evidence - portable proof of a refusal
Boundaries

What Originary does not do here.

  • It does not run your MCP server.
  • It does not choose which tools are safe.
  • It does not replace MCP auth.
  • It does not require your users to have an Originary account.
  • It does not need your raw logs.

It gives your MCP workflow a portable signed record.

Add records to one MCP tool this week.

Start with the tool another party already asks about. We will show what the signed record should contain.

Logs stay local. Signed records travel.