Skip to main content
Glama

Safe-MPC

An MCP (Model Context Protocol) server that connects a Safe smart-account wallet to AI agents so they can read DAO proposals and vote as the Safe — off-chain on Snapshot, and on-chain through OpenZeppelin or Compound-style Governors.

Point Claude Code, Claude Desktop, Cursor, or your own agent at this server and the Safe becomes a voter your agent can operate.

It runs two ways. On demand, as an MCP server your agent calls when you ask it to vote. Unattended, with the bundled safe-mpc-watch scheduler, which polls for new proposals and asks an agent to decide as each deadline approaches.

How voting works

Snapshot (off-chain, gasless). The Safe cannot sign an EIP-712 payload itself, so the vote is signed as an EIP-1271 contract signature. Safe-MPC builds the Snapshot Vote payload, registers it as a Safe message, waits for the Safe Transaction Service to assemble a signature meeting the Safe's threshold, then posts it to the Snapshot sequencer. Voting again on the same proposal replaces the earlier vote.

Governor (on-chain). Safe-MPC encodes castVoteWithReason and sends it as a Safe transaction. This costs gas and is final once mined. Every vote runs pre-flight checks against the Governor first: the proposal must be Active, the Safe must not have voted already, and it must have had voting power at the proposal's snapshot.

Proposals are discovered by reading ProposalCreated logs from the Governor contract, so no third-party indexer sits anywhere in the path, and no API key is needed to find a proposal. Nothing here depends on a hosted governance API staying up.

The EIP-712 vote types match @snapshot-labs/snapshot.js field for field, including the three distinct shapes Snapshot uses (uint32 for single-choice and basic, uint32[] for approval and ranked-choice, a JSON string for weighted and quadratic). The hub re-derives the typed-data hash from the payload it receives, so this has to agree exactly.

Related MCP server: Safe MCP Server

Where the Safe votes

You should not have to hand the agent a list of DAOs. Safe-MPC works out where the Safe can vote and asks it to vote there.

snapshot_spaces_with_voting_power assembles the candidates from four places — the spaces the Safe follows on Snapshot, the spaces it has voted in before, the spaces you configured, and the test space — then reads the Safe's voting power in each and keeps the ones where it has any. snapshot_open_proposals turns that into the Safe's actual ballot: every proposal open for a vote across those spaces, soonest deadline first.

> Which DAOs can this Safe vote in, and is anything open?

  snapshot_spaces_with_voting_power → 2 spaces
  snapshot_open_proposals           → 3 proposals, one closing in 4h

The scheduler uses the same discovery. With WATCH_SNAPSHOT_AUTO=true, which is the default, safe-mpc-watch re-resolves the watched spaces on every pass, so a Safe that is delegated voting power in a new space starts being asked to vote there without anyone editing a config file. WATCH_SNAPSHOT_SPACES still names spaces explicitly, and those are watched even at zero voting power, because a space you named on purpose may be about to grant the Safe weight.

Voting power here is read at the current block, which answers "is this space worth watching". Whether a particular vote will count is a different question, asked again per proposal at that proposal's snapshot block before anything is signed.

SNAPSHOT_TEST_SPACE defaults to staging.daoplomats.eth: a space that is always tested and always watched, so a fresh install has somewhere to exercise the whole path end to end before being pointed at a DAO that matters. Set it empty in .env to drop it.

If ALLOWED_SNAPSHOT_SPACES is set, it wins over all of this. Spaces outside the allowlist are never tested, never watched, and never voted in.

Setup

1. Install

git clone https://github.com/Zoldenburg-me/Safe-MPC.git
cd Safe-MPC
npm install
npm run build

2. Run setup

There is no web UI to pick a Safe in. Safe-MPC is a headless stdio process, so this command is the setup screen:

npm run setup

It generates the agent's EOA, shows you the address to add as a Safe owner, asks for the Safe and chain, and writes .env with mode 600. Votes are live from the start: setup writes DRY_RUN=false, and --dry-run is how you opt into a rehearsal instead. For scripts and containers there is a non-interactive form:

node dist/setup.js --safe 0xYourSafe --chain 1 --rpc https://... --api-key ...
node dist/setup.js --safe 0xYourSafe --space mydao.eth --dry-run
node dist/setup.js --new-key      # just print a fresh keypair, write nothing
npm run check                     # verify readiness against the live chain

npm run check is worth running before you wire up any agent. It reports the chain, both addresses, the agent's ETH balance, whether the agent is an owner, the threshold, every Snapshot space the Safe holds voting power in, and, if a Safe API key is set, every Safe the agent owns on that chain. It exits non-zero and names what is missing when the agent cannot vote — including a Safe with no voting power anywhere, which is the failure that otherwise only shows up when a vote is rejected.

The server and the watcher both read .env from the working directory and then from the package root, so you do not have to repeat the config in your MCP client. Real environment variables always win over the file.

3. Add the agent as a Safe owner

Setup prints the agent address. Add it at app.safe.global, under Settings, then Setup, then Add new owner. That is the only screen involved, and it is Safe's, not ours. The agent key never holds the treasury — it only signs.

The Safe's threshold decides how much the agent can do alone:

Threshold

What a vote tool does

1

Casts the vote outright.

2 or more

Queues the vote and reports what is still needed. Other owners confirm in the Safe UI, then snapshot_submit_pending_vote or safe_confirm_transaction finishes it.

A 1-of-N Safe gives the agent full autonomy. Raise the threshold to put a human in the loop without changing anything here.

4. Configure the rest

Setup writes the essentials. .env.example documents every other setting, and cp .env.example .env is the manual route if you would rather not use setup at all.

You need a SAFE_API_KEY from developer.safe.global. The key is free. The Safe SDK builds its Transaction Service client before any request is made, and that constructor refuses a missing key, so every tool that touches the Safe needs one. That includes governor_vote from a threshold-1 Safe, which executes straight over RPC and never calls the service. Read-only discovery works without a key, but voting does not, so the server refuses to start without either SAFE_API_KEY or a self-hosted SAFE_TX_SERVICE_URL.

Votes are live unless you ask otherwise. DRY_RUN is off by default and setup writes DRY_RUN=false. Set it to true — or run setup with --dry-run — and every vote tool returns the exact payload it would have submitted, signing nothing. A dry run reports blocked votes too, payload included, so the path can be demonstrated on a Safe that has no voting power yet.

A variable set in the process environment beats .env. An MCP client that launches the server with "DRY_RUN": "true" in its own config keeps winning over the file however many times you edit it, and a plain restart may not reload that config — the server entry has to be updated. safe_info reports both the value in force and where it came from, so this is visible rather than baffling.

5. Write a voting policy

Drop your operating values into knowledge/ as Markdown. Those files are served as MCP resources and inlined into the voting prompts, so the agent votes to a stated policy rather than improvising. See knowledge/README.md.

6. Connect an agent

Claude Code, which picks up the project's .env on its own:

claude mcp add safe-mpc -- node /absolute/path/to/Safe-MPC/dist/index.js

Claude Desktop or Cursor, in the MCP config file:

{
  "mcpServers": {
    "safe-mpc": {
      "command": "node",
      "args": ["/absolute/path/to/Safe-MPC/dist/index.js"],
      "env": {
        "SAFE_ADDRESS": "0x...",
        "SAFE_AGENT_PRIVATE_KEY": "0x...",
        "SAFE_CHAIN_ID": "1",
        "SAFE_RPC_URL": "https://...",
        "SAFE_API_KEY": "..."
      }
    }
  }
}

Then ask the agent to run safe_info. It reports whether the agent's signer is an owner and whether it can vote alone.

To poke at the server directly:

npm run inspect

Step-by-step guides for hosting the server beside a self-hosted agent:

Which account needs ETH

