pmqpip install pmquant, import pmq
A real MCP session against live Polymarket order books, captured 2026-07-04 and replayed here verbatim: five tool calls from market discovery to a simulated fill. Paper money, real books, no keys.
The whole setup, any MCP client
{ "mcpServers": { "pmq": { "command": "uvx", "args": ["--from", "pmquant[mcp]", "pmq-mcp"], "env": { "PMQ_MCP_PAPER": "1" } } } }
find_markets(query="fed decision july")
| How many dissent at the July Fed meeting? will-no-one-dissent-the-july-fed-decision-20260616001928666 agent picks this |
$164.99 |
| Fed Decision in July? will-the-fed-decrease-interest-rates-by-50-bps-after-the-july-2026-meeting |
$310,450 |
| Fed Decision in July? will-the-fed-decrease-interest-rates-by-25-bps-after-the-july-2026-meeting |
$310,450 |
plus 9 more of the 12 markets returned; right column: 24h event volume
Full-text market discovery across every Polymarket category. Works with zero credentials.
market(slug="will-no-one-dissent-the-july-fed-decision-20260616001928666")
Slug resolved to the condition id and one token id per outcome. Those token ids drive the book and the trading tools. Long ids are shortened here for display, nothing else on this page is.
book(token_id=<Yes>)
Best bid
0.54
592.75 shares showing
Best ask
0.56
21 shares showing
Served by the matching engine in real time, still no keys. The exchange minimums and tick come from the venue, not from constants in the library.
fak_buy(token_id=<Yes>, price_cap=0.58, usd=10)
The simulator fills at the real best ask, never at the wished
cap, caps the fill at the displayed size, refuses anything under the 5-share
exchange minimum, and uses the documented crypto-rate fee estimate,
rate·p·(1-p)·shares. No order was sent: with
PMQ_MCP_PAPER=1 none can be.
account_collateral()
989.69 paper USD, started at 1,000.00
One buy and its fee, nothing else. In live mode this tool reports the collateral the exchange actually sees, with a signature-type diagnostic when it disagrees with the chain.
Everything above ran keyless. Live trading must be switched on by the operator, in the server environment, out of the model's reach:
PMQ_MCP_LIVE unset |
the trading tools are never registered; an agent cannot call a tool that does not exist |
PMQ_MCP_PAPER=1 |
this page's mode: simulated fills on the real books, keyless; wins over live if both are set |
PMQ_MCP_MAX_USD |
hard cap per single order, default 10, enforced in live and paper alike |
PMQ_MCP_DAILY_USD |
durable cumulative buy budget per UTC day; unknown outcomes retain their requested reservation through that day |
PMQ_MCP_STATE_FILE |
local durable paper-ledger and daily-budget file; defaults to XDG state, otherwise ~/.local/state |
Structural rails on top: only fill-and-kill orders exist, so nothing ever rests unattended on the book; a fill is booked only from an exchange confirmation, never from optimism; any uncertain outcome is surfaced for reconciliation.
The local state contains paper cash, positions, fills, and the daily budget, never key material. It is atomically updated; use one state file per concurrently running server. A live buy reserves its requested amount before the client call and settles to the confirmed amount afterward. If its outcome is unknown, that full reservation remains through the UTC day.
uvx --from "pmquant[mcp]" pmq-mcp
Then point your MCP client (Claude Desktop or Code, ChatGPT,
LangChain, a bare SDK loop) at the uvx configuration above with
PMQ_MCP_PAPER=1, and ask the agent to find a market and trade it.
Books move, so your numbers will differ from this captured session.
Every figure on this page comes from the captured session of 2026-07-04, unedited. The page itself is one file of HTML and CSS: no JavaScript, no network requests, view source to check.