oracle3
Summary: Oracle3's MCP server lets an agent research prediction markets on Kalshi and Polymarket, test probability relations after fees, and paper-trade — all without live order placement or private keys.
Search markets (
search_markets) by keyword, or list a Kalshi series' open markets; no API key needed.Inspect a market (
get_market) for title, prices, volume, close date, resolution rules, outcomes, token ids, neg-risk flag and fee schedule.Read order books (
get_orderbook) — YES/NO[price, size]levels, best first, to gauge depth.Get top of book (
get_quote) — best YES/NO bid and ask plus the market's fee schedule.Compute fees (
trading_fee) for a taker or maker fill using Kalshi's multiplier/maker terms or Polymarket's taker rate.Check a relation offline (
check_constraint) on quotes you supply, returning the cheapest basket, gross and net edge after fees, and candidate baskets.Check a relation live (
check_constraint_live) — fetches current quotes and fee schedules across one or mixed venues and reports violation and profit after fees.List relation types (
list_relation_types) — implication, exclusivity, complement, same_event, event_sum and their bounds.List saved relations (
list_relations) from the local store, filtered by status, market id or spread type (e.g. Kairos cross-venue pairs).Compute fair value (
fair_value) by inverting the Wang transform to convert a price into an implied probability and show the premium.Paper trade (
paper_order) against the live book with fees, walking ask levels up to a limit price; writes a local ledger.Review the paper portfolio (
paper_portfolio) — cash, positions, fills; starts at $10,000 carried at cost.Reset the paper ledger (
paper_reset) to restore starting cash, requiringconfirm=true.Limits: research and simulation only — no live orders, no wallet or key access; real-money execution stays in the CLI.
Integrates with Solana (via DFlow) as a trading venue for prediction market contracts, supporting live order execution with Jito bundle submission alongside Kalshi and Polymarket.
Oracle3
Build prediction-market agents that discover markets, analyze opportunities, and test strategies.
Connect AI agents to Kalshi and Polymarket through MCP. Give them reusable Skills for market research and strategy development, then build on a Python engine for paper and live execution.
13 MCP tools · 6 agent Skills · Kalshi & Polymarket data · Python 3.10+
Quickstart · MCP tools · Agent Skills · Project and contributions · Documentation
Why Oracle3
A connected research workflow. Discover contracts, inspect their rules and order books, compare related outcomes, and track simulated positions.
Calculations that include trading costs. Five relationship checks return candidate baskets, per-leg fees, and calculated net edge.
Tools and workflows for agents. Use MCP for structured access and Skills for repeatable research, strategy authoring, and operations.
An engine you can extend. Build strategies with Python interfaces, risk controls, and paper/live venue adapters.
A foundation for experiments. Reproducible software checks, automated tests, and installed-package validation make the implementation inspectable.
Public Kalshi and Polymarket market reads need no exchange credentials. MCP provides market data, calculations, and a local paper ledger; real-order execution uses the separate CLI/Python engine.
Related MCP server: pmxt-mcp
Quickstart
Install the current development checkout:
git clone https://github.com/YichengYang-Ethan/oracle3-prediction-market-agent.git
cd oracle3-prediction-market-agent
python -m venv .venv
.venv/bin/python -m pip install -e .Connect it to Claude Code from this directory:
claude mcp add oracle3 -- "$PWD/.venv/bin/oracle3-mcp"For other MCP clients, configure the absolute path to .venv/bin/oracle3-mcp as the command with an empty argument list. On Windows, use .venv\Scripts\python.exe and .venv\Scripts\oracle3-mcp.exe.
Client configuration and first tool call · Published-package installation
Give your agent a first task
Find Kalshi and Polymarket contracts about the next Fed rate decision. Compare their outcome definitions, resolution rules, and order-book quotes. Summarize the markets with their IDs, prices, and the assumptions needed to compare them.
For a calculation that works offline after installation:
Use Oracle3 to check an implication: A implies B. A has a YES bid of $0.60 and B has a YES ask of $0.55. Use the default Kalshi taker fee schedule and 100 contracts per leg. Show the basket, gross edge, fees, and net edge.
The synthetic example returns $5.00 gross edge − $3.4125 fees = $1.5875 calculated net edge, conditional on the supplied implication and quotes. See exact inputs and output.
What agents can do
Task | Tools | Result |
Discover markets |
| Contracts, metadata, and available resolution rules |
Inspect market conditions |
| Prices, fee information, and displayed depth |
Analyze related contracts |
| Baskets and net edge under a stated relationship |
Calculate fees and model values |
| Fee estimates and parameterized model outputs |
Try a paper entry |
| Simulated fills and holdings in a local ledger |
Relationship checks cover implication, exclusivity, complement, same event, and event sum. They expose assumptions with their results, giving agents and researchers a common calculation layer.
All 13 MCP tools · Workflow examples
Reusable agent Skills
The repository includes six workflows that help agents move from individual tool calls to complete tasks:
Skill | Use it to |
Find markets and organize research inputs | |
Examine related contracts and calculate fee-aware baskets | |
Develop strategies with Oracle3's Python interfaces | |
Build agent-driven decision workflows | |
Run and inspect simulated trading sessions | |
Configure and operate the separate live engine |
Claude Code project copies are included in .claude/skills/. Open the checkout as your project, or use your client's supported Skill installation mechanism. Skill setup.
For AI agents: start with llms.txt for task routing, the MCP reference for tool schemas, and AGENTS.md for contributing code.
Build with Python and the CLI
Use the same project for research scripts, agent strategies, and engine operations:
.venv/bin/oracle3 market search --exchange kalshi --query "fed" --json
.venv/bin/oracle3 market search --exchange polymarket --query "fed decision" --jsonComponent | Build with it |
Structured market access and local paper operations for agents | |
Shared calculations for related-contract strategies | |
Logical-relation, statistical, and model-driven approaches | |
Paper/live adapters for Kalshi, Polymarket, and Solana via DFlow | |
Wang-transform models and estimators for research | |
Optional venue, data-provider, and wallet integrations |
CLI guide · Integration guide · Execution reference
Built for experimentation
Oracle3 combines a concrete decision environment with structured tools, observable state, and a software validation harness. This supports work on agent interfaces, workflow guidance, and reproducible evaluation.
CI runs automated tests and checks the built package through real MCP sessions on SDK 1.x and 2.x. The harness documentation explains the reproducible checks. Model-level agent evaluation is a next research direction.
Project overview and Yicheng Yang's contributions · Fee-frontier study · Companion pricing research
Contribute
Help build better agent workflows, labeled evaluation tasks, strategy examples, and client integrations. New venue, data-provider, and wallet integrations start in oracle3-extras.
Contributing guide · Open problems · Discussions
Origin and attribution
Oracle3 began as ulab-uiuc/oracle3, developed by Yicheng Yang and Haofei Yu at U Lab (University of Illinois Urbana-Champaign). It also bundles the lab's Coinjure package. Yicheng Yang continues to develop and maintain the extensions in this repository. Read the project story and contributions.
We acknowledge the foundational work of the Coinjure team at the University of Illinois Urbana-Champaign—Haofei Yu, Yicheng Yang, Yuxiang Liu, and Prof. Jiaxuan You—on which Oracle3 builds.
For software citation, use CITATION.cff and Zenodo. For the pricing model, see the working paper.
License
Apache 2.0; see LICENSE. Original U Lab and Coinjure portions retain their MIT license in NOTICE.
This software is for research and education. Trading involves financial risk.
Available Tools
13 toolscheck_constraintARead-onlyIdempotent
Check offline whether prices you supply violate a no-arbitrage relation, and price the cheapest exploiting basket after fees.
A pure calculation with no network calls: use it for hypothetical or
historical prices, and use check_constraint_live to fetch current quotes
instead. Returns violated, profitable_after_fees, the best basket (legs,
cost, guaranteed payoff, fees, gross and net edge), every candidate basket,
any missing quotes, and the assumptions behind the check (full fills at the
quoted prices, a correctly specified relation).
| Name | Required | Description | Default |
|---|---|---|---|
| maker | No | Price fees as resting maker orders instead of taker orders (default false). Maker fees are lower or zero, but a resting order may not fill. | |
| quotes | Yes | One quote per contract, in the order the relation expects: implication (A, B) where A implies B; complement and same_event (A, B); exclusivity and event_sum every outcome. | |
| relation | Yes | Bound to test: implication (A implies B, so P(A) <= P(B)), exclusivity (at most one outcome happens), complement (exactly one of two), same_event (one event quoted on two venues) or event_sum (exactly one of n). See list_relation_types. | |
| contracts | No | Contracts bought on every leg (default 1). Fees scale with size. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and closed-world, and the description reinforces this with 'a pure calculation with no network calls'. It goes beyond annotations by stating the modeling assumptions behind the check (full fills at quoted prices, correctly specified relation), which is genuinely useful context an agent cannot get elsewhere. It does not, however, discuss failure modes or edge handling such as missing quotes beyond noting they are returned.
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?
Front-loaded with the core purpose and the sibling routing in the first two sentences, which is exactly the ordering an agent needs. The return-value enumeration is somewhat long given an output schema exists, but it is not padded with filler.
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?
With an output schema present, the description need not enumerate return values, yet it briefly does while also covering prerequisites, the offline constraint, the sibling alternative, and modeling assumptions. Nothing an agent needs to invoke it correctly is missing.
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 100%, including enum semantics for relation and detailed QuoteInput field docs, so the schema carries the parameter burden; baseline 3 applies. The prose adds no parameter syntax or format guidance beyond what the schema already provides.
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?
States a specific verb and resource ('check offline whether prices you supply violate a no-arbitrage relation') plus a secondary capability ('price the cheapest exploiting basket after fees'). It explicitly contrasts itself with the sibling check_constraint_live, so an agent can distinguish them without opening either schema.
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?
Gives an explicit when-to-use rule ('hypothetical or historical prices') and names the alternative plus the condition that selects it ('use check_constraint_live to fetch current quotes instead'). The same sentence also clarifies the offline/no-network constraint that bounds usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_constraint_liveARead-only
Fetch live quotes and fee schedules for related markets, then check whether their prices violate a no-arbitrage relation after fees.
This is the main research call: find related contracts with search_markets,
confirm with get_market that their resolution rules really satisfy the
relation, then pass them here. Read-only: it calls the venues' public APIs
and places no orders. Returns the check_constraint result (violated,
profitable_after_fees, best basket with net edge) plus the quotes it used;
to simulate the trade, call paper_order for each leg of the best basket.
| Name | Required | Description | Default |
|---|---|---|---|
| maker | No | Price fees as resting maker orders instead of taker orders (default false). Maker fees are lower or zero, but a resting order may not fill. | |
| markets | Yes | Markets to check, each {venue, market_id}, in the order the relation expects: two for implication (A then B), complement and same_event; every outcome for exclusivity and event_sum. Venues may be mixed. | |
| relation | Yes | Bound to test: implication (A implies B, so P(A) <= P(B)), exclusivity (at most one outcome happens), complement (exactly one of two), same_event (one event quoted on two venues) or event_sum (exactly one of n). See list_relation_types. | |
| contracts | No | Contracts bought on every leg (default 1). Fees scale with size. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint and openWorldHint; the description reinforces this by stating it calls public APIs and places no orders, and it discloses the return payload (violated, profitable_after_fees, best basket, quotes used). It does not discuss rate limits or failure modes, but it adds solid behavioral 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?
Front-loads the action, then the workflow, then the return/simulation note. Slightly verbose, but every sentence carries routing or behavioral information rather than filler.
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?
With annotations covering safety and an output schema covering returns, the description still adds the call-order workflow and simulation next step. Nothing an agent needs to invoke it correctly is missing.
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 100% and the enums/field descriptions are thorough; the description reinforces the ordering requirement (two for implication, every outcome for exclusivity) which the schema also states. Baseline 3 is appropriate since the schema carries the parameter detail.
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?
States specific verbs and resources: fetches live quotes/fee schedules and checks a no-arbitrage relation after fees. It is clearly distinguished from the sibling check_constraint (static) by the 'live' framing and by naming the surrounding workflow tools.
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?
Explicitly routes the agent: find related contracts with search_markets, confirm with get_market, then call this, and use paper_order to simulate each leg of the best basket. This covers when to use it and the prerequisites/alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fair_valueARead-onlyIdempotent
Convert a market price into the probability it implies under the Wang transform, and report the premium.
Solves p_mkt = Phi(Phi^-1(p) + lam) for p; a pure calculation with no network
calls. Use it to strip the favourite-longshot premium from a quoted price
before comparing it with your own forecast. The default lam = 0.183 is the
pooled estimate in Yang (2026), SSRN 6468338; it pools real-money and
play-money venues, so treat it as illustrative. Returns market_price,
lambda, implied_probability and premium (price minus implied probability).
| Name | Required | Description | Default |
|---|---|---|---|
| lam | No | Pricing-wedge parameter lambda of the Wang transform. Positive values mean prices sit above the true probability, most of all for longshots. Default 0.183. | |
| market_price | Yes | Observed YES price in dollars, strictly between 0 and 1. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and non-open-world, so the safety profile is covered. The description goes beyond them by disclosing that it is a pure computation with no network calls, that the default lambda is a pooled/illustrative estimate with a cited source, and what the return payload contains.
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?
Front-loaded with the core purpose, then the formula, then usage, then the caveat and return fields. The formula and provenance sentence are justified, though the description runs a touch long for a two-parameter pure calculation.
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 stateless two-parameter calculation with an output schema present, the description covers purpose, usage context, the key parameter's provenance caveat, and the returned fields. Nothing an agent needs to invoke it correctly is missing.
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 100%, so baseline would be 3. The description adds provenance and interpretation for lam (pooled real-money/play-money estimate from Yang 2026, to be treated as illustrative) that the schema does not carry, and frames market_price as the quoted price being de-biased.
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?
States a specific verb and transformation: 'Convert a market price into the probability it implies under the Wang transform,' plus the accompanying premium. The math (solving p_mkt = Phi(Phi^-1(p) + lam)) and the pure-calculation framing distinguish it immediately from live-data siblings like get_quote and get_orderbook.
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?
Gives clear when-to-use guidance: strip the favourite-longshot premium from a quoted price before comparing it with your own forecast. It stops short of explicitly naming alternative tools or stating when not to use it, so it is strong context rather than a full routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_marketARead-only
Get one market's details: title, best bid and ask, volume and closing date.
Kalshi results include the resolution rules (rules_primary, rules_secondary);
Polymarket results include the outcomes, token ids, neg-risk flag and the
market's fee schedule. Read the rules of every leg here before trusting a
relation in check_constraint_live. For prices plus fee terms only, use
get_quote; for depth, use get_orderbook. Public data, no API key.
| Name | Required | Description | Default |
|---|---|---|---|
| venue | Yes | Venue: 'kalshi' or 'polymarket'. | |
| market_id | Yes | Kalshi market ticker (e.g. KXFEDDECISION-28JAN-H0) or Polymarket market id (e.g. 2589812), as returned by search_markets. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds value beyond that: it discloses the no-API-key/public-data auth posture, the venue-dependent payload shapes (Kalshi rules fields vs Polymarket outcomes/token ids/neg-risk/fees), and a workflow caveat about trusting relations. It does not cover rate limits or error behavior, but for a single-item read that is a minor 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?
Front-loaded with the core purpose, then venue-specific detail, then exclusions and alternatives. Every sentence carries distinct information; nothing is redundant padding.
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?
Output schema exists, so return values need not be explained, yet the description still surfaces the venue-dependent keys an agent must reason about. Combined with the routing guidance and auth note, an agent has everything needed to select and 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 coverage is 100%, so both parameters are already documented, making 3 the baseline. The description goes further by explaining what the venue choice actually changes in the response (Kalshi vs Polymarket result shapes), which is meaning the enum label alone does not convey.
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?
States a specific verb (get) and resource (one market's details) and enumerates the returned fields: title, best bid/ask, volume, closing date. It further differentiates behavior by venue, so an agent can distinguish it from get_quote, get_orderbook and search_markets without opening a schema.
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?
Explicitly routes the agent: get_quote for prices plus fee terms, get_orderbook for depth, and check_constraint_live for relations with the prerequisite that rules must be read first. When-to-use and when-to-use-something-else are both stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_orderbookARead-only
Get the displayed order book for YES and NO as [price, size] levels, best first.
Prices are dollars per contract and sizes are contracts. Use it to see how
much of a basket can fill near the quoted price before paper_order; use
get_quote when only the top of book matters. Kalshi publishes bids only, so
each side's asks are derived from the other side's bids (a YES ask of p is a
NO bid of 1 - p). Public data, no API key.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Price levels per side, 1-50 (clamped). Default 10. | |
| venue | Yes | Venue: 'kalshi' or 'polymarket'. | |
| market_id | Yes | Kalshi market ticker (e.g. KXFEDDECISION-28JAN-H0) or Polymarket market id (e.g. 2589812), as returned by search_markets. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint and openWorldHint, but the description adds behavior the annotations cannot convey: Kalshi publishes bids only so asks are derived from the other side's bids (with the 1 - p formula), plus 'public data, no API key' authentication context and price/size units. This is substantive domain-specific disclosure.
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?
Three tight sentences, front-loaded with purpose and output format, then usage routing, then pricing/data-source caveats. Every sentence adds distinct information with no padding.
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?
With an output schema present, return values need not be re-explained, and the description still supplies the venue-specific quoting quirk, units, and auth status. An agent has everything needed to call and interpret this 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 coverage is 100%, so the baseline is 3, but the description adds unit semantics the schema omits: prices are dollars per contract and sizes are contracts, and level ordering is best-first. It does not restate the depth range or venue enum, which the schema already covers.
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 first sentence names a specific verb and resource ('Get the displayed order book for YES and NO') and specifies the output shape ('[price, size] levels, best first'), which immediately separates it from siblings like get_quote and get_market.
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?
It states the concrete use case ('see how much of a basket can fill near the quoted price before paper_order') and names the alternative with its selecting condition ('use get_quote when only the top of book matters'). The when-to-use and when-not-to-use are both explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_quoteARead-only
Get the best bid and ask on YES and NO, in dollars, plus the market's fee schedule.
Use it to collect prices for check_constraint, or to read the fee terms
(Kalshi multiplier and maker fees, Polymarket taker rate) that trading_fee
takes. check_constraint_live fetches quotes itself, so this is not needed
before calling it. A missing ask is derived from the opposite side's bid.
Returns {venue, market_id, title, yes_bid, yes_ask, no_bid, no_ask,
fee_schedule}. Public data, no API key.
| Name | Required | Description | Default |
|---|---|---|---|
| venue | Yes | Venue: 'kalshi' or 'polymarket'. | |
| market_id | Yes | Kalshi market ticker (e.g. KXFEDDECISION-28JAN-H0) or Polymarket market id (e.g. 2589812), as returned by search_markets. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations give readOnlyHint and openWorldHint, and the description adds real behavioral context beyond them: a missing ask is derived from the opposite side's bid, and the data is public with no API key required. It stops short of describing latency, rate limits, or staleness of the quote.
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?
Front-loads the core purpose, then usage, then behavioral caveat, then return shape. Mostly tight, but the explicit enumeration of returned fields is partly redundant since an output schema exists.
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 two-parameter read tool with full schema coverage, annotations, and an output schema, the description covers purpose, routing, and derivation behavior adequately. The redundant return-field listing is harmless but unnecessary given the output schema.
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 100% and both parameters (venue enum, market_id formats) are fully documented in the schema, so the description owes little. It implies dollar-denominated output but adds no parameter-level meaning beyond the schema, matching the baseline of 3.
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?
Names a specific verb and resource (get quote), states exactly what is returned (best bid/ask on YES and NO in dollars plus fee schedule) and scopes it to two named venues. An agent can distinguish it from get_orderbook or get_market without opening either schema.
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?
Explicitly routes usage: use it to gather prices for check_constraint or to read fee terms consumed by trading_fee, and states the exclusion that check_constraint_live fetches quotes itself so this call is unnecessary beforehand. When/when-not and alternatives are both covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_relationsARead-only
List the market relations saved on this machine by the oracle3 research CLI, optionally filtered.
Reads ~/.oracle3/relations.json with no network calls. Use it to reuse pairs
already discovered or validated offline, then pass a pair to
check_constraint_live. For the abstract relation kinds and their bounds,
call list_relation_types instead. Returns the store path, a count and the
matching relations (markets, type, status and validation details); the list
is empty if the CLI has saved none.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | Only this lifecycle status: discovered, validated, deployed, retired or invalidated. Empty returns all. | |
| market_id | No | Only relations that include this market id (Kalshi ticker or Polymarket id). Empty returns all. | |
| spread_type | No | Only this relation type: same_event, cross_platform, implication, exclusivity, conditional, structural, cointegration or complement. Empty returns all. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds real behavioral context beyond the annotations: it reads ~/.oracle3/relations.json and makes no network calls, and notes the list is empty if nothing has been saved. readOnlyHint and openWorldHint=false already cover the safety/offline profile, but the concrete file path is useful added detail.
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?
Front-loaded with the core action, then file/read behavior, then routing guidance, then return summary. Every sentence carries information, though the return-details run slightly long given an output schema exists.
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?
With a full output schema present and 100% parameter coverage, the description need only establish purpose, usage and environment. It does all three, including the offline/local-file nature and the empty-result case, so an agent can 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 100%, so the schema already documents the status, market_id and spread_type filters including their empty-value semantics. The description only restates that results are optionally filtered and adds no filter syntax or format detail, so the baseline 3 applies.
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?
States a specific verb (List) and resource (market relations) plus the precise scope (saved on this machine by the oracle3 research CLI, optionally filtered). It explicitly names the sibling list_relation_types as the tool for the different concept of abstract relation kinds, so an agent can separate them without opening schemas.
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?
Gives explicit when-to-use (reuse pairs already discovered or validated offline) and what to do next (pass a pair to check_constraint_live). It also cleanly routes to an alternative for the abstract relation kinds via list_relation_types.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_relation_typesARead-onlyIdempotent
List the relation types the constraint checks support and the probability bound each enforces.
Static reference data with no network or file access, for example
implication: P(A) <= P(B). Use it to choose the relation argument of
check_constraint or check_constraint_live; to see concrete market pairs
saved on this machine, use list_relations instead. Returns
{relations: {name: bound}}.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real context beyond the annotations by declaring it is 'static reference data with no network or file access' and giving a concrete example of the semantics ('implication: P(A) <= P(B)'). It also previews the return shape, though it does not need to elaborate further given the readOnly/idempotent/closed-world annotations already fix the safety profile.
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?
Three short sentences, front-loaded with what the tool returns, then usage, then the sibling disambiguation. Each sentence earns its place and nothing is padded.
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?
An output schema exists, yet the description still summarizes the shape ({relations: {name: bound}}) and supplies the domain semantics an agent needs to pick a relation argument. Nothing needed to invoke it correctly is missing.
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 takes zero parameters, so the baseline is 4. The description correctly adds no parameter guidance because none is needed.
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?
States a specific verb and resource: 'List the relation types the constraint checks support and the probability bound each enforces.' It is immediately distinguishable from the sibling list_relations, which is called out separately for concrete market pairs.
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?
Explicitly says to use it 'to choose the relation argument of check_constraint or check_constraint_live' and names the alternative (list_relations) with the condition that selects it ('to see concrete market pairs saved on this machine'). When and when-not are both covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paper_orderA
Simulate buying YES or NO contracts in the local paper ledger, filling against the live order book with venue fees. Never sends an order to a venue.
Walks the displayed asks from the best price up to limit_price and charges
the venue fee on each level. Use it to test the legs of a basket found by
check_constraint_live. Writes ~/.oracle3/mcp_paper_ledger.json (or the path
in ORACLE3_MCP_LEDGER); only buys are supported and positions are held at
cost. Returns status (filled, partially_filled, unfilled, or rejected when
paper cash is short), requested and filled contracts, average price, cost,
fees and the per-level fills.
| Name | Required | Description | Default |
|---|---|---|---|
| side | Yes | Side of the binary contract to buy: 'yes' or 'no'. | |
| venue | Yes | Venue: 'kalshi' or 'polymarket'. | |
| contracts | Yes | Contracts to buy; must be positive. | |
| market_id | Yes | Kalshi market ticker (e.g. KXFEDDECISION-28JAN-H0) or Polymarket market id (e.g. 2589812), as returned by search_markets. | |
| limit_price | Yes | Highest price per contract to pay, in dollars, strictly between 0 and 1; ask levels above it are skipped. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses the ledger file path (~/.oracle3/mcp_paper_ledger.json or ORACLE3_MCP_LEDGER), per-level fee charging, held-at-cost positions, buy-only limitation, and the rejection case when paper cash is short. This is unusually rich behavioral disclosure for a mutation 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?
Front-loads the core purpose, then mechanics, then return values. Three compact sentences with little waste, though the return-value enumeration partly duplicates the output schema.
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 simulated-order tool with 5 required params, an output schema, and safety annotations, everything an agent needs is present: scope, side effects, file location, fill logic, and status outcomes. Nothing material is missing.
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 100%, so baseline is 3, but the description adds real semantics: the fill walks displayed asks from best price up to limit_price and charges the venue fee per level, which clarifies how limit_price and contracts actually interact with the book.
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?
States a precise verb+resource: simulates buying YES/NO contracts in a local paper ledger, filled against the live order book with fees. The opening line and the 'never sends an order to a venue' clause cleanly separate it from any real trading sibling.
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?
Explicitly says to use it to test the legs of a basket found by check_constraint_live, and states the constraint that only buys are supported. It lacks an explicit 'when not to use' or a named alternative for real orders, but context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paper_portfolioARead-only
Show the local paper ledger: cash, open positions and the number of fills.
Reads ~/.oracle3/mcp_paper_ledger.json (or ORACLE3_MCP_LEDGER) with no
network calls. Use it after paper_order to confirm fills and remaining cash.
Starting cash is $10,000; positions are carried at cost, and the ledger does
not mark to market or track resolution. Returns the ledger path,
initial_cash, cash, positions and fills.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/openWorldHint annotations, it discloses the backing file and env override, that there are no network calls, the $10,000 starting cash, and two important accounting caveats: positions are carried at cost and there is no mark-to-market or resolution tracking. These are exactly the behavioral traits an agent could not infer from structured fields.
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?
Front-loaded with the purpose, then source semantics, then usage, then caveats. Most sentences earn their place, though the final return-field enumeration partially duplicates the output schema and could be trimmed.
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 zero-parameter local read tool with an output schema and safety annotations already present, the description supplies everything else an agent needs: data source, absence of network calls, and the accounting semantics that make the numbers interpretable.
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 takes zero parameters, so the baseline is 4. The description correctly implies a parameterless call and adds no misleading argument guidance.
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?
States a specific verb (show) and resource (local paper ledger) and enumerates the contents (cash, open positions, fill count). It is clearly distinguishable from siblings like paper_order, paper_reset, and the market-data tools, since it is the read-side of the paper trading pair.
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?
Explicitly says 'Use it after paper_order to confirm fills and remaining cash,' naming the sibling and the triggering condition. It lacks an explicit when-not statement or mention of paper_reset, but the affirmative guidance is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paper_resetADestructive
Erase the local paper ledger and restore the $10,000 starting cash.
Deletes all paper positions and fill history; no venue is contacted and real
accounts are never touched. Without confirm=true it returns status
not_reset and changes nothing. Use it to start a fresh paper-trading
session.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Must be true to erase the ledger; otherwise nothing changes. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing what gets destroyed (all paper positions and fill history), what is NOT affected (no venue contacted, real accounts untouched), and the exact no-op behavior and return status (not_reset) when confirm is false. This is exactly the destructive-operation context an agent needs.
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?
Three short, front-loaded sentences: the destructive action first, then the safety scope, then the confirm gate. No sentence is wasted.
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 single-parameter destructive tool with annotations and an output schema, the description covers purpose, scope, safety, and gating behavior completely. Nothing needed to call it correctly is missing.
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 already 100%, so baseline is 3; the description adds value by explaining the consequence of the parameter's default state (returns not_reset and changes nothing without confirm=true), which is more than the schema's terse 'otherwise nothing changes'.
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?
States a specific verb+resource ('Erase the local paper ledger and restore the $10,000 starting cash') and scopes it to the local paper ledger, distinguishing it from sibling tools like paper_portfolio and paper_order. The agent can identify exactly what the tool does without opening the schema.
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?
Gives a clear use case ('start a fresh paper-trading session') and the gate condition for action (confirm=true). It does not explicitly contrast with alternatives such as paper_portfolio, but the reset-vs-read distinction is obvious from the sibling names and the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_marketsARead-only
Search open Kalshi or Polymarket markets and return candidates with their best prices.
Start here to find market ids, then call get_quote or get_orderbook for live
prices, or get_market for resolution details. Reads the venues' public APIs,
so no account or API key is needed; Kalshi keyword search scans up to 1,000
open events. Returns {venue, query, count, markets}; each market has
market_id, title, best bid and ask in dollars, volume and closing date.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum markets to return, 1-100 (clamped). Default 20. | |
| query | No | Case-insensitive keywords matched against event titles, market titles and (on Kalshi) tickers. Empty lists open markets without a keyword filter. | |
| venue | Yes | Venue: 'kalshi' or 'polymarket'. | |
| series_ticker | No | Kalshi only: list the open markets of this series (e.g. KXFEDDECISION) instead of searching by keyword; query is then ignored. Ignored on Polymarket. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, but the description adds meaningful context beyond them: no account or API key is required because it reads public APIs, and Kalshi keyword search scans up to 1,000 open events. It omits rate limits and pagination behavior, so it is strong but not complete.
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?
Three tight sentences, front-loaded with purpose then routing then behavior. The final sentence enumerating return fields is partially redundant with the output schema, which slightly blunts conciseness, but nothing is padded.
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 read-only, public-API search with an output schema and readOnly/openWorld annotations already present, the description covers purpose, sibling routing, auth requirements, and result contents. Nothing an agent needs to call it correctly is missing.
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 100%, so the schema already documents limit, query, venue and series_ticker including the Kalshi-only semantics. The description only echoes the Kalshi keyword-scan behavior, adding little parameter meaning beyond the structured fields; baseline 3 applies.
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 ('Search open Kalshi or Polymarket markets') and names the return shape ('candidates with their best prices'), which cleanly separates it from quote/orderbook/market-detail siblings. An agent can identify the tool's role without opening the schema.
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?
It explicitly positions itself as the entry point ('Start here to find market ids') and routes to alternatives by need: get_quote/get_orderbook for live prices, get_market for resolution details. The when-to-use and which-sibling-to-pick guidance is fully spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
trading_feeARead-onlyIdempotent
Compute the venue fee for one fill at a given price and size; a pure calculation with no network calls.
Kalshi charges round_up(0.07 x M x C x P x (1 - P)) on taker fills, and
0.0175 x M x C x P x (1 - P) on maker fills where the series has maker fees;
Polymarket charges takers rate x C x p x (1 - p) and makers nothing. Use it
to price a single leg or a hypothetical fill; take a live market's fee terms
from get_quote, and use check_constraint to price a whole basket. Returns
fee, fee_per_contract, order_type and the schedule used.
| Name | Required | Description | Default |
|---|---|---|---|
| maker | No | Price a resting maker order instead of a taker order (default false). | |
| price | Yes | Fill price in dollars per contract, strictly between 0 and 1. | |
| venue | Yes | Venue: 'kalshi' or 'polymarket'. | |
| contracts | Yes | Contracts in the fill; must be positive. | |
| polymarket_rate | No | Polymarket taker fee rate for the market, from get_quote. Defaults to 0.07, the highest documented rate. Ignored for Kalshi. | |
| kalshi_maker_fees | No | Whether the Kalshi series charges maker fees, from get_quote (default false). Ignored for Polymarket. | |
| kalshi_multiplier | No | Kalshi series fee multiplier M, from get_quote's fee_schedule (default 1). Ignored for Polymarket. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, but the description adds substantive behavior beyond them: the actual fee formulas per venue, the round_up rounding on Kalshi taker fills, that maker fills are free on Polymarket, and the default rate of 0.07. These are the details that determine what output an agent gets, which annotations cannot convey.
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?
Purpose is front-loaded in the first clause, followed by formulas and then routing guidance in a logical order. The two-venue formula sentence is dense but earns its length by making the calculation unambiguous; nothing is pure filler.
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 deterministic 7-parameter calculation tool, the description supplies purpose, formulas, input provenance and sibling routing, and an output schema exists so return values need not be enumerated (though fee, fee_per_contract, order_type and schedule are listed anyway). Nothing needed to invoke it correctly is missing.
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 100%, so the baseline would be 3, but the description adds cross-tool provenance for the non-obvious parameters (polymarket_rate, kalshi_maker_fees, kalshi_multiplier all come from get_quote's fee terms) and maps the formula symbols M/C/P onto the inputs. It stops short of explaining edge behavior for the new anyOf rate parameter beyond the documented 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 opening clause names a specific verb and resource ('Compute the venue fee for one fill') and immediately scopes it as a pure calculation with no network calls. It also distinguishes itself from siblings by naming check_constraint as the basket-level alternative, so an agent can route correctly without reading either schema.
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?
It states exactly when to use it ('price a single leg or a hypothetical fill') and where to obtain its inputs ('take a live market's fee terms from get_quote'). The explicit handoff to check_constraint for whole-basket pricing covers the alternative path rather than leaving it to inference.
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.
11 tool updates
v1.2.2- Changed
check_constraint13 fields changed- changed
Input schema / $defs / QuoteInput / descriptionPrevious value: -"Quotes for one contract, in dollars. A missing ask is derived from the other side's bid."New value: +"One contract's prices in dollars per contract. A missing ask is derived from the opposite side's bid." - changed
Input schema / $defs / QuoteInput / properties / kalshi_maker_fees / descriptionPrevious value: -"Whether the Kalshi series charges maker fees."New value: +"Whether the Kalshi series charges maker fees, from get_quote." - changed
Input schema / $defs / QuoteInput / properties / kalshi_multiplier / descriptionPrevious value: -"Kalshi series fee multiplier M (default 1)."New value: +"Kalshi series fee multiplier M, from get_quote (default 1)." - added
Input schema / $defs / QuoteInput / properties / market_id / descriptionAdded value: +"Label for this contract in the result, such as its ticker or market id." - added
Input schema / $defs / QuoteInput / properties / no_ask / descriptionAdded value: +"Best NO ask in dollars (0-1). If omitted, 1 - yes_bid is used." - added
Input schema / $defs / QuoteInput / properties / no_bid / descriptionAdded value: +"Best NO bid in dollars (0-1)." - added
Input schema / $defs / QuoteInput / properties / venue / descriptionAdded value: +"Venue whose fee schedule applies: 'kalshi' (default) or 'polymarket'." - added
Input schema / $defs / QuoteInput / properties / yes_ask / descriptionAdded value: +"Best YES ask in dollars (0-1). If omitted, 1 - no_bid is used." - added
Input schema / $defs / QuoteInput / properties / yes_bid / descriptionAdded value: +"Best YES bid in dollars (0-1)." - added
Input schema / properties / contracts / descriptionAdded value: +"Contracts bought on every leg (default 1). Fees scale with size." - added
Input schema / properties / maker / descriptionAdded value: +"Price fees as resting maker orders instead of taker orders (default false). Maker fees are lower or zero, but a resting order may not fill." - added
Input schema / properties / quotes / descriptionAdded value: +"One quote per contract, in the order the relation expects: implication (A, B) where A implies B; complement and same_event (A, B); exclusivity and event_sum every outcome." - added
Input schema / properties / relation / descriptionAdded value: +"Bound to test: implication (A implies B, so P(A) <= P(B)), exclusivity (at most one outcome happens), complement (exactly one of two), same_event (one event quoted on two venues) or event_sum (exactly one of n). See list_relation_types."
- Changed
check_constraint_live7 fields changed- added
Input schema / $defs / MarketRef / descriptionAdded value: +"A live market to check, identified by venue and market id." - added
Input schema / $defs / MarketRef / properties / market_id / descriptionAdded value: +"Kalshi ticker or Polymarket market id, as returned by search_markets." - added
Input schema / $defs / MarketRef / properties / venue / descriptionAdded value: +"'kalshi' or 'polymarket'." - added
Input schema / properties / contracts / descriptionAdded value: +"Contracts bought on every leg (default 1). Fees scale with size." - added
Input schema / properties / maker / descriptionAdded value: +"Price fees as resting maker orders instead of taker orders (default false). Maker fees are lower or zero, but a resting order may not fill." - added
Input schema / properties / markets / descriptionAdded value: +"Markets to check, each {venue, market_id}, in the order the relation expects: two for implication (A then B), complement and same_event; every outcome for exclusivity and event_sum. Venues may be mixed." - added
Input schema / properties / relation / descriptionAdded value: +"Bound to test: implication (A implies B, so P(A) <= P(B)), exclusivity (at most one outcome happens), complement (exactly one of two), same_event (one event quoted on two venues) or event_sum (exactly one of n). See list_relation_types."
- Changed
fair_value2 fields changed- added
Input schema / properties / lam / descriptionAdded value: +"Pricing-wedge parameter lambda of the Wang transform. Positive values mean prices sit above the true probability, most of all for longshots. Default 0.183." - added
Input schema / properties / market_price / descriptionAdded value: +"Observed YES price in dollars, strictly between 0 and 1."
- Changed
get_market2 fields changed- added
Input schema / properties / market_id / descriptionAdded value: +"Kalshi market ticker (e.g. KXFEDDECISION-28JAN-H0) or Polymarket market id (e.g. 2589812), as returned by search_markets." - added
Input schema / properties / venue / descriptionAdded value: +"Venue: 'kalshi' or 'polymarket'."
- Changed
get_orderbook3 fields changed- added
Input schema / properties / depth / descriptionAdded value: +"Price levels per side, 1-50 (clamped). Default 10." - added
Input schema / properties / market_id / descriptionAdded value: +"Kalshi market ticker (e.g. KXFEDDECISION-28JAN-H0) or Polymarket market id (e.g. 2589812), as returned by search_markets." - added
Input schema / properties / venue / descriptionAdded value: +"Venue: 'kalshi' or 'polymarket'."
- Changed
get_quote2 fields changed- added
Input schema / properties / market_id / descriptionAdded value: +"Kalshi market ticker (e.g. KXFEDDECISION-28JAN-H0) or Polymarket market id (e.g. 2589812), as returned by search_markets." - added
Input schema / properties / venue / descriptionAdded value: +"Venue: 'kalshi' or 'polymarket'."
- Changed
list_relations3 fields changed- added
Input schema / properties / market_id / descriptionAdded value: +"Only relations that include this market id (Kalshi ticker or Polymarket id). Empty returns all." - added
Input schema / properties / spread_type / descriptionAdded value: +"Only this relation type: same_event, cross_platform, implication, exclusivity, conditional, structural, cointegration or complement. Empty returns all." - added
Input schema / properties / status / descriptionAdded value: +"Only this lifecycle status: discovered, validated, deployed, retired or invalidated. Empty returns all."
- Changed
paper_order5 fields changed- added
Input schema / properties / contracts / descriptionAdded value: +"Contracts to buy; must be positive." - added
Input schema / properties / limit_price / descriptionAdded value: +"Highest price per contract to pay, in dollars, strictly between 0 and 1; ask levels above it are skipped." - added
Input schema / properties / market_id / descriptionAdded value: +"Kalshi market ticker (e.g. KXFEDDECISION-28JAN-H0) or Polymarket market id (e.g. 2589812), as returned by search_markets." - added
Input schema / properties / side / descriptionAdded value: +"Side of the binary contract to buy: 'yes' or 'no'." - added
Input schema / properties / venue / descriptionAdded value: +"Venue: 'kalshi' or 'polymarket'."
- Changed
paper_reset1 field changed- added
Input schema / properties / confirm / descriptionAdded value: +"Must be true to erase the ledger; otherwise nothing changes."
- Changed
search_markets4 fields changed- added
Input schema / properties / limit / descriptionAdded value: +"Maximum markets to return, 1-100 (clamped). Default 20." - added
Input schema / properties / query / descriptionAdded value: +"Case-insensitive keywords matched against event titles, market titles and (on Kalshi) tickers. Empty lists open markets without a keyword filter." - added
Input schema / properties / series_ticker / descriptionAdded value: +"Kalshi only: list the open markets of this series (e.g. KXFEDDECISION) instead of searching by keyword; query is then ignored. Ignored on Polymarket." - added
Input schema / properties / venue / descriptionAdded value: +"Venue: 'kalshi' or 'polymarket'."
- Changed
trading_fee7 fields changed- added
Input schema / properties / contracts / descriptionAdded value: +"Contracts in the fill; must be positive." - added
Input schema / properties / kalshi_maker_fees / descriptionAdded value: +"Whether the Kalshi series charges maker fees, from get_quote (default false). Ignored for Polymarket." - added
Input schema / properties / kalshi_multiplier / descriptionAdded value: +"Kalshi series fee multiplier M, from get_quote's fee_schedule (default 1). Ignored for Polymarket." - added
Input schema / properties / maker / descriptionAdded value: +"Price a resting maker order instead of a taker order (default false)." - added
Input schema / properties / polymarket_rate / descriptionAdded value: +"Polymarket taker fee rate for the market, from get_quote. Defaults to 0.07, the highest documented rate. Ignored for Kalshi." - added
Input schema / properties / price / descriptionAdded value: +"Fill price in dollars per contract, strictly between 0 and 1." - added
Input schema / properties / venue / descriptionAdded value: +"Venue: 'kalshi' or 'polymarket'."
13 tool updates
v1.2.1- First observed
check_constraint - First observed
check_constraint_live - First observed
fair_value - First observed
get_market - First observed
get_orderbook - First observed
get_quote - First observed
list_relation_types - First observed
list_relations - First observed
paper_order - First observed
paper_portfolio - First observed
paper_reset - First observed
search_markets - First observed
trading_fee
TDQS
Scored across 13 tools
Most tools have clearly distinct purposes and descriptions cross-reference each other, such as offline vs live constraint checks and orderbook depth vs top-of-book quotes. However, get_quote and get_market both return best bid/ask and fee schedule, so an agent could occasionally confuse them despite the resolution-rules guidance.
All names use snake_case consistently, with predictable prefixes like get_, check_, list_, and paper_. A few tools are noun phrases such as trading_fee and fair_value rather than verb_noun, but the overall convention is coherent.
The 13 tools are well-scoped for prediction-market research and paper trading, covering discovery, pricing, constraint analysis, and ledger operations without obvious redundancy or padding.
The surface covers search, market details, quotes, order books, fees, arbitrage checks, and paper-trade entry, but paper trading only supports buys with no sell, close, or settlement operation. That is a notable lifecycle gap for a trading-oriented server.
Maintenance
Related MCP Connectors
Hosted MCP for Kalshi prediction markets: search, odds, order books, settlement rules, and trading.
Historical tick, order book and settlement data for Polymarket and Predict.fun crypto up/down markets, plus smart-money lists and backtest quotes, over a read-only MCP server.
Matched Kalshi and Polymarket markets across sports, crypto, weather, and economics over MCP.
Live Kalshi + Polymarket prediction-market data and cross-venue arbitrage spreads, one schema.
Related MCP Servers
- AlicenseBqualityCmaintenanceA simple MCP server that grabs prediction market data from polymarket, PredictIt, & Kalshi.128 npm37MIT
- AlicenseCqualityDmaintenanceMCP server that provides a unified prediction market API for multiple venues like Polymarket and Kalshi, allowing AI agents to discover markets, fetch order books, and execute trades through a single interface.3223 npm8MIT
- AlicenseAqualityCmaintenanceA read-only MCP server exposing Polymarket's public prediction-market data. Search markets, read live odds and order books, pull historical probability time-series, and inspect public wallet positions.1441 PyPIMIT
- AlicenseNot gradedqualityCmaintenanceMCP server for querying and optionally trading across prediction markets (Polymarket, Kalshi, Limitless, Manifold) through a unified API.31MIT