The Safe does not pay gas for its own votes. The account that calls execTransaction pays, and that is the agent's EOA. Funding the Safe instead is the common mistake and does nothing for voting.

Case

Needs ETH

Why

Snapshot votes

No

Signing is off-chain and verification is an eth_call. Entirely gasless.

Governor votes

The agent EOA

It submits execTransaction and pays the gas.

The Safe itself

No

Only the governance token, or a delegation, for voting power.

So a Safe voting only on Snapshot needs no ETH anywhere. For on-chain voting, send a small amount of ETH to the agent EOA and top it up as it drains.

safe_info reports both balances and says plainly whether on-chain voting will work. governor_vote refuses before signing if the agent has no ETH, naming the cause rather than surfacing an opaque RPC rejection.

Safe supports refunding the executor out of the Safe's own balance, via the gasPrice, gasToken and refundReceiver transaction fields. Safe-MPC leaves those at zero, so no refund happens and the accounting stays simple.

Voting on Snapshot X

Snapshot X (snapshot.box) is Snapshot's fully on-chain protocol. Its gasless path has the voter sign an EIP-712 message for a relayer, which a Safe cannot do on its own; the path snapshot.box offers smart-contract wallets is a plain transaction instead. snapshot_x_vote takes that path: the Safe calls the space's EthTx authenticator, which checks the voter is the caller and forwards Space.vote(safe, proposalId, choice, strategies, metadataURI).

> Vote for https://snapshot.box/#/eth:0x594E…/proposal/7 — it funds the audit.

  snapshot_x_proposal → VotingPeriod, Safe power 12000 across strategy 0, not voted
  snapshot_x_vote     → executed 0xabc…, For with power 12000

