About POPCORN Witness Verifier
POPCORN Witness Verifier is a read-only MCP server for checking signed time and task receipts. It supports local verification of POPCORN-WITNESS/2.0 envelopes, expected payloads, nonces, time intervals, and receipt chains.
Key features
- 01Verify POPCORN-WITNESS/2.0 envelopes
- 02Check signatures, digests, nonces, and time
- 03Verify chained receipts locally
- 04Hash exact payload bytes locally
- 05Fetch the live catalog and public keys
Use cases
- 01Check a receipt received from another agent
- 02Confirm task evidence matches expected bytes
- 03Verify a deadline or authorization time window
- 04Reproduce historical receipt checks offline
MCP support
It exposes five free tools and two payment-enabled tools to MCP clients. Verification and hashing run locally; time and witness requests can be dry-run or explicitly approved for payment.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://popcorn-tain-verify-mcp-v2.violetherod.workers.dev/mcpclaude mcp add --transport http violetclaire-popcorn-tain-verifier https://popcorn-tain-verify-mcp-v2.violetherod.workers.dev/mcp{"mcpServers":{"violetclaire-popcorn-tain-verifier":{"type":"http","url":"https://popcorn-tain-verify-mcp-v2.violetherod.workers.dev/mcp"}}}Open in Cursor{"servers":{"violetclaire-popcorn-tain-verifier":{"type":"http","url":"https://popcorn-tain-verify-mcp-v2.violetherod.workers.dev/mcp"}}}Open in VS Code{"mcpServers":{"violetclaire-popcorn-tain-verifier":{"type":"http","url":"https://popcorn-tain-verify-mcp-v2.violetherod.workers.dev/mcp"}}}{"mcpServers":{"violetclaire-popcorn-tain-verifier":{"serverUrl":"https://popcorn-tain-verify-mcp-v2.violetherod.workers.dev/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
Tools
Details
From the project READMEBriarwood AI / POPCORN MCP server
For RFC 3161, FreeTSA, OpenTimestamps, a trusted timestamp, proof of existence, authorization expiry, a signed execution receipt, or independent verification, start with Proving an action happened before an authorization expired.
Read-only time and task evidence from Briarwood AI, usable across independent
agents. POPCORN supplies signed time and digest checkpoints at https://767-2676.com.
Try it first, without a wallet
Save sample.mjs, read it, then run
node sample.mjs with Node.js 20 or newer. This standalone sample includes an
exact eight-line schedule with who, its SHA-256 digest, and a real signed
receipt. It runs offline and rejects a one-byte change to who.
The plain-text contract and full packet can be retained locally. The receipt is historical evidence. Fetch new time for a new decision.
Run the current source from this public repository:
git clone https://github.com/violetclaire/popcorn-temporal-anchor.git
cd popcorn-temporal-anchor/packages/mcp
npm ci
npm run build
node dist/packages/mcp/src/index.js --sample
After version 0.1.4 is published to npm, run:
npx -y @violetclaire/[email protected] --sample
The evaluation checks the eight-line task schedule and two legacy, historically settled receipts with the
maintained verifier. It returns valid signatures, STOP for a checkpoint after
its task window, TIME_CHECK_PASSED for one inside its window, and a rejected
one-byte change for each. Every result retains authorization_granted: false.
The sample needs no account, wallet, or original task data. npm may download
the package; the verification itself runs entirely offline.
Inside a connected MCP client, call popcorn_sample with {} for the same
result. Its public source links let another developer repeat the check.
The bundled historical keys are for sample reproduction. A real task requires
independently trusted issuer keys; an old receipt is not a fresh clock reading.
This offline sample tests historical pre-TAIN receipts only. Passing it does
not test the currently deployed TAIN 2.0 service or establish integration
readiness.
Use it for a real task
| Need | Tool | What stays local |
|---|---|---|
| A fresh, signed time reference for a deadline or expiry | popcorn_time | The task and decision |
| Evidence of one exact task version at a stated time | popcorn_hash, then popcorn_witness | Raw task bytes; only the digest, nonce, and optional predecessor digest go to the witness |
| Check evidence received from another agent | popcorn_verify | The receipt, trusted keys, payload, and verification |
| Check a TAIN 2.0 witness receipt | popcorn_verify_v2 or local CLI verify-v2 | Exact expected bytes and independently trusted keys |
These uses apply across agent providers and industries. Share a receipt and the relevant exact bytes through your existing authorized handoff, then let the receiving system verify them. No account at the originating agent provider is required for offline verification. Each participant decides what to do.
This source checkout exposes five free tools and two x402 tools. The x402 tools are dry
run by default. They cannot spend unless the individual tool call contains
approve_payment: true. A wallet key is read only from EVM_PRIVATE_KEY in the
server process environment. It is never accepted as a tool parameter.
This is a clock and a seal. It does not refund, authorize, or hold funds.
Run with npx
Install and run the published package with:
npx -y @violetclaire/popcorn-mcp
Node.js 20 or newer is required.
Programmatic core
The supported @violetclaire/popcorn-mcp/core export exposes the same local
hashing, offline verification, and paid client functions used by the stdio
server:
import {
popcornHash,
popcornVerifyWitnessChain,
popcornWitness,
} from "@violetclaire/popcorn-mcp/core";
popcornVerifyWitnessChain accepts receipts in chronological order, starting
with a receipt whose previous_attestation_digest is null. It verifies each
receipt and signature once, checks each link against the prior receipt's exact
signed-payload bytes, and returns the verified entries plus the head digest.
It is free, local, and sends no network request.
Tools
popcorn_sample
Runs the two public receipt examples and their tamper controls locally. This
is a reproducible evaluation of historical evidence and makes no network
request or payment. Input: {}.
Its historical receipts are not a TAIN 2.0 conformance test.
popcorn_verify_v2
Verifies a POPCORN-WITNESS/2.0 signed envelope, required TAIN fields,
exact expected payload digest and nonce, and the signed time interval. Both
this local MCP tool and popcorn-mcp verify-v2 <vector.json> call the same
verifier. The fixed positive and negative vectors under
verify/test-vectors/interface-parity-v2/ run through both interfaces in
npm run check and fail the check on any result or reason mismatch.
Provide the full response, expected SHA-256 payload digest as canonical
unpadded base64url, the expected nonce, and issuer keys obtained independently
of the receipt. The local CLI and stdio MCP also accept exact payload bytes as
expected_payload_base64url instead of a digest; the remote HTTP MCP accepts
only a digest, including for predecessor receipts, so private payload bytes
need not leave the caller. Supply previous_receipt with its own response,
JWKS, and verification inputs for a chained receipt, up to eight links.
Caller-supplied keys alone do not establish issuer identity; this verifier
does not prove on-chain settlement or grant authority.
popcorn_catalog
Fetches the live service catalog, published JWKS, and public schemas. It is free and sends no payment.
Input:
{}
popcorn_hash
Hashes exact bytes locally and returns the SHA-256 digest plus byte length. It is free, local, and sends no network request.
Provide exactly one input form:
{ "payload_text": "exact UTF-8 text" }
{ "payload_base64url": "ZXhhY3QgYnl0ZXM" }
popcorn_verify
Verifies a POPCORN temporal or witness receipt locally against caller-supplied keys and expected values. It is free, local, and sends no payment.
For a witness receipt:
{
"receipt_type": "witness",
"response": { "witness_receipt": {}, "witness_attestation": {}, "payment_status": "settled" },
"jwks": { "keys": [] },
"verification": {
"expected_nonce": "<43-character-base64url>",
"expected_payload_base64url": "<exact-payload-bytes>",
"expected_node_id": "767-2676.com",
"max_clock_accuracy_radius_ms": 10000
}
}
Provide exactly one of expected_payload_text,
expected_payload_base64url, or expected_payload_digest.
When previous_attestation_digest is non-null, add this recursively under
verification:
{
"previous_receipt": {
"response": { "witness_receipt": {}, "witness_attestation": {}, "payment_status": "settled" },
"jwks": { "keys": [] },
"verification": {
"expected_nonce": "<predecessor-nonce>",
"expected_payload_digest": "<predecessor-payload-digest>"
}
}
}
The verifier first verifies the predecessor. It then hashes the exact bytes
obtained by base64url-decoding the predecessor compact JWS payload segment and
compares that digest with previous_attestation_digest.
For a temporal receipt, verification.observation carries the monotonic timer
values required by the existing offline verifier. An optional
verification.policy can carry execution_window_utc.
popcorn_time
Requests GET /v1/time. The default call is a free dry run:
{
"freshness_ms": 30000,
"approve_payment": false
}
It returns the HTTP 402 terms and the exact request that would be paid. To
authorize one payment, the caller must set approve_payment to true in that
specific call.
popcorn_witness
Requests POST /v2/receipt. POST /v1/receipt remains available to existing
integrations. The default call is a free dry run:
{
"digest": "<43-character-sha256-base64url>",
"nonce": "<43-character-random-base64url>",
"previous_attestation_digest": null,
"approve_payment": false
}
The optional predecessor digest is SHA-256 over the exact decoded signed payload bytes of the predecessor compact JWS. It is not a digest of the full compact JWS string.
Both paid tools lock payment to exactly $0.001 USDC on Base, the published
USDC contract, and POPCORN's published payTo. A changed challenge fails
closed. A successful paid result includes the settlement transaction hash and
server_processing_duration_ms.
Wallet environment
Paid calls require:
EVM_PRIVATE_KEY=0x<dedicated-32-byte-Base-payer-key>
Use a dedicated payer with a small balance. Do not commit this value. The free tools and all dry runs work without it.
Claude Desktop
Add this server to the mcpServers object in Claude Desktop's configuration:
{
"mcpServers": {
"popcorn": {
"command": "npx",
"args": ["-y", "@violetclaire/popcorn-mcp"]
}
}
}
That configuration supports all free tools and dry runs. For paid calls,
launch Claude Desktop from an environment containing EVM_PRIVATE_KEY, or add
an env object to its private local configuration. Never paste the key into a
tool call or chat.
Claude Code
claude mcp add --transport stdio popcorn -- npx -y @violetclaire/popcorn-mcp
Set EVM_PRIVATE_KEY in the environment that launches Claude Code only when
paid calls are needed. Every paid call still requires
approve_payment: true.
Local development
From packages/mcp:
npm install
npm run check
npm start
The package build includes the repository's existing TypeScript verifier in the published files. Runtime dependencies remain normal npm dependencies.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.