polymarket-mcp-server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| polymarket_search_marketsA | Discover Polymarket markets by keyword, or list the highest-volume markets. Use this first to find a market's slug and its current implied probability, then feed the slug into the other tools. Args:
Returns: { count, query, markets: [{ slug, question, conditionId, outcomes:[{outcome, tokenId, price, impliedProbabilityPct}], volume, liquidity, volume24hr, endDate, active, closed, acceptingOrders, eventSlug }] }. Examples:
|
| polymarket_get_marketA | Fetch the full detail of a single market by its slug, including the CLOB token ids for each outcome. Use this to follow a specific market you already know, or after a search to get the exact token ids needed by the order book / price history tools. Args:
Returns: { market: { slug, question, conditionId, description, startDate, endDate, negRisk, enableOrderBook, acceptingOrders, active, closed, volume, liquidity, volume24hr, eventSlug, outcomes:[{outcome, tokenId, price, impliedProbabilityPct}] } }. Errors: "No market found for slug '…'" if the slug is wrong — verify it with polymarket_search_markets. |
| polymarket_get_eventsA | Get Polymarket EVENTS, which group related markets under one question (e.g. a tournament or election, with a market per team/candidate). Use this when a question spans many outcomes: one event carries all its markets. Pass a slug for one event, or omit it for the top events by 24h volume. Args:
Returns: { count, events:[{ slug, title, startDate, endDate, active, closed, volume, liquidity, volume24hr, negRisk, marketCount, markets:[{ question, slug, conditionId, outcomes, volume, closed }] }] }. Errors: "No event found for slug '…'" if the slug is wrong. |
| polymarket_get_orderbookA | Get the live order book for one market outcome: best bid/ask, spread, mid price, implied probability, and top-of-book depth. This is where you check whether an edge is real: the implied probability (mid) is the market's estimate, while best ask is what you'd actually pay to buy and best bid what you'd receive to sell. A wide spread or thin depth means the "price" you saw elsewhere may not be executable. Identify the outcome either by token_id (preferred) OR by slug + outcome. Args:
Returns: { tokenId, outcome, slug, question, bestBid, bestAsk, mid, spread, impliedProbabilityPct, spreadPct, totalBidSize, totalAskSize, bids:[{price,size}], asks:[{price,size}], timestamp }. Errors: "No market found for slug…" (bad slug); an empty side is reported as bestBid/bestAsk = null. |
| polymarket_get_price_historyA | Get the historical price (implied probability over time) for one market outcome, plus summary stats. Use this to see how a market moved and where you might have entered or exited. Identify the outcome by token_id (preferred) OR slug + outcome. Args:
Returns: { tokenId, outcome, interval, count, truncated, summary:{first,last,min,max,changeAbs,changePct,from,to}, points:[{t, iso, p}] }. Prices are 0-1 (probability). 'count' is the number of returned points; 'truncated' indicates downsampling. |
| polymarket_get_quoteA | Get a lightweight live quote for one market outcome — midpoint, best buy/sell price, spread and last trade — WITHOUT pulling the full order book. Faster than polymarket_get_orderbook when you just want "what's this worth right now". Identify the outcome by token_id (preferred) OR slug + outcome. Args:
Returns: { tokenId, outcome, slug, question, midpoint, buyPrice, sellPrice, spread, spreadPct, impliedProbabilityPct, lastTradePrice, lastTradeSide }. Prices are 0-1 (midpoint ≈ implied probability; buyPrice is what you'd pay, sellPrice what you'd receive). Any value the book can't provide is null. For full depth, use polymarket_get_orderbook. |
| polymarket_get_tradesA | Get recent trades — either a MARKET's tape (who traded, at what price) or a WALLET's trade history. Provide market (a conditionId) for the market tape, OR wallet for that address's trades. Args:
Returns: { market, user, count, trades:[{ wallet, name, side, outcome, price, size, usdcSize, timestamp, iso, conditionId, title, slug, transactionHash }] }. Errors: "Provide either 'market' or 'wallet'." if neither is given. |
| polymarket_get_open_interestA | Get the OPEN INTEREST (total value of outstanding positions) for one or more markets — a measure of how much capital is currently at stake. Identify markets by conditionId(s), or pass a slug (resolved to its conditionId). Args:
Returns: { count, totalValue, openInterest:[{ market, value }] }. Errors: "Provide either 'condition_ids' or 'slug'."; "No market found for slug…". |
| polymarket_get_leaderboardA | Get the trader LEADERBOARD — top wallets ranked by realized profit (PnL) or traded volume over a time window. Args:
Returns: { orderBy, timePeriod, count, entries:[{ rank, wallet, name, pnl, volume }] }. This is a global ranking (unlike polymarket_get_market_holders, which is per-market). |
| polymarket_get_positionsA | Get the open positions and P&L for a public wallet address ("how is this wallet doing"). Returns each position's entry price, current price, current value and profit/loss, plus the wallet's total portfolio value. Read-only and public — anyone's positions are visible by address. Args:
Returns: { wallet, portfolioValue, openPositions, totalCurrentValue, totalCashPnl, positions:[{ title, slug, outcome, conditionId, tokenId, size, avgPrice, curPrice, initialValue, currentValue, cashPnl, percentPnl, realizedPnl, redeemable, endDate }] }. Errors: an invalid address is rejected before any request; an unknown wallet returns 0 positions. |
| polymarket_get_closed_positionsA | Get a wallet's CLOSED (resolved) positions with REALIZED profit/loss — the settled history behind polymarket_get_positions (which shows only open positions). Args:
Returns: { wallet, count, totalRealizedPnl, positions:[{ title, slug, outcome, conditionId, avgPrice, totalBought, realizedPnl, curPrice }] }. An unknown wallet returns 0 positions. |
| polymarket_get_user_activityA | Get a wallet's full on-chain ACTIVITY feed — beyond open positions: trades plus splits, merges, redeems, rewards, deposits and withdrawals. Complements polymarket_get_positions (current holdings) and polymarket_get_trades (just trades) with the complete history. Args:
Returns: { wallet, count, truncated, activities:[{ type, timestamp, iso, side, outcome, size, usdcSize, price, conditionId, title, slug, transactionHash }] }. The 'truncated' flag is true when more entries existed than were returned. An unknown wallet returns 0 activities. |
| polymarket_get_market_holdersA | Get the largest holders of each outcome in a market — the "whales" with the most exposure. Useful to see who is positioned on each side and how concentrated a market is. Identify the market by slug (preferred, so outcomes get named) OR conditionId. Args:
Returns: { conditionId, slug, question, outcomes:[{ outcome, tokenId, holders:[{ rank, name, wallet, amountShares }] }] }. Notes: amounts are share counts (each resolves to $1 if that outcome wins). Anonymous holders show a shortened wallet. This is per-market holder ranking, not a global leaderboard. Errors: "Provide either 'condition_id' or 'slug'"; "No market found for slug…". |
| polymarket_paper_openA | Record a SIMULATED bet in the local paper-trading ledger. No real money, no order is placed — this only writes a local file to track a hypothesis and score it later. Fills honestly at the executable ASK plus the category taker fee (Polymarket charges takers since 2026-03-30), so the simulated P&L isn't a fantasy. Prefer slug + outcome so the conditionId is captured for auto-scoring at resolution. Args:
Returns: the recorded bet + a fractional-Kelly sizing hint (full & half) + the virtual bankroll. |
| polymarket_paper_statusA | Show the SIMULATED paper-trading ledger: open bets marked-to-market, resolved bets scored automatically (a resolved market pays the winning outcome $1), and totals — realized/unrealized P&L net of fees, ROI, hit rate, and Brier scores (yours vs the market's implied probability at entry) on your probability estimates. No real money anywhere. Args:
|
| polymarket_paper_closeA | Manually close an OPEN paper bet at the current price (models selling before the market resolves). Fills at the executable BID minus the taker fee. No real money. Args:
|
| polymarket_paper_deleteA | Permanently remove one bet from the local paper-trading ledger. Works on any status (open, won, lost, closed). This rewrites simulated history — a deleted resolved bet stops counting towards realized P&L, ROI, hit rate and Brier, so your track record will change. To stop tracking a bet while keeping an honest record, use polymarket_paper_close instead. No real money is involved either way. Args:
|
| polymarket_paper_resetA | Wipe the local paper-trading ledger and start a fresh virtual bankroll. Erases every simulated bet, including resolved ones — realized P&L, ROI, hit rate and Brier all go back to zero. There is no undo. Requires confirm=true; without it the call is rejected so the ledger can't be wiped by accident. No real money is involved — this only rewrites a local file. Args:
|
| polymarket_find_arbitrageA | Scan for risk-free pricing gaps: a binary market whose best-ask(YES)+best-ask(NO) < $1, or a negRisk event basket whose Σ best-ask(legs) < $1. Fee-aware (reports gross AND net-of-fee edge) and depth-aware (estimates executable size). This is the one edge a read-only bot can DETECT precisely — but detection is not capture. Args:
Returns: { scanned, feePerShare, category, count, arbs:[{ type, title, legs, grossEdge/Pct, netEdge/Pct, executable:{sets,notionalUsd,estNetProfitUsd,bottleneckLeg} }] }. |
| polymarket_xrayA | The one-shot deep look at a market: detail + executable quote + whales + recent price history + recent trade tape, all in one call (several API calls bundled). Identify by token_id OR slug + outcome. Args:
Returns: { tokenId, outcome, slug, question, detail, quote, whales, history, tape } (sections null-tolerant). |
| polymarket_calibration_snapshotA | Record a SNAPSHOT of current open markets' implied probabilities (one per outcome) into a local file, so that when they resolve, polymarket_calibration_report can measure whether the market is well-calibrated (do 30% markets resolve Yes ~30% of the time?). Forward-only. Writes a local file; no real money. Args:
Returns: { recorded, skipped, totalSnapshots, byBucket }. Re-running the same day won't double-count. |
| polymarket_calibration_reportA | Score the calibration snapshots: resolve any that have settled since, then compute a reliability curve (predicted vs observed per decile) + Brier score + ECE. Tells you whether the market's prices are honest. Needs elapsed time for markets to resolve, so it's sparse early on. Args:
Returns: { totalSnapshots, resolvedCount, pendingCount, brier, ece, curve:[{bucket,label,n,predictedMean,observedFreq}] }. |
| polymarket_daily_digestA | A one-shot "morning briefing": your paper-trading status, a small arbitrage scan, the day's top movers, and your calibration status — all in one call. Read-only vs Polymarket (reads the local ledgers). Meant to be run each morning (see the README for scheduling it on Windows). Args:
|
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 23 tools
Most tools target clearly distinct resources and actions (market vs event vs orderbook vs positions). Composites like polymarket_xray and polymarket_daily_digest bundle existing tools but are explicitly described as shortcuts. Slight potential confusion between polymarket_get_quote and polymarket_get_orderbook, but descriptions clarify.
All tools share the polymarket_ prefix and snake_case formatting. Most follow a verb_noun pattern (search_markets, get_market, find_arbitrage), but there are mixed verb styles (get_ vs search_ vs paper_ vs xray) and a few noun-first names like calibration_snapshot.
At 23 tools, the set is above the typical 3–15 sweet spot and feels heavy for a read-only/paper-trading server. While each tool has a plausible role, several could be consolidated (e.g. paper status/close/delete/reset, calibration snapshot/report) without losing core functionality.
The surface covers market discovery, detailed data, user analytics, paper trading, arbitrage detection, calibration, and a daily digest. Missing real order execution, order cancellation, and real-time streaming, but those appear intentionally out of scope given the explicit no-real-money design.