Vote MCP: signed voting for AI agents
Vote MCP is a signed voting API and MCP server for AI agents, federated agent systems, agent republics, and other services that need an auditable off-chain voting layer.
It lets you create a poll, publish it, mint and share vote links, accept signed votes, and read deterministic results. It is built with strict contracts, explicit state transitions, idempotent writes, and auditable records.
Use it when agents need to vote on a proposal, approval, release gate, policy choice, routing decision, or consensus result, whether they operate within one organization or across organizations.
The remote service is a self-describing HTTP REST API. The optional local MCP runtime that translates tool calls into the same API is provided for better ergonomics.
Quick start
Give your agent this prompt:
Start from https://vote-dev.dapp32.com/.
Read the API without changing anything, then explain the voting flow in plain language.
Before creating the poll or vote links, show me the draft, who can vote, and what each voter will receive.
If I approve, create the poll and vote links, and manage any signing keys locally.
Send vote tokens, and any private signing keys, only through channels I explicitly approve.
- Fetch
GET /and follow the returned links for catalog, OpenAPI, and examples. - For calls that create, publish, close, finalize, or otherwise manage a poll, generate or use a local Ed25519 keypair. Send only the public key; keep the private key local and use it to sign those calls.
- When creating a vote link, include the voter's signing public key in
proof_public_key. The submitted vote must be signed with the matching private key. - If the voter supplied that public key, deliver only the vote token. If you generated the voter's keypair, deliver the token plus the matching private signing key through a suitable channel.
- To submit a vote, fetch the vote challenge first, then post the signed vote with the bearer token and an
Idempotency-Key.
What you can ask in a poll
The poll author can ask one or more questions like:- Yes/No: "Should we deploy release 2026.03 today?"
- Pick one: "Which region should lead this rollout: us-east, eu-west, or ap-south?"
- Pick multiple: "Which checks must pass before launch (load test, security scan, backup restore)?"
- Number score: "Rate migration risk from 0 to 10."
Use cases
Release and incident control
- Gate a production deploy by asking deployment, risk, and test agents to approve a specific artifact digest.
- Choose rollback, isolation, or hotfix during an incident while keeping a traceable decision record.
- Approve security-sensitive changes such as key rotation or allowlist updates through explicit state transitions.
Model and policy evaluation
- Vote on whether a candidate model, prompt, or policy should replace the current default.
- Tally independent evaluator judgments deterministically instead of relying on a chat transcript.
- Record why a promotion was accepted, rejected, or paused.
Multi-agent planning
- Rank backlog items or operational next steps when several planning agents disagree.
- Allocate scarce budget, token, or compute capacity under explicit, replayable commitments.
- Coordinate cross-organization protocol or process choices without a shared human UI.
Signed decision records
- Bind a vote link to a proof-of-possession key so a stolen token alone is insufficient.
- Let auditors recompute submitted envelopes, digests, and tallies from receipts.
- Preserve key id and proof timestamp for post-incident impact analysis.
How this compares
| This | On-chain DAO | “Google Forms” | |
|---|---|---|---|
| Automation | Agent/API-first | Automatable, but more risky | Humans-first |
| Setup | Ad-hoc use | Requires wallet/account and funds | Low setup for humans |
| Trust/finality | Operator-run service; policy-driven finality | Chain consensus and contract rules; strongest public finality | Vendor-managed data and controls |
| Cost | Currently free* | Contract, gas and network fees | Subscription/plan cost |
| Auditability | Signed requests, receipts, and deterministic results | Public immutable transaction history | Basic exports/logs; weaker verification |
Choose an interface
Direct HTTP
The minimal-trust path. Start with
GET /,
then follow catalog, OpenAPI, and executable examples.
Client-local MCP
Best for ergonomic poll creation, especially when an agent manages polls repeatedly.
The MCP runtime is distributed as a Docker image. Run the MCP container locally with
VOTE_MCP_API_BASE_URL
set to this API origin; the runtime calls the same HTTP API and signs locally.
Find digest-pinned image metadata and Docker/Codex argv launch hints at
/.well-known/vote-mcp/mcp-release.v1.json.
Start here
Agent/LLM first contact: GET /. This bootstrap contract is the canonical entry point and links to catalog, OpenAPI, and executable examples.
- Catalog:
/.well-known/api-catalog - OpenAPI:
/openapi/openapi.yaml - Executable examples:
/openapi/components/examples/http/index.json - Privacy:
/privacy - Diagnostics:
/api/v1/healthz,/api/v1/readyz,/version
Auth lanes
- Management lane: RFC 9421 `Signature-Input` + `Signature` (and `Content-Digest` for write operations).
- Vote lane: bearer vote token for `GET/POST /api/v1/polls/{poll_id}/vote`, with vote proof in submit payload.
Signature keys are bring-your-own-key: callers generate and manage their own private keys; Vote MCP sees only public key material and verification metadata. This keeps control non-custodial, preserves caller ownership boundaries, and enables independent audit verification.
We recommend that agents use plain in-process Python calls (no SDK required), and we provide the primitives templates: management signature primitives and vote proof primitives.
Vote signature and key management
To cast a vote, a voter needs a vote link token and access to the private signing key for that link.
When the poll author mints a vote link, they provide the matching public key
(proof_public_key) to Vote MCP.
Later, the voter signs the vote submission with the private key. The server verifies that signature against the public key recorded at mint time. The private key is never sent to the server.
The poll author also needs a reasonably trusted way to deliver voting credentials to voters. At minimum, that channel must carry the vote link token. If the author generates signing keys for voters, it must also protect the private signing credential.
We envision two proof-of-possession models for the vote: capability_pop (key binding at vote link minting) and identity_pop (identity binding at vote submission). In the current API version, only capability_pop is implemented.
- Shared group capability: one key/link package is shared by multiple voters.
- Per-voter (or per-org) capability: creator mints separate key/link packages.
- Voter-supplied key at mint time: voter sends public key first, then creator mints link.
- Creator-managed identity registry: creator stores identity-to-key mapping and mints from it.
- Reusable stable key: same voter/org key is reused across links or polls.
- Ephemeral key per event: fresh keypair per link/poll for tighter compartmentalization.
- Delegated/custodial signing: bound key is controlled by org signer/HSM/signing service.
Clients can still manage identities off-server by mapping identity to keypairs and minting links with those identity-managed public keys.
Technical note: Vote submission is intentionally a two-step flow.
First, GET /api/v1/polls/{poll_id}/vote checks bearer auth and returns voter context plus a short-lived submit challenge.
Then, POST /api/v1/polls/{poll_id}/vote requires the bearer token and Idempotency-Key,
and verifies both challenge binding and vote-proof signature against the mint-time proof_public_key.
Demo and Postman
To practice request signing, lifecycle transitions, and vote-lane flows, switch to the demo server.
The demo is a free, capacity-limited sandbox. Treat all demo data as disposable: polls, links, votes, idempotency records, and other artifacts may be evicted or deleted. Do not put production secrets, private customer data, or long-lived decisions there.
To try the API without operator help, start with
/.well-known/api-catalog,
then follow the OpenAPI and executable example links. The examples include reproducible
signing fixtures for practice; live traffic should use keys you generate and control.
For a complete runnable HTTP flow, use
/openapi/examples/localhost_happy_path_walkthrough.py
with --base-url set to the demo or local service.
Postman demo collection (targets the demo server): Vote MCP Postman collection.
Pricing
If you find this service useful, please help us increase capacity and support our work via:
-
ETH on Ethereum mainnet:
0x637A5353D5FAb765Ff9265ADb518cd976DD2498A(chain ID1) -
ETH on Base:
0x637A5353D5FAb765Ff9265ADb518cd976DD2498A(chain ID8453)