Polymarket With Veto MCP
Run a guarded MCP sidecar for Polymarket trading. Every mutating tool call is validated against YAML policy rules before execution.
This guide covers @plawio/polymarket-veto-mcp, a sidecar that wraps the Polymarket CLI with Veto policy guardrails exposed as MCP tools. The agent proposes, Veto permits.
Architecture
- Rust
polymarketCLI handles market access and execution - TypeScript MCP sidecar (
@plawio/polymarket-veto-mcp) wraps CLI commands as MCP tools - Every mutating tool call is validated against YAML rules before execution
- Simulation mode is on by default. No real orders run unless you explicitly unlock live execution.
- x402 protocol integration supports paid research endpoints
Install
Install the Polymarket CLI
brew install polymarketOr build from source:
git clone https://github.com/PlawIO/polymarket-cli-veto.git
cd polymarket-cli-veto
cargo build --releaseOr use the install script:
curl -sSf https://raw.githubusercontent.com/Polymarket/polymarket-cli/main/install.sh | shBuild the MCP sidecar
cd polymarket-cli-veto
pnpm --dir veto-agent install
pnpm --dir veto-agent buildInstall the Claude Code skill (optional)
cp -r skills/polymarket-veto ~/.claude/skills/
bash ~/.claude/skills/polymarket-veto/scripts/setup.shThe setup script writes .mcp.json to the current project directory. Pass a profile name to change the default:
bash ~/.claude/skills/polymarket-veto/scripts/setup.sh userThe skill is optional. The MCP server works with any MCP host that can launch the sidecar process.
Start the MCP sidecar
From source (local development)
pnpm --dir veto-agent exec tsx src/bin.ts serve --config polymarket-veto.config.yamlVia npm (any MCP host)
{
"mcpServers": {
"polymarket-veto": {
"command": "npm",
"args": [
"exec", "--yes", "--prefix", "/tmp",
"--package", "@plawio/polymarket-veto-mcp",
"--", "polymarket-veto-mcp", "serve",
"--policy-profile", "defaults"
]
}
}
}Inspect tools and health
pnpm --dir veto-agent exec tsx src/bin.ts doctor --config polymarket-veto.config.yaml
pnpm --dir veto-agent exec tsx src/bin.ts status --config polymarket-veto.config.yaml
pnpm --dir veto-agent exec tsx src/bin.ts print-tools --config polymarket-veto.config.yamlTool coverage
Read-only (no policy gating)
| Tool | Purpose | Key args |
|---|---|---|
markets_list | List markets | limit, active, closed |
markets_search | Search by text | query, limit |
markets_get | Market details | market (id or slug) |
clob_book | Order book | token |
clob_midpoint | Midpoint price | token |
clob_price | CLOB price | token, side |
portfolio_positions | Wallet positions | address |
Mutating (policy-guarded, simulation by default)
| Tool | Purpose | Key args |
|---|---|---|
order_create_limit | Limit order | token, side, price, size, orderType, postOnly |
order_market | Market order | token, side, amount |
order_cancel | Cancel one order | orderId |
order_cancel_all | Cancel all orders | (none) |
approve_set | On-chain approvals | (none) |
ctf_split | Split USDC to tokens | condition, amount |
ctf_merge | Merge tokens to USDC | condition, amount |
ctf_redeem | Redeem winners | condition |
Internal controls
| Tool | Purpose | Key args |
|---|---|---|
policy_create | Generate session policy from prompt | prompt, toolName |
policy_list | List active session policies | (none) |
policy_tighten | Tighten a session rule | ruleId, newCondition |
policy_request_edit | Request review for policy edit | ruleId, changes |
audit_query | Query audit log | since, agentId, toolName, limit |
pnl_snapshot | All positions with P&L | (none) |
pnl_position | Position details for token | token |
circuit_breaker_status | Circuit breaker state | (none) |
compliance_report | Generate compliance report | format, period, startDate, endDate |
budget_status | Session and category budgets | (none) |
runtime_status | Runtime readiness and capital controls | (none) |
approval_status | Check approval request status | approvalId |
x402-paid research
| Tool | Purpose | Key args |
|---|---|---|
intel_search | Paid research query | query, limit |
intel_market_context | Paid research context | market, event, token |
Architecturally excluded
wallet_import, wallet_reset, clob_delete_api_key are never exposed. The MCP layer rejects them with error code -32601 before policy evaluation.
Policy profiles
| Profile | Best for |
|---|---|
defaults | Getting started. Small orders allowed, larger require approval. |
agent | Autonomous bots. Adds off-hours gating (8am–8pm ET weekdays). |
user | Human-delegated trading. Hard caps, sell-side approvals, price discipline. |
conservative | Experimentation. Every mutation requires approval. |
Set the profile with --policy-profile <name> when starting the server.
Simulation vs live execution
Simulation is on by default. Mutating tools estimate shares and notional, run policy and economic checks, but do not submit real orders.
Live trading requires all three:
- Start the server with
--simulation off - Set
execution.allowLiveTrades: truein config - Export
ALLOW_LIVE_TRADES=truein the environment
Do not enable live execution unless you intend to submit real orders. The server stays in simulation unless all three controls are in place.
Economic authorization and x402
The same runtime governs both Polymarket trading notional and x402-paid research spend. It enforces payer requirements, approved payer lists, budget authorization, and fail-closed behavior for live priced actions when the economic authority is unavailable.
Error codes
| Code | Meaning | Response |
|---|---|---|
-32601 | Unknown tool | Tool not in registry. Do not retry. |
-32602 | Invalid arguments | Fix arguments and retry. |
-32001 | Denied by policy | Profile blocks this. Explain the rule. |
-32002 | Approval required | Human must approve. Inform the user. |
-32003 | Execution failed | Binary missing or command error. Run doctor. |