Skip to main content
Glama
ByBastianRok

polymarket-mcp-server

by ByBastianRok

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

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

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
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:

  • 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.

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:

  • 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.

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:

  • 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.

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:

  • 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.

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:

  • 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.

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:

  • 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.

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:

  • 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.

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:

  • 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…".

polymarket_get_leaderboardA

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).

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:

  • 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.

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:

  • 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.

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:

  • 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.

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:

  • 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…".

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:

  • 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.

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:

  • response_format ('markdown' | 'json'): default 'markdown'.

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:

  • id (string): the paper bet id (from polymarket_paper_status).

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:

  • id (string): the paper bet id (from polymarket_paper_status).

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:

  • confirm (boolean): must be true to proceed.

  • bankroll (number, optional): new virtual starting bankroll (default 1000).

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:

  • 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} }] }.

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:

  • 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).

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:

  • 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.

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:

  • min_resolved (number, default 1): note if fewer than this have resolved.

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:

  • 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.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.9/5.0

Scored across 23 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count3/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues