zkproofport-ai
This server is a ZK proof generation and verification service with x402 USDC payments, optional TEE encryption/attestation, and MCP/A2A agent interfaces.
Generate ZK proofs for five circuits: coinbase_kyc, coinbase_country, oidc_domain, arc_eligibility, and giwa_attestation.
Use all-in-one generate_proof or step-by-step prepare_inputs → request_challenge → submit_proof flows.
Verify proofs on-chain with verify_proof against deployed verifier contracts.
Discover supported circuits, verifier addresses, and authorized signers via get_supported_circuits.
Pay for proofs with USDC through x402, including direct settlement and arc-testnet-nano Gateway nanopayments.
Manage Circle Gateway balances with gateway_balance and deposit_to_gateway.
Optionally bind arc_eligibility and giwa_attestation proofs to an exact EIP-712 action.
In Nitro TEE mode, encrypt proof inputs end-to-end and obtain hardware attestation; plaintext endpoints are also available in non-Nitro modes.
Expose agent-facing interfaces: MCP tools (remote
/mcpand local stdio), A2A JSON-RPC, REST endpoints, Swagger docs, and agent cards.Register ERC-8004 agent identity and increment reputation after successful proofs.
Provides reverse proxy configuration for the Node.js server, enabling secure HTTPS routing and load balancing in AWS deployments.
Enables containerized deployment of the server, Redis, and AWS Nitro Enclave components through Docker Compose configurations for local development and AWS production environments.
Provides on-chain proof verification capabilities and USDC payment processing through Ethereum smart contract interactions using ethers v6 library.
Serves as the web server framework for REST API endpoints including proof generation, health checks, and integration endpoints for MCP and A2A protocols.
Enables fetching of EAS (Ethereum Attestation Service) attestations for circuit input construction through GraphQL queries.
Provides a Next.js-based signing page with WalletConnect integration for user authentication and transaction signing.
Serves as the runtime environment for the main server application, handling API requests, payment verification, and blind relay operations to the TEE enclave.
Provides package management for the server and client SDKs, including the @zkproofport-ai/sdk and @zkproofport-ai/mcp packages for proof generation and AI agent integration.
Provides LLM capabilities through OpenAI API client for chat functionality and multi-provider routing in the proof generation system.
Enables distributed tracing and observability for monitoring server performance and debugging proof generation workflows.
Provides structured logging for server operations, enabling detailed monitoring and debugging of proof generation and payment processing.
Provides data persistence for proof caching, rate limiting, task management, and session storage through Redis-backed implementations.
Provides API documentation through OpenAPI specification and Swagger UI for exploring REST endpoints and proof generation workflows.
Enables configuration of prover settings through TOML file generation for the Barretenberg CLI proof generation system.
Serves as the primary programming language for the server implementation, SDK development, and type-safe API definitions.
Enables wallet connectivity for user authentication and transaction signing through the Next.js signing page interface.
proofport-ai
Agent-native ZK proof infrastructure for ZKProofport, with a TEE-based proving architecture, SDK and local MCP package. Supported Nitro deployments encrypt inputs to the enclave; encryption and hardware-attestation guarantees depend on the selected endpoint and actual returned evidence. Arc exact-action authorization remains EXPERIMENTAL on Arc Testnet (5042002).
Architecture
The following diagram describes the Nitro deployment. Endpoints without an attested enclave key receive readable inputs over HTTPS; the current Arc staging demo uses that mode and does not supply hardware attestation. A valid proof alone is not evidence of enclave execution.
Client (AI Agent / SDK)
│
│ 1. POST /api/v1/prove → 402 { nonce, price, teePublicKey }
│ 2. Sign EIP-3009 USDC payment
│ 3. Encrypt inputs with TEE X25519 public key (ECIES)
│ 4. POST /api/v1/prove + X-Payment-TX + X-Payment-Nonce + encrypted_payload
│
▼
┌─────────────────────────────────────┐
│ Node.js Server (port 4002) │
│ ─ Verify USDC payment on-chain │
│ ─ Blind relay: pass encrypted │
│ payload to enclave via vsock │
│ ─ Return proof + TEE attestation │
└────────────┬────────────────────────┘
│ vsock
▼
┌─────────────────────────────────────┐
│ AWS Nitro Enclave │
│ ─ X25519 key pair (bound to NSM) │
│ ─ Decrypt inputs (AES-256-GCM) │
│ ─ bb prove (Barretenberg CLI) │
│ ─ NSM attestation of proof hash │
└─────────────────────────────────────┘Key properties:
E2E encryption — X25519 ECDH + AES-256-GCM. In
nitromode, plaintext inputs are rejected.Blind relay in Nitro mode — The host forwards enclave-encrypted inputs. This property does not apply to an endpoint accepting plaintext circuit inputs.
x402 payment — Single-step flow: 402 challenge → USDC payment → proof generation. No middleware.
Hardware attestation in Nitro mode — An actual validated NSM document binds the TEE key to enclave measurements (PCRs); do not infer it from proof validity.
Related MCP server: AgentStamp
Directory Structure
proofport-ai/
├── src/
│ ├── index.ts # Express server entry (port 4002)
│ ├── logger.ts # Pino logger
│ ├── swagger.ts # OpenAPI spec
│ ├── tracing.ts # OpenTelemetry tracing
│ ├── a2a/
│ │ ├── agentCard.ts # /.well-known/agent.json, agent-card.json
│ │ ├── proofportExecutor.ts # A2A task executor
│ │ └── redisTaskStore.ts # Redis-backed task persistence
│ ├── chat/
│ │ ├── geminiClient.ts # Gemini API client
│ │ ├── llmProvider.ts # LLM provider interface
│ │ ├── multiProvider.ts # Multi-provider routing
│ │ └── openaiClient.ts # OpenAI API client
│ ├── circuit/
│ │ └── artifactManager.ts # Circuit artifact download/cache
│ ├── config/
│ │ ├── index.ts # Environment config
│ │ ├── circuits.ts # Circuit metadata
│ │ └── contracts.ts # Deployed contract addresses
│ ├── identity/
│ │ ├── agentAuth.ts # Agent JWT authentication
│ │ ├── autoRegister.ts # ERC-8004 auto-registration
│ │ ├── register.ts # Identity registration
│ │ └── reputation.ts # Reputation management
│ ├── input/
│ │ ├── attestationFetcher.ts # EAS GraphQL attestation fetch
│ │ ├── inputBuilder.ts # Circuit input construction
│ │ └── merkleTree.ts # Merkle tree builder
│ ├── mcp/
│ │ ├── server.ts # StreamableHTTP MCP server
│ │ └── stdio.ts # stdio MCP server (local use)
│ ├── payment/
│ │ └── freeTier.ts # Payment mode config
│ ├── proof/
│ │ ├── proofRoutes.ts # x402 single-step proof API
│ │ ├── guideBuilder.ts # Dynamic proof generation guide
│ │ ├── paymentVerifier.ts # On-chain USDC payment verification
│ │ ├── sessionManager.ts # Proof session/nonce management
│ │ └── types.ts
│ ├── prover/
│ │ ├── bbProver.ts # bb CLI direct prover
│ │ ├── tomlBuilder.ts # Prover.toml builder
│ │ └── verifier.ts # On-chain verification (ethers v6)
│ ├── redis/
│ │ ├── client.ts # Redis client
│ │ ├── cleanupWorker.ts # Expired data cleanup
│ │ ├── constants.ts # Redis key prefixes
│ │ ├── proofCache.ts # Proof result caching
│ │ ├── proofResultStore.ts # Proof result persistence
│ │ └── rateLimiter.ts # Rate limiting
│ ├── skills/
│ │ ├── skillHandler.ts # Skill routing
│ │ └── flowGuidance.ts # Step-by-step flow guidance
│ ├── tee/
│ │ ├── index.ts # TEE mode config
│ │ ├── attestation.ts # NSM attestation validation (COSE Sign1)
│ │ ├── detect.ts # TEE environment detection
│ │ ├── enclaveBuilder.ts # Enclave image builder
│ │ ├── enclaveClient.ts # Nitro Enclave vsock client
│ │ ├── encryption.ts # AES-256-GCM encryption utilities
│ │ ├── teeKeyExchange.ts # X25519 ECDH key exchange
│ │ └── validationSubmitter.ts # TEE validation on-chain
│ └── types/
│ └── index.ts
├── packages/
│ ├── sdk/ # @zkproofport-ai/sdk (npm)
│ └── mcp/ # @zkproofport-ai/mcp (npm)
├── aws/
│ ├── enclave-server.ts # TypeScript TEE prover (Nitro Enclave)
│ ├── Dockerfile.enclave # Enclave image
│ ├── deploy-blue-green.sh # Zero-downtime deployment
│ ├── boot-active-slot.sh # Systemd boot script
│ ├── stop-active-slot.sh # Systemd stop script
│ ├── build-enclave.sh # Enclave build helper
│ ├── ec2-setup.sh # EC2 instance setup
│ ├── Caddyfile # Reverse proxy config
│ ├── docker-compose.aws.yml # AWS Docker Compose
│ ├── vsock-bridge.py # vsock-to-TCP bridge
│ └── systemd/ # Systemd service files
├── sign-page/ # Next.js signing page (WalletConnect)
├── tests/
│ ├── e2e/ # Full E2E tests (REST, MCP, A2A, proof, verify)
│ ├── a2a/ # A2A unit tests
│ ├── identity/ # ERC-8004 identity tests
│ ├── integration/ # Integration tests
│ ├── payment/ # Payment tests
│ ├── tee/ # TEE tests
│ └── *.test.ts # Unit tests
├── docker-compose.yml # Local dev: server + redis
├── docker-compose.test.yml # Test stack: + a2a-ui + Phoenix
├── Dockerfile # Node.js server image
└── README.mdQuick Start
npm (Development)
npm install
npm run dev # Hot reload with tsx
npm run build # Build TypeScript
npm start # Production
npm test # Run tests
npm run test:e2e # E2E tests against Docker stackDocker Compose (Local)
docker compose up --build # Start redis + server
docker compose down # Stop
docker compose down -v # Reset dataPort 4002: Node.js server
Port 6380 (host) → 6379 (container): Redis
E2E Encryption (Blind Relay)
For the supported Nitro deployment, proof inputs are encrypted between the client and the enclave. The host passes the encrypted blob without reading it. This section describes that protocol, not every endpoint.
Protocol: X25519 ECDH + AES-256-GCM (ECIES pattern)
TEE generates X25519 key pair on startup, binds public key to NSM attestation
Client fetches TEE public key from 402 response, verifies attestation
Client generates ephemeral X25519 keypair, computes ECDH shared secret, derives AES key via SHA-256
Client encrypts inputs with AES-256-GCM, sends
{ ephemeralPublicKey, iv, ciphertext, authTag, keyId }Server passes encrypted envelope to enclave via vsock (blind relay)
Enclave decrypts, generates proof, returns proof + NSM attestation
Enforcement: In nitro mode, plaintext inputs are rejected with PLAINTEXT_REJECTED.
x402 Payment Flow
The live 402 challenge determines the offered routes, price, asset, recipient and signing domain. Select a compatible wallet and explicit route, obtain user approval, then sign the exact terms and retry the request using the SDK's payment headers. Do not assume every endpoint is free or that every wallet works on every offered chain.
For Arc Gateway nanopayments, pay_on: "arc-testnet-nano" draws from an already funded Gateway balance. The initial direct deposit is an on-chain operation requiring gas; each proof payment signs an authorization against that balance. The demo proof fee is 0.001 USDC, but callers must validate the live offer rather than substitute a documentation price.
Use max_payment: "0.001" and approved_payment in local MCP, or maxPayment and approvedPayment in the SDK. Exact approved terms include network, scheme, amount (USDC base units), asset, payTo and extra: {name, version, verifyingContract}. The SDK rejects a changed fee, recipient, asset, network or signing domain before signing. Proof payment and an eventual staking transaction require separate approvals.
Base and Base Sepolia use Dexter first and PayAI as a backup. --pay-with key
and --pay-with cdp still choose the buyer's signing wallet; neither selects
the server's facilitator. Provider failover reuses the identical EIP-3009
authorization, including its nonce, amount and recipient. Ethereum/Arc direct
settlement and Circle Gateway nanopayments keep their own settlement routes.
The server tries each configured facilitator at most once for connection
failures, timeouts, HTTP 429/5xx or malformed responses. Payment rejections
such as insufficient balance, invalid signatures and expired authorizations
stop immediately. Before contacting the backup, the server checks the USDC
authorization state on the selected chain. A pending settlement or an
already consumed authorization is not submitted again. If that state cannot
be established, the API reports settlement_unknown; known pending responses
report settlement_pending, with a transaction hash when available. These
outcomes require reconciliation, not a newly signed payment. This failover
does not implement resumption of a proof request after its settlement response
was lost. Final on-chain payment verification still runs before proof generation.
REST Endpoints
Endpoint | Method | Purpose |
| GET | Health check + TEE status + payment mode |
| POST | x402 single-step proof generation |
| GET | Dynamic proof generation guide (JSON) |
| POST | StreamableHTTP MCP endpoint |
| POST | A2A JSON-RPC endpoint |
| GET | OASF Agent Card |
| GET | A2A Agent Card |
| GET | MCP discovery |
| GET | Swagger UI |
| GET | OpenAPI spec |
MCP Tools
Remote /mcp and the local npm MCP server have separate tool surfaces. Consult each actual tools/list response. The local package includes:
Tool | Purpose |
| All-in-one proof generation (x402 payment + E2E encryption auto-detect) |
| On-chain proof verification |
| List available circuits |
| Request 402 challenge (step-by-step flow) |
| Submit proof inputs (step-by-step flow) |
| Prepare circuit inputs (step-by-step flow) |
| Read Gateway balance using |
| Deposit to Gateway using |
npm Packages
@zkproofport-ai/sdk — TypeScript SDK for proof generation (ethers v6)
@zkproofport-ai/mcp — Local MCP server for AI agents (stdio transport)Install the MCP server for local AI agent usage:
npm install @zkproofport-ai/mcp@latest @zkproofport-ai/sdk@latest ethers
npx zkproofport-mcp # Starts stdio MCP serverArc/GIWA optional-action support requires SDK 0.2.14 or later and MCP 0.2.15 or later for the step-by-step input preparation path. MCP 0.2.14 has input-validation bugs in that path; its all-in-one tool delegates to the SDK. Install from npm and check the resolved version. Release Please manages package versions and the release workflow publishes them; repository source changes alone do not update @latest.
Circle Agent Wallet on Arc — EXPERIMENTAL
Use the existing Circle CLI login and wallet. walletFor('arc') / walletFromArcAgent wraps that CLI; MCP selects it with pay_with: "arc". This differs from pay_with: "circle", which uses Circle developer-controlled wallet credentials. Keep credential keys and login secrets out of model prompts and logs.
# Inspect the existing wallet; do not replace it or create a new one.
circle wallet list --chain ARC-TESTNET --type agent
circle gateway balance --address "$ARC_AGENT_WALLET" --chain ARC-TESTNET --output json
# Execute only after the user approves this funding amount:
circle gateway deposit --amount 0.1 --address "$ARC_AGENT_WALLET" --chain ARC-TESTNET --method directThe local gateway_balance and deposit_to_gateway tools remain PAYMENT_PRIVATE_KEY only. Use Circle CLI for the Circle Agent Wallet instead of substituting another wallet. Circle's backing EOA signs Gateway authorizations internally; the exact action still names the operational Wallet B.
The supported flow is: discover the dApp policy and prover → prepare the exact action → approve the action and live payment terms → call generate_proof with arc_eligibility, action, pay_with: "arc", pay_on: "arc-testnet-nano", max_payment and approved_payment → verify the actual proof → obtain separate stake approval → submit from Wallet B and check the receipt. No all-chain wallet compatibility is implied.
See the SDK Arc example and MCP setup and arguments. User-facing exact-action authorization retains the existing CredentialDelegation / delegate wire fields.
Guide System
GET /api/v1/guide/:circuit returns a comprehensive JSON guide for client AI agents to prepare all proof inputs. Includes:
Step-by-step instructions with code examples
Constants (attester keys, contract addresses, EAS schema UIDs)
Formulas (nullifier computation, signal hash, Merkle tree construction)
Input schema with types and descriptions
EAS GraphQL query templates
Circuits use aliases: coinbase_kyc → coinbase_attestation, coinbase_country → coinbase_country_attestation, oidc_domain → oidc_domain_attestation. arc_eligibility has no alias — it is named canonically or not at all.
A2A Protocol
A2A v0.3 JSON-RPC endpoint at POST /a2a:
Method | Purpose |
| Submit proof task (blocking) |
| Submit proof task (SSE streaming) |
| Query task status |
| Cancel a running task |
| Resubscribe to task events |
Agent Card at /.well-known/agent.json provides ERC-8004 on-chain identity and capability discovery.
TEE Integration (AWS Nitro Enclave)
Mode | Behavior |
| Standard Linux, no TEE, plaintext allowed |
| AWS Nitro Enclave, hardware attestation, E2E encryption enforced |
The enclave runs aws/enclave-server.ts (compiled to dist/aws/enclave-server.js) which executes bb prove with --oracle_hash keccak (required for Solidity verifier compatibility). NSM attestation binds the proof hash and TEE public key to the enclave measurement (PCR0/PCR1/PCR2).
Attestation validation chain: AWS Nitro Root CA → Regional → Zonal → Instance → Leaf certificate, verified with COSE ES384 signature.
Supported Circuits
Coinbase KYC (coinbase_attestation)
Proves holder has passed Coinbase KYC verification.
Aliases:
coinbase_kyc,coinbase_attestationPublic Inputs: address, scope
Nullifier: Yes (privacy, replay prevention)
Coinbase Country (coinbase_country_attestation)
Proves holder's KYC country matches attestation.
Aliases:
coinbase_country,coinbase_country_attestationPublic Inputs: address, country, scope
Nullifier: Yes (privacy, replay prevention)
OIDC Domain (oidc_domain_attestation)
Proves holder owns an email address at a specific domain via OIDC JWT verification.
Aliases:
oidc_domain,oidc_domain_attestationInput type: OIDC JWT (
id_tokenfrom Google, etc.)Public Inputs: domain hash, scope
Nullifier: Yes (privacy, replay prevention)
Arc Eligibility (arc_eligibility) — EXPERIMENTAL
The same Coinbase attestation as coinbase_attestation, optionally bound to
a named EIP-712 action signed by its credential wallet. The proof then carries
the action's domain separator and struct hash, so a verifier checks which
action was authorised rather than only that somebody eligible signed something.
That is the difference that matters once an agent moves money: personal_sign
over 32 opaque bytes shows a person a hex string.
Aliases: none — the canonical id only
Action inputs:
domainSeparatorandactionHashare provided together for an action-bound proof. Without an action, the wallet signs the request signal hash and the proof has no action binding.Public inputs, in order:
signal_hash,domain_separator,action_hash,signer_list_merkle_root,scope,nullifier— scope at fields 128–159 and nullifier at 160–191, which is 64 further along than every other circuit hereNullifier: Yes, derived from
signal_hashexactly as on Base, so it stays one-per-person rather than one-per-actionVerifier:
0xCbC8E63fF92659E8B44cFF117D33005Bb669a018on Arc Testnet (chain 5042002). No Arc mainnet support is claimed.Status:
experimentalin@zkproofport-app/sdk— provable and verifiable, but the layout and the verifier address can still change
Human wallet approval links
SDK/MCP 0.3.0 introduce a human wallet approval pause for requests containing an Arc or GIWA action. The AI service serves /approve/:id: a responsive request page with proof conditions, domain/network details, expandable typed action fields and wallet selection. Ordinary proofs without an action retain the existing flow. See the MCP human-approval instructions and SDK examples.
The service stores ten-minute approval sessions in Redis. Browser and requester capabilities are separate; approval is bound to the original action and consumed once before proof preparation/payment. Build the page with npm run build (included in the Docker image). A2A_BASE_URL must identify the externally reachable AI origin. Set WALLETCONNECT_PROJECT_ID to enable mobile-wallet pairing; browser extensions work without it. Deploy the compatible AI service before clients use the SDK/MCP 0.3.0 approval flow. The shared application SDK remains a separate dependency.
The approval UI ignores repeated, validated wallet state notifications while invalidating signatures on actual account/network changes or disconnects. Its WalletConnect 2.25.0 adapter consumes normalized chain events without echoing raw notifications back as switch commands, avoiding a request-before-provider-initialization race during pairing. Explicit network selection still uses the public provider API. Run the approval workspace tests, browser tests, and a real local wallet approval before deployment when changing this adapter. The modal uses the page's system font stack so AppKit does not preload unused remote font variants.
Contract Addresses
Arc Testnet — EXPERIMENTAL (5042002)
Contract | Address |
Arc eligibility verifier |
|
Ledger House EligibilityGate |
|
The gate checks the credential policy, authorized actor, exact action, unused nonce and deadline together with proof verification. Its deployed EIP-712 action shape is described in the package READMEs. The layout and deployments remain experimental; do not treat this as a mainnet guarantee.
Base Sepolia (Testnet)
Contract | Address |
KYC Verifier |
|
Country Verifier |
|
ERC-8004 Identity |
|
ERC-8004 Reputation |
|
Base Mainnet (Production)
Contract | Address |
ERC-8004 Identity |
|
ERC-8004 Reputation |
|
ERC-8004 Agent Identity
The agent auto-registers on-chain at startup via the ERC-8004 Identity contract. Reputation score increments after each successful proof generation.
Environment Variables
Required
Variable | Description |
| Redis connection string |
| Base chain RPC endpoint |
| RPC for proof verification |
| EAS GraphQL endpoint for attestation queries |
| Agent wallet private key (64 hex chars, optional 0x); also submits direct payment settlements |
|
|
| Public-facing service URL (for Agent Card) |
Optional
Variable | Default | Description |
|
| Express server port |
| Unset | Public WalletConnect project ID for human action approval; injected wallets remain available when unset |
| Unset (proxy trust disabled) | Integer |
|
| Node environment |
|
| Barretenberg CLI path |
|
| Circuit artifacts directory |
| (GitHub raw URL) | Circuit artifacts download URL |
|
|
|
| — | Nitro Enclave CID (required when |
|
| Nitro Enclave port |
|
| Enable attestation verification |
| — | Payment recipient (required when payment enabled); must match the prover wallet when direct settlement is offered |
|
| Price per proof (USD) |
|
| Primary Base / Base Sepolia facilitator |
|
| Backup for the same authorization; empty disables failover |
|
| Per-provider deadline including response body, integer 1–60000 ms |
| Legacy Arc pair only when both absent | Arc proof verification RPC/chain; independent of identity registration; partial pairs are errors |
| — | GIWA Sepolia input source and proof verification endpoints |
| — | ERC-8004 Identity contract |
| — | ERC-8004 Reputation contract |
| — | Gemini API key for chat |
| — | OpenAI API key for chat |
| — | Phoenix OTLP endpoint for tracing |
| Server package version | Optional advertised agent version override |
Human action approvals expire after ten minutes and retain an authenticated
tombstone for five more minutes. Creation allows ten requests per client IP
per minute. On Cloud Run, configure APPROVAL_TRUST_PROXY_HOPS only after
verifying the ingress proxy count and ensuring requests cannot take a shorter
path. With the setting unset, clients behind a proxy share its socket-IP
bucket; arbitrary X-Forwarded-For headers are ignored. This setting does not
change proxy trust for other service routes. Deployment workflows do not
enable it automatically.
Direct payment settlement wallet
PROVER_PRIVATE_KEY is the single operator key for agent identity signing and
direct x402 settlement. No separate PAYMENT_SETTLER_PRIVATE_KEY is read.
When a configured payment network uses payee settlement, startup checks that the
prover key is valid and its address matches PAYMENT_PAY_TO. A mismatch stops
startup before the service offers payment. Fund this wallet for transaction gas
on each directly settled network. Facilitator and Gateway settlement do not use
this wallet to submit each payment; payment-disabled operation skips this check.
For local paid-path tests, provide PROVER_PRIVATE_KEY and its public address as
PAYMENT_PAY_TO in the shell, then run ./scripts/ai-dev.sh --payment. The
script uses the same prover key in the server container. scripts/verify-payment.ts
also uses this pair for direct settlement, plus a distinct PAYMENT_BUYER_KEY
for the customer-side authorization; keep private keys out of shell history.
Deployment
The current deployment target is GCP Cloud Run, through the parent workspace's
deploy-ai.yml workflow. Commit service changes to main, update the parent's
pinned service commit, and dispatch that parent's main. Staging uses testnets;
production uses mainnets. Cloud Run uses TEE_MODE=local, so it does not provide
Nitro hardware attestation or the Nitro encrypted-payload endpoint.
The deployment gate verifies all configured ERC-8004 identities, all five circuit
discovery entries, and every payment offer. Actual paid proof E2E is a separate
check: use scripts/run-published-e2e.mjs with an explicit E2E_BASE_URL to install
and exercise the versions in the package manifests. It verifies generated proofs
on chain; a successful 402 response alone is not a paid proof test.
AWS Nitro reference
The retained AWS deployment supports hardware-attested proving and blue-green slot switching. It is not the current deployment target; use it only after an explicit change to that deployment decision.
Blue-Green Deployment
aws/deploy-blue-green.shTwo slots: blue (ports 4002/3200) and green (ports 4003/3201)
Active slot tracked in
/opt/proofport-ai/active-slotCaddy reload (not restart) switches traffic
In-flight request drain before switching (up to 660s for proof generation)
Automatic rollback if new container health check fails
Infrastructure
Caddy — Reverse proxy with HTTPS (Cloudflare Full SSL)
systemd — Services:
proofport-ai,proofport-ai-redis,proofport-ai-enclave,vsock-bridgeCloudWatch — Log driver
awslogs, 30-day retentionGitHub Actions —
deploy-ai-aws.ymlworkflow (NOTdeploy.ymlwhich is GCP)
Boot / Stop
aws/boot-active-slot.sh # Start active slot containers
aws/stop-active-slot.sh # Stop active slot containersTesting
npm run test:unit # Unit and integration tests
npm run test:e2e # E2E against Docker stack
npm run test:watch # Watch modeDeployed approval HTTP smoke
After deploying the approval feature, explicitly opt in to its canonical staging or production origin. This check uses a public deterministic fixture signer, creates two short-lived approval sessions, and never calls proof, payment, or chain RPC endpoints:
node scripts/verify-approval-deployment.mjs \
--allow-deployed --base-url https://stg-ai.zkproofport.app \
--expected-version "$(node -p 'require("./package.json").version')" \
--expected-assets-dir public/approval \
--output "${TMPDIR:-/tmp}/proofport-approval-staging-smoke.json"Use https://ai.zkproofport.app explicitly for production. The script rejects
other hosts, non-HTTPS origins, URL credentials, paths, queries, fragments, and
redirects. The existing local-container approval test remains localhost-only.
--expected-assets-dir compares the deployed HTML and referenced JS/CSS bytes
with the supplied build; --expected-index-sha256 can additionally pin an exact
HTML digest. Output contains case results, service version, and public asset
hashes, never capabilities, approval URLs, signatures, or response bodies.
Coverage includes capability separation, signature validation, altered-request
rejection, atomic consumption, terminal rejection, public-status privacy, and
fixed expiry without extension. Actual expiration is reported as untested in
the quick run because the server TTL is ten minutes. Add --wait-for-expiry to
create one more fixture and observe that transition; it takes about ten minutes.
This is a deployed HTTP check with a public test EOA, not a real human-wallet or
paid-proof end-to-end test.
Published SDK/MCP E2E
E2E_BASE_URL=https://stg-ai.zkproofport.app \
E2E_PAYMENT_NETWORK=base-sepolia \
npm run test:e2e:publishedThis installs the exact SDK/MCP versions from their package manifests into an
isolated temporary directory, together with the supported Circle CLI 1.1.4.
It also installs the SDK's optional wallet adapters: CDP and x402 extensions
use the tested versions in the root lockfile, and Circle developer-controlled
wallets uses the exact test pin 10.8.1. All adapter modules are imported from the
isolated installation before any paid test begins. Missing or newly added
optional peers fail this preflight instead of failing after a proof starts.
It verifies those versions and gives every test subprocess that CLI through its
PATH; the global installation is neither used nor changed. SDK imports and the
MCP process use the installed registry artifacts, not workspace links. The
installation is removed after testing. Use -- --sdk-version X.Y.Z --mcp-version X.Y.Z to validate a specific already published release.
The full run creates paid testnet proofs. Supply credentials in the untracked
.env.test or process environment: ATTESTATION_KEY, GIWA_ATTESTATION_KEY,
E2E_PAYER_WALLET_KEY, and E2E_OIDC_JWT (or an authenticated gcloud account).
E2E_PAYMENT_NETWORK selects the proof suites' payment network. The separate
payment matrix checks Base Sepolia, Arc immediate settlement, Ethereum Sepolia,
and Arc nano individually. Give it funded test wallets using explicit
E2E_PAYER_KEY_BASE_SEPOLIA, E2E_PAYER_KEY_ARC_TESTNET,
E2E_PAYER_KEY_ETHEREUM_SEPOLIA, and E2E_PAYER_KEY_ARC_TESTNET_NANO overrides
when the common payer cannot pay on those networks. Alternatively,
E2E_ARC_AGENT_ADDRESS selects an existing, authenticated Circle Agent Wallet
for both Arc cases. Immediate settlement needs on-chain USDC; nano needs Gateway
USDC. The runner never derives a payer from the prover key, transfers funds,
or deposits automatically.
For an existing Base Sepolia or Ethereum Sepolia payer that lacks USDC, use the
explicit faucet helper below. Put CDP_API_KEY_ID and CDP_API_KEY_SECRET in the
untracked .env.test; no wallet secret or payer private key is needed for this
request. Set E2E_PAYER_ADDRESS to the public address of the wallet already used
by your test fixture, then run:
node --env-file=.env.test --import tsx scripts/request-testnet-usdc.ts \
--network ethereum-sepolia --address "$E2E_PAYER_ADDRESS" --min-usdc 0.01
# Use --network base-sepolia for that testnet instead.The helper checks the USDC balance first and requests faucet funds only below
the minimum. It accepts only those two testnets and USDC, creates no wallet,
and spends no real assets. requested includes the public transaction hash;
wait for confirmation and rerun until the status is adequate before E2E.
rate_limited, missing_credentials, balance_unavailable, or faucet_failed
returns a failing exit status and a sanitized message, without automatic retry
or printing provider errors. Funding is a separate explicit action; the E2E
runner never invokes this helper automatically.
A free package/discovery check is:
E2E_BASE_URL=https://stg-ai.zkproofport.app \
npm run test:e2e:published -- -t 'should list all 5 circuits'That check does not establish proof generation or settlement success.
A2A Testing (a2a-ui + Phoenix)
docker compose -f docker-compose.yml -f docker-compose.test.yml up --build -dService | URL | Purpose |
proofport-ai |
| Agent server |
a2a-ui |
| A2A web test UI |
Phoenix |
| Trace visualization |
Version Locks
Tool | Version |
bb (Barretenberg) |
|
nargo |
|
ethers |
|
@modelcontextprotocol/sdk |
|
Node.js | 20 LTS |
License
Apache 2.0
Available Tools
9 toolsdeposit_to_gatewayA
Deposit USDC into Circle Gateway on Arc, so later proofs can be paid for with nanopayments (pay_on: "arc-testnet-nano").
Do this ONCE, not per proof. The deposit is the only on-chain step and it costs gas; every payment drawn against the balance costs almost none. Paying with "arc-testnet-nano" against an empty Gateway balance is refused.
Requires PAYMENT_PRIVATE_KEY -- the buyer signs authorizations with it and never sends a transaction per payment.
RETURNS: whether a deposit was made, its transaction hash, and the Gateway balance afterwards (in USDC's smallest units, so 1000000 is one USDC).
| Name | Required | Description | Default |
|---|---|---|---|
| amount | Yes | How much USDC to deposit, in whole USDC as a decimal string, e.g. "5" or "0.5". | |
| rpc_url | No | Arc RPC. Defaults to https://rpc.testnet.arc.io. | |
| at_least | No | Skip the deposit if the Gateway balance already covers this, in USDC's smallest units (1000000 = 1 USDC). Omitted deposits unconditionally. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well. It discloses that this is the only on-chain step, that it costs gas, that it should happen once, that empty balances cause payment refusal, and what the return values are. This is far beyond a bare 'deposit' statement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is efficiently structured: clear purpose paragraph, workflow guidance, prerequisite, and a returns summary. Every sentence adds useful information and nothing feels like filler or tautology.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter tool with no output schema, the description is complete: it explains the purpose, the workflow position, gas implications, the private key requirement, parameter nuances, and the exact return fields including units. An agent has enough to invoke it correctly and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents amount, rpc_url, and at_least with units and defaults. The description reinforces the decimal-string format and USDC smallest-unit convention, but mostly repeats what the schema already provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Deposit USDC into Circle Gateway on Arc', and immediately states the downstream purpose (paying for proofs via nanopayments). This clearly distinguishes it from the sibling tools like gateway_balance and generate_proof, which serve different steps in the workflow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Do this ONCE, not per proof' and explains why, including gas cost and refusal of payments against an empty balance. It also notes the PAYMENT_PRIVATE_KEY requirement. It does not explicitly name an alternative sibling, but the situational guidance is concrete enough to route an agent correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gateway_balanceA
What the buyer currently holds inside Circle Gateway on Arc — the balance nanopayments are drawn against. Amounts are in USDC's smallest units (1000000 = 1 USDC). Requires PAYMENT_PRIVATE_KEY.
| Name | Required | Description | Default |
|---|---|---|---|
| rpc_url | No | Arc RPC. Defaults to https://rpc.testnet.arc.io. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does meaningful work: it discloses that the operation reads a current balance, specifies USDC base units, and states the required private key. It does not explicitly say the call is read-only, but the wording strongly implies a non-mutating balance lookup.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with no filler: the first states the tool's purpose and its relationship to nanopayments, and the second packs in unit semantics and an authentication requirement. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter read tool, the description covers purpose, units, and auth. However, because there is no output schema, it does not specify the exact response shape or field name, and it does not address edge cases like an invalid key or missing gateway balance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, rpc_url, is fully documented in the schema with its type and default value, so schema coverage is 100%. The description adds no parameter-specific detail, which aligns with the baseline score for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as reporting the buyer's current balance inside Circle Gateway on Arc and notes this is the balance nanopayments draw against. It distinguishes itself from deposit_to_gateway and proof-flow siblings, though it lacks an explicit imperative verb like 'get' or 'fetch'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: call this when you need the current balance that nanopayments draw against. It also states a prerequisite (PAYMENT_PRIVATE_KEY), but it never explicitly says when to use this instead of deposit_to_gateway or other alternatives, nor provides exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_proofA
All-in-one ZK proof generation. Handles: prepare inputs, request challenge, and submit proof in a single call. Use this when you want the simplest path to a proof. For fine-grained control over each step, use prepare_inputs, request_challenge, and submit_proof individually.
CIRCUITS:
"coinbase_kyc": Proves the user passed Coinbase KYC verification.
"coinbase_country": Proves the user's country of residence is (or is not) in a given list. Requires country_list and is_included.
"oidc_domain": Proves the user authenticated via OIDC and their email belongs to a specific domain. Requires jwt and scope.
"arc_eligibility": Coinbase KYC, optionally binding the wallet's signature to ONE EIP-712 action. Without action it signs the request signal hash. The proof carries that action's hash, so a contract can check WHICH instruction was authorised -- not merely that somebody eligible signed something. Verified on Arc Testnet (chain 5042002).
"giwa_attestation": GIWA attestation, optionally binding one EIP-712 action. Uses a GIWA-attested wallet; verified on GIWA Sepolia (chain 91342).
WITH ACTION: Returns awaiting_approval with an approval URL for the HUMAN to review and sign in their wallet. Keep the request parameters unchanged, query get_action_approval, then repeat with approval_id when approved. ATTESTATION_KEY cannot authorize an action on the human's behalf. Ordinary proofs without action retain automatic signing.
RETURNS: awaiting_approval or the full ProofResult with proof bytes, public inputs, and timing information. Use verify_proof separately to verify on-chain.
| Name | Required | Description | Default |
|---|---|---|---|
| jwt | No | OIDC JWT token (id_token) for oidc_domain circuit | |
| scope | No | Scope string for nullifier derivation. Defaults to "proofport" if omitted. For oidc_domain circuit, this is the domain scope string. | |
| action | No | The EIP-712 action to authorise. Optional for arc_eligibility and giwa_attestation; rejected for other circuits. Any structure is provable: the circuit hashes it without reading it, so a deposit, a grant of authority or an agreement in prose all work. The wallet signs exactly these fields, and the proof carries their hash. | |
| pay_on | No | Which chain to pay on: a CAIP-2 id ("eip155:5042002") or a plain name ("arc-testnet", "arc-testnet-nano", "base-sepolia"). Call request_challenge to see what a service offers. Omitted takes the first chain offered. The payer signs an authorization and the service settles it, so no gas or native balance is needed on the paying chain -- only USDC. "arc-testnet-nano" is Arc nanopayments: the authorization goes to Circle Gateway, which verifies it off chain in under a second and settles it later in a batch with thousands of others, so the gas per payment approaches zero. It requires a Gateway balance -- deposit first with the deposit_to_gateway tool -- and is the right choice for an agent buying many proofs. "arc-testnet" settles each payment on chain immediately and costs gas every time. | |
| circuit | Yes | Which circuit to use | |
| pay_with | No | Which wallet pays, when the service charges. "arc" is an Arc agent wallet — Circle holds it, it carries spending policies the agent cannot ignore, and Circle CLI signs with it (install: npm i -g @circle-fin/cli, then circle wallet login <email> --testnet). "key" signs with PAYMENT_PRIVATE_KEY. "cdp" uses a Coinbase CDP server wallet (CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET). "circle" uses a Circle developer-controlled wallet (CIRCLE_API_KEY, CIRCLE_ENTITY_SECRET, CIRCLE_WALLET_ID) when that wallet supports the selected offer. Omit it and the single configured wallet is used; omit it with none configured against a paying service and the error names what to set. Wallet and chain are separate choices; both must support the actual offered signing domain. | |
| provider | No | OIDC provider. "google" (default) for Google Workspace, "microsoft" for Microsoft 365. | |
| approval_id | No | Resume the SAME original action request using the approval_id returned with awaiting_approval. Keep all original parameters unchanged. | |
| is_included | No | true = prove country IS in list, false = prove NOT in list. Required for coinbase_country circuit. | |
| max_payment | No | Maximum USDC proof fee allowed by the user. | |
| country_list | No | ISO 3166-1 alpha-2 country codes. Required for coinbase_country circuit. | |
| approved_payment | No | Exact user-approved terms. For direct EIP-3009 set extra.verifyingContract to the offer asset; for Gateway copy its required extra.verifyingContract. Changed fee, recipient, token, chain or signing domain is rejected before signing. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral disclosure. It explains that the tool is a composite flow, returns either awaiting_approval or a full ProofResult with timing info, and requires human approval for action-bound proofs while ordinary proofs auto-sign. It also notes that ATTESTATION_KEY cannot authorize actions, which is a critical limitation. This is thorough and goes beyond basic operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured with clear sections (CIRCUITS, WITH ACTION, RETURNS) and front-loaded with the core purpose. The length is justified by the complexity of the tool (12 parameters, 5 circuits, action approval flow). It is not wasteful; every section contributes necessary information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 12 parameters, nested objects, multiple circuits, and a two-step approval flow, the description covers all essential aspects: the combined operation, circuit-specific requirements, the action binding behavior, return types, and the separate verify_proof step. It is sufficiently complete for an agent to decide when to use it and how to handle the flows.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the description does not need to repeat parameter details. It adds value by tying parameters to circuits (e.g., 'Requires country_list and is_included' for coinbase_country, 'Requires jwt and scope' for oidc_domain) and by explaining the approval_id flow and the action parameter's role. This supplements the schema descriptions with cross-parameter context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear purpose: 'All-in-one ZK proof generation' that combines three steps (prepare inputs, request challenge, submit proof) in a single call. It explicitly differentiates itself from the individual step tools by naming them as alternatives for fine-grained control. The circuit list also clarifies the specific use cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is given: 'Use this when you want the simplest path to a proof. For fine-grained control over each step, use prepare_inputs, request_challenge, and submit_proof individually.' It also provides circuit-specific requirements (e.g., coinbase_country requires country_list and is_included) and explains the action approval flow, including when to query get_action_approval and reuse approval_id.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_action_approvalA
Read the status of a human wallet approval created by this MCP client. This operation never starts a proof or payment.
| Name | Required | Description | Default |
|---|---|---|---|
| approval_id | Yes | The approval_id returned by generate_proof or prepare_inputs |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description takes on the behavioral disclosure burden. It explicitly states the operation is read-only and has no side effects on proofs or payments, which is valuable for an agent deciding whether invocation is safe. It does not detail authorization requirements or possible returned statuses, but the core side-effect guarantee is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The primary purpose is front-loaded, and the safety-relevant negation is placed second to reinforce the read-only nature. Every word contributes value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read-only tool, this is largely complete: it identifies what the approval is, where its ID comes from, and that no proof or payment is initiated. It does not describe output fields, but no output schema exists and the tool's role as a status poller is adequately communicated through the sibling context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces that approval_id comes from generate_proof or prepare_inputs, but that same provenance detail also appears in the schema property description. No additional parameter semantics beyond the structured schema are provided.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action and resource: 'Read the status of a human wallet approval created by this MCP client.' This clearly separates it from sibling proof/payment tools, and the second sentence reinforces that it is not a proof-starting or payment-triggering operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: after an approval has been created by this MCP client, to read its status. It also states a key exclusion ('never starts a proof or payment'), although it does not explicitly name alternative tools or define exact polling conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_supported_circuitsA
List all ZK circuits supported by ZKProofport, including verifier addresses and authorized signers. No parameters required. Call this first to discover available circuits before starting proof generation.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description must disclose behavior. It mentions no parameters required but does not state if it's read-only or any side effects. Minimal behavioral info, but acceptable for a simple listing tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no wasted words. Efficiently conveys purpose, output contents, and usage order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has zero parameters and no output schema, the description adequately covers purpose and guidance. Could mention output format or safety of repeated calls, but it's mostly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters defined; description adds value by explicitly stating 'No parameters required,' which reassures the agent. Baseline 4 for zero-parameter tools with coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool lists all ZK circuits with specific details (verifier addresses and authorized signers). Distinguishes from siblings by being a discovery step before proof generation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Call this first to discover available circuits before starting proof generation,' which guides when to use it. Could be improved by specifying when not to use it or naming alternatives, but it's clear for a discovery tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prepare_inputsA
Step 1 of the step-by-step flow. WITH ACTION: human wallet approval is required; returns awaiting_approval until resumed with approval_id. Approved action witnesses stay in private local storage; pass the returned prepared_inputs_id to submit_proof. WITHOUT ACTION: retains the existing credential-key signature and private witness result. Handle private witness inputs only in trusted local code, never expose them to the dApp, model or logs. Call this BEFORE request_challenge. For oidc_domain provide jwt and scope.
| Name | Required | Description | Default |
|---|---|---|---|
| jwt | No | OIDC JWT token (id_token) for oidc_domain circuit | |
| scope | No | Scope string for nullifier derivation. Defaults to "proofport" if omitted. For oidc_domain circuit, this is the domain scope string. | |
| action | No | The EIP-712 action to authorise. Optional for arc_eligibility and giwa_attestation; rejected for other circuits. Any structure is provable: the circuit hashes it without reading it, so a deposit, a grant of authority or an agreement in prose all work. The wallet signs exactly these fields, and the proof carries their hash. | |
| circuit | Yes | Which circuit to use | |
| provider | No | OIDC provider. "google" (default) for Google Workspace, "microsoft" for Microsoft 365. | |
| approval_id | No | Resume the SAME original action request using the approval_id returned with awaiting_approval. Keep all original parameters unchanged. | |
| is_included | No | true = prove country IS in list, false = prove NOT in list. Required for coinbase_country circuit. | |
| country_list | No | ISO 3166-1 alpha-2 country codes. Required for coinbase_country circuit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so well. It discloses async behavior (returns awaiting_approval until resumed with approval_id), persistence semantics (witnesses stay in private local storage), the difference between action and no-action behavior, and a critical security caveat (never expose private witnesses to dApp/model/logs). This goes far beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized, with WITH ACTION/WITHOUT ACTION framing and a clear security warning. It front-loads the tool's role in the flow. A few ideas are compressed into long sentences, but every sentence contributes necessary behavioral or sequencing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 8 parameters, nested action objects, async approval, and no output schema, the description covers the essential runtime behaviors, sequencing, and security constraints. It partially describes return values (awaiting_approval, prepared_inputs_id) and the resume mechanismamazon. It does not enumerate all possible return fields or error cases, but the schema and flow context make it sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 and the schema already documents every parameter. The description adds workflow-level meaning: jwt and scope are explicitly required for oidc_domain, approval_id resumes the same original action, and action maps to the WITH ACTION mode. This enriches but does not replace the schema detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies this as 'Step 1 of the step-by-step flow' and explains its concrete role: producing a prepared_inputs_id to pass to submit_proof)SkipSignal. It also distinguishes itself from sibling tools by naming the required ordering ('Call this BEFORE request_challenge') and the handoff to submit_proof. The action/no-action modes further clarify what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit invocation conditions: WITH ACTION requires human wallet approval, WITHOUT ACTION retains existing signatures, and oidc_domain requires jwt and scope. It also states the correct ordering relative to request_challenge. It does not, however, explicitly say when to prefer sibling tools like get_action_approval or generate_proof, so guidance is strong but not fully exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_challengeA
Step 2 of the step-by-step flow: Request a challenge from the server. Pass inputs: {} to discover the live payment offers, nonce and optional TEE key without transmitting private witness inputs. You MUST pass the returned "nonce" to submit_proof — without it the server just issues another challenge. MCP submit_proof does not sign payments or encrypt inputs; use generate_proof or the SDK for paid/encrypted orchestration.
| Name | Required | Description | Default |
|---|---|---|---|
| inputs | Yes | Use {} to discover the nonce, payment offers and optional TEE key without transmitting private witness inputs. Also accepts a JSON string or object from trusted local code; any supplied witness is sent to the selected prover and must stay out of model context, dApp/UI and logs. | |
| circuit | Yes | Which circuit to use |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses security-relevant behavior: that the tool does not sign payments or encrypt inputs, and that '{}' prevents transmission of private witness data. It also highlights the server-side nonce issuance and its necessity for subsequent steps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise yet information-dense, with critical points front-loaded: step indication, the recommendation to use '{}', and the nonce requirement. Every sentence earns its place, covering purpose, usage, and security implications without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (2 params, no output schema), the description provides comprehensive guidance on what the tool does, when to use it, how to use it safely, and what to do with the result (pass nonce to submit_proof). It also covers the alternative for paid/encrypted use, making it self-sufficient for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds crucial meaning: it explains that '{}' is sufficient for anonymous discovery, warns that providing witness data sends it to the prover and must be kept out of context/logs, and clarifies the circuit enum's purpose. This goes well beyond the schema's minimal descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it is 'Step 2 of the step-by-step flow: Request a challenge from the server' and specifies the resource and action. It distinguishes itself from siblings like submit_proof by explaining its role and the critical dependency on the returned nonce.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly recommends passing '{}' to avoid transmitting private data, warns against using submit_proof for signing, and directs to generate_proof or the SDK for paid/encrypted flows. This provides clear when-to-use and when-not-to-use guidance with specific alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_proofA
Step 3 of the step-by-step flow: Submit prepared inputs to generate the ZK proof. The TEE server runs the Noir circuit and returns the UltraHonk proof. This step may take 30-90 seconds. The TEE server builds Prover.toml from these inputs.
You MUST pass the nonce returned by request_challenge. POST /api/v1/prove answers every request that arrives without that nonce with a fresh 402 challenge, so a submission that omits it can never produce a proof.
| Name | Required | Description | Default |
|---|---|---|---|
| nonce | Yes | The "nonce" field from the request_challenge response. Single-use and bound to the circuit it was issued for — request a new challenge for every submission and for every circuit. | |
| inputs | No | Full ProveInputs object from prepare_inputs. Accepts a JSON string or a structured object. | |
| circuit | Yes | Which circuit to use | |
| prepared_inputs_id | No | Private local action witness handle returned by prepare_inputs. Use instead of inputs; consumed once. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure, and it delivers: it states the TEE server runs the Noir circuit, the operation takes 30-90 seconds, Prover.toml is built from inputs, the response is an UltraHonk proof, and omitting the nonce triggers a fresh 402 challenge. This is strong, concrete behavioral transparency for a no-annotation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with its purpose and structured as a short overview followed by a critical usage warning. It is not bloated, though the first paragraph mentions the TEE server twice ('runs the Noir circuit' and 'builds Prover.toml'), which is a minor redundancy. Otherwise, every sentence contributes useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations and no output schema, the description covers workflow position, prerequisites, latency, a failure mode, and the expected result type. The schema covers the parameter-level details such as the choice between `inputs` and `prepared_inputs_id`. It is not exhaustive about the exact response shape, but it gives enough context for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the schema already documents `nonce`, `inputs`, `circuit`, and `prepared_inputs_id` with their constraints. The description adds emphasis that the nonce is mandatory and that the server builds Prover.toml from inputs, but it does not add substantial new parameter-level meaning. A 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Step 3 of the step-by-step flow' and a specific verb+object: 'Submit prepared inputs to generate the ZK proof.' It clearly identifies the resource (prepared inputs) and the outcome (UltraHonk proof). However, it does not explicitly contrast itself with the sibling `generate_proof`, so differentiation is implicit rather than direct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear positional context ('Step 3'), names the required prerequisite inputs (prepared inputs, nonce from request_challenge), and states the hard requirement to include the nonce. The warning about the 402 challenge tells the agent when a submission cannot succeed. It does not enumerate alternatives or when-not-to-use, but the step-based context is sufficient for routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_proofA
Step 4 (optional): Verify a ZK proof on-chain against the deployed verifier contract. Pass the full generate_proof result object directly — verification info (verifierAddress, chainId, rpcUrl) is extracted automatically. Returns { valid: true } if the proof is valid.
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes | Full result object from generate_proof — pass it directly without extracting fields |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose all behavioral traits. It states the tool verifies on-chain and returns a success object, but does not mention potential gas costs, network dependencies, failure responses, or side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no wasted words. It front-loads the purpose and incrementally adds context on how to use the tool and what to expect.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the nested object parameter and lack of output schema, the description effectively covers the main use case and expected return for a valid proof. However, it omits error handling, edge cases, and a full return structure description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with descriptions for all properties. The description adds value by explaining to pass the result object directly, but it reinforces usage rather than adding new semantic meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action ('Verify a ZK proof on-chain'), the specific resource ('against the deployed verifier contract'), and its place in a workflow ('Step 4 (optional)'). It distinguishes itself from siblings like generate_proof and submit_proof.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description instructs users to 'Pass the full generate_proof result object directly,' providing clear how-to guidance. It frames the tool as an optional step after proof generation, but lacks explicit when-not-to-use or mention of alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.2.45- Changed
generate_proof1 field changed- added
Input schema / properties / approval_idAdded value: +{ + "description": "Resume the SAME original action request using the approval_id returned with awaiting_approval. Keep all original parameters unchanged.", + "type": "string" +}
- Added
get_action_approval - Changed
prepare_inputs1 field changed- added
Input schema / properties / approval_idAdded value: +{ + "description": "Resume the SAME original action request using the approval_id returned with awaiting_approval. Keep all original parameters unchanged.", + "type": "string" +}
- Changed
submit_proof2 fields changed- added
Input schema / properties / prepared_inputs_idAdded value: +{ + "description": "Private local action witness handle returned by prepare_inputs. Use instead of inputs; consumed once.", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "circuit", - "inputs", - "nonce" -]New value: +[ + "circuit", + "nonce" +]
4 tool updates
v0.2.44- Changed
generate_proof3 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"The EIP-712 action to authorise. Required for arc_eligibility and rejected for every other circuit. Any structure is provable: the circuit hashes it without reading it, so a deposit, a grant of authority or an agreement in prose all work. The wallet signs exactly these fields, and the proof carries their hash."New value: +"The EIP-712 action to authorise. Optional for arc_eligibility and giwa_attestation; rejected for other circuits. Any structure is provable: the circuit hashes it without reading it, so a deposit, a grant of authority or an agreement in prose all work. The wallet signs exactly these fields, and the proof carries their hash." - changed
Input schema / properties / approved_payment / descriptionPrevious value: -"Exact user-approved terms. The SDK rejects any changed fee, recipient, token, chain or Gateway signing domain before signing the actual challenge."New value: +"Exact user-approved terms. For direct EIP-3009 set extra.verifyingContract to the offer asset; for Gateway copy its required extra.verifyingContract. Changed fee, recipient, token, chain or signing domain is rejected before signing." - changed
Input schema / properties / circuit / enumPrevious value: -[ - "coinbase_kyc", - "coinbase_country", - "oidc_domain", - "arc_eligibility" -]New value: +[ + "coinbase_kyc", + "coinbase_country", + "oidc_domain", + "arc_eligibility", + "giwa_attestation" +]
- Changed
prepare_inputs2 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"The EIP-712 action to authorise. Required for arc_eligibility and rejected for every other circuit. Any structure is provable: the circuit hashes it without reading it, so a deposit, a grant of authority or an agreement in prose all work. The wallet signs exactly these fields, and the proof carries their hash."New value: +"The EIP-712 action to authorise. Optional for arc_eligibility and giwa_attestation; rejected for other circuits. Any structure is provable: the circuit hashes it without reading it, so a deposit, a grant of authority or an agreement in prose all work. The wallet signs exactly these fields, and the proof carries their hash." - changed
Input schema / properties / circuit / enumPrevious value: -[ - "coinbase_kyc", - "coinbase_country", - "oidc_domain", - "arc_eligibility" -]New value: +[ + "coinbase_kyc", + "coinbase_country", + "oidc_domain", + "arc_eligibility", + "giwa_attestation" +]
- Changed
request_challenge1 field changed- changed
Input schema / properties / circuit / enumPrevious value: -[ - "coinbase_kyc", - "coinbase_country", - "oidc_domain", - "arc_eligibility" -]New value: +[ + "coinbase_kyc", + "coinbase_country", + "oidc_domain", + "arc_eligibility", + "giwa_attestation" +]
- Changed
submit_proof1 field changed- changed
Input schema / properties / circuit / enumPrevious value: -[ - "coinbase_kyc", - "coinbase_country", - "oidc_domain", - "arc_eligibility" -]New value: +[ + "coinbase_kyc", + "coinbase_country", + "oidc_domain", + "arc_eligibility", + "giwa_attestation" +]
6 tool updates
v0.2.43- Added
deposit_to_gateway - Added
gateway_balance - Changed
generate_proof6 fields changed- added
Input schema / properties / actionAdded value: +{ + "additionalProperties": false, + "description": "The EIP-712 action to authorise. Required for arc_eligibility and rejected for every other circuit. Any structure is provable: the circuit hashes it without reading it, so a deposit, a grant of authority or an agreement in prose all work. The wallet signs exactly these fields, and the proof carries their hash.", + "properties": { + "domain": { + "additionalProperties": false, + "properties": { + "chainId": { + "type": "number" + }, + "name": { + "type": "string" + }, + "verifyingContract": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version", + "chainId", + "verifyingContract" + ], + "type": "object" + }, + "message": { + "additionalProperties": {}, + "type": "object" + }, + "primaryType": { + "type": "string" + }, + "types": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "type": "object" + } + }, + "required": [ + "domain", + "types", + "primaryType", + "message" + ], + "type": "object" +} - added
Input schema / properties / approved_paymentAdded value: +{ + "additionalProperties": false, + "description": "Exact user-approved terms. The SDK rejects any changed fee, recipient, token, chain or Gateway signing domain before signing the actual challenge.", + "properties": { + "amount": { + "pattern": "^\\d+$", + "type": "string" + }, + "asset": { + "type": "string" + }, + "extra": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "verifyingContract": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version", + "verifyingContract" + ], + "type": "object" + }, + "network": { + "type": "string" + }, + "payTo": { + "type": "string" + }, + "scheme": { + "type": "string" + } + }, + "required": [ + "network", + "scheme", + "amount", + "asset", + "payTo", + "extra" + ], + "type": "object" +} - changed
Input schema / properties / circuit / enumPrevious value: -[ - "coinbase_kyc", - "coinbase_country", - "oidc_domain" -]New value: +[ + "coinbase_kyc", + "coinbase_country", + "oidc_domain", + "arc_eligibility" +] - added
Input schema / properties / max_paymentAdded value: +{ + "description": "Maximum USDC proof fee allowed by the user.", + "pattern": "^\\d+(\\.\\d{1,6})?$", + "type": "string" +} - added
Input schema / properties / pay_onAdded value: +{ + "description": "Which chain to pay on: a CAIP-2 id (\"eip155:5042002\") or a plain name (\"arc-testnet\", \"arc-testnet-nano\", \"base-sepolia\"). Call request_challenge to see what a service offers. Omitted takes the first chain offered. The payer signs an authorization and the service settles it, so no gas or native balance is needed on the paying chain -- only USDC. \"arc-testnet-nano\" is Arc nanopayments: the authorization goes to Circle Gateway, which verifies it off chain in under a second and settles it later in a batch with thousands of others, so the gas per payment approaches zero. It requires a Gateway balance -- deposit first with the deposit_to_gateway tool -- and is the right choice for an agent buying many proofs. \"arc-testnet\" settles each payment on chain immediately and costs gas every time.", + "type": "string" +} - added
Input schema / properties / pay_withAdded value: +{ + "description": "Which wallet pays, when the service charges. \"arc\" is an Arc agent wallet — Circle holds it, it carries spending policies the agent cannot ignore, and Circle CLI signs with it (install: npm i -g @circle-fin/cli, then circle wallet login <email> --testnet). \"key\" signs with PAYMENT_PRIVATE_KEY. \"cdp\" uses a Coinbase CDP server wallet (CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET). \"circle\" uses a Circle developer-controlled wallet (CIRCLE_API_KEY, CIRCLE_ENTITY_SECRET, CIRCLE_WALLET_ID) when that wallet supports the selected offer. Omit it and the single configured wallet is used; omit it with none configured against a paying service and the error names what to set. Wallet and chain are separate choices; both must support the actual offered signing domain.", + "enum": [ + "key", + "cdp", + "circle", + "arc" + ], + "type": "string" +}
- Changed
prepare_inputs2 fields changed- added
Input schema / properties / actionAdded value: +{ + "additionalProperties": false, + "description": "The EIP-712 action to authorise. Required for arc_eligibility and rejected for every other circuit. Any structure is provable: the circuit hashes it without reading it, so a deposit, a grant of authority or an agreement in prose all work. The wallet signs exactly these fields, and the proof carries their hash.", + "properties": { + "domain": { + "additionalProperties": false, + "properties": { + "chainId": { + "type": "number" + }, + "name": { + "type": "string" + }, + "verifyingContract": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version", + "chainId", + "verifyingContract" + ], + "type": "object" + }, + "message": { + "additionalProperties": {}, + "type": "object" + }, + "primaryType": { + "type": "string" + }, + "types": { + "additionalProperties": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "type": "object" + } + }, + "required": [ + "domain", + "types", + "primaryType", + "message" + ], + "type": "object" +} - changed
Input schema / properties / circuit / enumPrevious value: -[ - "coinbase_kyc", - "coinbase_country", - "oidc_domain" -]New value: +[ + "coinbase_kyc", + "coinbase_country", + "oidc_domain", + "arc_eligibility" +]
- Changed
request_challenge2 fields changed- changed
Input schema / properties / circuit / enumPrevious value: -[ - "coinbase_kyc", - "coinbase_country", - "oidc_domain" -]New value: +[ + "coinbase_kyc", + "coinbase_country", + "oidc_domain", + "arc_eligibility" +] - changed
Input schema / properties / inputs / descriptionPrevious value: -"Full ProveInputs object from prepare_inputs. Accepts a JSON string or a structured object."New value: +"Use {} to discover the nonce, payment offers and optional TEE key without transmitting private witness inputs. Also accepts a JSON string or object from trusted local code; any supplied witness is sent to the selected prover and must stay out of model context, dApp/UI and logs."
- Changed
submit_proof3 fields changed- changed
Input schema / properties / circuit / enumPrevious value: -[ - "coinbase_kyc", - "coinbase_country", - "oidc_domain" -]New value: +[ + "coinbase_kyc", + "coinbase_country", + "oidc_domain", + "arc_eligibility" +] - added
Input schema / properties / nonceAdded value: +{ + "description": "The \"nonce\" field from the request_challenge response. Single-use and bound to the circuit it was issued for — request a new challenge for every submission and for every circuit.", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "circuit", - "inputs" -]New value: +[ + "circuit", + "inputs", + "nonce" +]
TDQS
Scored across 9 tools
Each tool maps to a distinct workflow stage (deposit, challenge, submit, verify) or resource (circuits, balance, approvals). The only overlap is generate_proof bundling prepare_inputs/request_challenge/submit_proof, but its description explicitly frames it as the all-in-one alternative to the step-by-step tools.
Most tools follow a verb_object pattern: prepare_inputs, submit_proof, verify_proof, request_challenge, get_supported_circuits, get_action_approval. gateway_balance breaks the pattern by omitting the verb, and deposit_to_gateway includes a preposition, but the naming is otherwise consistent and predictable.
Nine tools is well-scoped for the domain: payment management, proof-generation steps, an all-in-one path, approval handling, and verification. Each tool has a distinct role and none feel redundant or excessive.
The set covers the full proof lifecycle: discovering circuits, depositing and checking funds, preparing inputs, requesting challenges, submitting proofs, verifying on-chain, and handling human approvals. There are no dead ends in the core workflow, and the all-in-one generate_proof covers the paid/encrypted pathway that individual steps cannot.
Maintenance
Related MCP Connectors
A paid remote MCP for ZeroID, built to return verdicts, receipts, usage logs, and audit-ready JSON.
MCP server for verifying EUDI/Talao wallet data via OIDC4VP (pull) for AI agents.
Remote MCP server exposing 330 production AI-agent services for web/data processing, validation, AI utilities, blockchain/crypto utilities, and x402 pay-per-use access.
- mcpOAuthai.agentgates
Confidential compute and inference sold to agents over x402 USDC, plus an agent wallet over MCP.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server for on-chain attestation and wallet trust profiles across 31 EVM chains and Solana. Privacy-preserving boolean verification, ECDSA-signed responses, compliance templates.27426 npm1MIT
- AlicenseAqualityDmaintenanceTrust intelligence MCP server for AI agents. 19 tools for identity stamps, reputation scoring (0-100), agent registry, forensic audit trails, ERC-8004 bridge, and A2A passports via x402 USDC micropayments.191Apache 2.0
- AlicenseNot gradedqualityDmaintenanceMCP Server for AI agent identity and authorization. Create, verify, and manage agent identities with trust scores and scoped authorization tokens.MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server for agentic commerce, enabling AI agents to discover services, make x402 payments with USDC across multiple chains, and manage crypto wallets and token swaps.335 npm1MIT