POPCORN Witness Verifier

io.github.violetclairePublished by GitHub account violetclairev2.0.1Updated Oct 27, 2026

MCP server for verifying receipts: POPCORN-WITNESS/2.0 signature, digest, and time. Free, read only.

VerifiedStreamable HTTPWeb executableFinanceSecurity & Monitoring

Overview

AI-generated overview

Verifies POPCORN-WITNESS/2.0 signed time and digest receipts against caller-supplied keys, so an assistant can check evidence that an action happened at a…

What you can do
  • Verify a POPCORN-WITNESS/2.0 receipt against an expected SHA-256 digest, nonce and independently trusted issuer keys, including chained predecessor receipts
  • Hash exact bytes locally to a SHA-256 digest and byte length
  • Verify older temporal or witness receipts offline against caller-supplied keys and expected values
  • Run the bundled sample receipts and tamper controls as a reproducible evaluation
  • Fetch the live service catalog, published JWKS and public schemas
  • Request a fresh signed time reference or a new witness receipt (dry run by default, paid on explicit approval)
When to use it
Use it when an assistant or agent needs to check a signed receipt received from another party, confirm that a specific payload existed at a stated time, or obtain a fresh signed time reference for a deadline or authorization expiry. Verification is read-only and can be repeated by any recipient without an account at the originating provider.
Requirements
Remote endpoint over streamable HTTP, or the npm package run with Node.js 20 or newer. No account or wallet is needed for the free tools, dry runs and offline verification. Paid time and witness calls need a dedicated Base payer key supplied as EVM_PRIVATE_KEY in the server process environment, plus network access.
Before you install
Paid calls spend 0.001 USDC on Base and only proceed when a specific call sets approve_payment to true; keep EVM_PRIVATE_KEY dedicated, low-balance and out of tool calls or chat. Caller-supplied keys do not establish issuer identity, and a passing check does not prove on-chain settlement or grant authority. The remote HTTP endpoint accepts only a digest, not payload bytes. The bundled sample keys and receipts are for reproduction only and do not test the current deployed service.

Installation

In SourceWeft

  1. Open POPCORN Witness Verifier in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.violetclaire%2Fpopcorn-tain-verifier/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "popcorn-witness-verifier": {
      "type": "http",
      "url": "https://popcorn-tain-verify-mcp-v2.violetherod.workers.dev/mcp"
    }
  }
}

README

Briarwood 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:

bash
git clone https://github.com/violetclaire/popcorn-temporal-anchor.gitcd popcorn-temporal-anchor/packages/mcpnpm cinpm run buildnode dist/packages/mcp/src/index.js --sample

After version 0.1.4 is published to npm, run:

bash
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

NeedToolWhat stays local
A fresh, signed time reference for a deadline or expirypopcorn_timeThe task and decision
Evidence of one exact task version at a stated timepopcorn_hash, then popcorn_witnessRaw task bytes; only the digest, nonce, and optional predecessor digest go to the witness
Check evidence received from another agentpopcorn_verifyThe receipt, trusted keys, payload, and verification
Check a TAIN 2.0 witness receiptpopcorn_verify_v2 or local CLI verify-v2Exact 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:

bash
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:

ts
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:

json
{}

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:

json
{ "payload_text": "exact UTF-8 text" }
json
{ "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:

json
{  "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:

json
{  "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:

json
{  "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:

json
{  "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:

text
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:

json
{  "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

bash
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:

bash
npm installnpm run checknpm start

The package build includes the repository's existing TypeScript verifier in the published files. Runtime dependencies remain normal npm dependencies.

Source: packages/mcp/README.md at commit 432c016

Tools

1

popcorn_verify_v2

Verify a TAIN 2.0 witness receipt

Verify a POPCORN-WITNESS/2.0 receipt against a caller-computed SHA-256 payload digest, nonce, and independently trusted issuer keys. Send only the digest, never private payload bytes. Caller-supplied keys do not establish issuer identity. This does not prove on-chain settlement, establish current time, or grant authority. Free and read-only.

Parametersjwksrequiredresponserequiredexpected_noncerequiredexpected_node_idprevious_receiptexpected_payload_digestrequiredmax_clock_accuracy_radius_ms

Version history

2
  1. v2.0.1LatestOct 18, 2026
  2. v2.0.0Oct 18, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

    Declare a license in the repository or the registry entry.