EVIDIQ Notary
Cryptographic receipts for AI outputs. Submit a prompt + response + model id and receive a signed, timestamped, 0G-anchored receipt that proves existence, integrity, and provenance — verifiable offline by anyone.
Quickstart
Connect the EVIDIQ Notary MCP server to any MCP-capable agent:
claude mcp add --transport http evidiq-notary https://mcp.evidiq.dev/notary/mcp
Or probe the live pricing discovery endpoint:
curl -s https://mcp.evidiq.dev/notary/x402
MCP server
The remote MCP endpoint is https://mcp.evidiq.dev/notary/mcp (Streamable HTTP). It exposes six tools — two paid, four free:
- notarize_inference — single AI output notarization (x402-paid, $0.001)
- notarize_batch — up to 20 inferences in one call (x402-paid, $0.005)
- verify_attestation — verify receipt signature, hash, and Merkle proof (free)
- get_receipt — fetch proof material (free)
- notary_stats — live volume and top models (free)
- notary_pubkey — notary address + algorithm (free)
{
"mcpServers": {
"evidiq-notary": { "url": "https://mcp.evidiq.dev/notary/mcp" }
}
}notarize_inference
Submit a single AI inference and receive a signed receipt anchored on 0G Storage.
{
"prompt": "What is the capital of France?",
"response": "The capital of France is Paris.",
"modelId": "glm-5.2",
"agentId": "0x1234…",
"context": "User query via chat"
}prompt, response, and modelId are required. agentId, trustReportHash, and context are optional.
It returns a receipt:
{
"attestationId": "0xfbd95c81…eeb1",
"contentHash": "0xfbd95c81…eeb1",
"promptHash": "0x1c8aff…",
"responseHash": "0x8452c9…",
"signature": "0x2f012d7f… (EIP-191)",
"notaryAddress": "0x8a3c7524Aaed081825aC88eC7f4cCECFc583ee7D",
"timestamp": "2026-07-17T00:41:15.303Z",
"modelId": "glm-5.2",
"merkleRoot": "0xfbd95c81…eeb1",
"merkleProof": ["0x…"],
"storageRoot": "0xae8526f7…e894",
"storageTx": "0xa43c8186…1a5e1"
}Paying from your agent (x402)
notarize_inference and notarize_batch are metered with x402 v2 (scheme exact, EIP-3009, USDT0 on X Layer / eip155:196). An unpaid call returns HTTP 402 with the payment requirements; the agent signs a gasless authorization and retries with a PAYMENT-SIGNATURE header. The four free tools need no payment — a plain application/json request works.
// 1. Unpaid call -> HTTP 402 with payment requirements
const { accepts: [req] } = await (await callNotarize()).json();
// 2. Sign EIP-3009 transferWithAuthorization (gasless for the payer)
const authorization = {
from: account.address, to: req.payTo, value: req.amount,
validAfter: "0", validBefore: String(now + 600), nonce: randomHex32(),
};
const signature = await account.signTypedData({
domain: { name: req.extra.name, version: req.extra.version,
chainId: Number(req.network.split(":")[1]), verifyingContract: req.asset },
types: { TransferWithAuthorization: EIP3009_TYPES },
primaryType: "TransferWithAuthorization", message: authorization,
});
// 3. Retry with PAYMENT-SIGNATURE -> server settles, returns receipt + settlement tx
const paid = await callNotarize({
"PAYMENT-SIGNATURE": base64({ x402Version: 2, accepted: req,
payload: { signature, authorization } }),
});Per-tool pricing lives at https://mcp.evidiq.dev/notary/x402 — it returns the full 6-tool pricing table in one call.
verify_attestation (free)
Verify any receipt offline-style: recompute keccak256(prompt ‖ response), recover the EIP-191 signer, and brute-force the Merkle proof against the root.
{
"attestationId": "0xfbd95c81…eeb1",
"prompt": "What is the capital of France?",
"response": "The capital of France is Paris.",
"modelId": "glm-5.2"
}Returns:
{
"valid": true,
"contentMatch": true,
"signatureValid": true,
"merkleValid": true,
"notaryAddress": "0x8a3c7524…3ee7D",
"note": "Receipt verified: content hash matches, EIP-191 signature valid, Merkle proof valid."
}What a receipt proves
- Existence — this exact prompt/response existed at this timestamp.
- Integrity — change one character and the hash changes; verification fails.
- Provenance — the model id, notary address, and optional trust report are bound into the signature.
- Independence — verify offline with the notary address; Merkle roots anchor batches on 0G Storage.
0G Storage anchoring
Every paid receipt is anchored on 0G mainnet (Aristotle, chain 16661) via the @0gfoundation/0g-ts-sdk. The receipt JSON is uploaded as a ZgFile through the turbo indexer; the returned storageRoot and storageTx are durable, tamper-evident, and fetchable by anyone.
- storageRoot — 0G Storage merkle root of the receipt JSON.
- storageTx — on-chain 0G mainnet transaction hash (SUCCESS).
- signature — EIP-191 over "EVIDIQ Notary Receipt v1" + reportHash + merkleRoot, signed by the notary's EVM key.
Offline verification
Anyone can verify a receipt without contacting the notary:
- Fetch the notary address: notary_pubkey tool.
- Recompute contentHash = keccak256(prompt ‖ response).
- Recover the EIP-191 signer from signature over the attestation message — must equal notaryAddress.
- Verify the Merkle proof against merkleRoot.
Pricing
| Tool | Cost | Token | Chain |
|---|---|---|---|
| notarize_inference | $0.001 | USDT0 | X Layer (196) |
| notarize_batch | $0.005 | USDT0 | X Layer (196) |
| verify_attestation | Free | — | — |
| get_receipt | Free | — | — |
| notary_stats | Free | — | — |
| notary_pubkey | Free | — | — |
Proven on-chain
Every notarization is verifiable end-to-end — the payment settles on X Layer and the receipt is anchored on 0G Storage.
- Payment — x402 settlement on X Layer: 0.001 USDT0 via EIP-3009 transferWithAuthorization. Tx 0x53f72073…0070f2 · SUCCESS
- Receipt — 0G Storage anchor: signed by 0x8a3c7524…3ee7D (EIP-191), anchored on 0G mainnet. Tx 0xa43c8186…1a5e1 · SUCCESS
EVIDIQ Notary produces evidence, not permission. A receipt proves the output existed — it does not vouch for the output's correctness. Pair receipts with the EVIDIQ trust layer when you need a capability/risk verdict on the agent that produced it.