oddsrail
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| KALSHI_DEMO | No | Set to 1 to hit the Kalshi demo environment. | |
| KALSHI_KEY_ID | No | Kalshi API key ID. | |
| ODDSRAIL_DRY_RUN | No | 1 = orders are simulated and returned, never posted. Set 0 to trade. | 1 |
| KALSHI_PRIVATE_KEY | No | The Kalshi private key itself (alternative to KALSHI_PRIVATE_KEY_PATH). | |
| ODDSRAIL_BUILDER_CODE | No | Your bytes32 builder code. Overrides the bundled project default so attribution (and any reward-pool share) accrues to you instead. | |
| POLYMARKET_PRIVATE_KEY | No | Operator wallet key; required only for real trading. Never leaves this machine. | |
| KALSHI_PRIVATE_KEY_PATH | No | Path to PKCS#8 PEM private key for Kalshi. | |
| POLYMARKET_WALLET_ADDRESS | No | Proxy/deposit wallet address, if the account uses one. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| search_marketsA | Search Polymarket markets by text (Gamma public-search under the hood); empty query lists open markets. Returns token ids, prices, metrics, resolution info. |
| get_marketA | Get one market's details. Accepts the market slug, the Gamma market id, or either of its CLOB token ids (the market_id that find_markets and search_markets return), so a token id from a search can be passed straight in. |
| get_orderbookB | Get the live orderbook (bids/asks) for a CLOB token id. |
| price_historyB | Recent price history for a CLOB token id: hours back, at fidelity_minutes resolution. |
| get_positionsC | Current positions for a wallet address. |
| overshoot_signalB | PREMIUM SIGNAL — overshoot/fade detector. Analyzes a token's recent price series for fresh panic jumps and reports whether a fade setup is active plus this market's historical reversion tendency. |
| dispute_riskA | PREMIUM SIGNAL — dispute-risk triage. Scores 0-100 how likely a market's resolution gets contested (UMA dispute risk) with transparent reasons. Takes the market slug, the Gamma id, or a CLOB token id (the market_id a search returns). |
| check_orderA | CHECK BEFORE YOU PLACE: deterministic verification of a proposed order against the operator's intent, the live market and the guardrails. Pass the operator's own words as |
| place_orderA | Place a limit order. DRY-RUN by default: returns the order it would post. Real trading needs ODDSRAIL_DRY_RUN=0 and POLYMARKET_PRIVATE_KEY. The operator's builder code is signed into the order. price is the implied probability in (0,1); size is in SHARES (notional = price * size), and the exchange enforces a $1 minimum notional on marketable orders. post_only=True rejects rather than crosses the book. |
| cancel_orderB | Cancel an open order by id (respects dry-run). |
| open_ordersA | List the operator wallet's open orders. |
| builder_statsA | Builder attribution stats: the public builder leaderboard, and (if ODDSRAIL_BUILDER_CODE is set) matched trades attributed to this operator's code. |
| attribution_ledgerA | Attribution ledger for the builder code in use: every trade carrying it, aggregated per Sunday-start week and per wallet, with the maintainer's own wallets split out into an honest 'external' line. Built from Polymarket's own public builder feed, so any figure it reports can be checked at data-api.polymarket.com/v1/builders/leaderboard. |
| kalshi_search_marketsA | Search Kalshi markets. Kalshi has no text-search endpoint, so this pages open markets and filters on title/ticker; auto-generated MVE combo shards are excluded. Prices are dollar strings, not cents. |
| kalshi_get_marketB | Get one Kalshi market by ticker. |
| kalshi_get_orderbookA | Kalshi orderbook for a ticker, normalised to a YES-book bid/ask view (Kalshi publishes bid ladders only; asks are derived as 1 - NO bid). Raw ladders included. |
| kalshi_get_tradesB | Recent public trades for a Kalshi ticker. |
| kalshi_balanceA | Kalshi account balance (needs the operator's API key). |
| kalshi_positionsD | Kalshi positions (needs the operator's API key). |
| kalshi_open_ordersD | Kalshi resting orders (needs the operator's API key). |
| kalshi_place_orderB | Place a Kalshi limit order. State it naturally: outcome yes|no, action buy|sell, price = probability of THAT outcome in (0,1). Translated to Kalshi's YES-book bid/ask internally. DRY-RUN by default. |
| kalshi_cancel_orderA | Cancel a Kalshi order by id (respects dry-run). |
| find_marketsA | Search BOTH Polymarket and Kalshi at once and return one normalised shape per market: venue, market_id (the id that venue's place_order takes), title, yes/no price as probabilities in (0,1), best bid/ask, spread, 24h volume, close time. Use this instead of the per-venue search tools when you do not already know the venue. |
| compare_venuesA | Find markets that may be the SAME event on both Polymarket and Kalshi. NOT an arbitrage scanner: matches are candidates from title similarity plus a close-date check, and a price difference between two candidates is not profit. Identical wording does not mean identical resolution criteria — read both, and run quote_cost on each leg, before acting. |
| quote_costA | What a given size would ACTUALLY cost, by walking the order book rather than reading the top level. Returns average fill price, slippage vs best, notional, and the levels consumed — plus the venue's fee schedule where it publishes one. Call this before sizing any trade, and on both legs before acting on a cross-venue gap. |
| order_statusA | Status of one Polymarket order: resting, partially filled, filled, or gone. The lifecycle answer an agent needs after place_order. |
| my_fillsB | Recent executions (fills) for the operator wallet — confirms what actually traded, with tx hashes. |
| my_positionsA | The operator's current Polymarket positions (uses the configured wallet; no address needed). |
| my_balanceA | Authenticated Polymarket cash and allowance snapshot for an existing configured wallet. Cash is separate from positions value; available-to-trade remains unknown until outstanding orders and unsettled fills are reconciled. Requires local account credentials. In simulation use paper_positions. |
| cancel_all_ordersA | KILL SWITCH — cancel every resting Polymarket order on the operator account at once. Use when exposure must go to zero fast. Respects dry-run. |
| split_positionA | Split USDC collateral into a full YES+NO share set for one market, GASLESS via Polymarket's relayer. amount_usdc is collateral in USDC (e.g. 25). Needs POLYMARKET_RELAYER_API_KEY and POLYMARKET_RELAYER_API_KEY_ADDRESS (polymarket.com -> Settings -> Relayer API keys). DRY-RUN by default. Never falls back to a gas-paying broadcast. |
| merge_positionsA | Merge matching YES+NO shares back into USDC, GASLESS via the relayer. amount is in shares, or 'max' for the largest balanced amount held. Needs the operator's relayer key. DRY-RUN by default. |
| redeem_positionsA | Redeem the winning shares of a RESOLVED market for USDC, GASLESS via the relayer. Pass exactly one of condition_id or market_id. Needs the operator's relayer key. DRY-RUN by default. |
| paper_positionsA | Paper-trading portfolio for dry-run: cash, positions at current marks, realized and unrealized P&L, resting paper orders (filled here if the market has crossed them). Dry-run Polymarket orders are papered against the live book automatically. Simulated: no queue, no impact, no fees, so results are an upper bound. |
| paper_resetA | Reset the paper-trading ledger to its starting bankroll (ODDSRAIL_PAPER_BANKROLL, default 1000 USDC). Deletes simulated fills and positions; touches nothing real. |
| watch_bookA | Stream one Polymarket token's realtime market events (book snapshot, price changes, trades) for up to |
| redeemable_positionsA | What the operator can turn back into USDC now: redeemable (resolved, winning) positions and mergeable (hold both YES and NO) positions, with the ids the gasless tools take. Uses the configured wallet. |
| resolution_criteriaA | READ BEFORE TRUSTING A PRICE: the full resolution contract for a market — what exactly resolves YES, who resolves it, from which sources. venue is 'polymarket' (pass the slug, the Gamma id, or the market_id a search returned, which is a CLOB token id) or 'kalshi' (pass the ticker). |
| closing_soonA | Markets closing within N hours on either venue, by volume — where trading activity concentrates. |
| settlement_auditA | Settlement-divergence audit for a cross-venue pair, on LIVE data (no pre-curated pair list). Compares close times, resolution sources, UMA dispute status and market structure, and returns ok / caution / block with reasons. polymarket_id takes the slug, the Gamma id or the market_id a search returned (a CLOB token id); kalshi_ticker takes the ticker. Run this before treating any cross-venue price difference as an edge. |
| position_sizeA | Fractional-Kelly position size for a binary contract, given your bankroll, the market price, and YOUR fair value estimate. Caps at a fraction of full Kelly and refuses negative-edge bets. Returns its assumptions — subtract quote_cost before trusting the number. |
| server_infoA | Server status: dry-run state, attribution config, enabled capabilities, venue reachability from this machine, and Polymarket's geoblock verdict for this machine's IP (advisory — not a compliance check). Call this before the first order of a session. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| find_fade_setup | Find and evaluate a fade (mean-reversion) setup on prediction markets, end to end. |
| check_cross_venue_edge | Check whether a cross-venue price difference is a real edge or a settlement mismatch. |
| settle_resolved | Turn resolved and hedged positions back into USDC, gasless, with a dry-run read-back first. |
| daily_review | Daily review of open exposure: positions, resting orders, recent fills, attribution. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 42 tools
The venue prefixes (kalshi_ vs no prefix) and action nouns keep most tools distinct. Only mild overlaps exist—notably find_markets vs search_markets vs kalshi_search_markets, and my_positions vs get_positions—but the descriptions clarify when to use each. No tools are truly indistinguishable.
Names are consistently lowercase snake_case and mostly follow a predictable venue_action_noun pattern, e.g. kalshi_place_order, get_orderbook, cancel_all_orders. A few noun-style names like server_info, builder_stats, and position_size break the verb-first feel, but there is no chaotic style mixing.
42 tools is well beyond the 25+ threshold for 'too many' and feels heavy even for a two-venue trading platform. Many tools could be consolidated or grouped, such as search variants, position variants, and several signal/analysis utilities. The breadth is real, but the count creates selection overhead.
The toolkit is broad: market discovery, order placement/cancellation, balances/positions, paper trading, redemption, resolution checks, builder attribution, and cross-venue settlement audits are all covered. Minor gaps include Kalshi-specific order status/fill history and a dedicated Polymarket trade history tool, so agents may need to work around those edges.