attest_decision
Verify and anchor AI agent decisions on Base and Solana with cryptographic signatures, producing auditable on-chain proof URLs for autonomous approvals or model attestation.
Instructions
Verify a wallet signature over (input_hash, output_hash, decision) with domain separation, then dual-chain anchor the resulting Merkle root on Base and Solana mainnet. Returns the verified signer plus on-chain proof URLs. Use when an AI agent's decision needs a cryptographic, auditable receipt — autonomous trade approvals, AI-assisted contract decisions, model-output attestation for liability records. $0.010 USDC.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| input_hash | Yes | 64-char hex SHA-256 of the agent's input. | |
| output_hash | Yes | 64-char hex SHA-256 of the agent's output / decision payload. | |
| decision | Yes | Free-form short label, e.g. "APPROVED", "REJECTED", "CONFIDENCE=0.93" (max 64 chars). | |
| scheme | Yes | Signature scheme. | |
| signature | Yes | 0x-prefixed hex (eip191) or base58 (ed25519). | |
| signer_pubkey | No | Required for ed25519 (Solana base58 pubkey). |
Implementation Reference
- index.js:105-121 (schema)Tool definition and inputSchema for 'attest_decision' — defines the name, description, and inputSchema (input_hash, output_hash, decision, scheme, signature, signer_pubkey) for the tool.
{ name: "attest_decision", description: "Verify a wallet signature over (input_hash, output_hash, decision) with domain separation, then dual-chain anchor the resulting Merkle root on Base and Solana mainnet. Returns the verified signer plus on-chain proof URLs. Use when an AI agent's decision needs a cryptographic, auditable receipt — autonomous trade approvals, AI-assisted contract decisions, model-output attestation for liability records. $0.010 USDC.", inputSchema: { type: "object", properties: { input_hash: { type: "string", description: "64-char hex SHA-256 of the agent's input." }, output_hash: { type: "string", description: "64-char hex SHA-256 of the agent's output / decision payload." }, decision: { type: "string", description: 'Free-form short label, e.g. "APPROVED", "REJECTED", "CONFIDENCE=0.93" (max 64 chars).' }, scheme: { type: "string", enum: ["eip191", "ed25519"], description: "Signature scheme." }, signature: { type: "string", description: "0x-prefixed hex (eip191) or base58 (ed25519)." }, signer_pubkey: { type: "string", description: "Required for ed25519 (Solana base58 pubkey)." }, }, required: ["input_hash", "output_hash", "decision", "scheme", "signature"], }, }, - index.js:202-204 (registration)Registration of the tool via ListToolsRequestSchema handler — the TOOLS array is exposed through the MCP ListTools handler.
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS, })); - index.js:226-241 (handler)Handler case for 'attest_decision' in the buildRequest switch — constructs the HTTP POST request to /v1/attest with the tool's arguments (input_hash, output_hash, decision, scheme, signature, optional signer_pubkey).
case "attest_decision": return { url: `${BASE_URL}/v1/attest`, opts: { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ input_hash: args.input_hash, output_hash: args.output_hash, decision: String(args.decision).slice(0, 64), scheme: args.scheme, signature: args.signature, ...(args.signer_pubkey ? { signer_pubkey: args.signer_pubkey } : {}), }), }, };