Command Palette

Search for a command to run...

UnylyUnyly
Browse all

Server Kalshi

FreeNot checked

A Model Context Protocol (MCP) server for the Kalshi prediction market trading platform. It provides automated access to market data, order management, and port

GitHubEmbed

About

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

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 page
  • status (optional): Filter by position status
  • market_ticker (optional): Filter by market ticker
  • event_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 cursor
  • status (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 page
  • cursor (optional): Pagination cursor

get_settlements

Get a list of all of your settlements.

Parameters:

  • limit (optional): Number of results per page
  • cursor (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 ticker
  • series_ticker (optional): Filter by series ticker
  • status (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 tickers
  • limit (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 ticker
  • depth (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 ticker
  • status (optional): Event status filter
  • with_nested_markets (optional): Include market data in response
  • limit (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 ticker
  • side (required): "yes" or "no"
  • count (required): Number of contracts
  • type (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 amend
  • new_count (optional): New contract count
  • new_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

Setting up with UVX
"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"
    }
  }
}
Setting up with Docker
  1. Build the container from root directory docker build -t mcp-server-kalshi .

  2. 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"
    }
  }
}

Local Development

  1. Create a .env file in the root directory with the following variables

    • BASE_URL The kalshi API URL
    • KALSHI_API_KEY The API key for the corresponding environment
    • KALSHI_PRIVATE_KEY_PATH A filepath to a file containing your Kalshi RSA private key
  2. Install deps via uv pip install -e . Dev deps can be installed with uv pip install -e .[dev]

  3. Run with uv run start

Authentication Setup

Getting Kalshi API Credentials

To use this MCP server, you'll need Kalshi API credentials:

  1. 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
  2. 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"
            }
        }
    }
}

from github.com/solenyaresearch0000/kalshi-MCP

Install Server Kalshi in Claude Desktop, Claude Code & Cursor

Recommended · one command, every IDE
unyly install mcp-server-kalshi

Installs into Claude Desktop, Claude Code, Cursor & VS Code — handles npx, uvx and build-from-source repos for you.

First time? Get the CLI: curl -fsSL https://unyly.org/install | sh

Or configure manually

Run in your terminal:

claude mcp add mcp-server-kalshi -- uvx mcp-server-kalshi

FAQ

Is Server Kalshi MCP free?

Yes, Server Kalshi MCP is free — one-click install via Unyly at no cost.

Does Server Kalshi need an API key?

No, Server Kalshi runs without API keys or environment variables.

Is Server Kalshi hosted or self-hosted?

A hosted option is available: Unyly runs the server in the cloud, no local setup required.

How do I install Server Kalshi in Claude Desktop, Claude Code or Cursor?

Open Server Kalshi on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

Compare Server Kalshi with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All development MCPs