Before anything is signed, the tool:

  • reads the proposal and requires it to be open (VotingPeriod or VotingPeriodAccepted) and not already voted on by the Safe;

  • evaluates every strategy active on the proposal at its snapshot block, the same getVotingPower call the space makes, and submits only those that give the Safe power (a strategy that reverts would revert the whole vote);

  • checks the space whitelists the authenticator (by default snapshot.box's EthTx deployment, 0xBA06…Aed1, on every standard network);

  • simulates authenticate(...) from the Safe's address, so the chain itself vets the vote.

Choices are for, against and abstain (sx-evm values 1, 0 and 2 — not the Governor order). A reason is pinned to IPFS through pineapple.fyi, Snapshot's pinning service, and attached as the vote's metadata URI, which is how snapshot.box displays it; if pinning fails the vote still goes through and the reason stays in the local vote log. Like a Governor vote, this costs gas, and Snapshot X votes are final: there is no revote.

Vanilla, Comp and OZ Votes strategies need no input. A merkle-whitelist or ApeGas strategy needs a per-voter proof; pass it as strategyParams ([{ index, params }]), and the tool reports any strategy it had to leave out. At threshold 1 the vote executes immediately; above that it queues on the Safe like the cancel below, with the to / data / value co-signers should check.

Vetoing a Snapshot X proposal

Snapshot X (snapshot.box) is Snapshot's fully on-chain protocol: a space is a contract, and cancelling a proposal means the space's controller — usually the DAO's Safe — calling cancel(proposalId) on it. Done by hand, that is the worst flow in DAO operations: someone opens app.safe.global, bridges snapshot.box into the Safe over WalletConnect, double-checks they are acting as the Safe and not their own wallet, clicks Cancel proposal, signs, and then posts the calldata in the group chat so every co-signer can verify the bytes before confirming.

snapshot_x_cancel_proposal collapses the first half of that into one call. Given a snapshot.box proposal URL — or the space and proposal number — it verifies the Safe is the space controller, simulates the cancel from the Safe's address so the chain itself vets the call, then proposes the transaction to the Safe:

> Cancel https://snapshot.box/#/eth:0x594E…/proposal/3 — it duplicates #2.

  snapshot_x_proposal        → status VotingPeriod, this Safe controls the space
  snapshot_x_cancel_proposal → queued as 0xf00…, needs 4 more of 5 signatures

At threshold 1 the cancel executes immediately. Above that, the tool reports the queued safeTxHash, a link to the Safe's queue, and the exact to / data / value the transaction must show — the same checklist co-signers used to assemble by hand, now generated from the transaction that was actually proposed. The other owners just open the queue, compare, and confirm; the final signature executes the cancel. snapshot_x_proposal read afterwards confirms the proposal is Cancelled.

Every attempt is recorded in the vote log with platform snapshot-x, and DRY_RUN behaves as everywhere else: the tool returns the transaction it would have proposed, blockers included, without signing anything.

Tools

Tool

Reads or writes

What it does

safe_info

read

Chain, owners, threshold, nonce, balance, and whether the agent can vote alone. Needs the API key.

safe_pending_transactions

read

Transactions queued on the Safe. Needs the API key.

safe_confirm_transaction

write

Adds the agent's signature to a queued transaction, executing it if that meets the threshold. Needs the API key.

snapshot_spaces_with_voting_power

read

Every Snapshot space this Safe can vote in, found without being told where to look.

snapshot_open_proposals

read

Everything open for a vote across those spaces, soonest deadline first.

snapshot_list_proposals

read

Proposals in a space, open ones by default.

snapshot_get_proposal

read

Full body, indexed choices, scores, the Safe's voting power, and any vote it already cast.

snapshot_voting_power

read

The Safe's voting power on one proposal, by strategy.

snapshot_query

read

Any GraphQL query against the Snapshot hub, for everything the fixed reads don't cover. Query operations only; responses over 1 MB are refused.

snapshot_vote

write

Casts an off-chain Snapshot vote as the Safe. Needs the API key.

snapshot_submit_pending_vote

write

Submits a vote whose Safe message needed more signatures. Needs the API key.

snapshot_x_proposal

read

A Snapshot X proposal's live status and tally, the Safe's voting power and whether it voted, read from the space contract, and whether this Safe controls the space. No API key.

snapshot_x_vote

write

Casts an on-chain Snapshot X vote as the Safe through the space's EthTx authenticator. Needs the API key.

snapshot_x_cancel_proposal

write

Vetoes a Snapshot X proposal by proposing Space.cancel from the Safe. Needs the API key.

governor_find_proposals

read

On-chain proposals, read from ProposalCreated logs. No API key.

governor_list_proposals

read

Legacy: proposals via a hosted indexer API. Needs a key.

governor_get_proposal

read

Legacy: title, description and vote counts via the same API.

governor_proposal_state

read

Live Governor state, read straight from the contract. No API key needed.

governor_vote

write

Casts castVoteWithReason on-chain from the Safe. Needs the API key, even at threshold 1.

vote_log

read

Every vote this Safe has cast, with the choice and reason, so decisions stay consistent with precedent.

vote_schedule

read

Proposals the scheduler has queued, and which are due now.

Tools marked "Needs the API key" build a Safe client and fail without SAFE_API_KEY or SAFE_TX_SERVICE_URL. The rest are plain RPC or Snapshot hub reads and work with neither.

Four prompts wrap the tools into a reviewed workflow: vote_on_snapshot_proposal, vote_on_governor_proposal, vote_on_every_open_proposal, which works through the Safe's whole ballot, and review_open_proposals, which recommends votes without casting any.

Choice format

Snapshot choices are 1-indexed, matching the UI, and their shape follows the proposal's voting system:

Voting system

choice argument

single-choice, basic

1

approval, ranked-choice

[2, 1, 3]

weighted, quadratic

{"1": 70, "2": 30}

Governor votes take "for", "against" or "abstain" instead of the raw support integers.

Vote log

Every vote attempt is appended to data/votes.jsonl: the proposal, the choice, the reason given, the voting power, and the resulting vote id or transaction hash. Failed and queued attempts are recorded too, so a vote that never landed is visible rather than lost in a chat transcript.

It is a plain JSONL file, not a database. The authoritative record of a vote is on Snapshot or on-chain; this exists so that you can audit what the agent did, and so the agent can read its own precedent through vote_log before deciding. The scheduler also uses it to guarantee it never votes twice on one proposal, even across restarts.

jq -r '[.at, .venue, .choice, .outcome] | @tsv' data/votes.jsonl | column -t

Unattended voting

safe-mpc-watch is the unattended path. It polls every Snapshot space the Safe can vote in — plus any space or Governor you name — queues each open proposal, and when a proposal is within VOTE_BEFORE_CLOSE of its deadline it runs your agent command to decide and vote. Voting late rather than on discovery means the decision reflects how sentiment developed, and leaves room to retry before the deadline.

# In .env. Snapshot spaces are discovered automatically; everything here is
# optional except the agent command.
WATCH_SNAPSHOT_AUTO=true                # watch wherever the Safe has voting power
WATCH_SNAPSHOT_SPACES=ens.eth,aavedao.eth   # watched as well, power or not
WATCH_GOVERNORS=0x408ED6354d4973f66138C91495F2f2FCbd8724C3
VOTE_BEFORE_CLOSE=6h
POLL_INTERVAL=1h
AGENT_COMMAND=claude -p "{prompt}" --mcp-config .mcp.json --allowedTools mcp__safe-mpc__*
npm run watch:plan     # show what is queued and due, dispatch nothing
npm run watch          # poll continuously
node dist/watch.js --once   # a single pass, for system cron

--once is usually the better choice in production: let cron own the schedule and the restarts.

*/30 * * * * cd /srv/safe-mpc && node dist/watch.js --once >> watch.log 2>&1

The queue lives in data/schedule.json and survives restarts. A proposal keeps its status across passes, so a vote already cast is never repeated, and one that failed stays pending and is retried on the next pass until its deadline. Run --plan first, and set DRY_RUN=true for the first live pass if you want to read the agent's reasoning before any vote is real.

The agent command

AGENT_COMMAND is parsed into an argument list and run without a shell, so nothing in it is interpreted by sh. These placeholders are substituted: {prompt}, {platform}, {proposalId}, {venue}, {endsAt}.

The same values plus the proposal title are also passed in the environment as SAFE_MPC_PROMPT, SAFE_MPC_PLATFORM, SAFE_MPC_PROPOSAL_ID, SAFE_MPC_VENUE, SAFE_MPC_PROPOSAL_TITLE and SAFE_MPC_ENDS_AT, which is how you drive an agent that takes its input from the environment.

Proposal titles are written by whoever submitted the proposal, so they are never placed on the command line, only in the environment. Proposal ids and venues are checked against a strict character allowlist before substitution, and a dispatch is refused outright if either could alter how the command parses.

On-chain discovery and its limits

governor_find_proposals and the scheduler's Governor path both scan ProposalCreated logs, then filter by the contract's live state().

The scan window comes from the Governor, not from a guess. A proposal can only be open if it was created within votingDelay + votingPeriod of now, so that is exactly how far back the scan reaches, plus GOVERNOR_LOOKBACK_MARGIN. A DAO with a one-day delay and a three-day voting period is scanned six days back, not a fixed month. Every result reports the window it used and where that came from. GOVERNOR_LOOKBACK is only the fallback for a Governor fork that does not expose those two methods, and the lookback argument overrides both.

This does mean a proposal created before that window is invisible, which matters only if the DAO shortened its voting period very recently. Widen GOVERNOR_LOOKBACK_MARGIN or pass an explicit lookback if so.

Deadlines are estimated on a Governor that counts in blocks. OpenZeppelin Governor v5 and later can report time in seconds via ERC-6372, and those deadlines are exact. Older Governors and Compound Bravo count in block numbers, so the deadline is derived from the chain's recent average block time, measured by sampling two blocks rather than from a hardcoded table. Results flag this with endsAtIsEstimate, and the estimate drifts as block times change. Leave enough room in VOTE_BEFORE_CLOSE to absorb that drift.

Scans are chunked because most RPC providers cap the block span of a single eth_getLogs call. Deriving the window from the contract keeps that cost proportionate: on a chain producing a block every quarter second, a three-day voting period is a far smaller scan than a blanket month would be. A scan needing more than GOVERNOR_MAX_LOG_CHUNKS calls is still refused, reporting the measured block time and where the window came from, rather than quietly hammering your provider.

One known gap: a Governor fork that changed the ProposalCreated parameter types would need its own event definition. Renaming parameters is fine, which is why one definition covers both OpenZeppelin and Compound Bravo.

Guardrails

An agent with a Safe owner key is a real capability, so the server constrains it in five ways:

  • ALLOWED_SNAPSHOT_SPACES and ALLOWED_GOVERNORS confine voting to named spaces and contracts. Anything else is refused before a signature is made. This is the single most effective control here; set it.

  • DRY_RUN signs and submits nothing while still exercising every read and every validation. It is off by default — votes are real unless you turn it on.

  • Pre-flight checks refuse votes that would be rejected or reverted anyway: closed proposals, zero voting power, a Governor proposal already voted on. Under DRY_RUN these become reported blockers rather than refusals, and the payload comes back anyway, so a rehearsal still shows you what it would sign.

  • The Safe's own threshold stays authoritative. Nothing here can execute past it.

  • The vote log makes every attempt reviewable after the fact, including the ones that failed.

Beyond that, the agent key is an owner like any other: remove it in the Safe UI to revoke access immediately.

Unattended voting deserves more care than on-demand voting, because nobody is reading the agent's reasoning as it happens. Set the allowlists, keep VOTE_BEFORE_CLOSE long enough that you can still intervene, and read the vote log for the first few proposals.

Development

npm run dev        # watch mode
npm run typecheck
npm run build
npm test           # offline, no network or keys needed

The tests cover the parts that fail silently rather than loudly. The most important one checks that the EIP-712 hash viem derives (what the Safe SDK signs) matches the hash ethers derives (what the Snapshot hub recomputes before verifying the Safe's EIP-1271 signature), across all six Snapshot voting systems. If those two ever diverge, votes are rejected at the hub with no obvious cause.

The rest cover the scheduler's timing and its double-vote guard, and the command dispatch path, including that a hostile proposal title cannot reach the command line.

src/
  index.ts            MCP server entry, stdio transport
  config.ts           Environment validation and the allowlist guards
  chains.ts           Chain registry and RPC resolution
  safe.ts             Safe client construction and owner checks
  setup.ts            safe-mpc-setup CLI: key generation, .env, readiness check
  dotenv.ts           Minimal .env loader, so config is not duplicated per client
  policy.ts           Reads the voting-policy documents
  prompts.ts          Prompts and policy resources
  voteLog.ts          Append-only JSONL record of every vote attempt
  schedule.ts         The scheduler's queue and its timing rules
  watcher.ts          Proposal discovery and agent dispatch
  watch.ts            safe-mpc-watch CLI
  duration.ts         Duration parsing for the config
  platforms/
    snapshot.ts       Hub queries, EIP-712 vote types, sequencer submission
    snapshotX.ts      Snapshot X space ABI, vote and cancel calldata, on-chain reads
    governor.ts       Governor ABI, calldata encoding, on-chain state reads
    governorIndexer.ts  On-chain discovery from ProposalCreated logs
    tally.ts          Legacy hosted-indexer client, superseded by governorIndexer
  tools/
    safeTools.ts      safe_*
    snapshotTools.ts  snapshot_*
    snapshotXTools.ts snapshot_x_*
    governorTools.ts  governor_*
    logTools.ts       vote_log, vote_schedule
    shared.ts         Tool result helpers and the in-band error guard

Troubleshooting

"SAFE_API_KEY is not set" at startup — the Safe SDK needs a Transaction Service key to construct its client, even for paths that never call the service. Get one free at developer.safe.global, or set SAFE_TX_SERVICE_URL if you run your own service.

"is not an owner of Safe" — the address in SAFE_AGENT_PRIVATE_KEY has not been added as a Safe owner. safe_info prints the current owner list.

"holds no ETH" — the agent EOA, not the Safe, pays gas for on-chain votes. Send ETH to the address safe_info reports as agentSigner. Snapshot voting is unaffected and needs no ETH at all.

"no voting power" — the Safe did not hold or was not delegated the governance token at the proposal's snapshot block. Delegation set up after that block does not apply retroactively. snapshot_spaces_with_voting_power with includeZero: true shows every space that was tested and what each returned, which is the quickest way to tell "wrong space" from "no tokens". Under DRY_RUN the vote tool returns the payload anyway, flagged as blocked, so the path can still be demonstrated.

dryRun: true when .env says otherwise — a variable in the process environment beats the file, and MCP clients pass their own env block to the server. Editing .env cannot fix that, and neither can a restart if the client re-reads its cached config: remove DRY_RUN from the client's server entry, or set it there to "false". safe_info reports dryRunSource, which says which of the two is in force.

"signed by 1 of 2 required owners" — expected on a multi-owner Safe. The message hash is in the result; once the other owners sign it in the Safe UI, call snapshot_submit_pending_vote with it.

Snapshot sequencer rejects the vote — usually the space's validation, not the signature: a minimum-balance requirement, or voting closed between the read and the submission. The sequencer's own message is passed through verbatim.

The watcher queues nothing — --plan prints the spaces it resolved, the Safe's voting power in each, and what every space and governor returned. An empty result usually means the Safe has no voting power anywhere and no space was named explicitly, or the space id or governor address is wrong, or nothing is open right now. For on-chain proposals, the log line reports the scan window that was used; check that it reaches back past the proposal's creation, and that the governor is on SAFE_CHAIN_ID.

"needs N eth_getLogs calls" — the window is too wide for this chain's block time. The error names where the window came from. If it was derived from the Governor, the DAO genuinely has a long voting period, so raise GOVERNOR_LOG_CHUNK_BLOCKS if your provider allows wider ranges. If it fell back to GOVERNOR_LOOKBACK, shorten that instead.

The watcher dispatches but no vote appears — the entry stays pending with lastError set in data/schedule.json, and the agent's output tail is on stderr. The usual cause is an agent command that cannot reach the MCP server, so check that --mcp-config points at a file naming this server.

License

MIT

Available Tools

21 tools
governor_find_proposalsFind on-chain Governor proposals (no API key)A
Read-only

Discovers proposals by reading ProposalCreated logs straight from a Governor contract, then filtering by the contract's live state. Returns the full proposal description, so no third-party indexer is involved. This is the supported way to find on-chain proposals: Tally shut down in March 2026. Works with OpenZeppelin Governor and Compound Bravo.

NameRequiredDescriptionDefault
statesNoWhich proposal states to return
governorYesGovernor contract address
lookbackNoOverride how far back to scan, e.g. "7d". By default the window is derived from the Governor's own votingDelay and votingPeriod, which is the shortest span that can still contain an open proposal. Only set this if the Governor's parameters changed recently.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/openWorld annotations, the description discloses the data source (on-chain logs, no third-party indexer), that results are filtered against live contract state, and that full proposal descriptions are returned. It's missing any note on cost, rate limits, or scan size, which matters for an unbounded log scan.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the mechanism, then the no-indexer guarantee, then applicability. Mostly earns its space, though the Tally-shutdown justification is closer to marketing rationale than invocation information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully states the return shape (full proposal description) and the compatibility surface (OpenZeppelin Governor, Compound Bravo). For a three-parameter read tool this is largely sufficient; result size or pagination behavior is the remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so governor, states, and lookback are already documented, including the default state set and the lookback derivation rationale. The description's mention of 'filtering by the contract's live state' loosely ties to the states parameter but adds no syntax or behavior beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('discovers proposals by reading ProposalCreated logs straight from a Governor contract') and explains the filtering mechanism. It doesn't differentiate itself from the near-identically named sibling governor_list_proposals, which an agent would also consider.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'supported way ... Tally shut down in March 2026' line implies when to prefer this tool, and the compatibility note scopes its applicability. But it never explicitly contrasts with governor_list_proposals or governor_get_proposal, so the agent must infer which sibling to pick.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

governor_get_proposalRead a Governor proposal via a hosted indexer (legacy)A
Read-only

Legacy path: fetches a proposal's title, description and tallies from the Tally-compatible hosted API, which shut down in March 2026. Prefer governor_find_proposals for the description and governor_proposal_state for live on-chain state; neither needs an API key.

NameRequiredDescriptionDefault
tallyIdNoTally's internal proposal id
onchainIdNoThe Governor contract's proposal id
governorIdNoRequired alongside onchainId

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnly and open-world; the description adds the decisive fact that the upstream service is gone, plus an implicit hint that this path may need an API key while the alternatives do not. It doesn't say what a call actually returns now (error, timeout, stale cache), which is the remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero waste, with the depreciation warning front-loaded before the redirect. Every clause carries operational value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a dead legacy endpoint the agent needs the deprecation notice and the exit path, both of which are present. What's missing is the failure mode on invocation and whether historical tallies are recoverable elsewhere.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents tallyId, onchainId and the governorId-alongside-onchainId constraint. The description adds no parameter guidance, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (fetches a proposal's title, description and tallies) and pins the source (Tally-compatible hosted API). Explicitly separates it from governor_find_proposals and governor_proposal_state, so an agent can route without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-not (the backing API shut down in March 2026) and names two concrete alternatives with the axis to choose between them (description vs. live on-chain state). The 'prefer X for Y' mapping leaves nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

governor_list_proposalsList Governor proposals via a hosted indexer (legacy)A
Read-only

Legacy path: lists proposals through the Tally-compatible hosted API. Tally shut down in March 2026 and is now Cactus, so this may fail even with a key. Prefer governor_find_proposals, which reads the Governor contract directly and needs no API key.

NameRequiredDescriptionDefault
limitNo
governorIdNoTally governor id, e.g. "eip155:1:0x408E..."
organizationIdNo
organizationSlugNoTally slug from the DAO's tally.xyz URL, e.g. "uniswap"

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnly and openWorld; the description adds the crucial facts that this hits an external hosted service that may be dead and that an API key may be required — context not available in structured fields. It stops short of describing response shape or pagination, but for a deprecated read-only list tool that is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the legacy status and ending with the actionable alternative. No filler, though the deprecation notice is nearly repeated via 'Tally shut down' and 'Legacy path'.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

It covers the important migration/deprecation and auth context, but with four parameters, only half documented, and no output schema, the description leaves the agent without guidance on what the proposals response looks like or how limit/organizationId interact. Adequate for steering away, incomplete for actually calling it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50% and the description mentions no parameters at all. The two undocumented parameters (limit, organizationId) and the Tally id format get no compensating explanation, so an agent must infer usage from the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names the specific verb+resource (lists proposals) and the specific backend (Tally-compatible hosted API), and immediately labels it legacy, which separates it cleanly from governor_find_proposals.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states to prefer governor_find_proposals because it reads the contract directly and needs no API key, plus the condition under which this path fails (Tally shut down, now Cactus). When-to-use and when-not-to-use are both present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

governor_proposal_stateRead live Governor state for a proposalA
Read-only

Reads the Governor contract directly: the proposal's state, whether the Safe has already voted, the Safe's voting power at the proposal's snapshot, the quorum and the running tally. Needs no API key. Call this before voting.

NameRequiredDescriptionDefault
decimalsNoGovernance token decimals, for readable vote weights
governorYesGovernor contract address
proposalIdYesOn-chain proposal id (decimal or 0x hex)

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint and openWorldHint already declared, the description adds real value by revealing the read source (reads the Governor contract directly) and that no API key is needed, which is important auth/routing context. It doesn't cover failure modes or rate limits, but that's minor against the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the operation and its returned fields, then the usage cue and auth note. Every clause earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, but the description compensates by enumerating the returned values (state, voted status, voting power, quorum, tally). Combined with the schema-documented inputs and annotations, an agent has everything needed to call and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so governor, proposalId, and decimals are already documented in the schema. The description adds no parameter-level detail beyond what structured data provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (reads) and resource (the Governor contract for a proposal) and enumerates exactly what is returned: state, Safe's voted status, voting power at snapshot, quorum, and running tally. This distinguishes it functionally from siblings like governor_get_proposal or governor_list_proposals, though it does not name them explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear timing guidance with 'Call this before voting,' which tells the agent when to invoke it. It does not name an alternative tool or state when not to use it, so it falls short of the explicit alternatives-based 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

governor_voteCast an on-chain Governor vote from the SafeA

Votes on an OpenZeppelin or Compound-style Governor by executing castVoteWithReason from the Safe. This is a real on-chain transaction that costs gas and cannot be undone or changed. Check governor_proposal_state first to confirm the proposal is Active and the Safe has voting power.

NameRequiredDescriptionDefault
reasonNoPublic rationale stored on-chain with the vote. Costs extra gas but is strongly recommended for an agent vote.
supportYesHow to vote. Maps to Governor support values 1, 0 and 2.
governorYesGovernor contract address
proposalIdYesOn-chain proposal id (decimal or 0x hex)
skipChecksNoBypass the pre-flight state and voting-power checks. Only for unusual Governor forks that do not implement the standard view methods.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as a non-read-only, non-idempotent, open-world operation. The description adds material context beyond that: it is a real on-chain transaction, costs gas, and is irreversible. It does not mention the return/confirmation format, but there is no output schema to defer to.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with zero waste. The irreversible-transaction warning is front-loaded and the prerequisite follows, making the key facts easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a gas-costing, irreversible mutation with no output schema, the description covers the essentials: mechanism, cost/irreversibility, and preconditions. Minor gaps remain (e.g., what skipChecks does behaviorally, expected confirmation behavior), but the schema handles the parameter-level caveats.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so each parameter (including reason's gas cost note and skipChecks' fork caveat) is already documented in the schema. The description only alludes to castVoteWithReason, adding no detail beyond the structured fields, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (votes) and resource (Governor) and names the exact mechanism (castVoteWithReason from the Safe). This clearly distinguishes it from the snapshot_vote siblings, which operate off-chain.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent to governor_proposal_state first and states the preconditions (proposal Active, Safe has voting power). A clear prerequisite plus the named check tool leaves little to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

safe_confirm_transactionConfirm a queued Safe transactionA

Adds the agent's signature to a queued Safe transaction. When this signature meets the threshold, the transaction is executed on-chain. Use this to help along a vote that was proposed but not yet executed.

NameRequiredDescriptionDefault
safeTxHashYesThe safeTxHash from safe_pending_transactions

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false and destructiveHint=false, so the mutating nature is already known; the description adds real value by disclosing the threshold mechanic and that execution can occur on-chain as a result. It omits permission/ownership requirements and expected failure modes, which for an on-chain-signing tool would be worth stating.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action and its consequence; no redundant restatement of the name or title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description conveys the meaningful outcome (threshold reached → executed) well. It does not describe what is returned or how a below-threshold signature is reported, leaving a modest gap for a single-parameter mutation tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter, with 100% schema coverage that already describes the hash format and points to safe_pending_transactions as its source. The description adds no further parameter detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("adds the agent's signature to a queued Safe transaction") and immediately explains the consequence (threshold execution on-chain). This distinguishes it from the listing sibling safe_pending_transactions, which the schema names as the source of the hash.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Use this to help along a vote that was proposed but not yet executed" gives a clear usage condition. It does not explicitly state exclusions (e.g., don't call when already executed or when the agent isn't an owner), so it falls short of a full when/when-not/alternatives treatment.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

safe_infoSafe wallet infoA
Read-only

Reports the configured Safe and the agent's readiness to vote: chain, owners, threshold, nonce, both ETH balances, and whether the agent's signer key is an owner that can execute alone. The agent's own balance is what pays gas for on-chain votes; Snapshot votes are gasless and need none. Call this first.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the description's job is to add operational meaning — and it does: the agent's own ETH balance is the gas source for on-chain votes, while Snapshot votes are gasless. It also surfaces the execution-authority fact (sole owner vs. needing confirmations), which materially affects downstream tool choice.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, each carrying distinct information: return fields, gas semantics, invocation priority. Slightly suboptimal that the most actionable instruction ('Call this first') is buried at the end rather than front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameters, the description must carry the return-value burden itself, and it does by enumerating every reported field. It also supplies the interpretive context (what the balances mean for voting) that an agent needs to act on the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes no parameters, so there is nothing for the description to disambiguate; baseline for zero params is 4. Nothing in the description misleads about inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb ('Reports') and a precisely enumerated resource: chain, owners, threshold, nonce, both ETH balances, and whether the signer key is a sole-executing owner. The scope is clearly a read-only configuration/readiness check, which separates it from siblings like safe_pending_transactions and safe_confirm_transaction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Call this first' gives an explicit ordering instruction that tells the agent when to reach for it relative to the rest of the Safe/Snapshot workflow. It also explains the gas distinction that determines whether on-chain voting is even viable. It stops short of naming a concrete alternative or a when-not-to-use condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

safe_pending_transactionsList queued Safe transactionsA
Read-only

Lists transactions queued on the Safe Transaction Service that are waiting for confirmations or execution.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety and external-service profile is covered. The description adds that the source is the Safe Transaction Service, which is useful, but says nothing about authentication requirements, pagination, result limits, or how the endpoint is scoped (which Safe or network).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler. The resource and qualifying state both appear before any subordinate clause, so the key information survives a truncated read.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters and no output schema, the description carries the full descriptive burden, yet it never says which Safe or network the results belong to, nor what a returned entry contains or how many come back. For a zero-argument list tool scoped to an external service, that scope ambiguity is a real gap an agent may trip over.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. There is nothing for the description to disambiguate, and it doesn't waste words on parameter detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb (Lists) plus a well-defined resource (transactions queued on the Safe Transaction Service) with a state qualifier: waiting for confirmations or execution. That state qualifier distinguishes it from a generic transaction history or from safe_confirm_transaction. It stops short of naming a sibling, so it is a 4 rather than a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word 'queued' plus 'waiting for confirmations or execution' implies the use case (finding transactions that still need action), but no explicit when-to-use, when-not, or alternative is stated. An agent could reasonably infer it should call this before safe_confirm_transaction, but that inference is left unstated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_get_proposalRead a Snapshot proposalA
Read-only

Fetches a Snapshot proposal in full, including the body text, the voting system, every choice with its index, current scores, and how much voting power the Safe holds. Read this before voting.

NameRequiredDescriptionDefault
proposalIdYesSnapshot proposal id (0x… hash)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds real value by disclosing the returned contents — body text, voting system, indexed choices, current scores, and the Safe's voting power — which matters since there is no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the action and payload, ending with the actionable usage cue. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does so well by listing the fields an agent will get back. It omits edge behavior (invalid/unknown proposalId, missing proposal), which keeps it just short of complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single proposalId parameter is documented as a 0x… hash in the schema. The description adds nothing about the parameter, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Fetches a Snapshot proposal in full') and enumerates the payload fields, so an agent knows exactly what it retrieves. The 'in full' framing implicitly separates it from siblings like snapshot_list_proposals, but no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Read this before voting' gives a concrete usage condition tied to the voting workflow. It stops short of naming alternatives (e.g., snapshot_list_proposals for discovery), so selection between siblings still requires inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_list_proposalsList Snapshot proposalsA
Read-only

Lists proposals in a Snapshot space, newest first. Defaults to proposals that are currently open for voting.

NameRequiredDescriptionDefault
limitNo
spaceYesSnapshot space id, e.g. "ens.eth" or "aavedao.eth"
stateNoWhich proposals to returnactive

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds two useful behavioral facts (sort order and default state filter) but says nothing about result volume, pagination behavior, or what a proposal record contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, no filler, with the resource and ordering front-loaded ahead of the default-behavior note. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A simple three-parameter read tool with no output schema, so the bar is modest. Still, an agent gets no signal about whether 'limit' caps the page or total results, and no sense of the returned shape, which the description could cheaply have supplied.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% — the space id and state enum are documented in the schema, and the description usefully restates that the default state means 'open for voting'. The limit parameter (default 10, max 50) is not explained in either place, so the description only marginally improves on the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Lists proposals in a Snapshot space') plus ordering ('newest first'), so the core action is unambiguous. However, it never distinguishes itself from close siblings like snapshot_open_proposals or snapshot_query, which an agent must choose between.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Defaults to proposals that are currently open for voting' implies the default filter behavior but gives no explicit when-to-use or when-not-to-use guidance. With snapshot_open_proposals and snapshot_query in the sibling set, a routing sentence is conspicuously absent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_open_proposalsEvery open proposal this Safe can vote onA
Read-only

Lists the proposals currently open for voting across every Snapshot space the Safe holds voting power in, soonest deadline first, with the Safe's voting power on each. This is the whole of the Safe's Snapshot ballot: use it to decide what needs a vote, then snapshot_get_proposal to read one.

NameRequiredDescriptionDefault
spacesNoRestrict to these space ids instead of every space with voting power
limitPerSpaceNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered; the description adds real value beyond them by disclosing sort order (soonest deadline first), the per-proposal inclusion of the Safe's voting power, and the implicit 'all spaces with voting power' default. It does not explain truncation/pagination behavior, which is a gap given a per-space limit exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with the scope and ordering front-loaded, followed by the routing hint. No filler, and every clause carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With readOnly/openWorld annotations but no output schema, the description does the right work by describing what is returned (open proposals with the Safe's voting power, deadline-ordered). The remaining omission is pagination/cap semantics for limitPerSpace, which matters for a zero-required-param list tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50%: `spaces` is documented in the schema but `limitPerSpace` (default 20, max 50) has no description anywhere. The description's 'across every Snapshot space the Safe holds voting power in' hints at the default filtering behavior of `spaces`, but it never mentions restricting spaces or the per-space cap, so it does not compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Lists), resource (open proposals for voting), and precise scope (every Snapshot space the Safe holds voting power in), plus ordering (soonest deadline first) and payload (the Safe's voting power). This clearly separates it from generic siblings like snapshot_list_proposals and snapshot_query.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly frames the tool as 'the whole of the Safe's Snapshot ballot' and prescribes the next step: use it to decide what needs a vote, then snapshot_get_proposal to read one. It lacks an explicit when-not statement (e.g., versus snapshot_list_proposals or snapshot_query), which keeps it short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_queryRun a GraphQL query against the Snapshot hubA
Read-only

