polymarket-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@polymarket-mcp-server show me the order book for the next Fed rate cut"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
polymarket-mcp-server
A read-only MCP server for Polymarket. It lets an MCP client (Claude Code, Claude Desktop, …) query markets, order books, price history, wallet positions, and market holders — using Polymarket's three public, unauthenticated APIs.
No trading. No private keys. No signer. No authenticated CLOB endpoints. It only uses the SDK's public read-only client; viem/ethers are not installed (note: @polymarket/client depends on ox, so npm install pulls some crypto primitives transitively, unused here). The market/data tools are readOnlyHint: true; the paper-trading + calibration tools only write a local, gitignored data/ ledger of simulated bets — never real money, no order is ever placed.
What it can do — 23 tools
13 read-only market/data tools, 5 simulated paper-trading tools (local ledger, no real money), and 5 analytics/automation tools.
Tool | API | Purpose |
| Gamma | Find markets by keyword, or list top markets by volume. |
| Gamma | Full detail of one market by slug, incl. CLOB token ids per outcome. |
| Gamma | Events grouping related markets (a whole tournament/election). |
| CLOB (SDK) | Live best bid/ask, spread, mid, depth — is an edge executable? |
| CLOB (SDK) | Historical implied probability over a window, with summary stats. |
| CLOB (SDK) | Quick midpoint / buy / sell / spread / last-trade for one outcome. |
| Data | Recent trades — a market's tape, or a wallet's trade history. |
| Data | Open interest (capital at stake) for one or more markets. |
| Data | Global trader ranking by realized P&L or volume. |
| Data | Open positions + P&L for a public wallet. |
| Data | A wallet's resolved positions with realized P&L. |
| Data | A wallet's full activity feed (trades, splits, merges, …). |
| Data | Largest holders ("whales") of each outcome in a market. |
| local | SIMULATED paper trading — record bets to a local ledger (fills at ask + taker fee), mark-to-market, auto-score at resolution, Brier vs the market. Opening is capped by the available virtual bankroll. No real money, no order placed. |
| local | Rewrite the simulated ledger: drop one bet, or wipe it and start a fresh virtual bankroll ( |
| CLOB (SDK) | Scan for baskets priced under $1 (Yes+No, or a negRisk event) net of fees — the one edge a read-only bot can detect. Detection ≠ capture. |
| mixed | One-call deep look: detail + quote + whales + price history + trade tape. |
| mixed | Snapshot markets now; when they resolve, score a reliability curve + Brier — is the market well-priced? |
| mixed | A "morning briefing": paper status + arbitrage scan + top movers + calibration status. |
The CLOB read tools run on the official @polymarket/client SDK (public read-only client — no keys, no wallet); Gamma and Data run on native fetch. The paper-trading and calibration tools write only a local, gitignored data/ ledger — never real money.
Related MCP server: polymarket-mcp
The identifier model (read this once)
Polymarket uses several ids and it's easy to get lost:
A binary market has a human
slug, aconditionId, and twoclobTokenIds— one per outcome (Yes / No).The order book and price history key on the
token_id(a ~77-digit number), not the slug.
Flow: slug → polymarket_get_market gives you the clobTokenIds → CLOB tools use a token_id.
For convenience, the CLOB tools (get_orderbook, get_price_history, get_quote) accept either:
token_iddirectly (preferred if you have it), orslug+outcome(e.g."Yes") — the server resolves the token id for you via Gamma.
Prerequisites
Node.js ≥ 24 (required by the official Polymarket SDK; Gamma/Data still use the built-in
fetch). Check withnode --version.Windows:
winget install OpenJS.NodeJS.LTSor download from nodejs.org.
Install & build
npm install
npm run build # compiles TypeScript to dist/Try it with the MCP Inspector
npm run inspector # builds, then opens the MCP Inspector against dist/index.jsThen call e.g. polymarket_search_markets with { "query": "bitcoin" }.
Register in Claude Code
This repo already ships a project-scoped .mcp.json with a relative path, so it works on any machine once you've run npm install && npm run build from the project root:
{
"mcpServers": {
"polymarket": {
"command": "node",
"args": ["dist/index.js"]
}
}
}The relative dist/index.js resolves from the project root (where Claude Code is launched). If your client needs an absolute path, substitute the full path to dist/index.js on that machine. No secrets or environment variables are required — everything it touches is public.
Install from a clone
git clone <your-repo-url>
cd polymarket-mcp
npm install
npm run buildThen reload MCP / restart Claude Code (project .mcp.json servers need a one-time approval in an interactive session). Requires Node ≥ 24 on the new machine.
Usage examples
"What Polymarket markets are there about the Fed?" →
polymarket_search_markets { query: "Fed" }"What's the real spread on Argentina to win the World Cup?" →
polymarket_get_orderbook { slug: "will-argentina-win-the-2026-fifa-world-cup-245", outcome: "Yes" }"How has that market moved this month?" →
polymarket_get_price_history { slug: "…", outcome: "Yes", interval: "1m" }"How is wallet 0xabc… doing?" →
polymarket_get_positions { wallet: "0xabc…" }"Who are the whales on the Yes side?" →
polymarket_get_market_holders { slug: "…" }"Give me the full picture on this market" →
polymarket_xray { slug: "…", outcome: "Yes" }"Any arbitrage in the top events?" →
polymarket_find_arbitrage { scan_top: 10 }"Track a simulated bet" →
polymarket_paper_open { slug: "…", outcome: "No", size_usdc: 50, p_estimate: 0.6 }, thenpolymarket_paper_status"Start the paper lab over" →
polymarket_paper_reset { confirm: true, bankroll: 500 }(erases every simulated bet — there is no undo)"My morning briefing" →
polymarket_daily_digest
Scheduling the daily digest (Windows)
The server is a local stdio process, so a cloud routine can't reach it. To get the digest unattended, use Windows Task Scheduler to run a headless Claude command with its "Start in" set to the project root:
claude -p "Run polymarket_daily_digest and print it" --allowedTools "mcp__polymarket__polymarket_daily_digest" --output-format text >> "%USERPROFILE%\polymarket-digest.log"Requires: the PC on/awake at the trigger time; Claude Code installed and authenticated for
non-interactive use; the task's Start in = the project folder (so .mcp.json's relative
dist/index.js resolves); and the one tool pre-allowed (a scheduled run can't answer permission
prompts). Each run consumes Claude usage. (/loop also works, but only while a session stays open;
cloud /schedule does not reach a local stdio server.)
Design notes
APIs / transport: Gamma
gamma-api.polymarket.comand Datadata-api.polymarket.comover nativefetch; the CLOB reads (order book, price history, quote) go through the official@polymarket/clientpublic client (createPublicClient(), no keys). Seesrc/clobSdk.ts.Rate limits: Gamma allows ~60 req/min unauthenticated. The client backs off exponentially (honoring
Retry-After) on 429/5xx and retries transient network errors.Context discipline: responses default to concise Markdown; pass
response_format: "json"for full structured data. Every tool also returns machine-readablestructuredContent.JSON-string fields: Gamma returns
outcomes,outcomePrices, andclobTokenIdsas JSON-encoded strings; the client parses and zips them so each outcome is paired with its token id and implied price.
Project layout
src/
index.ts # entry: McpServer + stdio transport
constants.ts # base URLs, limits
types.ts # raw API + normalized types
client.ts # PolymarketClient: Gamma/Data fetch+backoff, error mapping, slug→token; CLOB via SDK
clobSdk.ts # official @polymarket/client public client + pure response mappers (CLOB reads)
arbMath.ts # pure arbitrage math (edge + depth-walked executable size)
calibrationMath.ts # pure calibration math (buckets, reliability curve, Brier, ECE)
paperFees.ts # taker-fee model + fractional-Kelly + Brier (pure)
paperStore.ts / calibrationStore.ts / dataDir.ts # local JSON ledgers (gitignored data/)
schemas.ts # Zod input/output schemas
format.ts # formatting + result/error helpers
tools/ # one file per tool (23)Scope / non-goals
Read-only by design. Order placement, cancellation, approvals, or anything requiring a signature/API key is intentionally out of scope — the official SDK is used only via its public read-only client (createPublicClient()), which pulls no wallet/crypto libraries. Global trader rankings are available via polymarket_get_leaderboard; polymarket_get_market_holders covers per-market whale visibility.
License
MIT
Screenshots
How it was built
Most of the code was written by Claude Code. I set the scope, made the design decisions and tested the behaviour.
Available Tools
23 toolspolymarket_calibration_reportCalibration 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:
min_resolved (number, default 1): note if fewer than this have resolved.
Returns: { totalSnapshots, resolvedCount, pendingCount, brier, ece, curve:[{bucket,label,n,predictedMean,observedFreq}] }.
Inputs: min_resolved, response_format. Returns: ece, brier, curve, pendingCount, +2 more
polymarket_calibration_snapshotSnapshot markets for calibrationA
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:
query (string, optional): snapshot markets about a keyword; omit for top markets by volume.
limit (1-50, default 25), min_volume (default 0, filters dead markets).
Returns: { recorded, skipped, totalSnapshots, byBucket }. Re-running the same day won't double-count.
Inputs: limit, query, min_volume, response_format. Returns: skipped, byBucket, recorded, totalSnapshots
polymarket_daily_digestPolymarket daily digestARead-onlyIdempotent
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:
arb_scan_top (1-15, default 5): top events to scan for arbitrage.
movers_limit (1-15, default 5): how many top markets to rank by 24h move.
Inputs: arb_scan_top, movers_limit, response_format. Returns: arbs, paper, movers, calibration, +1 more
polymarket_find_arbitrageFind Polymarket arbitrageARead-onlyIdempotent
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:
event_slug (string, optional) OR scan_top (1-25): scan one event, or sweep the top-N events by 24h volume.
min_edge_pct (number, default 0.5): only flag arbs whose NET edge% ≥ this.
category ('crypto'|'sports'|'politics'|'macro'|'geopolitics'|'other'): taker-fee assumption (geopolitics free).
max_legs (number, default 12): skip baskets larger than this.
Returns: { scanned, feePerShare, category, count, arbs:[{ type, title, legs, grossEdge/Pct, netEdge/Pct, executable:{sets,notionalUsd,estNetProfitUsd,bottleneckLeg} }] }.
Inputs: category, max_legs, scan_top, event_slug, +2 more. Returns: arbs, count, scanned, category, +1 more
polymarket_get_closed_positionsGet Polymarket closed positionsARead-onlyIdempotent
Get a wallet's CLOSED (resolved) positions with REALIZED profit/loss — the settled history behind polymarket_get_positions (which shows only open positions).
Args:
wallet (string): 0x… address (42 chars).
limit (number): max closed positions, 1-100 (default 25).
response_format ('markdown' | 'json'): default 'markdown'.
Returns: { wallet, count, totalRealizedPnl, positions:[{ title, slug, outcome, conditionId, avgPrice, totalBought, realizedPnl, curPrice }] }. An unknown wallet returns 0 positions.
Inputs: wallet (required), limit, response_format. Returns: count, wallet, positions, totalRealizedPnl
polymarket_get_eventsGet Polymarket eventsARead-onlyIdempotent
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:
slug (string, optional): event slug for one event with all its markets. If omitted, returns top events.
limit (number): max events when listing, 1-20 (default 5).
active_only (boolean): only open/unresolved events (default true).
response_format ('markdown' | 'json'): default 'markdown'.
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.
Inputs: slug, limit, active_only, response_format. Returns: count, events
polymarket_get_leaderboardGet Polymarket trader leaderboardARead-onlyIdempotent
Get the trader LEADERBOARD — top wallets ranked by realized profit (PnL) or traded volume over a time window.
Args:
order_by ('PNL' | 'VOL'): rank by profit or volume (default 'PNL').
time_period ('DAY' | 'WEEK' | 'MONTH' | 'ALL'): window (default 'MONTH').
category (string, optional): e.g. OVERALL, POLITICS, SPORTS, CRYPTO, CULTURE, ECONOMICS, TECH, FINANCE.
limit (number): top N traders, 1-50 (default 10).
response_format ('markdown' | 'json'): default 'markdown'.
Returns: { orderBy, timePeriod, count, entries:[{ rank, wallet, name, pnl, volume }] }. This is a global ranking (unlike polymarket_get_market_holders, which is per-market).
Inputs: limit, category, order_by, time_period, +1 more. Returns: count, entries, orderBy, timePeriod
polymarket_get_marketGet one Polymarket marketARead-onlyIdempotent
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:
slug (string): the market slug (from polymarket_search_markets).
response_format ('markdown' | 'json'): default 'markdown'.
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.
Inputs: slug (required), response_format. Returns: market
polymarket_get_market_holdersGet Polymarket market holders (whales)ARead-onlyIdempotent
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:
slug (string, optional): market slug. Provide this OR condition_id.
condition_id (string, optional): market conditionId (0x…). Provide this OR slug.
limit (number): top holders per outcome, 1-20 (default 5).
response_format ('markdown' | 'json'): default 'markdown'.
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…".
Inputs: slug, limit, condition_id, response_format. Returns: slug, outcomes, question, conditionId
polymarket_get_open_interestGet Polymarket open interestARead-onlyIdempotent
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:
condition_ids (string[], optional): one or more market conditionIds (0x…). Provide this OR slug.
slug (string, optional): market slug (resolved to its conditionId). Provide this OR condition_ids.
response_format ('markdown' | 'json'): default 'markdown'.
Returns: { count, totalValue, openInterest:[{ market, value }] }. Errors: "Provide either 'condition_ids' or 'slug'."; "No market found for slug…".
Inputs: slug, condition_ids, response_format. Returns: count, totalValue, openInterest
polymarket_get_orderbookGet Polymarket order bookARead-onlyIdempotent
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:
token_id (string, optional): the ~77-digit CLOB token id for one outcome.
slug (string, optional) + outcome (string, optional): e.g. slug + "Yes". Outcome defaults to the first.
depth (number): price levels per side to include, 1-50 (default 10).
response_format ('markdown' | 'json'): default 'markdown'.
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.
Inputs: slug, depth, outcome, token_id, +1 more. Returns: mid, asks, bids, slug, +11 more
polymarket_get_positionsGet Polymarket wallet positionsARead-onlyIdempotent
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:
wallet (string): 0x… address (42 chars). The on-chain proxy wallet, not a username.
limit (number): max positions, 1-100 (default 25).
min_value (number): hide positions worth less than this USD (default 1, filters dust).
redeemable_only (boolean): only resolved positions ready to redeem (default false).
response_format ('markdown' | 'json'): default 'markdown'.
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.
Inputs: wallet (required), limit, min_value, redeemable_only, +1 more. Returns: wallet, positions, totalCashPnl, openPositions, +2 more
polymarket_get_price_historyGet Polymarket price historyARead-onlyIdempotent
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:
token_id (string, optional): the ~77-digit CLOB token id.
slug (string, optional) + outcome (string, optional): e.g. slug + "Yes".
interval ('1h'|'6h'|'1d'|'1w'|'1m'|'max'): look-back window (default '1w').
fidelity (number, optional): minutes between points.
max_points (number): downsample to at most this many points (default 150).
response_format ('markdown' | 'json'): default 'markdown'.
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.
Inputs: slug, outcome, fidelity, interval, +3 more. Returns: count, points, outcome, summary, +3 more
polymarket_get_quoteGet a quick Polymarket quoteARead-onlyIdempotent
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:
token_id (string, optional): the ~77-digit CLOB token id.
slug (string, optional) + outcome (string, optional): e.g. slug + "Yes". Outcome defaults to the first.
response_format ('markdown' | 'json'): default 'markdown'.
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.
Inputs: slug, outcome, token_id, response_format. Returns: slug, spread, outcome, tokenId, +8 more
polymarket_get_tradesGet Polymarket tradesARead-onlyIdempotent
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:
market (string, optional): market conditionId (0x…). Provide this OR wallet.
wallet (string, optional): 0x… address. Provide this OR market.
taker_only (boolean): only taker trades (default true); false adds maker fills for the full tape.
limit (number): max trades, 1-100 (default 20).
response_format ('markdown' | 'json'): default 'markdown'.
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.
Inputs: limit, market, wallet, taker_only, +1 more. Returns: user, count, market, trades
polymarket_get_user_activityGet Polymarket wallet activityARead-onlyIdempotent
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:
wallet (string): 0x… address (42 chars).
type (string[], optional): filter to types like TRADE, SPLIT, MERGE, REDEEM, REWARD, DEPOSIT, WITHDRAWAL (default: all).
limit (number): max entries to request, 1-500 (default 50). At most 200 are returned.
response_format ('markdown' | 'json'): default 'markdown'.
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.
Inputs: wallet (required), type, limit, response_format. Returns: count, wallet, truncated, activities
polymarket_paper_closeClose a SIMULATED (paper) bet earlyA
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:
id (string): the paper bet id (from polymarket_paper_status).
Inputs: id (required), response_format. Returns: bet, bankroll
polymarket_paper_deleteDelete a SIMULATED (paper) betADestructive
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:
id (string): the paper bet id (from polymarket_paper_status).
Inputs: id (required), response_format. Returns: bet, bankroll
polymarket_paper_openOpen a SIMULATED (paper) Polymarket betA
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:
token_id (string, optional) OR slug (string) + outcome (string).
size_usdc (number): simulated stake (virtual money).
p_estimate (number 0-1, optional): your probability for this outcome (for Brier scoring + the Kelly hint).
category ('crypto'|'sports'|'politics'|'macro'|'geopolitics'|'other'): taker-fee bucket.
note (string, optional): the hypothesis you're testing.
Returns: the recorded bet + a fractional-Kelly sizing hint (full & half) + the virtual bankroll.
Inputs: size_usdc (required), note, slug, outcome, +4 more. Returns: bet, bankroll, kellyFull, kellyHalf
polymarket_paper_resetReset the SIMULATED paper-trading ledgerADestructiveIdempotent
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:
confirm (boolean): must be true to proceed.
bankroll (number, optional): new virtual starting bankroll (default 1000).
Inputs: confirm, bankroll, response_format. Returns: bankroll, deletedCount
polymarket_paper_statusPaper-trading status & scoringA
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:
response_format ('markdown' | 'json'): default 'markdown'.
Inputs: response_format. Returns: bets, roiPct, hitRate, bankroll, +7 more
polymarket_search_marketsSearch Polymarket marketsARead-onlyIdempotent
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:
query (string, optional): keyword(s) like 'bitcoin' or 'election'. If omitted, returns the top markets by volume.
limit (number): max markets, 1-50 (default 10).
active_only (boolean): only open/unresolved markets (default true).
response_format ('markdown' | 'json'): default 'markdown'.
Returns: { count, query, markets: [{ slug, question, conditionId, outcomes:[{outcome, tokenId, price, impliedProbabilityPct}], volume, liquidity, volume24hr, endDate, active, closed, acceptingOrders, eventSlug }] }.
Examples:
"What markets are there about the Fed?" -> query="Fed".
"Show me the biggest markets right now" -> no query. Note: 'price' is the implied probability of that outcome (0-1). For an executable price/spread, use polymarket_get_orderbook.
Inputs: limit, query, active_only, response_format. Returns: count, query, markets
polymarket_xrayX-ray a Polymarket marketARead-onlyIdempotent
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:
token_id (string, optional) OR slug (string) + outcome (string).
history_interval ('1h'|'6h'|'1d'|'1w'|'1m'|'max'): default '1d'.
trade_limit (1-50, default 10), holder_limit (1-20, default 5).
Returns: { tokenId, outcome, slug, question, detail, quote, whales, history, tape } (sections null-tolerant).
Inputs: slug, outcome, token_id, trade_limit, +3 more. Returns: slug, tape, quote, detail, +5 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
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.
Maintenance
Related MCP Connectors
Historical tick, order book and settlement data for Polymarket and Predict.fun crypto up/down markets, plus smart-money lists and backtest quotes, over a read-only MCP server.
Polymarket in your AI: market rules, real fill costs, who is trading, top traders. Read-only.
Read-only Polymarket search, market details, order books, price history, and market cards.
Read-only MCP server for live Polymarket, Kalshi, Limitless odds; Manifold sentiment.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server for Polymarket prediction markets, providing real-time market data, prices, and AI-powered analysis tools for Claude Desktop integration.48MIT
- FlicenseAqualityCmaintenanceAI-agent ready FastMCP server for Polymarket market discovery, wallet analytics, and public CLOB data, providing a read-only interface for querying markets, wallets, and order books.22-
- AlicenseAqualityCmaintenanceA read-only MCP server exposing Polymarket's public prediction-market data. Search markets, read live odds and order books, pull historical probability time-series, and inspect public wallet positions.1435 PyPIMIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables seamless integration with Polymarket, providing tools to search markets, fetch events, analyze leaderboards, query user activity, and more via MCP-compatible clients like Claude.41 npmMIT