quorum
Attested multi-agent consensus: proposals, votes, and outcomes stamped and traced.
Should I use this
Quality & Safety
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"quorum": {
"url": "https://quorum-mcp.terradev.cloud/mcp"
}
}
}Remote endpoints
https://quorum-mcp.terradev.cloud/mcpstreamable-httpWhat it can do
Tool inventory
Tools (7)
⚪register(api_key, telinea_key)
OPTIONAL one-time setup -- only needed if you want proposal telemetry (OTLP spans) pushed to your Telinea account. Call once before propose: it binds an api_key you choose to your Telinea API key. Afterwards, pass the same api_key on propose and every span for that proposal is pushed to your Telinea with standard OTLP bearer auth. Storage: the Telinea key is sealed with AES-256-GCM under a key derived from your api_key (HKDF-SHA256, per-account salt); only sha256(api_key) is kept as the lookup id, so neither key is ever stored in the clear. Re-registering with the same api_key rotates the stored Telinea key. Skip this tool entirely for anonymous use -- propose works without an api_key, just with no span streaming.
Input Schema
{
"type": "object",
"properties": {
"api_key": {
"type": "string",
"description": "Your Quorum API key -- chosen by you, presented on propose, never stored."
},
"telinea_key": {
"type": "string",
"description": "Your Telinea API key -- stored encrypted, used to authenticate span pushes."
}
},
"required": [
"api_key",
"telinea_key"
]
}⚪propose(api_key, name, namespace, question, voters, ...)
Open a new proposal: a question, named options, expected voter identities, an aggregation algorithm, a deadline, and a quorum threshold. Returns the proposal id, the creation attestation, and the deadline. All later operations key off the proposal id.
Input Schema
{
"type": "object",
"properties": {
"api_key": {
"type": "string",
"description": "Optional. Your Quorum API key (from register). Binds the proposal to your account so its spans push to your Telinea. Omit for anonymous use -- everything works, no spans."
},
"name": {
"type": "string",
"description": "Human-readable proposal id, e.g. pr-review-2026-09-18. Letters, digits, . _ - only; becomes the key for all subsequent calls."
},
"namespace": {
"type": "string",
"description": "Optional tenant namespace. The proposal id becomes '<namespace>:<name>' -- different teams can reuse names without colliding. Same charset as name."
},
"question": {
"type": "string",
"description": "The thing being decided."
},
"voters": {
"type": "array",
"items": {
"type": "string"
},
"description": "Expected voter identities. Only these may vote; missing voters at resolution are recorded abstained."
},
"deadline_minutes": {
"type": "number",
"description": "Minutes until voting closes."
},
"options": {
"type": "array",
"items": {
"type": "string"
},
"description": "Named options. Default [\"yes\",\"no\"]."
},
"algorithm": {
"type": "string",
"enum": [
"plurality",
"borda",
"condorcet",
"approval",
"opinion_pool",
"supermajority"
],
"description": "Aggregation algorithm. Default approval -- robust general-purpose choice with no strategic incentive."
},
"quorum": {
"type": "number",
"description": "Min percent of expected voters that must vote before resolution. Default 100."
},
"threshold": {
"type": "number",
"description": "Supermajority only: required share of votes cast, percent. Default 66.67."
},
"description": {
"type": "string",
"description": "Optional context for the audit trail."
}
},
"required": [
"name",
"question",
"voters",
"deadline_minutes"
]
}🟡write(proposal_id, key, value, author)
Append a key-value entry to a proposal's blackboard. Any agent may write; writes are appended, never replaced -- the full ordered history is preserved and attested.
Input Schema
{
"type": "object",
"properties": {
"proposal_id": {
"type": "string"
},
"key": {
"type": "string",
"description": "Key other agents use to filter this entry on read."
},
"value": {
"description": "Any JSON value."
},
"author": {
"type": "string",
"description": "Optional author identity, recorded and attested."
}
},
"required": [
"proposal_id",
"key",
"value"
]
}🟡read(proposal_id, key)
Read a proposal's blackboard: every write in order with timestamp, author, and attestation id -- the complete deliberation record, or filtered to one key.
Input Schema
{
"type": "object",
"properties": {
"proposal_id": {
"type": "string"
},
"key": {
"type": "string",
"description": "Optional: only entries with this key."
}
},
"required": [
"proposal_id"
]
}🟡vote(proposal_id, voter, value, reasoning)
Submit a vote from an expected voter identity, with optional reasoning stored in the attested record. Vote shape depends on the algorithm: plurality/supermajority take an option string; approval takes an option or list of options; borda takes a ranking of all options; condorcet takes a ranking or a single option; opinion_pool takes a probability distribution over options. Duplicates and post-deadline votes are rejected.
Input Schema
{
"type": "object",
"properties": {
"proposal_id": {
"type": "string"
},
"voter": {
"type": "string"
},
"value": {
"description": "Ballot in the algorithm's format."
},
"reasoning": {
"type": "string",
"description": "Free-text rationale, kept in the audit trail."
}
},
"required": [
"proposal_id",
"voter",
"value"
]
}🟢resolve(proposal_id)
Compute and attest the outcome once quorum is met (or the deadline has passed). Idempotent: resolving twice returns the recorded outcome. Condorcet cycles and missed supermajority thresholds return co_winners with status unresolved rather than an arbitrary tiebreak.
Input Schema
{
"type": "object",
"properties": {
"proposal_id": {
"type": "string"
}
},
"required": [
"proposal_id"
]
}⚪history(proposal_id, filter)
The complete attested record of a proposal in chronological order: creation, every blackboard write, every vote with reasoning, the outcome. Optional filter: all | writes | votes | outcome.
Input Schema
{
"type": "object",
"properties": {
"proposal_id": {
"type": "string"
},
"filter": {
"type": "string",
"enum": [
"all",
"writes",
"votes",
"outcome"
],
"description": "Default all."
}
},
"required": [
"proposal_id"
]
}Community
Evidence