polymarket-paper-trader

Simulated Polymarket and Kalshi trading with $10k of paper money against live order books and real fees

By Agent Next Python Local · stdio Finance and payments

62 popularity score ★ 502 ↓ 2.2k/mo

Connect your client

Local (PyPI)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

Claude CodeTerminal
claude mcp add polymarket-paper-trader -- uvx --from polymarket-paper-trader pm-trader-mcp
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "polymarket-paper-trader": {
      "command": "uvx",
      "args": [
        "--from",
        "polymarket-paper-trader",
        "pm-trader-mcp"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "polymarket-paper-trader": {
      "command": "uvx",
      "args": [
        "--from",
        "polymarket-paper-trader",
        "pm-trader-mcp"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "polymarket-paper-trader": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "--from",
        "polymarket-paper-trader",
        "pm-trader-mcp"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.polymarket-paper-trader]
command = "uvx"
args = ["--from", "polymarket-paper-trader", "pm-trader-mcp"]
Gemini CLITerminal
gemini mcp add --scope user polymarket-paper-trader uvx -- --from polymarket-paper-trader pm-trader-mcp

Settings 6

PM_TRADER_AUTH_ISSUER Optional: OAuth/OIDC issuer whose bearer tokens are accepted (same as --auth-issuer). Needs PM_TRADER_AUTH_AUDIENCE and PM_TRADER_RESOURCE_URL too, and streamable-http. For remote mode.
PM_TRADER_AUTH_AUDIENCE Optional: Audience the tokens must carry (same as --auth-audience). For remote mode.
PM_TRADER_RESOURCE_URL Optional: Public URL of this server, given in its protected-resource metadata (same as --resource-url). For remote mode.
PM_TRADER_RATE_LIMIT_PER_MINUTE Optional: Tool calls each signed-in user may make per minute. Default 60. For remote mode.
PM_TRADER_MAX_ACCOUNTS Optional: Paper accounts each signed-in user may create. Default 20. For remote mode.
PM_TRADER_PRUNE_IDLE_DAYS Optional: Deletes user folders idle this many days, at start and every 24 hours; 0 turns it off. Default 90. For remote mode.

What it does

This is a practice account for Polymarket, and since 0.4.13's README also for Kalshi, run as a local Python MCP server. Market lists, prices and order books come live from the two exchanges' public APIs. The orders themselves are only simulated. A buy eats through the real ask levels and pays the fee from that market's published schedule (Kalshi uses each series' own curve). Once a market closes, you can settle it and collect a simulated $1 for each winning share. You never connect a wallet or a key, and nothing is sent to either exchange.

The server registers 33 tools in `pm_trader/mcp_server.py` at v0.4.13. With them an assistant opens an account (10,000 dollars unless told otherwise), searches and browses Polymarket markets and reads an order book. It can also list Kalshi markets and their books. Trading covers market buys and sells plus resting limit orders, and it tracks the portfolio, trade history and stats such as ROI, win rate, Sharpe and drawdown. Named accounts sit side by side. Card tools turn results into head-to-head comparisons, a local top 10 or text to post. A Kalshi market is traded by giving `kalshi:<TICKER>` as the market.

Accounts are SQLite files under `~/.pm-trader/<account>`. The MCP server builds that path from your home folder and does not read the `PM_TRADER_DATA_DIR` setting the README lists, which only the `pm-trader` command line uses. Code caps market lists at 100 per call (`search_markets` returns 10 by default, the other list tools 20) and trade history at 1,000 rows. The server also ships a `trading_playbook` prompt with the makers' trading guide, and two HTML views that MCP Apps hosts show for `portfolio`, `stats` and `get_market`.

What it needs

RuntimePython 3.10+
Runs onmacOS, Windows, Linux
Also
  • uv, for the uvx launch command

The documented launch command uses uvx, so uv must be installed. Or run `pip install polymarket-paper-trader` and start `pm-trader-mcp` directly. It needs network access to the public Polymarket and Kalshi APIs, which take no key. Remote mode is optional: you run the HTTP server yourself and, for sign-in, an OAuth/OIDC issuer you operate.

Limits

  • Not covered Paper trading only: it cannot place real orders, hold funds or connect a wallet on Polymarket or Kalshi
  • Limit Its docs say real execution adds queue position, latency and counterparty behaviour that the simulator leaves out
  • Limit Resting limit orders fill only when check_orders is called
  • Size cap Market lists are capped at 100 per call and trade history at 1,000 rows in code
  • Not covered backtest and pk_battle only load strategy modules under the examples. package, and are removed over streamable-http
  • Limit Without all three auth settings, streamable-http has no sign-in and every caller shares the same accounts
  • Rate limit Remote mode with sign-in allows 60 tool calls a minute and 20 accounts per user by default
  • Limit Remote mode deletes user folders idle for 90 days by default (PM_TRADER_PRUNE_IDLE_DAYS, 0 turns it off)
  • Limit No hosted endpoint and no published image: the Dockerfile must be built yourself and serves HTTP only

Paper trading only: it cannot place real orders, hold funds or connect a wallet, and its own docs note that real execution adds queue position, latency and counterparty behaviour the simulator does not model. Limit orders only fill when `check_orders` is called. `backtest` and `pk_battle` are removed when serving over streamable-http. That HTTP transport has no authentication unless all three of `--auth-issuer`, `--auth-audience` and `--resource-url` are given, and without them every caller shares the same accounts. There is no hosted endpoint and no published container image; the Dockerfile must be built yourself and serves HTTP only.

Who it suits

Suits developers who want an assistant or a trading strategy to practise on Polymarket or Kalshi markets, or to compare models and accounts, with no money at stake. It runs locally, needs no key, and its writes only touch its own local account files. It is a poor fit for anyone who wants to trade for real, since it has no wallet or order submission at all, and it is published by neither exchange. Pick the HTTP mode only if your host cannot run a local stdio server, and then keep it on 127.0.0.1 or behind the OAuth mode.

Tools 33

22 only read, 9 change things, 2 can delete or overwrite. A ? marks an optional parameter.

init_account deletes
Create a paper account with a starting cash balance, or replace the balance of an existing onebalance?: numberaccount?: string
get_balance
Show cash, reserved and available cash, position value and total profit or lossaccount?: string
reset_account deletes
Erase an account's trades, positions and orders and start overaccount?: string
search_markets
Find Polymarket markets matching a keywordquery: stringlimit?: integer
list_markets
Browse active Polymarket markets ordered by volume or liquiditylimit?: integersort_by?: string
get_market
Get one market's outcomes, prices, volume and status, on Polymarket or Kalshislug_or_id: string
get_order_book
Snapshot of the live bids and asks for one outcomeslug_or_id: stringoutcome?: string
kalshi_markets
List Kalshi markets by status, series or eventlimit?: integerstatus?: enumseries_ticker?: stringevent_ticker?: string
kalshi_market
Get one Kalshi market by its tickerticker: string
kalshi_book
Live YES order book for a Kalshi market, with asks worked out from the NO bidsticker: stringdepth?: integer
get_tags
List the Polymarket categories and their tag slugs
get_markets_by_tag
List open Polymarket markets under one tagtag_slug: stringlimit?: integer
get_event
Get a Polymarket event and the related markets grouped in itslug: string
watch_prices
Get current midpoint prices for several markets at onceslugs: stringoutcomes?: string
buy changes
Simulate a market buy that fills against the live ask levelsslug_or_id: stringoutcome: stringamount_usd: numberorder_type?: stringaccount?: string
sell changes
Simulate a market sell of held shares against the live bid levelsslug_or_id: stringoutcome: stringshares: numberorder_type?: stringaccount?: string
portfolio
Open positions valued at live prices with unrealised profit or lossaccount?: string
history
Recent simulated trades with price, shares and feelimit?: integeraccount?: string
place_limit_order changes
Place a resting limit order that stays open until filled, cancelled or expiredslug_or_id: stringoutcome: stringside: stringamount: numberlimit_price: numberorder_type?: stringexpires_at?: stringaccount?: string
list_orders
List pending limit ordersaccount?: string
cancel_order changes
Cancel one pending limit order by its ID and free its reserved cashorder_id: integeraccount?: string
cancel_all_orders changes
Cancel every pending limit order on an accountaccount?: string
check_orders changes
Test pending limit orders against live prices and fill those that crossaccount?: string
stats
Performance figures: win rate, ROI, profit, Sharpe ratio and maximum drawdownaccount?: string
stats_card
Format account results as a text card for a tweet, markdown or plain textaccount?: stringformat?: string
leaderboard_entry
Build an account's leaderboard record as JSON, qualified from 10 tradesaccount?: string
share_content
Write results text for Twitter, Telegram or Discord from a templateaccount?: stringplatform?: stringtemplate?: string
pk_card
Head-to-head comparison card for two existing accountsaccount_a?: stringaccount_b?: string
leaderboard_card
Top 10 ranking by ROI of local accounts with 10 or more tradesaccounts?: string
pk_battle changes
Run two strategy modules from scratch on equal balances and compare them (stdio only)strategy_a: stringstrategy_b: stringname_a?: stringname_b?: stringbalance?: number
resolve changes
Settle positions in one closed market, paying $1 per winning shareslug_or_id: stringaccount?: string
resolve_all changes
Settle positions in every closed market heldaccount?: string
backtest
Replay a strategy over a historical price file on synthetic order books (stdio only)data_path: stringstrategy_path: stringbalance?: numberspread?: numberdepth?: number

Resources 3

skill://trading-playbook
The makers' trading guide as markdown
ui://pm-trader/portfolio
HTML portfolio dashboard for portfolio and stats in MCP Apps hosts
ui://pm-trader/market
HTML market card with a paper order ticket for get_market

Prompts 1

trading_playbook
Returns the makers' trading guide

Similar servers