Kalshi Read-Only MCP Server
Click on "Install 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., "@Kalshi Read-Only MCP ServerFind markets on whether the Fed will cut rates in September and show me the order book."
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.
Kalshi Read-Only MCP Server (v0.1)
A tiny MCP server that lets an AI agent (Grok, Claude, anything that speaks MCP) read real Kalshi market data instead of guessing prices from web search.
It exposes exactly three tools:
Tool | What it does |
| Find markets by keyword, series, or event |
| Full detail for one market ticker |
| Resting bid levels, best prices, depth totals |
Read-only by design. The server only sends GET requests to Kalshi's public
market-data endpoints. It has no Kalshi login, asks for no API keys, stores no
credentials, and cannot place, change, or cancel an order.
1. What you need
Python 3.10 or newer (this project was built and tested on 3.14)
An internet connection (it calls
https://api.elections.kalshi.com)No Kalshi account
Related MCP server: Prediction Markets MCP Server
2. Install
From the project folder:
python -m venv .venv
.venv\Scripts\python.exe -m pip install -r requirements-dev.txtrequirements.txt holds just what the server needs to run (that is what a host
installs). requirements-dev.txt adds the test tools on top.
On macOS/Linux the interpreter is .venv/bin/python instead.
3. Run the tests
.venv\Scripts\python.exe -m pytestThe tests use a fake Kalshi API (no network, no rate limits), so they run in about a second and always give the same answer.
4. Start the server
.venv\Scripts\python.exe server.pyYou will see:
Kalshi read-only MCP server 0.1.0
MCP endpoint : http://127.0.0.1:8000/mcp
Health check : http://127.0.0.1:8000/healthzMCP endpoint:
http://127.0.0.1:8000/mcp— this is the URL an MCP client connects to.Health check:
http://127.0.0.1:8000/healthz— open it in a browser to confirm the server is alive.
Useful flags and environment variables:
Option | Default | Meaning |
|
| Port to listen on (also |
|
| Listen on all interfaces, not just this machine |
| unset | If set, callers must send |
| Kalshi production | Point at a different Kalshi base URL |
Stop the server with Ctrl+C.
5. Give it a public HTTPS URL
Grok connects over the internet, so 127.0.0.1 is not reachable from it.
Recommended: deploy to Render
This repo includes render.yaml, so Render can configure itself.
Push this project to a GitHub repository.
In Render: New → Blueprint, pick the repo, and confirm.
Render prompts for
MCP_AUTH_TOKEN. Paste a long random string — or leave it blank to run without auth. Generate one with:python -c "import secrets; print(secrets.token_urlsafe(32))"Wait for the first build, then open
https://<your-service>.onrender.com/healthzto confirm it is alive.Your MCP URL is
https://<your-service>.onrender.com/mcp.
Know this about the free tier: Render spins a free service down after 15 minutes with no traffic, and waking it takes roughly a minute. The first tool call after an idle period can therefore time out inside Grok. Two ways around it:
Point a free uptime monitor (UptimeRobot, cron-job.org) at
/healthzevery 10 minutes. That keeps the service awake and fits inside the 750 free instance hours per month for a single service./healthzneeds no auth, so this works even with a token set.Or upgrade to Render's paid Starter tier, which never sleeps.
Temporary alternative: a tunnel from your own PC
Useful for a quick test; the server stays on your machine.
cloudflared tunnel --url http://localhost:8000 # winget install --id Cloudflare.cloudflared
ssh -R 80:localhost:8000 nokey@localhost.run # no install, uses built-in sshBoth hand you a random HTTPS URL that changes every restart, and both stop working when your PC sleeps. localhost.run also drops idle tunnels and rotates its hostnames while connected.
Protecting a public URL
Anything on the open internet gets scanned, and a permanent hostname gets found far sooner than a random tunnel one. Set a token so only your agent can call it:
set MCP_AUTH_TOKEN=pick-a-long-random-string
.venv\Scripts\python.exe server.pyCallers then need the header Authorization: Bearer pick-a-long-random-string.
/healthz stays open so uptime checks and Render's own health probe keep working.
6. Connect it to Grok
Start the server and the tunnel (or deploy it).
In Grok, add a Custom MCP connector.
Paste the full MCP URL, including
/mcp:https://your-public-host.example.com/mcpIf you set
MCP_AUTH_TOKEN, add theAuthorization: Bearer <token>header in the connector's auth settings.Save. Grok should list three tools:
kalshi_search_markets,kalshi_get_market,kalshi_get_orderbook.
The server uses the streamable HTTP transport in stateless mode, which is what remote MCP connectors expect, and it survives restarts and load balancers because no session state is kept between requests.
Tool reference
kalshi_search_markets
Parameter | Default | Notes |
|
| Keywords; all words must appear |
| none | Restrict to one series, e.g. |
| none | Restrict to one fixture, e.g. |
|
|
|
|
| Max markets returned (1–100) |
|
| Pages scanned per series (1–25) |
Kalshi has no server-side text search, so this server filters locally:
Your words are matched against the ~14,000 Kalshi series (competitions).
The best-matching series are searched for open events (fixtures).
Each event's markets are matched against your words, including the event title — so
liverpoolfinds the win, tie, spread, and totals markets for "Ipswich Town vs Liverpool".
Every response carries a coverage block (events_scanned, pages_fetched,
total_matches_found, scan_complete). If scan_complete is false, more
data existed than the request budget allowed — narrow the search with
series_ticker for an exhaustive answer.
Handy soccer series tickers:
Series | Competition |
| English Premier League — match winner |
| EPL spread / total goals |
| UEFA Champions League |
| La Liga |
| Serie A |
| Bundesliga |
| Ligue 1 |
| MLS |
kalshi_get_market
Takes an exact ticker. Returns prices, volume, open interest, liquidity,
settlement rules, strike details, and timestamps, plus the parent event's title.
kalshi_get_orderbook
Takes an exact ticker and optional depth (1–100, default 10). Returns YES and
NO bid levels sorted best-price-first, top-of-book prices, level counts, and
totals, plus a price snapshot of the market itself.
Kalshi returns an empty order book with HTTP 200 for tickers that do not exist,
so this tool checks the market first. market_not_found and
is_empty: true are therefore two different, honest answers.
How to read the JSON
{
"ok": true,
"market": {
"ticker": "KXEPLGAME-26SEP04IPSLFC-LFC",
"prices": {
"yes_bid": { "dollars": 0.66, "cents": 66 },
"derived": { // computed here, NOT quoted by Kalshi
"yes_mid_dollars": 0.665,
"yes_mid_implied_probability_percent": 66.5
}
}
},
"retrieved_at": "2026-09-04T07:20:11Z",
"source": "https://api.elections.kalshi.com/trade-api/v2/markets/..."
}Three rules the server follows so an agent can trust the numbers:
Quoted vs computed are separated. Anything under a
derivedkey was calculated by this server (mid price, implied ask from the opposite bid). Everything else came from Kalshi as-is.Missing means
null. If Kalshi does not send a price or volume, the field isnull. The server never estimates, interpolates, or carries values over.Failure is explicit. Errors return
"ok": falsewith a machine-readablecode(market_not_found,event_not_found,invalid_parameter,rate_limited,timeout,network_error,http_error), never a plausible-looking empty result.
Prices are dollars per contract. A Kalshi contract pays $1.00 if YES resolves
true, so 0.66 means a 66% implied probability. Cents are included alongside
every price because Kalshi's own UI quotes cents.
Project layout
kalshi-mcp/
├─ server.py MCP server: tool definitions + web app
├─ tools.py The three tools and all JSON shaping
├─ kalshi_client.py HTTP GETs, timeouts, retries, error mapping
├─ tests/
│ ├─ conftest.py Fake Kalshi API used by every test
│ ├─ test_tools.py Tool behavior
│ └─ test_mcp_server.py Real MCP protocol round-trips
├─ requirements.txt
└─ README.mdTroubleshooting
Symptom | Cause / fix |
| Kalshi throttles public data. Wait a few seconds; the client already retries twice with back-off. |
Search returns 0 results | Add |
Grok cannot connect | Make sure the URL ends in |
|
|
Search feels slow the first time | The series catalogue (~16 MB) is downloaded once and cached in memory for 15 minutes. |
Limits of v0.1
Read-only market data. No trading, no portfolio, no account data — by design.
No WebSocket streaming; every call is a fresh REST read.
Keyword search is best-effort and says so; series/event-scoped search is exhaustive.
The series catalogue cache lives in memory, so a restart re-downloads it.
Data source
Kalshi public Trade API v2 — https://api.elections.kalshi.com/trade-api/v2
(docs: https://docs.kalshi.com). Market data is Kalshi's; this server only
reformats it. Nothing here is trading advice.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Hosted MCP for Kalshi prediction markets: search, odds, order books, settlement rules, and trading.
Kalshi MCP — US-regulated prediction-market data (no auth on public reads).
Live prediction markets: Polymarket + Kalshi prices, odds, order books. Pay-per-call USDC, no key.
Order-book depth & history for Polymarket, Kalshi & Limitless. Keyless demo, key for full access.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables comprehensive read access to Polymarket prediction market data, including live prices, order books, and market statistics. It allows AI assistants to analyze events, search markets, and monitor real-time signals without requiring API keys or authentication.221MIT
- AlicenseNot gradedqualityFmaintenanceUnified access to prediction market data from Kalshi and Polymarket, enabling natural language queries for real-time odds, orderbooks, and trade history.1712MIT
- AlicenseNot gradedqualityCmaintenanceProvides access to Polymarket prediction-market data via Gamma and CLOB public APIs, enabling AI agents to query market information.15MIT
- AlicenseNot gradedqualityCmaintenanceProvides access to US-regulated prediction-market data from Kalshi, enabling queries on market events without authentication.15MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/palm8-dev/kalshi-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server