MCP Server Kalshi
A Model Context Protocol (MCP) server for the Kalshi prediction market trading platform. It provides automated access to market data, order management, and portfolio operations through Kalshi's REST API.
README
MCP Server Kalshi
A Model Context Protocol (MCP) server for the Kalshi prediction market trading platform. This server provides automated access to market data, order management, and portfolio operations through Kalshi's REST API.
Features
Portfolio Management
- View account balance and portfolio value
- Track positions across all markets
- Monitor order history and fills
- Review settlement history
Market Discovery
- Search and filter markets by various criteria
- Get real-time market prices and statistics
- View orderbook depth and bid/ask spreads
- Browse events and series
Order Management
- Create buy/sell orders (market or limit)
- Cancel existing orders
- Amend orders atomically
- Submit batch orders (up to 20)
Available MCP Tools
Portfolio Tools
get_balance
Get the portfolio balance of the logged-in member in cents.
Returns: Available balance, portfolio value, total returns, etc.
Example:
# No parameters required
balance = await get_balance()
print(f"Available balance: ${balance['balance'] / 100:.2f}")
get_positions
Get a list of all of your positions.
Parameters:
limit(optional): Number of results per page (1-1000, default 100)cursor(optional): Pagination cursor for next pagestatus(optional): Filter by position statusmarket_ticker(optional): Filter by market tickerevent_ticker(optional): Filter by event ticker
Example:
positions = await get_positions({"limit": 50, "status": "open"})
get_orders
Get a list of all of your orders.
Parameters:
limit(optional): Number of results per page (1-1000)cursor(optional): Pagination cursorstatus(optional): Filter by order status
Example:
orders = await get_orders({"status": "open", "limit": 100})
get_fills
Get a list of all of your order fills.
Parameters:
limit(optional): Number of results per pagecursor(optional): Pagination cursor
get_settlements
Get a list of all of your settlements.
Parameters:
limit(optional): Number of results per pagecursor(optional): Pagination cursor
Market Discovery Tools
search_markets
Search and filter Kalshi markets by various criteria (event, series, status, time ranges).
Parameters:
event_ticker(optional): Filter by event tickerseries_ticker(optional): Filter by series tickerstatus(optional): Market status filter ("open", "closed", "settled")max_close_ts(optional): Markets closing before this Unix timestamp (ms)min_close_ts(optional): Markets closing after this Unix timestamp (ms)tickers(optional): Comma-separated list of market tickerslimit(optional): Results per page (1-1000, default 100)cursor(optional): Pagination cursor
Example:
markets = await search_markets({
"status": "open",
"series_ticker": "PRES",
"limit": 50
})
for market in markets['markets']:
print(f"{market['ticker']}: ${market['yes_price']}¢")
get_market
Get detailed information about a specific market by ticker.
Parameters:
ticker(required): Market ticker
Returns: Full market details including prices, volume, open interest, and status.
Example:
market = await get_market({"ticker": "PRES-2025-WINNER-DEM"})
print(f"YES price: {market['yes_price'] / 100:.2%}")
print(f"Volume: {market['volume']}")
get_orderbook
Get current bid/ask spreads and orderbook depth for a market.
Parameters:
ticker(required): Market tickerdepth(optional): Number of price levels (1-100, default 5)
Returns: Orderbook with YES and NO side price levels.
Example:
book = await get_orderbook({"ticker": "PRES-2025-WINNER-DEM", "depth": 10})
print(f"Best YES bid: {book['yes'][0]['price']}¢")
print(f"Best YES ask: {book['yes'][-1]['price']}¢")
Event/Series Tools
search_events
Search for events (collections of related markets) by series or status.
Parameters:
series_ticker(optional): Filter by series tickerstatus(optional): Event status filterwith_nested_markets(optional): Include market data in responselimit(optional): Results per page (1-1000, default 100)cursor(optional): Pagination cursor
Example:
events = await search_events({"series_ticker": "PRES", "limit": 20})
for event in events['events']:
print(f"{event['event_ticker']}: {event['title']}")
get_event
Get details about a specific event by its ticker.
Parameters:
event_ticker(required): Event ticker
Returns: Event metadata including title, status, and category.
get_series
Get information about a market series (category/topic).
Parameters:
series_ticker(required): Series ticker
Returns: Series metadata including title, category, frequency, and tags.
Example:
series = await get_series({"series_ticker": "POLITICS"})
print(f"Series: {series['title']}")
print(f"Frequency: {series['frequency']}")
Order Management Tools
create_order
Create an order to buy or sell contracts in a market.
Parameters:
action(required): "buy" or "sell"ticker(required): Market tickerside(required): "yes" or "no"count(required): Number of contractstype(required): "market" or "limit"yes_price(optional): YES limit price in cents (1-99, required for limit orders)no_price(optional): NO limit price in cents (1-99, required for limit orders)expiration_ts(optional): Order expiration Unix timestamp (ms)client_order_id(optional): Client-specified order ID
Example:
order = await create_order({
"action": "buy",
"ticker": "PRES-2025-WINNER-DEM",
"side": "yes",
"count": 10,
"type": "limit",
"yes_price": 52
})
cancel_order
Cancel an existing order by its order ID.
Parameters:
order_id(required): Kalshi order UUID
Returns: Cancelled order confirmation.
Example:
result = await cancel_order({"order_id": "abc-123-xyz"})
print(f"Cancelled order status: {result['order']['status']}")
amend_order
Modify an existing order's price or quantity (atomic cancel + create operation).
Parameters:
order_id(required): Order UUID to amendnew_count(optional): New contract countnew_yes_price(optional): New YES price in cents (1-99)new_no_price(optional): New NO price in cents (1-99)
Note: At least one of new_count, new_yes_price, or new_no_price must be provided.
Example:
new_order = await amend_order({
"order_id": "abc-123-xyz",
"new_yes_price": 55,
"new_count": 20
})
print(f"Amended to new order: {new_order['order_id']}")
batch_orders
Submit multiple orders atomically (all succeed or all fail, max 20 orders).
Parameters:
orders(required): List of order objects (max 20)
Returns: List of created order objects.
Example:
result = await batch_orders({
"orders": [
{
"action": "buy",
"ticker": "MARKET-1",
"side": "yes",
"count": 10,
"type": "limit",
"yes_price": 50
},
{
"action": "buy",
"ticker": "MARKET-2",
"side": "no",
"count": 5,
"type": "limit",
"no_price": 45
}
]
})
print(f"Created {len(result['orders'])} orders")
Common Usage Scenarios
Scenario 1: Browse Markets and Place a Trade
# 1. Search for open markets in the PRES series
markets = await search_markets({
"status": "open",
"series_ticker": "PRES",
"limit": 20
})
# 2. Get detailed information about a specific market
market = await get_market({"ticker": "PRES-2025-WINNER-DEM"})
print(f"Current YES price: {market['yes_price']}¢")
print(f"Volume: {market['volume']}")
# 3. Check the orderbook for liquidity
book = await get_orderbook({"ticker": "PRES-2025-WINNER-DEM", "depth": 5})
print(f"Best YES bid: {book['yes'][0]['price']}¢")
# 4. Place a limit order
order = await create_order({
"action": "buy",
"ticker": "PRES-2025-WINNER-DEM",
"side": "yes",
"count": 10,
"type": "limit",
"yes_price": 52
})
print(f"Order created: {order['order_id']}")
Scenario 2: Monitor and Manage Active Positions
# 1. Check account balance
balance = await get_balance()
print(f"Available: ${balance['balance'] / 100:.2f}")
# 2. View open positions
positions = await get_positions({"status": "open", "limit": 100})
for pos in positions['positions']:
print(f"{pos['market_ticker']}: {pos['quantity']} contracts, PnL: ${pos['unrealized_pnl_cents'] / 100:.2f}")
# 3. View open orders
orders = await get_orders({"status": "open"})
for order in orders['orders']:
print(f"{order['ticker']}: {order['count']} @ {order['yes_price']}¢")
# 4. Cancel or amend an order if needed
await cancel_order({"order_id": "abc-123-xyz"})
Scenario 3: Explore Events and Series
# 1. Browse available series
series = await get_series({"series_ticker": "POLITICS"})
print(f"Series: {series['title']}")
# 2. Find related events
events = await search_events({
"series_ticker": "POLITICS",
"status": "active",
"limit": 50
})
# 3. Get markets for a specific event
event = await get_event({"event_ticker": "PRES-2025"})
markets = await search_markets({"event_ticker": "PRES-2025"})
Scenario 4: Batch Trading
# Submit multiple orders atomically (all or nothing)
result = await batch_orders({
"orders": [
{
"action": "buy",
"ticker": "MARKET-A",
"side": "yes",
"count": 10,
"type": "limit",
"yes_price": 50
},
{
"action": "buy",
"ticker": "MARKET-B",
"side": "no",
"count": 15,
"type": "limit",
"no_price": 45
},
{
"action": "sell",
"ticker": "MARKET-C",
"side": "yes",
"count": 5,
"type": "limit",
"yes_price": 60
}
]
})
print(f"Successfully created {len(result['orders'])} orders")
Configuration
Claud Desktop
<details> <summary>Setting up with UVX</summary>
"mcpServers": {
"kalshi": {
"command": "uvx",
"args": ["mcp-server-kalshi"],
"env": {
"KALSHI_PRIVATE_KEY_PATH": "PATH TO YOUR RSA KEY FILE",
"KALSHI_API_KEY": "<YOUR KALSHI API KEY>",
"BASE_URL": "https://api.elections.kalshi.com"
}
}
}
</details>
<details> <summary>Setting up with Docker</summary>
-
Build the container from root directory
docker build -t mcp-server-kalshi . -
Configure client to run the container (ensure the bind command gives the container access to your rsa key files)
"mcpServers": {
"kalshi": {
"command": "docker",
"args": ["run", "--rm", "-i", "--mount", "type=bind,src=/Users/username,dst=/Users/username", "-e", "KALSHI_PRIVATE_KEY_PATH", "-e", "KALSHI_API_KEY","-e", "BASE_URL", "mcp-server-kalshi"],
"env": {
"KALSHI_PRIVATE_KEY_PATH": "PATH TO YOUR RSA KEY FILE",
"KALSHI_API_KEY": "<YOUR KALSHI API KEY>",
"BASE_URL": "https://api.elections.kalshi.com"
}
}
}
</details>
Local Development
-
Create a
.envfile in the root directory with the following variablesBASE_URLThe kalshi API URLKALSHI_API_KEYThe API key for the corresponding environmentKALSHI_PRIVATE_KEY_PATHA filepath to a file containing your Kalshi RSA private key
-
Install deps via
uv pip install -e .Dev deps can be installed withuv pip install -e .[dev] -
Run with
uv run start
Authentication Setup
Getting Kalshi API Credentials
To use this MCP server, you'll need Kalshi API credentials:
-
Production Environment (real money):
- Create a Kalshi account at kalshi.com
- Follow the API Keys documentation to generate:
- An API Key (string)
- An RSA Private Key (PEM file)
- Set
BASE_URL=https://api.elections.kalshi.com
-
Demo Environment (test account, recommended for development):
- Create a demo account following these instructions
- Generate demo API credentials
- Set
BASE_URL=https://demo-api.kalshi.co
Environment Variables
The server requires three environment variables:
| Variable | Description | Example |
|---|---|---|
KALSHI_API_KEY |
Your Kalshi API key string | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
KALSHI_PRIVATE_KEY_PATH |
Absolute path to your RSA private key PEM file | /Users/username/.kalshi/private_key.pem |
BASE_URL |
Kalshi API base URL | https://api.elections.kalshi.com (prod) or https://demo-api.kalshi.co (demo) |
Security Note: Keep your private key secure and never commit it to version control. The server uses RSA-PSS with SHA-256 for authentication.
UVX
To run in MCP inspector
npx @modelcontextprotocol/inspector uv --directory /path/to/your/mcp-server-kalshi run start
To run in claud desktop, update your MCP config to:
{
"mcpServers": {
"kalshi": {
"command": "uv",
"args": [
"--directory",
"/<path to repo root directory>",
"run",
"start"
],
"env": {
"KALSHI_PRIVATE_KEY_PATH": "PATH TO YOUR RSA KEY FILE",
"KALSHI_API_KEY": "<YOUR KALSHI API KEY>",
"BASE_URL": "https://api.elections.kalshi.com"
}
}
}
}
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。