feat(mcp): governance tools, and a vendor-neutral setup guide - #361
Merged
Conversation
Three governance tools, answering the three questions a treasury actually
asks:
governance_list_ballots the team's internal decision log — how the
signers decided on each proposal, with any
drafted rationale
governance_vote_history what the wallet's DRep actually put on-chain,
newest first, with proposal titles
governance_open_proposals active proposals this wallet has NOT voted on
— the outstanding decisions. Cross-references
live proposals against on-chain vote history;
includeVoted returns the whole active set
annotated with how we voted.
open_proposals degrades rather than fails: if the DRep is unset or Koios is
unreachable it still returns the active set and flags
voteHistoryUnavailable, so a model can say "I could not check" instead of
implying nothing has been voted on.
Two handler changes to support them, both mirroring the pattern already
used for botBallotsUpsert:
- botBallots gains a human branch. It was bot-only and required
ballot:write even to GET; a wallet signer can already read these ballots
through the tRPC router, so the bot gate now sits behind isBotJwt and
humans are authorized by the same signer-or-owner predicate.
- drepInfo gains a wallet-access check. It previously looked up ANY
walletId for ANY authenticated caller, letting anyone map a wallet id to
its DRep credential. Now goes through authorizeProxyReadForV1, the
canonical dual-identity read check. This is a pre-existing hole, fixed
here because this change exposes the endpoint through MCP.
Landing page: the hero now leads with MCP rather than one vendor. It shows
the endpoint and a plain `mcpServers` JSON block that works in any client,
with a per-vendor CLI mentioned only as an aside. Prompts in the demo were
rewritten to match tools we actually expose, including the governance
ones. The setup card is vendor-neutral for the same reason and gained an
anchor the hero links to.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three governance tools, answering the three questions a treasury actually asks:
governance_list_ballots the team's internal decision log — how the
signers decided on each proposal, with any
drafted rationale
governance_vote_history what the wallet's DRep actually put on-chain,
newest first, with proposal titles
governance_open_proposals active proposals this wallet has NOT voted on
— the outstanding decisions. Cross-references
live proposals against on-chain vote history;
includeVoted returns the whole active set
annotated with how we voted.
open_proposals degrades rather than fails: if the DRep is unset or Koios is unreachable it still returns the active set and flags voteHistoryUnavailable, so a model can say "I could not check" instead of implying nothing has been voted on.
Two handler changes to support them, both mirroring the pattern already used for botBallotsUpsert:
botBallots gains a human branch. It was bot-only and required ballot:write even to GET; a wallet signer can already read these ballots through the tRPC router, so the bot gate now sits behind isBotJwt and humans are authorized by the same signer-or-owner predicate.
drepInfo gains a wallet-access check. It previously looked up ANY walletId for ANY authenticated caller, letting anyone map a wallet id to its DRep credential. Now goes through authorizeProxyReadForV1, the canonical dual-identity read check. This is a pre-existing hole, fixed here because this change exposes the endpoint through MCP.
Landing page: the hero now leads with MCP rather than one vendor. It shows the endpoint and a plain
mcpServersJSON block that works in any client, with a per-vendor CLI mentioned only as an aside. Prompts in the demo were rewritten to match tools we actually expose, including the governance ones. The setup card is vendor-neutral for the same reason and gained an anchor the hero links to.