Runs any GraphQL query against the Snapshot hub API — spaces, proposals, votes, follows, users, strategies, anything the schema exposes — for questions the fixed read tools do not cover (a space's full vote history, who follows it, strategy parameters, cross-space voter lookups). The tool only sends query operations — mutations and subscriptions are rejected. Use first/skip and select only the fields you need: responses over 1 MB are refused, and results over 50k characters are truncated. Schema reference: https://docs.snapshot.box.

NameRequiredDescriptionDefault
queryYesGraphQL query, e.g. "query { space(id: \"ens.eth\") { name followersCount } }"
variablesNoValues for the query's $variables, if it declares any

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior beyond annotations: only query operations are allowed, responses over 1 MB are refused, and results over 50k characters are truncated. Annotations already declare readOnly/openWorld, but the response-size and operation-type constraints are valuable context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then constraints and schema reference in a compact paragraph. Every sentence earns its place by clarifying scope, limits, or safe usage.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for an open-ended GraphQL query tool with no output schema: it explains allowed operations, size limits, truncation behavior, pagination guidance, and points to the external schema reference. Nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the query and variables parameters are already documented. The description adds meaningful usage semantics beyond the schema: use first/skip, select only needed fields, and keep responses within size limits.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — runs GraphQL queries against the Snapshot hub API — and enumerates the domains it can query. It explicitly positions itself as the fallback for questions the fixed read tools do not cover, distinguishing it from sibling read tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance: for questions the fixed read tools do not cover, with concrete examples. It also gives when-not guidance by stating that mutations and subscriptions are rejected, and recommends pagination/field selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_spaces_with_voting_powerSnapshot spaces this Safe can vote inA
Read-only

Finds every Snapshot space where the Safe holds voting power, without needing a list up front: it tests the configured spaces, the spaces the Safe follows, and the spaces it has voted in before. Start here when you do not know where this Safe votes.

NameRequiredDescriptionDefault
spacesNoExtra space ids to test, on top of the ones discovered automatically
includeZeroNoAlso return spaces where the Safe has no voting power

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the description is not obligated to restate safety, yet it usefully discloses the three discovery sources (configured spaces, followed spaces, prior votes), which explains why the tool is open-world and potentially slow. Return shape and cost/latency are left unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the outcome and followed by the call-to-action condition; no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-parameter, read-only discovery tool with no output schema, the description conveys enough to invoke it correctly, though it never sketches what the result set looks like (space ids, names, voting power values).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are fully documented in the schema and the baseline of 3 applies. The description only hints at the 'spaces' parameter via 'on top of the ones discovered automatically' and never mentions includeZero.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Finds') and a precisely scoped resource ('every Snapshot space where the Safe holds voting power'), and the phrase 'without needing a list up front' separates it from sibling tools like snapshot_voting_power that require a known space id.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Start here when you do not know where this Safe votes' gives an explicit entry-point condition, but there is no complementary when-not guidance (e.g. use snapshot_voting_power when the space is already known) beyond the implied contrast.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_submit_pending_voteSubmit an already-signed Snapshot voteA

Finishes a vote whose Safe message was created earlier but not submitted, usually because the Safe needed more owner signatures. Pass the safeMessageHash reported by snapshot_vote.

NameRequiredDescriptionDefault
safeMessageHashYesThe safeMessageHash from an earlier snapshot_vote call

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare write (readOnlyHint=false), non-destructive, open-world. The description adds real context beyond them: this operates on a pre-existing Safe message rather than creating one, and the typical reason it is needed is a signature shortfall. It stops short of saying what happens if the message was already submitted or whether the call is safely repeatable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, and the state that makes the tool necessary is front-loaded before the parameter instruction. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter submission tool with no output schema, the description covers the precondition and input origin well. It leaves minor gaps: what a successful call returns and how it behaves on a message that was already submitted, which an agent might want before retrying.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter and schema coverage is 100%, so the schema already documents the format and origin of safeMessageHash. The description restates that the hash comes from snapshot_vote without adding syntax, validation, or lifecycle detail, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (finishes/submits) and resource (a vote whose Safe message already exists), and scopes it to the incomplete-signature case. This cleanly separates it from snapshot_vote, which is where the message is originally created.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the trigger condition clearly: the Safe message was created earlier but not submitted, usually due to missing owner signatures. It implies snapshot_vote is the originating call and that this is the recovery path, though it never explicitly says 'do not use this to start a new vote.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_voteCast a Snapshot vote from the SafeA

Casts an off-chain, gasless Snapshot vote on behalf of the Safe. Signs an EIP-712 vote as a Safe message, waits for the Safe's EIP-1271 signature, then submits it to the Snapshot sequencer. Read the proposal with snapshot_get_proposal first so the choice index and voting system match. Voting again on the same proposal replaces the earlier vote.

NameRequiredDescriptionDefault
choiceYes1-indexed choice. A single number for single-choice/basic proposals, an array for approval or ranked-choice, or an object of option->weight for weighted or quadratic (e.g. {"1": 70, "2": 30}).
reasonNoPublic rationale recorded with the vote. Strongly recommended.
proposalIdYesSnapshot proposal id (0x… hash)

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare this is a non-read-only but non-destructive, open-world operation; the description adds real context beyond that: it is gasless, requires a Safe EIP-1271 signature round-trip, goes to the Snapshot sequencer, and a repeat call silently replaces the prior vote. Failure modes and timing of the signature wait are not described, keeping it below a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with the action and its mechanism, then the prerequisite, then the replacement caveat. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, the description covers the signing flow, prerequisite lookup and re-vote semantics, which is enough to call it correctly. What an agent gets back on success/failure, and how long the signature wait may take, are unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description adds genuine meaning by tying the meaning of 'choice' to the proposal's voting system and directing the agent to inspect the proposal before choosing an index. It does not restate the choice shapes, but the schema already does.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb, resource and mechanism: casts an off-chain gasless Snapshot vote on behalf of the Safe via EIP-712/EIP-1271. An agent can distinguish this from sibling vote tools like snapshot_x_vote or snapshot_submit_pending_vote because the signing path is spelled out.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit prerequisite: read the proposal with snapshot_get_proposal first so the choice index and voting system match. It also clarifies the re-vote case (voting again replaces the earlier vote). It stops short of routing the agent away from the other sibling vote-submission tools, so no explicit when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_voting_powerSafe voting power on a Snapshot proposalA
Read-only

Reports how much voting power the Safe has on a specific proposal, broken down by the space's strategies. Zero means the vote would carry no weight.

NameRequiredDescriptionDefault
spaceYes
proposalIdYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds useful behavior context by explaining that results are broken down by strategies and that zero means the vote carries no weight, but it does not discuss data freshness, required auth, or failure behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the core purpose and followed by a decision-relevant caveat. There is no redundant or wasted text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only query, the description gives enough to understand the high-level output: voting power broken down by strategies. However, with no output schema and no parameter documentation, it leaves out return-value shape, parameter formats, and any error or edge-case behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for both required parameters, so the description must compensate. It barely does: it implies that 'space' refers to the space whose strategies are used and that 'proposalId' identifies the proposal, but it gives no format, naming, or lookup guidance for either parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it reports the Safe's voting power on a specific Snapshot proposal, broken down by strategies. This clearly distinguishes it from siblings like snapshot_vote (casting a vote) and snapshot_spaces_with_voting_power (listing spaces).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the zero-power note, which helps an agent decide whether a vote would matter, but the description never explicitly says when to use this tool rather than snapshot_vote or snapshot_get_proposal. No alternatives or exclusions are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_x_cancel_proposalCancel a Snapshot X proposal from the SafeA
Destructive

Cancels (vetoes) an on-chain Snapshot X proposal by proposing Space.cancel(proposalId) from the Safe — the streamlined replacement for wiring snapshot.box to the Safe over WalletConnect by hand. Only works when the Safe is the space controller. At threshold 1 the transaction executes immediately; above that it lands in the Safe queue with the exact to/data/value for the other owners to verify and sign, and the final signer's confirmation executes it.

NameRequiredDescriptionDefault
spaceYesThe Snapshot X space: a space contract address, a prefixed id like "eth:0x594E…", or a full snapshot.box proposal URL (in which case proposalId can be omitted).
reasonNoWhy the proposal is being cancelled. Recorded in the local log only.
proposalIdNoThe proposal number, e.g. 3. Not needed when the space is a proposal URL.
skipChecksNoBypass the pre-flight controller/state checks and simulation. Only for sx-evm forks that break the standard view methods.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag this as destructive, non-idempotent and open-world, but the description adds real context beyond them: execution behavior varies by Safe threshold (immediate at 1, queued with to/data/value above that) and the final signer's confirmation executes it. It doesn't cover failure modes or whether a cancel can be undone on-chain.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core action and mechanism. The WalletConnect aside and the threshold explanation are dense but each earns its place; the final sentence carries several clauses that could be split.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description covers the outcome (immediate execution vs. queued Safe transaction) and the key precondition, which is everything an agent needs to know before invoking a destructive on-chain tool. Schema covers the parameters fully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents space, proposalId, reason and skipChecks, including the URL-omits-proposalId rule. The description adds no parameter-level detail beyond what the schema provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Cancels (vetoes) an on-chain Snapshot X proposal') plus the exact on-chain call it makes (Space.cancel(proposalId) from the Safe). This clearly separates it from siblings like snapshot_x_vote, snapshot_x_proposal, and safe_confirm_transaction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a hard precondition ('Only works when the Safe is the space controller') and positions itself against the manual WalletConnect alternative. It stops short of naming sibling tools (e.g. safe_pending_transactions for queue follow-up, snapshot_open_proposals to find the id), so it is clear but not fully routed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_x_proposalRead an on-chain Snapshot X proposalA
Read-only

Reads a Snapshot X (snapshot.box) proposal straight from its space contract: live status, the running For/Against/Abstain tally, the Safe's voting power at the proposal's snapshot block, whether the Safe already voted, and whether this Safe is the space controller that could cancel it. Use it before snapshot_x_vote or snapshot_x_cancel_proposal, and again afterwards to confirm the vote landed or the proposal shows Cancelled.

NameRequiredDescriptionDefault
spaceYesThe Snapshot X space: a space contract address, a prefixed id like "eth:0x594E…", or a full snapshot.box proposal URL (in which case proposalId can be omitted).
proposalIdNoThe proposal number, e.g. 3. Not needed when the space is a proposal URL.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered; the description adds meaningful behavior beyond that, namely that data is read on-chain from the space contract, that voting power is evaluated at the proposal's snapshot block, and that Safe-specific state (already voted, is space controller) is included. It says nothing about RPC failures or staleness of 'live status', which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the verb and source, then the returned data, then the workflow. Every clause carries information an agent would otherwise have to infer.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by listing the returned fields (status, tally, snapshot-block voting power, voted flag, controller flag). Combined with the schema's parameter documentation and the read-only annotations, an agent has everything needed to call and interpret this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters are documented in the schema, including the address / prefixed-id / URL forms of `space` and the URL-implies-no-proposalId rule. The description only echoes 'from its space contract' and adds no syntax or format detail beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Reads a Snapshot X (snapshot.box) proposal straight from its space contract') and enumerates exactly what information comes back, so the agent knows the payload without opening a schema. It distinguishes itself functionally from the write siblings it names, but never explicitly contrasts with the confusable read siblings snapshot_get_proposal / snapshot_query.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete call sequence: use before snapshot_x_vote or snapshot_x_cancel_proposal, and again afterwards to confirm the vote landed or the proposal shows Cancelled. That is real when-to-use guidance, though there are no exclusions and no routing advice against the other proposal-reading tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshot_x_voteCast an on-chain Snapshot X vote from the SafeA

Votes For, Against or Abstain on a Snapshot X (snapshot.box) proposal as the Safe. The Safe calls the space's EthTx authenticator, which forwards Space.vote with the Safe as voter — the path snapshot.box itself uses for smart-contract wallets, since a Safe cannot produce the gasless EIP-712 signature. This is an on-chain transaction: it costs gas and is final, Snapshot X does not allow changing a vote. The Safe's voting strategies are resolved automatically and the vote is simulated from the Safe before anything is signed. Read the proposal with snapshot_x_proposal first.

NameRequiredDescriptionDefault
spaceYesThe Snapshot X space: a space contract address, a prefixed id like "eth:0x594E…", or a full snapshot.box proposal URL (in which case proposalId can be omitted).
choiceYesHow to vote. Maps to the sx-evm Choice values 1, 0 and 2.
reasonNoPublic rationale. Pinned to IPFS and attached to the vote as its metadata URI, which is how snapshot.box shows a reason.
proposalIdNoThe proposal number, e.g. 3. Not needed when the space is a proposal URL.
skipChecksNoBypass the pre-flight checks and simulation, and submit every active strategy. Only for sx-evm forks that break the standard view methods.
metadataUriNoUse this metadata URI (e.g. ipfs://…) instead of pinning the reason. Pass an empty string to vote with no metadata.
authenticatorNoThe space's EthTx authenticator. Defaults to the snapshot.box deployment 0xBA06E6cCb877C332181A6867c05c8b746A21Aed1; only needed for custom spaces.
strategyParamsNoPer-strategy user params, for strategies that need them (a merkle whitelist proof, for instance). Other active strategies use 0x00.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: on-chain, costs gas, final, Snapshot X forbids changing a vote, strategies resolved automatically, and the vote is simulated from the Safe before signing. This tells the agent the irreversibility and pre-flight behavior that the hint flags alone (non-idempotent, non-destructive) cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Five tight sentences with no filler; the action, mechanism, and irreversibility warning are front-loaded and the read-first prerequisite closes it.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers mechanism, cost, finality, and simulation for an 8-parameter mutation with no output schema. The remaining gap is what happens after submission — whether this executes immediately or becomes a pending Safe transaction needing co-owner confirmation, which the sibling safe_pending_transactions/safe_confirm_transaction tools suggest is relevant.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter is already documented, and the description adds only the note that strategies are resolved automatically (relevant to strategyParams) and that skipChecks exists for broken forks. Baseline 3 applies since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Votes For, Against or Abstain on a Snapshot X proposal as the Safe') and immediately explains the mechanism (EthTx authenticator → Space.vote with the Safe as voter). The gasless EIP-712 contrast distinguishes it from the off-chain sibling snapshot_vote.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to read the proposal with snapshot_x_proposal first, and explains that this is the path for smart-contract wallets because a Safe cannot produce a gasless signature — which implicitly tells the agent when to prefer it over the gasless vote path. It does not name snapshot_vote as the excluded alternative outright.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

vote_logRead this Safe's voting recordA
Read-only

Returns votes this Safe has already cast through Safe-MPC, newest first, with the choice and the reason given. Read it before deciding so the Safe votes consistently with its own precedent, and to check whether a proposal has already been handled.

NameRequiredDescriptionDefault
limitNo
venueNoSnapshot space id, Snapshot X space contract, or Governor contract address
outcomeNo
platformNo
proposalIdNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds useful behavior beyond that: results are newest-first and include the vote choice and reason. It does not discuss pagination or auth requirements, keeping it below a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences with no wasted words. The purpose and ordering are front-loaded, followed by the usage rationale.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tool with annotations and no output schema, the description covers purpose, return content, and when to use it. However, with five optional filter parameters and low schema coverage, the description leaves too much unexplained about how to target a specific proposal, platform, outcome, or result limit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20%, with just the 'venue' parameter documented, so the description needs to compensate. Instead it provides no guidance on limit, outcome, platform, or proposalId, leaving most filter semantics undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it returns votes this Safe has already cast through Safe-MPC. It also specifies ordering ('newest first') and returned content ('choice and the reason'), which distinguishes it from mutation siblings like snapshot_x_vote or governor_vote.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage context: read it before deciding so the Safe votes consistently with precedent, and to check whether a proposal has already been handled. It does not explicitly name alternatives or exclusion conditions, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

vote_scheduleRead the scheduled vote queueA
Read-only

Shows proposals the watcher has queued for a decision, when each is due, and which are due now. Populated by safe-mpc-watch; empty if the watcher is not running.

NameRequiredDescriptionDefault
statusNopending

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, openWorldHint=false), so the description is free to add real value — and it does, by disclosing the external dependency on safe-mpc-watch and the critical gotcha that an empty result may mean the watcher isn't running rather than no pending items. Return shape is not described, but with a simple list output that is a minor omission.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no waste, and the core purpose is front-loaded ahead of the operational caveat. Nothing could be cut without losing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Purpose and the empty-result caveat are covered, but for a tool whose only knob is a six-value status enum, leaving that filter entirely unexplained is a real gap. No output schema exists, so a brief note on what a queued entry looks like would also have helped.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the single status parameter (pending/dispatched/voted/failed/expired/all) is never mentioned in the description. The phrase 'which are due now' hints at the default pending view, but the agent gets no explanation of what each enum value filters, which is the one thing the description needed to compensate for.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — a read of the watcher's queued vote schedule — plus what each entry contains (due time, due-now flag). It is distinguishable from vote_log by being a forward-looking queue rather than a historical record, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implied usage is clear (inspect the pending queue before a decision), and the note about safe-mpc-watch gives useful context. But there is no explicit when-to-use vs vote_log or snapshot_pending_vote siblings, and no guidance on when to prefer each.

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.

  1. 21 tool updatesv0.1.0
    • First observedgovernor_find_proposals
    • First observedgovernor_get_proposal
    • First observedgovernor_list_proposals
    • First observedgovernor_proposal_state
    • First observedgovernor_vote
    • First observedsafe_confirm_transaction
    • First observedsafe_info
    • First observedsafe_pending_transactions
    • First observedsnapshot_get_proposal
    • First observedsnapshot_list_proposals
    • First observedsnapshot_open_proposals
    • First observedsnapshot_query
    • First observedsnapshot_spaces_with_voting_power
    • First observedsnapshot_submit_pending_vote
    • First observedsnapshot_vote
    • First observedsnapshot_voting_power
    • First observedsnapshot_x_cancel_proposal
    • First observedsnapshot_x_proposal
    • First observedsnapshot_x_vote
    • First observedvote_log
    • First observedvote_schedule

TDQS

A3.9/5.0

Scored across 21 tools

Disambiguation4/5

Most tools target a clearly distinct resource and voting path (Safe queue, Snapshot off-chain, Snapshot X on-chain, Governor). There is some potential overlap among Snapshot read tools and among the several vote-casting tools, plus legacy Governor read tools, but descriptions usually make the intended path clear.

Naming Consistency4/5

All names use snake_case and most are grouped by domain prefix (safe_, snapshot_, governor_). However, several are noun phrases rather than verb_noun, and vote_log/vote_schedule lack the domain prefix used elsewhere, so the pattern is not fully uniform.

Tool Count3/5

At 21 tools the surface is heavy, though some size is justified by supporting three different voting systems. Legacy Governor read tools and the generic snapshot_query add breadth that could likely be consolidated.

Completeness4/5

The voting lifecycle is well covered: discover spaces/proposals, inspect state and voting power, cast votes, confirm Safe transactions, and review past votes. Minor gaps remain around generic Safe transaction proposal/execution and Governor queue/execute operations, but core Safe voting workflows are supported.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI agents to check balances and send transactions across multiple blockchains with automatic spending limit protection and policy enforcement.
    3
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to analyze Ethereum wallets, simulate transactions, and draft transfers with deterministic policy and risk scoring, requiring human approval before on-chain execution.
    6 npm
    ISC
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables autonomous agents to create and operate an Ethereum Safe wallet, send ETH or call contracts with their own signatures, and check transaction status without human approval or custody.
    0
    1
    Apache 2.0