oddsrail
An MCP server that lets agents search, analyze, and trade prediction markets on Polymarket and Kalshi.
Market data: search markets, fetch market details, orderbooks, and price history on Polymarket; search markets, get quotes, trades, and orderbooks on Kalshi.
Trading: place, cancel, and list orders on both venues (dry-run by default; real trading requires setting ODDSRAIL_DRY_RUN=0 and providing keys).
Portfolio: view Polymarket positions and Kalshi positions/balance.
Signals/analytics: run the premium overshoot/fade detector and the dispute-risk heuristic.
Operations: check builder attribution/leaderboard with builder_stats and server configuration with server_info.
Click on "Deploy 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., "@oddsrailfind Polymarket World Cup final markets and run overshoot on the favorite"
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.
oddsrail
The rail AI agents use to trade prediction markets.
An MCP server that gives any agent (Claude Code, Claude Desktop, or anything MCP-compatible) prediction-market access across Polymarket and Kalshi: market search, orderbooks, price history, positions, and order routing, with on-chain builder-code attribution on Polymarket, plus two premium signal tools (in-play overshoot/fade detection, resolution dispute-risk).
Free to use, and free of fees. oddsrail ships with a project builder code
registered at 0 bps, so orders routed through it are attributed without
adding a single basis point to anyone's trade. The project's income is a share
of Polymarket's weekly builder reward pool, paid by Polymarket's own program,
not by you. Running your own builder profile instead is one environment
variable (ODDSRAIL_BUILDER_CODE), and server_info always tells you which
code is in use. No fee tiers, no paywalled tools, no account required.
How oddsrail compares
Verified against each alternative directly (their repos, live endpoints, and registry entries, September 2026), not from their marketing:
oddsrail | raw venue APIs | pmxt | Simmer | Polymarket agent-skills | |
What it is | self-hosted MCP server | the venues themselves | unified API + SDK + MCP, "CCXT for prediction markets" | agent trading platform + SDK + MCP | markdown skill docs for agents |
Venues you can trade | Polymarket, Kalshi | one each | Polymarket, Opinion, Limitless (hosted writes); a dozen more for data | Polymarket, Kalshi, plus its own $SIM sandbox markets | Polymarket only |
Custody | non-custodial; keys never leave your machine | yours | hosted mode: "PMXT handles custody, signing infrastructure"; self-hosted mode: your keys | self-custody, local signing | yours (documentation only) |
Attribution you control | yes: | n/a | not documented | not documented | documents builder headers for your own code |
Cost to the trader | 0 bps, free tools | free | hosted pricing not in the README | not documented | free |
Open source | MIT, full source | n/a | MIT, ~2.1k stars | not stated | docs; license not stated |
Operator guardrails | notional caps, open-order cap, allowed markets; enforced pre-request, in dry-run too | none | not documented | per-trade limits, daily caps, stop-loss/take-profit, kill switch | none |
Paper trading | dry-run fills against the live book, P&L | none | not documented | virtual $SIM sandbox, then graduate to real money | none |
Book-walked cost, settlement audit, jurisdiction-classified failures, dated venue-quirk notes | yes, all four | no | not documented | not documented | quirks partly documented |
Realtime |
| websocket, yours to wire | not documented in the README | not documented | websocket documented |
Verified 2026-09-02 from each project's own README or docs (pmxt: github.com/pmxt-dev/pmxt; Simmer: docs.simmer.markets; agent-skills: github.com/Polymarket/agent-skills). "Not documented" means exactly that, not "absent". Re-check before quoting; these projects move.
The wedge, in one line: pmxt is the reference for trading everywhere; Simmer is the reference for an agent economy with a sandbox and a reputation layer; oddsrail is the reference for trading correctly, non-custodially, with attribution you own.
Where the others are honestly ahead: pmxt trades three venues to our two and covers a dozen more for data, with hosted convenience and a community many times ours. Simmer has a virtual-balance sandbox, stop-loss and take-profit rails we do not have, a public reasoning/reputation layer, and a strategy-skills marketplace. Polymarket's agent-skills is the venue's own documentation and covers bridging and deposits, which oddsrail does not.
¹ The raw Polymarket API has the endpoints. It also models rejections as
ok:false return values, orders its books worst-first, ships a trades
endpoint that returns the market's public tape, and enforces an
undocumented $1 minimum notional. oddsrail exists because we hit every one of
those and encoded the fix.
² Kalshi prices are dollar strings (integer cents were removed 2026-03), its orderbook is bids-only on both sides, and its current SDK requires Python ≥3.13. All normalised here.
Related MCP server: telekash-mcp-server
Quickstart
Python 3.11+ required.
pip install oddsrailclaude mcp add --transport stdio oddsrail -- oddsrailOr from a clone, without installing:
python3 -m venv .venv && .venv/bin/pip install -r requirements.txtclaude mcp add --transport stdio oddsrail -- /abs/path/to/oddsrail/.venv/bin/python -m oddsrail.serverThen ask the agent: "search markets about the World Cup final and run the overshoot signal on the favorite".
Install in one step
Client | How |
Claude web or desktop, nothing to install (hosted, paper trading) | Settings, Connectors, Add custom connector, URL |
Claude Code (hosted, paper trading) |
|
Claude Code (plugin, with the four workflow skills) |
|
Claude Code (server only) |
|
Any agent that reads skills |
|
Cursor | |
VS Code | |
Anything else that speaks MCP over stdio |
|
The plugin and the one-click links launch the server with uvx, so they
need uv on the machine. Without uv, pip install oddsrail gives you an oddsrail command to point any client at.
Everything starts in dry-run.
The four skills (skills/*/SKILL.md) are generated from the server's own
MCP prompts by scripts/gen_skills.py, and a test fails if they drift, so a
skill and the prompt it mirrors can never disagree.
Hosted: nothing to install
mcp.oddsrail.app runs the same server as a remote MCP endpoint with
accounts, so an agent inside Claude can use it without a machine of its own.
Add the URL as a custom connector (Pro, Max, Team and Enterprise plans), sign
in with your email when Claude asks, and every call from then on carries
your account.
What the hosted server is, in one breath: Polymarket market data, the signal
tools, check_order, and paper trading with a $1,000 virtual bankroll per
account, filled against the live book. What it is not: a place where money
moves. It holds no wallet keys, executes no real order, and serves no Kalshi
tools (Kalshi's API Developer Agreement limits API use to a member's own
trading, so a shared service cannot route it). Account-scoped tools such as
open_orders and the gasless relayer tools are absent, because on a shared
server they would describe nobody's account. Twenty-four tools remain: the
public-data and paper tools plus arena_register, arena_unregister and
arena_status, which put the account's paper ledger on the public board.
Live trading stays self-hosted: pip install oddsrail with your own key, and
the same place_order posts real orders when you set ODDSRAIL_DRY_RUN=0.
The paper ledger you build up in Claude is yours to reset with
paper_reset; nothing else about the account exists. Privacy policy:
oddsrail.app/privacy. Source:
oddsrail/cloud/ and oddsrail/hosted.py; deployment notes in
deploy/cloud/.
Builder page and arena
oddsrail.app/build is a set of switches:
strategies (fade overshoots, buy near-certain resolutions, trade your own
probability, follow the move, two-sided quotes), risk rules (stop loss as a
review rule, take profit, daily loss limit, never add to losers, exposure
caps) and market hygiene (dispute risk, fill quality, watching the book).
Press Run and the switches execute on the hosted server as a
deterministic paper pass (oddsrail/cloud/runner.py): the universe is
scanned, each strategy's signal is computed with the same code the MCP
tools use, every order goes through check_order, fills come from the live
book into a paper ledger that belongs to your browser, and the pass comes
back as a list of decisions with verdicts and reasons. No account, no
install, no key, no model. One pass is one tick at the current book, not a
backtest: the ledger carries positions and resting quotes between passes,
and nothing is watched in between, so a record needs many passes. The same switches also compose into a prompt for
running the pieces inside your own Claude with the connector; the
two-sided-quotes piece carries the maintainer's own warning about markout
either way.
oddsrail.app/arena is the public board. Paper
division: hosted accounts that entered themselves with arena_register,
ranked by return on the virtual bankroll, served as JSON from
mcp.oddsrail.app/arena/paper.json. Live division: wallets whose Polymarket
fills carry the oddsrail builder code, ranked by attributed volume from the
public feed, with realized and open P&L from Polymarket's data API; register
by pull request or the form on the page (site/arena/agents.json). No
prizes yet; the rules are on the page.
See the footguns yourself, no keys
pip install oddsrail && python examples/footguns.pySix things the venue APIs get wrong, shown live against the public endpoints: the worst-first order book, Kalshi's bids-only dollar-string ladders, geoblocks that look healthy until the order, the advisory geoblock verdict, the deprecated Gamma endpoint, and naive cross-venue matching. Each section prints the raw trap, then the oddsrail call that returns the right answer. About ten seconds, read-only.
How attribution works (CLOB V2, verified Aug 2026)
Get your builder code (a bytes32) at polymarket.com → Settings → Builders. Set your fee rates there: taker up to 100 bps, maker up to 50 bps, additive on top of platform fees, settled to your builder wallet.
export ODDSRAIL_BUILDER_CODE=0x...where the server runs.Every order any agent routes through
place_orderhas the code placed in the V2 order struct'sbuilderfield before signing, so attribution is on-chain, visible in everyOrderFilledevent on CTF Exchange V2.Verify with the
builder_statstool (public builder-trades endpoint + leaderboard).
If you skip this, orders carry the bundled oddsrail builder code
(0xa576c5ce…, registered at 0 bps maker / 0 bps taker), costing you nothing
and funding the project. If you set your own, yours wins; the default is a
default, not a lock-in.
The oddsrail builder profile is Verified in Polymarket's builder program (2026-09-02), and Polymarket's builder team confirmed builder-code attribution as the right pattern for a self-hosted, non-custodial tool: no keys ship with the product, and the code is attached and signed by the operator's own wallet.
Environment variables
Variable | Default | Meaning |
|
|
|
| project default | Your bytes32 builder code. Overrides the bundled project default so attribution (and any reward-pool share) accrues to you instead. |
| unset | Operator wallet key; required only for real trading. Never leaves this machine. |
| unset | Proxy/deposit wallet address, if the account uses one. |
| unset | Your own Relayer API key (polymarket.com → Settings → Relayer API keys), for gasless |
| unset | The address the relayer key was issued for. Both halves are required; without them the gasless tools send nothing. |
| unset | Guardrail: max USDC notional per order. Enforced before any request, in dry-run too. |
| unset | Guardrail: max cumulative notional of live orders submitted by this server process. |
| unset | Guardrail: max resting orders on the account (live; checked against the venue before placing). |
| unset | Guardrail: comma-separated Polymarket token ids and/or Kalshi tickers the agent may trade. Anything else is refused. |
|
| Paper-trade dry-run Polymarket orders against the live book. |
|
| Where the paper ledger lives. One local JSON file. |
|
| Starting paper cash in USDC. |
Status
Offline tests: 175 tests covering the paths where a bug costs money: the Kalshi yes/no→bid/ask translation, Kelly sizing, book walking, cross-venue pairing, signal edge cases, the dry-run safety net, and jurisdiction-failure handling (a geoblock must never read as an empty search result or a resting order), plus the hosted server end to end (dynamic client registration, PKCE, magic-link sign-in, token rotation, one paper ledger per account) against a real local process. They need no keys and no network:
pip install -e ".[dev]" && pytestCI runs them on Python 3.11, 3.12 and 3.13 on every push and pull request.
Live venues: every read tool and both dry-run order paths have been driven end-to-end against real Polymarket and Kalshi through a real MCP client session. Two attributed Polymarket orders (a buy and a sell) have been placed and confirmed on-chain.
Not yet exercised live: the Kalshi order placement path. Its request
shape is unit-tested and its endpoint verified, but no order has been sent to
a real Kalshi account, because the author does not yet have a funded,
verified one. This is untested, not untestable. Treat kalshi_place_order as
unproven and start in dry-run.
Where this works
Two different things can stop oddsrail from trading, and they have opposite remedies. One is a venue restriction, enforced at the order. The other is a network filter, which breaks the connection itself.
Polymarket restrictions. Polymarket publishes its restricted-jurisdiction list as an API reference: https://docs.polymarket.com/api-reference/geoblock. There are three tiers. OFAC-sanctioned jurisdictions (Iran, Syria, Cuba, North Korea, and the Crimea, Donetsk and Luhansk regions of Ukraine) are blocked on both the frontend and the API, with no new orders and no closing of existing positions. A longer second tier is close-only on both the frontend and the API: existing positions can be closed, new ones cannot be opened. It includes the United States, the United Kingdom, France, Germany, Italy, Poland, Slovakia, Belgium, Singapore, Australia, New Zealand, Brazil, Russia, Taiwan, Thailand and the Canadian provinces of Ontario, Quebec, British Columbia and Alberta. A third group, Ireland, Japan, Malta (sports only) and the Netherlands, is close-only on Polymarket's frontend, with the API explicitly not restricted.
Note the shape of that failure: it lands on the order, not the connection. Public reads answer normally, so oddsrail will look like it is working right up until an order is rejected. Verified against Polymarket's documentation on 2026-08-31; Polymarket updates the list without notice, so read the URL rather than this paragraph.
Kalshi restrictions. Kalshi is a single CFTC-designated contract market and it does admit members outside the United States, but its Member Agreement §VI names a long list of Restricted Jurisdictions whose members may not trade Event Contracts, among them Australia, Belgium, Canada, France, Ireland, Italy, New Zealand, Poland, Portugal, Singapore, Switzerland, the United Kingdom, Hungary, India, the United Arab Emirates and mainland China. The list is published in Kalshi's Exchange Notice of 22 June 2026 (https://kalshi-public-docs.s3.amazonaws.com/regulatory/notices/Kalshi%20Exchange%20Notice%20(Updated%20Member%20Agreement)%20(22%20June%202026).pdf), and Kalshi reserves the right to change it. The same section is explicit that the restriction applies only to trading Event Contracts and does not by itself bar membership or non-trading access, so oddsrail's Kalshi read tools stay usable even where its order tools do not.
The two lists overlap heavily. Kalshi is not a general fallback for a Polymarket-restricted operator, and the difference runs in both directions. Among the jurisdictions polymarket.com lists as close-only, Germany, Brazil, Slovakia and the United States are not on Kalshi's restricted list; Japan and the Netherlands are restricted by neither API (only by Polymarket's frontend). Check both lists for your own jurisdiction rather than assuming the other venue is open. The US case has its own wrinkle.
The United States. polymarket.com, the venue oddsrail talks to, is close-only for the US. Polymarket separately operates Polymarket US (polymarket.us), run by QCX LLC as a CFTC-regulated Designated Contract Market. oddsrail does not support it. It is a different API host, a different authentication model (API-key headers rather than EIP-712 wallet signatures), a different SDK and a different funding rail. A polymarket.us account and its keys will not work with this server. Kalshi does not list the US as restricted, so for a US operator Kalshi is the venue oddsrail can actually reach, with no builder-code attribution, since Kalshi's REST API has no such field.
Network filters. Separately from any venue rule, a national filter can block the domains outright. Turkey does this: Polymarket does not restrict Turkey, and Turkey is not on Kalshi's list either, but Turkish ISPs block polymarket.com. That is a connectivity problem, not an eligibility one, and it looks different: DNS failures, TLS errors, resets, or an ISP interstitial page served where JSON was expected. oddsrail classifies both shapes and tells the calling agent which one it hit.
Eligibility is the operator's, not the tool's. oddsrail is self-hosted
and non-custodial, which is a real advantage and also means you hold the
account and you make the venue's representations; there is no intermediary
making them for you. Polymarket's trading flow requires an attestation that
you are not a U.S. person, are not located in a restricted jurisdiction, and
are not "using a VPN or other measures to circumvent or attempt to
circumvent" restrictions, and states that Polymarket reserves the right to
put a non-compliant wallet in close-only mode. Kalshi's §VI is a
representation about where you are domiciled, organized and located, re-made
each time you place an order. server_info reports Polymarket's geoblock
verdict for this machine's IP, but a technical probe is not a compliance
check: the terms bind on residence, citizenship and incorporation, not on
egress IP. Read the terms; if any of this matters to you, get your own legal
advice. Nothing here is legal advice.
The signal logic, the MCP layer and the whole test suite run fine offline regardless.
Guardrails: limits the agent cannot argue with
Anyone handing keys to an agent wants three things first: a cap on one order, a cap on a session, and a fence around which markets it may touch. All three are operator-set environment variables (table above), enforced before any request goes out, in dry-run as well as live, so the agent meets the fence in rehearsal. A refusal is a structured answer that names the rule, the limit and the request:
{"accepted": false, "blocked_by": "guardrail", "rule": "max_order_notional",
"limit": 25.0, "requested": 99.5, "note": "refused by an operator-set guardrail ... Nothing was sent."}The session counter lives in the server process; restarting it resets the
budget, which is the operator's call. server_info reports the active limits
and how much of the session budget is used.
Paper trading: dry-run with a memory
By default, every dry-run Polymarket order is filled against the live
order book, walked within the limit price; whatever does not fill rests as a
paper order and fills later if the market crosses it. paper_positions
reports cash, positions at current marks, realized and unrealized P&L and the
resting paper orders; paper_reset starts over. The ledger is one local JSON
file. Be clear about what this is: fills assume no queue position, no latency,
no market impact and no fees, so paper results are an upper bound on the same
strategy live. Kalshi dry-run orders still return the intent only.
Realtime: watch the book move
watch_book(token_id, seconds, max_events) subscribes to a token's realtime
stream and returns the events that arrived (book snapshot, then price changes
and trades), bounded to at most 60 seconds so an agent cannot hang a session
on a quiet market. Use it after get_orderbook when the decision depends on
the book moving, not just where it is.
If the stream fails with CERTIFICATE_VERIFY_FAILED while the REST tools
work, your Python has no CA bundle (common with python.org macOS installs).
oddsrail classifies that as local_tls and tells the agent the fix: run
Install Certificates.command from the Python folder in /Applications, or
set SSL_CERT_FILE to the path printed by python -m certifi.
Gasless position management (relayer)
Three tools move collateral without paying gas, through Polymarket's relayer:
split_position (USDC → a full YES+NO set), merge_positions (matching
YES+NO → USDC, or max), and redeem_positions (a resolved market's winning
shares → USDC). All three respect dry-run and return the relayer transaction
id and hash plus the terminal outcome.
They use your own Relayer API key, created at polymarket.com → Settings →
Relayer API keys and exported as POLYMARKET_RELAYER_API_KEY +
POLYMARKET_RELAYER_API_KEY_ADDRESS. That is the pattern Polymarket's builder
team recommends for a self-hosted tool: no builder secret ships with oddsrail,
and each operator authenticates the relayer as themselves. Relayer limits are
per builder tier: 100 requests/day unverified, 10,000 verified. Without the
key the tools return a structured "not configured" answer and send nothing;
they never fall back to a gas-paying broadcast from the signer.
Exercised live (2026-09-02): a 1 USDC split and the matching merge went
through the relayer from this code, gasless, on the maintainer's test account
with its own Relayer API key. Relayer ids and Polygon transaction hashes are
in docs/live-proof.md. redeem_positions is still
unproven live: it needs a resolved market with winning shares, which that
account has not held yet. redeemable_positions lists what the configured
wallet could redeem or merge right now, and the settle_resolved prompt
chains the two.
Kalshi (venue #2)
Kalshi is bring-your-own-key and single-tenant by design: the operator supplies their own API key, trades their own account, and this server caches nothing. That is deliberate: Kalshi's Developer Agreement limits API use to a member's own trading (§3), bars facilitating other members' trading (§3.2) and sublicensing the API (§3.7), and restricts storing/sharing API data (§3.1). A hosted multi-tenant Kalshi service would not be compliant; a self-hosted one is.
Attribution does not exist here. Kalshi Builder Codes are a Solana/DFlow/Jupiter integration; there is no builder or affiliate field anywhere on the REST API, so Kalshi order flow cannot be attributed or monetised the way Polymarket's can. Kalshi is in oddsrail for coverage and signal reach, not for routing revenue.
Two shapes on this API are easy to get wrong, so oddsrail normalises both:
Prices are dollar strings, not cents (
"0.5600"), sizes are fixed-point strings ("10.00"); the legacy integer-cent fields were removed in MarchAll arithmetic uses
Decimal.
The orderbook is bids-only on both sides.
yes_dollarsandno_dollarsare both bid ladders, ascending, so the best bid is the last element, and a NO bid at $0.99 is a YES ask at $0.01.kalshi_get_orderbookreturns a conventional best-first bid/ask view of the YES book plus the raw ladders.
Order placement speaks natural terms, outcome (yes/no), action
(buy/sell), price = probability of that outcome, and translates to Kalshi's
YES-book bid/ask internally (buy NO @ 0.25 becomes ask @ 0.75). That translation is
exhaustively unit-tested (tests/test_money_paths.py), since it is the
obvious place to ship an inverted-position bug.
Credentials: KALSHI_KEY_ID plus KALSHI_PRIVATE_KEY_PATH (PKCS#8 PEM) or
KALSHI_PRIVATE_KEY. Set KALSHI_DEMO=1 to hit the demo environment. Read
tools need no key at all.
Cross-venue tools
find_markets(query): searches Polymarket and Kalshi in one call and returns one normalised shape per market:venue,market_id(the id that venue's order tool takes),title, yes/no price as probabilities in (0,1), best bid/ask, spread, 24h volume, close time, andtrade_withnaming the tool to call. Use this when you do not already know the venue.quote_cost(venue, market_id, side, size): what a size would actually cost, by walking the book rather than reading the top level. Returns average fill price, slippage vs best, notional, levels consumed, and whether the size is fillable at all, plus Polymarket's per-market fee schedule where it publishes one. Kalshi does not publish fees in its market payload, so they are reported as unknown rather than estimated.compare_venues(query): candidate same-event listings across venues. Not an arbitrage scanner. Matching an event across venues is an unsolved entity-resolution problem: naive title overlap cheerfully pairs a Brazilian election with a Ukrainian one and reports a 70-point "gap" that is fiction. Two gates apply (title similarity ≥ 0.5 and close dates within a week), so it usually returns nothing, which is the honest answer. A price delta between candidates is reported asyes_price_difference, never as profit.
Kalshi search
Kalshi has no text-search endpoint. oddsrail searches by event (the
human-readable index, with with_nested_markets) rather than paging tens of
thousands of machine-named markets, and matches on word boundaries, without
that, "fed" matches "German Bundestag" and a Fed-rate query returns German
election markets. Results carry truncated, because a bounded scan means an
empty result is not proof a market does not exist.
Order lifecycle & discovery
order_status(order_id): resting / partially_filled / filled / gone, with size_matched. The answer an agent needs after place_order.my_fills(),my_positions(): the operator's executions and holdings, no address juggling. (Fills come from the Data API activity feed; the SDK's list_account_trades returns the market's public tape and is not used.)cancel_all_orders(): kill switch, flattens every resting order at once.resolution_criteria(venue, market_id)returns the full resolution contract: what resolves YES, who resolves it, from which sources. Read it before trusting a price.closing_soon(hours): markets closing within N hours on either venue, where activity concentrates.
Workflow prompts
MCP prompts show up in clients as ready-made workflows, and they encode the order of operations that keeps an agent out of trouble; the sequencing is the expertise, which a flat tool list cannot convey.
/find_fade_setup(query, bankroll): signal → book → cost → resolution → size → dry-run, with the rejection criteria at each step/check_cross_venue_edge(query): candidates → settlement audit → cost on both legs, and says plainly when the answer is "no edge"/daily_review: positions, resting orders, fills, closing-soon, attribution
Risk & settlement
settlement_audit(polymarket_id, kalshi_ticker): the check that decides whether a cross-venue price difference is an edge or a mismatch. Compares close times, resolution sources, UMA dispute status and market structure on live data with no pre-curated pair list, returningok/caution/blockwith reasons, and listing the checks it did not perform.check_order(venue, market_id, side, price, size, intent): the last step beforeplace_order. Deterministic checks of the proposed order against the operator's own words and the live market: does the market exist and accept orders, do the intent's words match the market and the YES/NO side, is the price sane against the book, is the size above Polymarket's $1 minimum and inside the guardrails, is there liquidity within the limit, is a resolution source named. Returnsok/caution/blockwith the evidence per check and a one-line read-back. No second model judges anything; nothing is sent.position_size(bankroll_usd, price, fair_value): fractional-Kelly sizing, capped, refusing negative-edge bets, returning its own assumptions.
Tools (42)
search_markets,get_market,get_orderbook,price_history,get_positions: read-only, no keysovershoot_signal, premium: fresh panic-jump detection + this market's historical reversion tendency (ported from the polymarket-wc analyzer)dispute_risk, premium: transparent 0–100 heuristic for contested (UMA-dispute-prone) resolutionsplace_order,cancel_order,open_orders: trading, dry-run by default.priceis a probability in (0,1),sizeis in SHARES, and the exchange enforces a $1 minimum notional on marketable orders. Trading tools carrydestructiveHintannotations so clients can gate them.builder_stats: attribution verification + public builder leaderboardfind_markets,compare_venues,quote_cost: cross-venue (above)server_info: config status, per-venue
Kalshi: kalshi_search_markets, kalshi_get_market, kalshi_get_orderbook,
kalshi_get_trades, kalshi_balance, kalshi_positions,
kalshi_open_orders, kalshi_place_order, kalshi_cancel_order.
Stack notes
Official unified SDK
polymarket-client(0.6.x):AsyncPublicClientfor data,AsyncSecureClient.place_limit_order(..., builder_code=...)for attributed orders. The legacypy-clob-clientis archived and cannot attach builder codes. Do not use it.MCP SDK 2.0:
MCPServerfrommcp.server.mcpserver(the oldmcp.server.fastmcp.FastMCPimport is gone in 2.x).Kalshi is on plain
httpx+cryptography, not the official SDK:kalshi-python-syncrequires Python >=3.13 and re-releases weekly in lockstep with the spec version. Auth is RSA-PSS(SHA256, salt=digest length) overstr(unix_ms) + METHOD + path, where the path includes/trade-api/v2and excludes the query string. Base URL is nowexternal-api.kalshi.com.x402 (planned): the official
x402PyPI package (v2.20+) can wrap MCP tools directly (x402.mcp, payment rides in tool-call_meta), but its MCP helpers currently target mcp 1.x, so integrating means pinningmcp>=1.28,<2or waiting for the 2.x-compatible release. Mainnet settlement needs a facilitator (Coinbase CDP: 1,000 free settlements/mo, then $0.001). Keep free tiers of both signals so registries can index the server.
Who this is for
Polymarket's public builder leaderboard shows what a single operator routing
their own flow is worth. Pulled 2026-08-31 via this server's own
builder_stats tool. Re-run it, the numbers move:
weekly volume | |
#1 (traderline) | $7.70M |
median of top 25 | $533K |
entry to top 25 | $140K |
The instructive rows are the small ones: MagicMarkets routes $901K/week with a single active user; Jupiter $515K with one; Sharkbetting $1.15M with two. Those are bot operators routing their own flow, which is exactly who this is built for.
Roadmap
Live smoke test from an unblocked network: done 2026-08-23, all tools passRegister builder code (polymarket.com → Settings → Builders), set fees to 0 bps at launch, export
ODDSRAIL_BUILDER_CODE; first attributed order on a tiny sizeKalshi as venue #2: done 2026-08-23, 9 tools, verified livex402 paid wrapping for the two signals once the mcp-2.x conflict clears
Registry listings: official MCP registry (
mcp-publisher, PyPImcp-name:marker), Smithery (needs public streamable-HTTP + a free tool for their scanner), Glama (glama.json)
Listing / distribution
GitHub: https://github.com/hmesutozsoy/oddsrail (public, MIT)
Glama: auto-crawls GitHub;
glama.jsonin the repo root claims maintainership.PyPI: https://pypi.org/project/oddsrail/ (
pip install oddsrail)Official MCP registry: listed as
app.oddsrail/polymarket-kalshi-trading(renamed from…-arbitragein 0.10.1; the old name is deprecated) (published 2026-08-30, status active). Re-publish after a version bump withmcp-publisher publish; keepserver.json's version in step withpyproject.tomlor the registry rejects it.Smithery: requires a public HTTPS streamable-HTTP endpoint, available once oddsrail is hosted rather than run locally over stdio.
Available Tools
21 toolsbuilder_statsCInspect
Builder attribution stats: the public builder leaderboard, and (if ODDSRAIL_BUILDER_CODE is set) matched trades attributed to this operator's code.
| Name | Required | Description | Default |
|---|---|---|---|
| time_period | No | WEEK |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full behavioral burden. It discloses the conditional dependency on ODDSRAIL_BUILDER_CODE, which is a useful behavioral trait. However, it does not explicitly state whether this is a read-only operation, nor describe any side effects, authentication requirements, or rate limits. The mention of 'stats' implies non-mutating, but this is left to inference.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the core purpose. It contains no redundancy or filler. However, it is brief to the point of under-specification, so it is not a model of completeness, but as far as conciseness and structure go, it is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity (conditional output, external environment variable, and one undocumented parameter), the description is notably incomplete. It does not explain the time_period parameter, does not describe the output shape (despite an output schema existing), and does not clarify the semantics of 'matched trades'. An agent would struggle to use this correctly without additional context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has a single optional parameter 'time_period' with a default of 'WEEK', yet schema description coverage is 0% and the description makes no mention of it whatsoever. The agent is given no information about acceptable values, format, or the meaning of 'time_period'. Since the schema itself has no enums or explanations, the description must compensate, but it entirely fails to do so.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource ('builder attribution stats') and details two concrete outputs: the public leaderboard and matched trades when ODDSRAIL_BUILDER_CODE is set. This distinguishes it from sibling tools focused on markets, orders, or positions. However, it does not explicitly name what 'stats' encompasses beyond those two items, so it is clear but not exhaustive.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. With 21 sibling tools covering markets, orders, and balances, the description does not state any condition for selection, nor any exclusions. The only contextual hint is the conditional ODDSRAIL_BUILDER_CODE dependency, which is a behavioral condition rather than a usage instruction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancel_orderAInspect
Cancel an open order by id (respects dry-run).
| Name | Required | Description | Default |
|---|---|---|---|
| order_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the dry-run behavior, which is a notable behavioral trait beyond the schema. However, it omits other potentially relevant behaviors such as error handling, idempotency, or side effects (e.g., what happens if the order is already canceled). The single disclosed trait is valuable but the coverage is thin.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, short sentence that conveys the core purpose and a key behavioral nuance. There is no redundancy or filler; every word contributes to the tool's understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity and the presence of an output schema, the description covers the essential purpose and dry-run behavior. However, it lacks guidance on when to use the tool relative to alternatives, and does not mention error conditions or the expected outcome for non-existent orders. The dry-run reference is helpful but the description is otherwise minimal.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It says 'by id', which clarifies that order_id is the order identifier, but it does not provide format, example, or any validation hints. For a single-parameter tool, the description adds minimal semantic value beyond the field name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: cancel an open order, identified by id. It clearly distinguishes the action from placing or viewing orders, and the 'respects dry-run' note adds a unique behavioral qualifier that helps differentiate it from a hypothetical raw cancel.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implicitly indicates when to use the tool (when you want to cancel an open order) but does not explicitly mention alternatives or exclusions. There is no guidance on when to use this versus kalshi_cancel_order or other sibling tools. The dry-run mention provides a contextual clue but no direct comparison or condition for choosing this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dispute_riskCInspect
PREMIUM SIGNAL — dispute-risk triage. Scores 0-100 how likely a market's resolution gets contested (UMA dispute risk) with transparent reasons.
| Name | Required | Description | Default |
|---|---|---|---|
| id_or_slug | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden for behavioral disclosure. It states the output includes a score and 'transparent reasons', but it does not disclose any side effects, auth requirements, rate limits, or whether the operation is read-only. It implies a read operation but never explicitly states it. Given the lack of annotations, this is a significant gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that is concise and front-loaded with the premium signal label. It conveys the purpose without unnecessary words. It could benefit from a bit more detail on the parameter, but as far as conciseness, it scores well.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While an output schema exists (which might cover return values), the description remains incomplete. It fails to explain the input parameter, any prerequisites, or access constraints (as it's a 'premium signal'). For a tool with one required parameter and zero schema coverage, the description should provide much more context to enable correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% parameter description coverage, and the lone parameter 'id_or_slug' is completely unexplained in the description. The description mentions 'a market's resolution' but does not clarify what id_or_slug refers to (e.g., is it a market ID or slug format?). The description fails to compensate for the schema's lack of parameter documentation, making it impossible to know how to fill the required field correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: it 'scores 0-100 how likely a market's resolution gets contested' and specifically mentions 'UMA dispute risk'. This distinguishes it from sibling tools like get_market or search_markets, which serve different purposes. The verb 'scores' and resource 'market's resolution' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It does not mention any conditions, exclusions, or sibling tools. The only contextual hint is 'PREMIUM SIGNAL', which is not a usage guideline. There is no indication of when this should be preferred over other market-related tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_marketBInspect
Get one market's details by slug (or id).
| Name | Required | Description | Default |
|---|---|---|---|
| id_or_slug | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full behavioral burden. While 'Get' implies a read operation, the description does not explicitly state that it is non-destructive, nor does it disclose any error behavior, rate limits, or side effects. For a read-only tool with zero annotation coverage, this is a significant lack of transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, precise sentence with no wasted words. The key information (what it gets and how to identify the market) is front-loaded. Perfectly sized for a simple getter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter) and the presence of an output schema (which covers return values), the description is arguably sufficient to invoke correctly. However, it omits any usage context, edge-case behavior, or relationship to sibling tools, leaving the agent without a clear decision framework. For a tool in a rich ecosystem of similar getters, this is a moderate gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does clarify that the parameter 'id_or_slug' accepts either a market slug or an ID, which adds meaning beyond the bare schema property label. However, it does not specify how to differentiate slug from ID, format expectations, or behavior when given an invalid value. This is a minimal but real contribution.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Get'), resource ('market's details'), and identification method ('by slug (or id)'). It unambiguously distinguishes from search_markets (which lists multiple) and other siblings. No ambiguity about what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like search_markets or the kalshi_get_market sibling. There is no mention of when-not to use it, nor any differentiation from the similar kalshi_get_market. The agent must infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_orderbookAInspect
Get the live orderbook (bids/asks) for a CLOB token id.
| Name | Required | Description | Default |
|---|---|---|---|
| token_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. The 'Get' verb and 'live' qualifier together signal a read-only, real-time snapshot operation. It doesn't mention aggregation depth, pagination limits, or invalid-token behavior, but for a simple one-parameter read this conveys the core behavior adequately.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single 12-word sentence that is front-loaded with the core action and scope. Every element — 'live', 'bids/asks', 'CLOB token id' — earns its place, with zero filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity tool (one required parameter, no nested objects, plus an output schema that covers return values), the description is nearly sufficient. The main gap is the lack of an explicit differentiation from the sibling kalshi_get_orderbook, though the 'CLOB' qualifier partially handles this. Minor depth/format details aside, an agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the schema only provides the title 'Token Id', so the description must compensate. It adds the key concept that token_id is a 'CLOB' token identifier, which gives meaningful context beyond the schema. However, it omits any format guidance (e.g., numeric string, hex), leaving part of the burden unmet given the 0% coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get'), resource ('live orderbook (bids/asks)'), and scope ('for a CLOB token id'), which fully answers what the tool does. The 'live' qualifier and 'CLOB' framing clearly distinguish it from the sibling price_history and kalshi_get_orderbook, so an agent can tell them apart from the description alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'CLOB token id' phrasing implies a use context (central-limit-order-book prediction-market tokens) and the 'live' qualifier suggests a real-time snapshot rather than history. However, it never explicitly names an alternative such as kalshi_get_orderbook or states when-not-to-use this tool, leaving the routing decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_positionsCInspect
Current positions for a wallet address.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| address | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It only states what the tool returns, not whether it is read-only, the response format, or any constraints (e.g., rate limits, authentication). Minimal transparency beyond the purpose.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no wasted words. It front-loads the core purpose efficiently. However, it is so sparse that it borders on under-specification, but conciseness itself is well-handled.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 2 parameters, no annotations, and an output schema, the description is incomplete. It lacks usage context, parameter semantics, and behavioral details. The agent cannot fully assess when or how to call this tool based solely on the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate by explaining parameters. The description mentions 'wallet address' which loosely maps to the 'address' parameter, but it does not explain the 'limit' parameter or any default behavior. The description adds virtually no meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb+resource: it returns current positions for a wallet address. It is specific enough to understand the core function, but it does not differentiate from sibling tools like kalshi_positions or open_orders, so it loses one point.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives. No mention of scenarios, limitations, or exclusions. The agent must infer that this is the tool for wallet positions, but no explicit direction is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kalshi_balanceAInspect
Kalshi account balance (needs the operator's API key).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It does state a key requirement ('needs the operator's API key'), which is useful context. However, it does not describe the nature of the operation (read-only), potential rate limits, or other behaviors. Since an output schema exists, return format is not needed, but the description could add more about authentication or expected behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, direct sentence that is front-loaded with the core purpose and the key prerequisite. No wasted words, appropriate for the simplicity of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless balance-check tool with an output schema present, the description is largely sufficient. It conveys the purpose and the API key requirement. Minor omissions, such as clarifying this is a read-only operation, are not critical given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is nothing to explain. The baseline for 0 parameters is 4, and the description adds no conflict or extra meaning that detracts from this.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the resource ('Kalshi account balance') and implies retrieval. It is specific and easily distinguished from sibling tools, none of which directly reference account balance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives, nor are any alternatives mentioned. Since the tool is simple and has no parameters, some guidance on prerequisites or typical use cases would be helpful but is absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kalshi_cancel_orderBInspect
Cancel a Kalshi order by id (respects dry-run).
| Name | Required | Description | Default |
|---|---|---|---|
| order_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must carry the burden of behavioral disclosure. It only adds 'respects dry-run,' which is a notable behavioral trait but is not explained—what does respecting dry-run mean for the actual cancellation? It does not mention side effects, error behavior, or whether the operation is reversible. This is minimal and leaves significant ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence with no wasted words. The action and key qualifier are front-loaded, making it immediately scannable. It is an exemplary model of brevity for a simple operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one parameter and has an output schema, which covers return-value details. However, the description omits explanation of the dry-run behavior, potential failure modes, or any conditions that might affect execution. Given the complexity is low, a slightly more descriptive note on what 'respects dry-run' entails would improve completeness. As it stands, it is adequate but not thorough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The parameter 'order_id' has no description in the schema, and schema description coverage is 0%. The description's phrase 'by id' clarifies that the parameter is the identifier of the order to cancel, which adds minimal semantic value beyond the schema. However, it does not specify any format, constraints, or validation rules. For a single, obvious parameter, this is acceptable but not rich.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Cancel', the resource 'Kalshi order', and the method 'by id'. It fully conveys what the tool does and is specific enough to stand alone, distinguishing it from other operations like placing orders or fetching data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. There is no mention of exclusions, prerequisites, or conditions under which this tool should be chosen over the sibling 'cancel_order'. The parenthetical about dry-run hints at a condition but does not explain it or tie it to usage decisions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kalshi_get_marketBInspect
Get one Kalshi market by ticker.
| Name | Required | Description | Default |
|---|---|---|---|
| ticker | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description is minimal. It does not disclose behavior on missing tickers, error handling, rate limits, or any side effects (though it is clearly a read operation). With no annotations, the description carries the full burden, and it fails to provide meaningful behavioral context beyond the basic action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with zero redundancy. It directly states the function and key parameter, making it highly efficient and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-ticker operation, the description is adequate but not fully complete. The output schema exists, so return format is covered. However, it lacks information about behavior when the ticker does not exist, pagination, or any authentication requirements. Given the simplicity, the missing pieces are minor, but the lack of any usage or error guidance keeps it at a mid-level score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, 'ticker', is mentioned in the description ('by ticker'), which adds the context that the tool fetches a single market identified by this string. However, schema description coverage is 0%, so the description does not elaborate on format, examples, or constraints. It compensates minimally by naming the field, but does not add substantial value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and the resource 'one Kalshi market by ticker', which precisely identifies the operation. It distinguishes this from search_markets (which searches multiple markets) and get_orderbook (which fetches order book data).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like get_market or kalshi_search_markets. The context of a ticker is implicit, but there is no explicit statement about prerequisites, when to prefer this over search_markets, or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kalshi_get_orderbookAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | ||
| ticker | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and discloses the key quirk: 'Kalshi publishes bid ladders only; asks are derived as 1 - NO bid' — revealing that asks are computed, not native — plus 'Raw ladders included' flags that both raw and normalized forms are returned. This is genuinely useful beyond the schema. Minor omissions (auth, error behavior) keep it from a 5. No annotation contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences (~25 words) that front-load the purpose then add the essential derivation detail in a parenthetical. Every clause earns its place — including the final 'Raw ladders included,' which conveys a distinct fact. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema covers return format, so the description need only handle retrieval semantics, and it delivers the critical normalization/derivation quirk. Gaps: no sibling-routing guidance and no depth semantics. Adequate for a 2-param read tool but short of fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it partly does: the normalization/derivation context clarifies what the ticker's ladder values represent. But it never explicitly defines `depth` (number of ladder levels) or the ticker format, relying on standard naming and the default of 10. Meaningful but incomplete compensation for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a clear verb-resource-scope ('Kalshi orderbook for a ticker') and goes further to specify the normalized YES-book bid/ask view. It's concrete and specific. However, it doesn't differentiate from the generic `get_orderbook` sibling in the same tool set, so an agent must rely on the kalshi_ prefix to infer how the two differ.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use or when-not-to-use guidance. With both `get_orderbook` and `price_history` as siblings, the description offers no basis for choosing `kalshi_get_orderbook` over them, and never mentions alternatives or exclusion conditions. The normalization note clarifies data semantics, not tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kalshi_get_tradesCInspect
Recent public trades for a Kalshi ticker.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| ticker | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are absent, so the description carries the full burden of behavioral disclosure. It only states that trades are 'public', implying read-only access, but does not explicitly confirm no side effects, does not mention rate limits, pagination, or the nature of the returned data. The description is too sparse to inform the agent about important behavioral aspects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words, which is concise. However, it is under-specified: while it conveys the core purpose, it omits necessary detail about parameters and usage. It is not verbose, but the brevity reduces its utility, making it borderline between adequate conciseness and excessive terseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema, return format may be defined there, but the description still lacks essential context for calling the tool correctly. It does not clarify the ticker format, the meaning of the limit parameter, or how this tool relates to other market data tools. For a simple tool with two parameters and no schema descriptions, the description is incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema coverage is 0%, so the description must explain both parameters. It mentions 'ticker' as a Kalshi ticker but provides no guidance on how to obtain or format it, and it completely omits 'limit' (which has a default of 50 but its effect on the result is unexplained). The description adds minimal value beyond the parameter names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Recent public trades for a Kalshi ticker' clearly indicates the tool retrieves public trade data for a given ticker. It is specific to trades, distinguishing it from siblings like get_orderbook and price_history, though it does not explicitly name alternatives. The lack of a verb is mitigated by the tool name 'kalshi_get_trades', which implies retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No usage guidance is provided. The description does not mention when to use this tool versus alternatives such as get_orderbook or price_history, nor does it state any prerequisites like needing a valid ticker from search_markets. An agent would have to infer usage solely from the tool name and description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kalshi_open_ordersCInspect
Kalshi resting orders (needs the operator's API key).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavior. It only mentions the API key requirement, but does not state whether the operation is read-only, the return format, or any side effects. This is a significant gap for a tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the resource and includes the critical API key requirement. It is concise with no fluff, though the brevity comes at the cost of missing necessary details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter), it is still incomplete: it does not describe the output, provide usage context, or mention any constraints beyond the API key. The presence of an output schema helps, but the description alone leaves significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has a single 'limit' parameter with no description, and the tool description provides no additional meaning. With 0% schema description coverage, the description should compensate but does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description identifies the resource (Kalshi resting orders) and hints at the operation, but lacks an explicit verb (list, fetch, etc.). It does not distinguish from the sibling tool 'open_orders' which likely serves the same purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only usage hint is the API key necessity. No guidance is provided on when to choose this over alternative tools like 'open_orders' or other Kalshi query tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kalshi_place_orderAInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| count | Yes | ||
| price | Yes | ||
| action | Yes | ||
| ticker | Yes | ||
| outcome | Yes | ||
| time_in_force | No | good_till_cancelled |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations are provided, the description carries the full burden. It discloses the critical 'DRY-RUN by default' behavior, preventing accidental real orders, and reveals internal translation to the YES-book bid/ask. However, it does not mention authentication, error handling, or what happens when dry-run is disabled, leaving some gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four short, focused sentences with no redundancy. It front-loads the core purpose first and adds critical behavioral details concisely. Every sentence contributes value with zero fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter tool with 5 required fields, the description lacks essential information on ticker (market identifier format) and count (number of contracts). While dry-run is mentioned, its exact output (simulated order?) is not clarified. An agent cannot reliably construct a correct call without guessing these semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains outcome (yes/no), action (buy/sell), and price as probability in (0,1), which is essential. But it omits ticker, count, and time_in_force, leaving their meaning and format ambiguous. Partial compensation only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Place a Kalshi limit order', specifying the verb and resource. It further clarifies the natural-language semantics for outcome and action, distinguishing it from the generic sibling 'place_order' by the Kalshi-specific and translation detail. This makes the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives like 'place_order'. The description implies it is for Kalshi orders but does not state exclusions or offer a comparison to the generic 'place_order' sibling. An agent must infer the selection criteria without direct support.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kalshi_positionsDInspect
Kalshi positions (needs the operator's API key).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations are given, the description must carry the full burden of behavioral disclosure. It only mentions that the operator's API key is needed, which is a prerequisite, but does not state what the tool actually does (e.g., returns positions), whether it's read-only, or any side effects. This is insufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely short, but this is under-specification rather than conciseness. It lacks essential information and does not earn its place by adding value; it reads more like a placeholder than a complete definition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although an output schema exists, the description still fails to clarify the tool's purpose and parameters. An agent cannot determine what action to expect or how to use the limit parameter, making the description incomplete for effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must explain the limit parameter, but it does not. The sole parameter is left undocumented, providing no additional meaning beyond the schema's type and default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Kalshi positions' is ambiguous; it doesn't specify an action verb like 'list' or 'get' and does not differentiate from sibling tools such as get_positions. It merely names the resource without stating what is done with it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like get_positions or other kalshi_* tools. The description does not mention any context, preconditions, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
kalshi_search_marketsBInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | No | ||
| min_volume | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It clearly states that the tool pages open markets (not all markets), filters on title/ticker, excludes auto-generated MVE combo shards, and that prices are dollar strings rather than cents. These are non-obvious behaviors that materially affect how results should be interpreted. The only gap is that it doesn't mention pagination behavior or how volume filtering works, but the core transparency is above average.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a concise three sentences, front-loaded with the primary purpose ('Search Kalshi markets'). Each sentence adds new information: the API limitation, the filtering/exclusion behavior, and the price format. There is no redundancy, and the structure is logical and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers key behavioral quirks (no text search, MVE exclusion, dollar string prices) and an output schema exists, so return details are handled. However, it omits documentation of its own parameters, which are all optional but could each affect results significantly. Additionally, it doesn't differentiate from the sibling 'search_markets', which might be a similar or overlapping tool. This leaves gaps for an agent trying to decide on usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% — the description never mentions 'limit', 'query', or 'min_volume'. It hints that filtering is done on title/ticker, which likely maps to the 'query' parameter, but it does not explicitly confirm this or explain what each parameter does. Given the low coverage, the description should compensate by documenting parameter behavior, but it does not, leaving the agent to guess at semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Search') and resource ('Kalshi markets'), and goes beyond a simple restatement by explaining the lack of a text-search endpoint and the fallback approach of paging and filtering. It also notes the exclusion of auto-generated MVE combo shards, which adds specificity. However, it does not explicitly name sibling alternatives like 'search_markets', so differentiation is implicit rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides context about why this tool exists (Kalshi has no text-search endpoint) and how it operates (pages open markets and filters), which indirectly informs usage. However, it does not explicitly state when to use this tool versus alternatives, such as when a user wants a full-text search or a more efficient lookup. The 'when' is implied but not directly addressed, leaving the agent to infer usage boundaries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_ordersBInspect
List the operator wallet's open orders.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It only states 'List' without revealing whether this operation is read-only, requires special permissions, or has side effects. The agent has no indication of safety or side effects, which is a significant gap for a trading-related tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the action and scope with no filler. It is appropriately concise for a zero-parameter tool, though it might be slightly under-specified when considering behavioral context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema and no parameters, the description is minimally sufficient. However, it does not clarify the meaning of 'operator wallet' or distinguish from the similar-sounding sibling 'kalshi_open_orders'. It lacks any extra context that would help an agent decide when this tool is the right choice beyond the literal wording.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so schema coverage is trivially 100%. Per the rubric, a description for a 0-parameter tool gets a baseline of 4 because there is nothing to explain. The description adds no parameter details, but that is unnecessary here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and resource ('open orders') scoped to 'the operator wallet', which is clear and actionable. However, it does not differentiate from the sibling tool 'kalshi_open_orders', which likely serves a similar purpose, so a perfect score is not warranted.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. Siblings like 'place_order', 'cancel_order', and 'get_positions' exist, but no context is given for selecting this tool. The agent is left to infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
overshoot_signalCInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| hours | No | ||
| token_id | Yes | ||
| threshold | No | ||
| lookback_s | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full behavioral disclosure burden. It states the tool analyzes and reports, implying a read-only operation, but does not explicitly confirm it has no side effects, nor does it disclose potential limitations (e.g., data sufficiency, time windows). The mention of 'fresh panic jumps' and 'historical reversion tendency' adds some context but lacks depth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, consisting of a single sentence that front-loads the core purpose. The 'PREMIUM SIGNAL' label is extraneous but does not add bulk. It avoids unnecessary verbosity while conveying the primary function, though it could be tightened further.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although an output schema exists (so return values need not be described), the description is incomplete for agent usage. It does not explain the parameters, nor does it provide usage context such as when the signal is considered active or how to interpret the reversion tendency. For a tool with four configurable parameters and no schema descriptions, this is a significant gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description provides zero information about the four parameters (hours, token_id, threshold, lookback_s). With schema description coverage at 0%, the description must compensate, but it does not map any parameter to its role or default behavior. The agent is left to guess what 'hours' or 'threshold' mean based solely on the schema property names, which is insufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose as an overshoot/fade detector that analyzes a token's recent price series for panic jumps and reports on fade setups and historical reversion tendencies. It uses a specific verb 'analyzes' and names the resource, distinguishing it from raw data tools like price_history. However, it does not explicitly differentiate from siblings beyond implying signal generation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to use this tool versus alternatives like price_history or get_market, nor any conditions or exclusions. The description implies it is for fade detection but does not state scenarios where it is appropriate or inappropriate, leaving the agent without clear selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
place_orderAInspect
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 = implied probability.
| Name | Required | Description | Default |
|---|---|---|---|
| side | Yes | ||
| size | Yes | ||
| price | Yes | ||
| token_id | Yes | ||
| order_type | No | GTC |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the non-destructive dry-run default, the conditions required for real trading (env vars), the signing of builder code, and the price semantics. This is thorough and goes beyond a simple 'place order' statement, giving agents critical safety and operational context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, two sentences, with the most important information (dry-run default) front-loaded. Every sentence adds value, and there is no wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While an output schema exists, the description does not compensate for the 0% parameter coverage. It explains dry-run behavior and price but omits essential details about token_id, side, size, and order_type. An agent would struggle to correctly fill all required parameters without additional documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description must compensate. It only clarifies the meaning of 'price' (implied probability) but leaves token_id, side, size, and order_type unexplained. This is a significant gap for an agent trying to populate these parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Place a limit order') and resource (an order). It distinguishes itself from siblings like cancel_order and open_orders simply by being the order-placement tool. The added detail about dry-run behavior further sharpens its purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear guidance on when to use it in dry-run mode versus real trading, explicitly requiring environment variables for live execution. It does not explicitly mention alternative tools, but since this is the only order-placement tool among the siblings (kalshi_place_order is for a different platform), the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
price_historyBInspect
Recent price history for a CLOB token id: hours back, at fidelity_minutes resolution.
| Name | Required | Description | Default |
|---|---|---|---|
| hours | No | ||
| token_id | Yes | ||
| fidelity_minutes | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral disclosure duty, but it only states the purpose and parameters. It does not mention read-only nature, return format, pagination, rate limits, or any side effects. For a data retrieval tool, some behavioral context is missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, well-structured sentence that front-loads the core purpose and parameter semantics. No fluff or redundancy, making it easy for an agent to quickly grasp the tool's function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (3 parameters, no schema descriptions), the description covers the essential parameter meanings. However, it omits behavioral aspects like read-only nature and any limitations, which would be expected in a fully complete definition. The presence of an output schema mitigates the need to describe return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description explicitly explains the meaning of the key parameters: 'hours back' maps to hours, and 'fidelity_minutes resolution' maps to fidelity_minutes. With schema coverage at 0%, this inline clarification significantly compensates for the lack of parameter descriptions in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns recent price history for a CLOB token, with parameters for time window and resolution. It uses a specific resource ('CLOB token id') and implies a retrieval action, making its purpose clear. However, it does not explicitly differentiate from sibling tools like get_market or get_orderbook, which could offer price-related data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like get_market, get_orderbook, or historical data tools. The description only states what the tool does without indicating suitable scenarios or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_marketsAInspect
Search Polymarket markets by text (Gamma public-search under the hood); empty query lists open markets. Returns token ids, prices, metrics, resolution info.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals the underlying API and lists return fields (token ids, prices, metrics, resolution info), but it does not mention whether the operation is read-only, requires authentication, or has any side effects. For a search tool this is likely safe, but the absence of explicit safety cues keeps it at a middling score.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The primary purpose is front-loaded, and each clause adds value: the search action, the underlying API, the empty-query behavior, and the return fields. There is no redundancy or extraneous detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, return values are adequately covered. The description explains the essential behavior (text search and empty-query listing) and the underlying API. It does not clarify the effect of 'limit' or pagination/sorting, but these are minor for a simple search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds meaning for the 'query' parameter (text search and empty-query behavior) but provides no information about 'limit' beyond its existence in the schema. Partial compensation is insufficient for a fully undocumented parameter set.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action: 'Search Polymarket markets by text' with a distinct resource (Polymarket markets) and mentions the underlying API (Gamma public-search). It differentiates from siblings by naming the platform, distinguishing it from kalshi_search_markets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for text-based searching and explicitly notes that an empty query lists open markets, which is a key behavior for selecting this tool. However, it doesn't explicitly contrast with alternatives like get_market or kalshi_search_markets, though the platform name inherently routes the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
server_infoAInspect
Server status: dry-run state, attribution config, and which capabilities are enabled.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states the tool returns status information, which strongly implies a read-only operation with no side effects. However, it does not explicitly declare 'read-only' or mention any potential effects. The listed return content (dry-run, attribution, capabilities) makes the informational nature clear, so this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one tightly packed sentence that lists the key return categories without any filler. It is front-loaded with the core concept ('Server status') and then specifies details. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema (not shown here, but referenced as existing), which likely defines the exact return fields. The description covers the three main aspects, but does not elaborate on what 'capabilities' means or how they are listed. Given the output schema fills in details, this is reasonably complete, though a touch more context (e.g., 'capabilities such as X, Y') would elevate it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there are no parameter semantics to explain. The description correctly does not attempt to describe params. With no parameters, the schema is trivially complete, and the description adds no unnecessary clutter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reports server status and enumerates three specific aspects: dry-run state, attribution config, and enabled capabilities. It uses a noun phrase but the purpose is unambiguous. It differentiates from siblings like get_market or place_order by focusing on server internals rather than market or trading operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for checking server configuration, but it does not explicitly state when to use it (e.g., before placing orders to verify dry-run mode) or exclude scenarios where other tools are more appropriate. Since it's a status tool, the usage context is somewhat obvious, but explicit guidance would improve clarity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
21 tool updates
v0.3.0- First observed
builder_stats - First observed
cancel_order - First observed
dispute_risk - First observed
get_market - First observed
get_orderbook - First observed
get_positions - First observed
kalshi_balance - First observed
kalshi_cancel_order - First observed
kalshi_get_market - First observed
kalshi_get_orderbook - First observed
kalshi_get_trades - First observed
kalshi_open_orders - First observed
kalshi_place_order - First observed
kalshi_positions - First observed
kalshi_search_markets - First observed
open_orders - First observed
overshoot_signal - First observed
place_order - First observed
price_history - First observed
search_markets - First observed
server_info
TDQS
Scored across 21 tools
Tools are cleanly partitioned by exchange (Polymarket vs. Kalshi with the kalshi_ prefix), and within each exchange each tool targets a distinct resource or action. No two tools appear to serve the same purpose; even the premium signals (overshoot_signal, dispute_risk) are clearly unique.
Kalshi tools follow a consistent 'kalshi_verb_noun' pattern, but Polymarket tools mix conventions: get_* verbs (get_market, get_orderbook, get_positions) coexist with noun phrases (price_history, overshoot_signal, dispute_risk, builder_stats, server_info) and imperative verbs (place_order, cancel_order, open_orders). The lack of a uniform verb-first pattern or exchange prefix for Polymarket creates mild inconsistency.
21 tools is slightly above the typical 3-15 range, but the server covers two distinct prediction-market platforms, each with its own market data, order management, and account tools. The extra tools are justifiable additions for Kalshi, making the count reasonable rather than bloated.
Both exchanges have solid coverage: market retrieval, search, orderbooks, order placement/cancellation, and positions. Minor gaps exist—Kalshi lacks a dedicated price-history tool (only recent trades), and Polymarket has no explicit balance endpoint—but these are not critical and can be worked around with existing tools.
Maintenance
Related MCP Connectors
Calibrated world model for AI agents. 40 tools: world state, markets, trading. Kalshi + Polymarket.
Polymarket + Hyperliquid + macro for AI agents. 38 tools, signal backtest, SSE streaming. Free tier.
Hosted MCP for Kalshi prediction markets: search, odds, order books, settlement rules, and trading.
Calibrated probabilistic foresight for AI agents, powered by live prediction-market signal.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceReal-time prediction market intelligence for AI agents. Query Polymarket and Kalshi markets, wallet profiles, smart money leaderboards, social pulse signals, price candlesticks, and orderbook data — 13 agents, one MCP connection. Powered by 1.1TB+ of historical data.MIT
- AlicenseAqualityDmaintenancePrediction market probability oracle for AI agents. 26 tools across 500+ live markets from Kalshi and Polymarket. Cross-source arbitrage detection, structured TPF signals, Kelly Criterion sizing, agent performance tracking, and webhook alerts.927 npm1MIT
- AlicenseAqualityFmaintenanceProvides prediction market intelligence, research, and strategy signals for platforms like Kalshi, Polymarket, and Robinhood. It enables AI assistants to perform market screening, arbitrage detection, and deep causal analysis to support informed trading decisions.271MIT
- AlicenseNot gradedqualityBmaintenanceAn MCP server and Python toolkit that provides AI agents with real-time tools for Polymarket prediction markets, including liquidity scanning, arbitrage detection, and slippage estimation. It also offers advanced wallet intelligence, portfolio risk calculation, and probabilistic reasoning to enhance market analysis and strategy.1MIT