Stock SDK
Market data for China A-shares, Hong Kong and US stocks, funds, futures and options over MCP
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
Opens the app, which asks before it adds the server.
claude mcp add polymarket-paper-trader -- uvx --from polymarket-paper-trader pm-trader-mcp{
"mcpServers": {
"polymarket-paper-trader": {
"command": "uvx",
"args": [
"--from",
"polymarket-paper-trader",
"pm-trader-mcp"
]
}
}
}{
"mcpServers": {
"polymarket-paper-trader": {
"command": "uvx",
"args": [
"--from",
"polymarket-paper-trader",
"pm-trader-mcp"
]
}
}
}{
"servers": {
"polymarket-paper-trader": {
"type": "stdio",
"command": "uvx",
"args": [
"--from",
"polymarket-paper-trader",
"pm-trader-mcp"
]
}
}
}[mcp_servers.polymarket-paper-trader]
command = "uvx"
args = ["--from", "polymarket-paper-trader", "pm-trader-mcp"]gemini mcp add --scope user polymarket-paper-trader uvx -- --from polymarket-paper-trader pm-trader-mcpPM_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. |
|---|---|
PM_TRADER_AUTH_AUDIENCE |
Optional: Audience the tokens must carry (same as --auth-audience). |
PM_TRADER_RESOURCE_URL |
Optional: Public URL of this server, given in its protected-resource metadata (same as --resource-url). |
PM_TRADER_RATE_LIMIT_PER_MINUTE |
Optional: Tool calls each signed-in user may make per minute. |
PM_TRADER_MAX_ACCOUNTS |
Optional: Paper accounts each signed-in user may create. |
PM_TRADER_PRUNE_IDLE_DAYS |
Optional: Deletes user folders idle this many days, at start and every 24 hours; 0 turns it off. |
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`.
| Runtime | Python 3.10+ |
|---|---|
| Runs on | macOS, Windows, Linux |
| Also |
|
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.
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.
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.
22 only read, 9 change things, 2 can delete or overwrite. A ? marks an optional parameter.
init_account deletesbalance?: numberaccount?: stringget_balanceaccount?: stringreset_account deletesaccount?: stringsearch_marketsquery: stringlimit?: integerlist_marketslimit?: integersort_by?: stringget_marketslug_or_id: stringget_order_bookslug_or_id: stringoutcome?: stringkalshi_marketslimit?: integerstatus?: enumseries_ticker?: stringevent_ticker?: stringkalshi_marketticker: stringkalshi_bookticker: stringdepth?: integerget_tagsget_markets_by_tagtag_slug: stringlimit?: integerget_eventslug: stringwatch_pricesslugs: stringoutcomes?: stringbuy changesslug_or_id: stringoutcome: stringamount_usd: numberorder_type?: stringaccount?: stringsell changesslug_or_id: stringoutcome: stringshares: numberorder_type?: stringaccount?: stringportfolioaccount?: stringhistorylimit?: integeraccount?: stringplace_limit_order changesslug_or_id: stringoutcome: stringside: stringamount: numberlimit_price: numberorder_type?: stringexpires_at?: stringaccount?: stringlist_ordersaccount?: stringcancel_order changesorder_id: integeraccount?: stringcancel_all_orders changesaccount?: stringcheck_orders changesaccount?: stringstatsaccount?: stringstats_cardaccount?: stringformat?: stringleaderboard_entryaccount?: stringshare_contentaccount?: stringplatform?: stringtemplate?: stringpk_cardaccount_a?: stringaccount_b?: stringleaderboard_cardaccounts?: stringpk_battle changesstrategy_a: stringstrategy_b: stringname_a?: stringname_b?: stringbalance?: numberresolve changesslug_or_id: stringaccount?: stringresolve_all changesaccount?: stringbacktestdata_path: stringstrategy_path: stringbalance?: numberspread?: numberdepth?: numberskill://trading-playbookui://pm-trader/portfolioui://pm-trader/markettrading_playbook