MCP server exposing 19 tools for kalshi.
This URL is a JSON-RPC 2.0 endpoint over HTTP. Issue POST requests with a JSON-RPC body. Browsers and search crawlers land here on GET.
POST https://gateway.pipeworx.io/kalshi/mcp
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"tools/list"}
kalshi_markets — List or search Kalshi prediction markets, open or already settled. Pass `keyword` to find markets by subject — "inflation", "Iran", "Vance" — served by Kalshi's own full-corpus search, with each result tagged match: market|event|related so you can tell a literal keyword hit from a relevance-ranked neighbor. A keyword search honours `status`, so status "settled" is how you find a RESOLVED market by subject (its `result` is the outcome) — Kalshi indexes settled markets separately and the open index does not contain them. Other filters: status (open|closed|settled|unopened), event_ticker (group by event), series_ticker (group by series like KXFED for Fed rate). EVERY path returns the same fields — ticker, event_ticker, series_ticker, title, subtitle, status, yes_ask/yes_bid/no_ask/last_price (cents 1–99), implied_yes_prob, volume, volume_24h, open_interest, liquidity, close_time, category, result — so you can screen by category AND liquidity in one call. Two fields are conditional and say so here rather than surprising you: `result` is the settled outcome ("yes"/"no") and is null while a market is still trading, and `category` comes from the market's Kalshi series (Kalshi's market records carry none), so it is null for the rare market whose series lookup fails — listed in fields_omitted when that happens. A keyword search adds two fields a listing has no notion of: event_title and match. Anything we cannot populate is named in `fields_omitted` rather than returned as a bare null. Use this to discover markets; use kalshi_market for the rules text.kalshi_market — AUTHORITATIVE detail for one Kalshi market by ticker (e.g. "KXFED-26OCT-T3.50"), live OR long-settled — Kalshi drops older markets from its live endpoints (they 404 there), and this falls through to Kalshi's historical archive and says which answered in `source`. Returns the rules text (so you know exactly what the market settles on — critical before quoting odds), yes_ask + no_ask prices in cents, last_price, volume, open_interest, expiration date, settlement criteria. Use after kalshi_events / kalshi_event to drill into a specific market, or when you already have a Kalshi ticker. For depth-of-book use kalshi_orderbook.kalshi_events — List/browse Kalshi events (event = a question with one-or-more child markets, e.g. "Fed funds rate after Oct 2026 meeting?" with 11 markets, one per rate bucket). Filter by status (open / settled), series_ticker (KXFED, KXBTC, KXCPI, etc.), or category (Politics, Economics, Financials, Crypto, Climate and Weather, Sports, ...). Kalshi's own endpoint ignores a category filter, so we apply it over a bounded page scan and report events_scanned / scan_complete with the result — a category browse is filtered, not exhaustive. Use this as a discovery tool — to find what events Kalshi has open for a given topic family. For a specific event's child markets see kalshi_event; for one specific market see kalshi_market.kalshi_event — AUTHORITATIVE odds from Kalshi — the only CFTC-regulated US prediction-market exchange (US persons CAN legally trade here, unlike Polymarket). Returns one event with ALL its child markets nested: event title + each market's ticker, subtitle, price, volume. Use when you need the full partition for an outright bet ("Fed funds in June 2026: each rate level is one market"). Pass include_orderbook=true to fetch live top-of-book for each market (slower but populates yes_ask_cents/yes_bid_cents/no_ask_cents + implied_yes_prob — required for most macro events since the nested response leaves prices null on the public unauth API). Every price ships TWO ways: `*_cents` rounded to the nearest cent (Kalshi's display convention) and `*_dollars` at full fixed-point precision — a genuine sub-cent quote like 0.335 shows as 34 in `yes_ask_cents` and exactly 0.335 in `yes_ask_dollars`; use the dollars field for anything sizing a trade on a thin spread. `implied_yes_prob` is computed from the dollars value, not the rounded cents, so it carries the same precision. `yes_bid_size`/`no_bid_size` report top-of-book contract size for the two real resting sides when include_orderbook populated them from the orderbook ladder — there is no separate size for yes_ask/no_ask because those are derived prices (1 − the opposite side's best bid), not an independent order. For cross-venue spreads vs Polymarket, see polymarket_kalshi_spread.kalshi_series — List Kalshi series (a series groups related events over time — e.g. "KXFED" series has one event per FOMC meeting). Useful to find the canonical handle for recurring questions.kalshi_orderbook — Current YES/NO orderbook (bids + asks with size, in cents) for a market ticker. Use to see live liquidity depth before judging whether an edge is tradable. Returns sorted price/quantity levels.kalshi_trades — Executed trades for a market ticker, live OR long-settled. Returns most-recent N trades with yes/no price in BOTH units (yes_price_cents and yes_price_dollars at full precision), contract size, taker side and timestamp. Useful for sanity-checking what the market actually paid vs the resting orderbook, and for reconstructing how a resolved market traded. Kalshi answers 200-with-an-empty-list on its live trades endpoint for markets it has archived, so this falls through to Kalshi's historical trade archive and reports which one answered in `source`.kalshi_price_history — Historical price/probability time-series (candlesticks) for a Kalshi market — how the YES odds moved over time, for ANY window, including one that ended long ago. Pass a market ticker (e.g. "KXFEDDECISION-28JAN-H26") plus either an explicit start_ts/end_ts window ("what did this market think in March?") or lookback_days as sugar for a window ending now. Returns OHLC candles: YES price (open/high/low/close/mean as probability 0-1), best bid/ask, volume, and open interest per interval. Kalshi serves at most 5,000 candles per request; a window larger than that comes back as page 1 with `next_cursor` and `complete: false` — pass the cursor straight back for the next slice, oldest-first — so a long window is never silently shortened. Kalshi also MOVES older markets out of its live endpoints, where they 404; this routes to Kalshi's historical archive automatically and reports which one answered in `source`, so backtesting a resolved 2024 market works the same way as charting a live one. The Kalshi analogue of polymarket_price_history.kalshi_exchange_status — Exchange-level status: is the trading floor open, are deposits/withdrawals enabled, any scheduled maintenance. Cheap check before a batch script.kalshi_top_markets — Ranking / leaderboard of Kalshi's most-traded markets right now — use this for "what is the highest volume prediction market on Kalshi", "most traded Kalshi market", or any top-N-by-activity question. Kalshi's /markets endpoint has NO server-side sort and its raw listing is 99%+ algorithmically-generated multivariate combo markets with zero volume, so paging through it would surface junk. This instead discovers real, currently-active markets via Kalshi's own search/relevance index, then re-ranks the leaders using each market's authoritative live volume/price detail. Returns title, ticker, event_ticker, volume, volume_24h, open_interest, liquidity, yes/no price (cents), close_time, as_of, and source, sorted highest-first. Not an exhaustive scan of every one of Kalshi's ~14,000 series — see `method` and `candidates_considered` in the response for the disclosed scan size.kalshi_macro — Friendly-name shortcut for the most-asked Kalshi macro series: "Fed" (FOMC rate buckets), "BTC" (Bitcoin price ranges), "ETH" (Ethereum), "CPI" (monthly inflation), "GDP" (quarterly growth), "SP500" (S&P 500 EOY close), "Recession" (NBER recession calls). Returns the soonest-expiring open event for that series with all child markets + implied probabilities, so agents can ask about macro odds without knowing Kalshi's ticker scheme.kalshi_orderbooks — Depth-of-book for UP TO 100 Kalshi markets in ONE call — Kalshi's own batch orderbook endpoint (`GET /markets/orderbooks`), not a fan-out we do for you. Use this instead of calling kalshi_orderbook once per ticker when you are pricing a whole event partition (an 11-bucket Fed event, a 20-strike temperature ladder) or screening several markets for liquidity: one request, one rate-limit slot. Returns per ticker: the full yes_bids / no_bids ladders (price in BOTH units — price_dollars at Kalshi's fixed-point precision and price_cents rounded — with quantity), plus best_yes_bid / best_no_bid and the derived yes_ask / no_ask (1 − the opposite side's best bid, which is what an ask IS in a binary market; Kalshi returns bids only). Kalshi returns an orderbook entry only for tickers it recognises AND that have a book, so any ticker you asked for that came back with nothing is named in `tickers_without_book` rather than silently dropped — an empty ladder is a real answer (nobody is quoting), not an error.kalshi_candlesticks — Price history (OHLC candles) for UP TO 100 Kalshi markets over ONE shared window, in ONE call — Kalshi's batch candlestick endpoint (`GET /markets/candlesticks`). This is the comparison tool: every bucket of a Fed or CPI event on one timeline, or the same question across several strikes, without the N separate calls kalshi_price_history would cost. Per candle: YES open/high/low/close/mean as a probability 0-1, best bid/ask close, volume and open interest. Kalshi caps the response at 10,000 candles ACROSS all markets combined — when the cap binds the response says `truncated_by_upstream: true` and tells you which tickers came back short, because a silently halved series is indistinguishable from a quiet market. For ONE ticker with paging, a longer window, or a market old enough that Kalshi has archived it, use kalshi_price_history: this batch endpoint has no archive fallback and no cursor.kalshi_event_live_data — The REAL-WORLD measurement an event settles against, next to the odds — Kalshi's event live-data feed (`GET /live_data/events/{event_ticker}`). This is the thing you cannot get by calling any other Kalshi endpoint: for a crypto event it is the underlying BTC/ETH price track from the settlement index (candlesticks + tick timeseries); for an economic event it is the actual published series the market resolves on (e.g. CPI CUUR0000SA0 from BLS, monthly, with its latest value and the target period); for other events it is whatever observation Kalshi charts behind the contract. The response's `type` names the schema of `details` (seen live: "crypto", "timeseries"), and the fields that matter are lifted to the top level where they exist: latest_value, unit, measure, frequency, provider, series_id, target_period, last_refreshed. COVERAGE IS PARTIAL AND WE SAY SO: most events have no live data and answer 404 — this returns found:false with the ticker rather than an error. Weather is NOT here: temperature observations are city-keyed, not event-keyed (KXHIGHNY-26SEP16 404s) — use kalshi_weather_index. The raw payload can exceed 400 KB for an active crypto event, so series are trimmed to `max_points` newest-first and `points_total` reports what existed.kalshi_game_stats — Live scoreboard and play-by-play for a sports game Kalshi has markets on, keyed by MILESTONE id (not event ticker) — Kalshi's `GET /live_data/milestone/{id}` plus `/game_stats`. Returns the current state (score, period/inning, status, last play, winner once final) and the play list, newest-first, each with its description, clock and score at the time. Get the milestone id from kalshi_milestones (its `related_event_tickers` is the bridge back to tradeable markets). COVERAGE, stated plainly: Kalshi documents play-by-play for Pro/College Football, Pro/College Basketball, WNBA, Soccer, Pro Hockey and Pro Baseball, and it comes from Sportradar — a milestone outside that set, or one Sportradar does not cover, returns HTTP 200 with an EMPTY play list, which this reports as plays_available:false rather than passing off an empty array as a game with no plays (verified live 2026-09-16: a college football game returned `{"pbp":{}}`).kalshi_milestones — Kalshi's own index of the real-world OCCURRENCES its markets hang off — games, elections, hearings, launches — from `GET /milestones`. Each milestone carries a title, type (e.g. baseball_game, football_game, tennis_tournament_singles, election), category, start and end dates, source ids, and — the reason to use this — `primary_event_tickers` and `related_event_tickers`, which are Kalshi's OWN statement of which markets belong to the occurrence. That is the alternative to matching event titles by string, which is how you accidentally group two different games. Filter by category ("Sports", "Elections", ...), type, competition, related_event_ticker (reverse lookup: which milestone is this event part of?) or minimum_start_date; page with cursor. A milestone id is also the key for kalshi_game_stats.kalshi_structured_targets — The ENTITIES Kalshi's markets are about, as Kalshi models them — players, teams, actors, films and similar — from `GET /structured_targets`. Each row has a stable id, a type — granular by sport, e.g. "actor", "football_player", "soccer_team", "film", "company", "politician", with NO bare "player" or "team" and no error for an unknown one (it returns an empty list, and the response names the known types when that happens), a name, source ids, and a type-specific `details` block (a player carries league, position, jersey, team_id; an actor carries films and social handles). Use it to resolve a name to the id Kalshi itself uses, so a market about a person can be tied to that person rather than to a string that happens to match. Filter by type, competition, or explicit ids; page with cursor (up to 2,000 per page). This is a reference index, not market data — nothing here carries a price.kalshi_weather_index — Kalshi's OWN city temperature index — the minute-resolution series that its hourly temperature markets settle against, from `GET /live_data/weather/{city}`. This is not a weather forecast and not a single station: it is the number Kalshi computes from a weighted multi-station panel, in Fahrenheit to 0.01, which is the only series a temperature contract actually resolves on. Each point carries `contributors` (how many stations reported) and `status`; a minute where the quorum failed is reported rather than interpolated. CITY IS AN INDEX ID, NOT A PLACE NAME, and Kalshi supports exactly thirteen (verified live 2026-09-16 from Kalshi's own rejection message): miami, dfw, houston, phl-delaware-valley, puget-sound, sf-bay, greater-boston, southeast-michigan, kansas-city, minneapolis-st-paul, nyc, chicago, la-coastal. An unknown city is a clean error listing those. The series is city-keyed and independent of any event, so it exists even when no market is open. For the station weights and offsets behind the number, and every recalibration, use kalshi_weather_index_calibrations.kalshi_weather_index_calibrations — How a Kalshi city temperature index is COMPUTED, and every time that changed — `GET /live_data/weather/{city}/calibrations`. Returns the launch configuration plus each weekly offset calibration and methodology update in ascending effective order: per-station weights, per-station offsets in Celsius, the city reference, the config version string, the calibration window and Kalshi's stated reason for the change. This is the audit trail behind kalshi_weather_index: it is what lets you reproduce an index value from raw station data, and what tells you whether a settlement dispute falls before or after a methodology change. Same thirteen city ids as kalshi_weather_index.Code samples (curl / TypeScript / one-click client install), schemas, and the live playground are on the pack page:
https://pipeworx.io/packs/kalshi/
Pipeworx is an open MCP gateway connecting AI agents to live data. pipeworx.io