MCP tools reference

Generated by scripts/docgen/mcp-tools. Do not edit by hand — run make docs-regen after changing internal/mcp/tools.go.

These are the tools ibkr mcp exposes to MCP clients (Claude Code, claude-desktop, any other MCP host). Each entry lists the tool name an LLM picks against, the description the LLM reads to decide whether to invoke, and the parameter schema the LLM binds against.

15 tools total. Listed in registration order, aligned with the agent-appropriate CLI commands. Local lifecycle commands such as setup, update, mcp, daemon, and version are intentionally excluded from MCP tools.

ibkr_status

Daemon + gateway health snapshot: connection state, account, server version, members-list source, last-error, background tasks, and per-subsystem health for quote/watchlist/scanner/chain/gamma/breadth. Run this first when troubleshooting connectivity or tool-specific slowness ("why is data missing / stale / wrong-account?", "will scanner or gamma be busy?"). subsystems[].status can be ready/computing/unavailable and is more specific than the top-level gateway connection. NOT for portfolio state — use ibkr_account for cash/margin or ibkr_positions for what you own.

No parameters.

ibkr_account

Account-level financials: net liquidation, buying power, cash, margin — all in base currency. Use when the question is about the account as a whole ("how much cash?", "how much margin am I using?", "what's today's P&L?"). Includes daily_pnl (start-of-trading-day to now), with daily_pnl_unrealized and daily_pnl_realized breakdown when the gateway provides them — these are distinct from session-running unrealized/realized totals. For multi-currency accounts, also returns currency_exposure: one row per non-base currency holding with net liquidation in that currency, gateway-reported exchange rate, and the base-currency conversion. Useful for attributing P&L between underlying moves and FX moves. NOT for per-position detail — use ibkr_positions to see what you actually own.

No parameters.

ibkr_positions

Open positions: stocks and options separated, plus normalized per-underlying exposure. Use when the question is about what you own ("show me my positions", "what's my exposure to AAPL?", "how much delta do I have?"). Stock rows separate the IBKR account valuation mark (mark/valuation_mark) from market context: regular_close is the latest completed regular-session close, prior_regular_close is the close before that, and quote_price is the live/pre/post/overnight indication when IBKR supplies one. day_change/day_change_pct compare the account mark to regular_close; do not treat quote_price as the position valuation. Quote context includes data_type, feed_type, quote_price_source, quote_quality, indicative, spread_pct, day/52-week ranges, volume/avg_volume, volume_phase, quote_price_at/quote_price_as_of, warning_details, stale flags, and session_context from the trading calendar. Position money fields are explicit: market_value_ccy, unrealized_pnl_ccy, realized_pnl_ccy, and daily_pnl_ccy are in the contract currency; market_value_base, unrealized_pnl_base, realized_pnl_base, and daily_pnl_base are present when the account base currency and FX rate are known. Non-base rows carry fx_rate as BASE per CCY. daily_pnl_ccy is null when the daemon hasn't yet pre-warmed that contract's reqPnLSingle subscription or the account isn't entitled; never zero-substituted. Option legs include option_bid/option_ask, option_prev_close, and per-leg Greeks (delta/gamma/theta/vega) when IBKR delivers the model-computation tick within budget; daily_theta_base converts portfolio theta bleed to account base when every theta-bearing leg has an FX path; mark_outside_bid_ask and warning_details flag option marks away from bid/ask. The by_underlying rows include group_market_value_base, group_market_value_pct_nlv, group_dollar_delta_base, group_unrealized_pnl_base, and group_daily_pnl_base so agents do not need to re-aggregate currencies. The portfolio.exposure_base table is sorted by absolute base-currency market value and is the preferred portfolio map for multi-currency accounts. Top-level effective_delta is a cross-symbol share-equivalent diagnostic; use per-underlying effective/dollar delta for coherent exposure. NOT for cash/margin totals (use ibkr_account) and NOT for live quotes on symbols you don't hold (use ibkr_quote).

Parameters:

NameTypeRequiredDescription
symbolstringnofilter to a single underlying symbol (case-insensitive)
typestringnofilter to stock or option positions

ibkr_quote

Snapshot quotes for one or more equity / ETF symbols. Returns bid/ask/last, mark, sizes, regular_close (latest completed regular-session close), prior_regular_close, regular close change, quote_price (current live/pre/post/overnight indication), quote-vs-close change, volume, avg_volume, avg_volume_20d, avg_dollar_volume_20d, liquidity_status/source, effective data_type for the legacy selected price, feed_type when the gateway subscription state differs, quote_quality (firm/indicative/wide/prev_close/stale/missing), indicative, spread_pct, volume_phase, warning_details, and session_context when the official market calendar explains stale/frozen/missing data. Use for current quote and close context questions on stocks/ETFs ("what's SPY trading at?", "what was IBM's close and what is overnight quoting?") and quick liquidity gates; for multi-symbol trend/RS screens use ibkr_technical because it batches daily-history calculations. Off-hours, prefer regular_close for the official close that matters and treat quote_price as an indication; gate decisions on quote_quality/spread_pct/data_type/quote_price_at rather than assuming live means regular-session executable. price/price_source are retained for compatibility and mirror quote_price when an indication exists, otherwise regular_close. Stock/ETF IV tick 106 is opportunistic and often null/unavailable; for a real IV read use ibkr_chain expiry IV or an expiry strike grid. US symbols default to SMART/USD. For German/Xetra equities whose ticker collides with the US default route (for example MBG), set market: "de" or explicit exchange/currency. NOT for options (use ibkr_chain with an expiry argument), NOT for historical bars (use ibkr_history), NOT for full technical screens (use ibkr_technical), NOT for the position valuation of something you already hold (ibkr_positions carries account marks plus quote context).

Parameters:

NameTypeRequiredDescription
currencystringnooptional ISO currency override for stocks, e.g. USD or EUR
exchangestringnooptional IBKR exchange/venue override for stocks, e.g. SMART or IBIS; omit unless the default market route fails
marketstringnooptional stock routing shortcut; omit or use "us" for SMART/USD, use "de" for German/Xetra EUR equities via SMART with primary_exchange=IBIS
primary_exchangestringnooptional IBKR primary-exchange hint when routing a stock through SMART, e.g. NASDAQ or IBIS
symbolsarrayyesticker symbols, e.g. ["AAPL","MSFT"] or ["MBG"] with market="de"

ibkr_watch

Read the user's local ibkr watchlist: symbols they explicitly saved with the CLI via ibkr watch SYMBOL --add. Defaults to a decision-making monitor with close-vs-indication context: regular_close and regular close change, quote_price and quote-vs-close change, currency, day range, 52-week range, volume, average volume, 20-day average volume/dollar volume from daily bars, effective data freshness, quote_quality/spread_pct/volume_phase, warning_details, session context, and optional held-stock context. In pre/post/overnight sessions, regular_close is the close that matters; quote_price is an outside-hours indication. Set include_quotes: false only when the user explicitly wants the saved symbol list without market data (still requires a reachable daemon). This MCP tool is read-only: it does NOT add, remove, clear, create IBKR/TWS watchlists, or place trades. For ad-hoc symbols that are not saved in the watchlist, use ibkr_quote instead; for trend/RS ranking use ibkr_technical.

Parameters:

NameTypeRequiredDescription
include_positionsbooleannowhen include_quotes is true, attach compact held-stock context where available; default true
include_quotesbooleannoreturn enriched quote rows for saved symbols; default true. Set false only for the daemon-reachable list-only symbol inventory
timeout_msintegernoper-symbol quote timeout when include_quotes is true; default 5000 ms

ibkr_calendar

Official market-session calendar for supported first-release markets: U.S. cash equities (market: "us" / "us-equity"), U.S. listed options regular sessions ("us-options"), and German Xetra cash equities ("de" / "de-xetra"). Use for questions like "is the market open?", "when is the next session?", "is today a holiday or early close?", "why is this quote frozen at 1am ET?", or risk-manager context before a long market holiday weekend. NOT for prices (use ibkr_quote), NOT for broad futures/FX/bonds/Eurex/crypto calendars, and NOT for per-contract SPX/VIX global-hours nuance — v1 is official exchange calendars only and returns unknown outside embedded coverage rather than guessing from weekdays.

Parameters:

NameTypeRequiredDescription
datestringnooptional local market date YYYY-MM-DD; omit to use now
daysintegernonumber of calendar days to include in sessions (default 14, capped at 400)
marketstringnowhich official calendar to query: us/us-equity for U.S. stocks and ETFs, us-options for U.S. listed options regular sessions, de/de-xetra for Xetra cash equities

ibkr_chain

Option chain — use whenever the user asks anything about options ("AAPL puts", "this Friday's chain", "call wall on SPY"). Two shapes: **omit expiry** to get the expiry list (each row carries ATM IV, iv_source, iv_quality, DTE, and the 1-σ implied move spot × IV × √(DTE/365) — the desk-standard expected dollar move by expiration, used for earnings sizing and strike selection; daemon caches IV results, second call within ~60 s during RTH is instant; warning_details[].code=expiry_iv_unavailable means IV/move is unusable); **provide expiry** (YYYY-MM-DD) for the ATM±width strike grid. For 3-6 month screening, prefer expiry-list filters such as min_dte:90,max_dte:180 or target_dte:120 instead of all_expiries:true; filters are applied before IV fan-out. Set require_live_iv:true for preflight/readiness checks: outside U.S. option RTH it returns a fast warning instead of spending the IV fan-out budget. The strike grid leads with tradable_summary and liquidity_summary: live bid/ask leg counts, stale/model-only/subscribe-error/no-quote counts, OI coverage, options_tradable, feed_gap, liquidity_grade, ATM spread, nearest live call/put, tightest live spread, and recommended_structure_hint (stock_only, shares_or_spreads, calls_ok, untradable_chain). Treat options_tradable:false as a hard gate for option structures. The grid also has top-level data_type/session_state/feed_type plus warning_details; outside regular option hours data_type is closed even if the underlying stock feed is live. Per-leg fields include bid/ask/last, prev_close, IV, delta, OI, as_of, data_status (quoted, prev_close, model_only, no_quote, subscribe_error), iv_status, and oi_status. call_prev_close / put_prev_close are the option contract's own prior close and are stale context, not executable quotes. call_oi / put_oi are option open interest from IBKR ticks 27/28 and stay null when the gateway did not push OI within budget; never treat missing OI as zero. Off-hours, prev_close and model_only legs can be useful context but are not executable quotes. no_iv returns the fast skeleton for the expiry list (DTE only). all_expiries lifts the default 12-expiry cap (nearest 12 normally — back-half LEAPS rarely on the decision path). NOT for stock-level quotes (use ibkr_quote), NOT for historical bars (use ibkr_history).

Parameters:

NameTypeRequiredDescription
all_expiriesbooleannowhen listing expiries, return every listed date (default: nearest 12 with IV)
expirystringnoexpiry date YYYY-MM-DD; omit to list available expiries
max_dteintegernoexpiry-list filter: maximum calendar days to expiration, applied before IV fan-out
min_dteintegernoexpiry-list filter: minimum calendar days to expiration, applied before IV fan-out; useful for 3-6 month option screening
no_ivbooleannowhen listing expiries, skip ATM IV (faster)
require_live_ivbooleannoexpiry-list preflight guard; when true, skip slow IV fan-out outside U.S. option regular hours and return warning_details code live_option_iv_unavailable
sidestringnofilter strike legs (default both)
symbolstringyesunderlying ticker
target_dteintegernoexpiry-list filter: return the listed expiry closest to this calendar DTE, after min/max DTE filters when present
widthintegernostrikes ATM ± this count (default 5; 0 returns ATM only)

ibkr_history

Daily OHLCV bars for an equity / ETF symbol. Use for trend / moving-average / lookback questions ("is AAPL above its 50-DMA?", "what's the 90-day range?"). Non-trading days are skipped, so the row count is typically smaller than days. NOT for intraday bars (not exposed today), NOT for options (use ibkr_chain), NOT for the live current price (use ibkr_quote).

Parameters:

NameTypeRequiredDescription
daysintegernocalendar-day lookback (default 90); the returned row count is smaller because non-trading days are skipped
symbolstringyesequity / ETF ticker, case-insensitive (e.g. "AAPL", "spy")

ibkr_technical

One-call technical and relative-strength screen for equity / ETF symbols. Use for weekly stock screening questions such as "is IREN above its 50/200-DMA?", "rank these names vs SPY", "is this extended from the 200-DMA?", or "does this pass liquidity?" Returns price, SMA50/SMA200, percent distance from those moving averages, 21/63/126-trading-bar returns, 63/126-bar RS versus the benchmark (symbol return minus benchmark return), ATR14/ATR%, avg_volume_20d, avg_dollar_volume_20d, trend_state, data_quality, and missing_reasons. Values ending in _pct and return_* are decimal fractions (0.10 = 10%). For German/Xetra equities set market:"de"; for ETF resolver gaps use primary_exchange:"ARCA" or an explicit exchange/currency. Large batches can return partial rows with warning_details, so agents should cap screening batches and drop rows with data_quality != ok. Uses daily bars only; not for live quotes (use ibkr_quote) and not for options (use ibkr_chain).

Parameters:

NameTypeRequiredDescription
benchmarkstringnorelative-strength benchmark, default SPY
currencystringnooptional ISO currency override for symbols, e.g. USD or EUR
exchangestringnooptional IBKR exchange override for symbols, e.g. SMART or IBIS
lookback_daysintegernocalendar-day history lookback; default 420, enough for 200-DMA and 126 trading-bar returns
marketstringnooptional route for symbols, not the benchmark; omit/use us for SMART/USD, use de for Xetra/IBIS EUR equities
primary_exchangestringnooptional primary-exchange hint for symbols, e.g. ARCA for ETFs or IBIS for Xetra
symbolsarrayyesticker symbols, e.g. ["ASTS","IREN","BB"]

ibkr_scan

Run a market scanner. Three call shapes: (1) preset by name — {preset: "top-movers"} — for the configured shortcuts; (2) ad-hoc — {type: "HIGH_LAST_VS_EMA50", exchange: "STK.US.MAJOR", instrument: "STK"} for US stock breakouts, {type: "MOST_ACTIVE_USD", exchange: "STK.US.MAJOR", instrument: "STK"} for broad liquid activity, or {type: "HIGH_VS_52W_HL", exchange: "STK.EU.IBIS", instrument: "STOCK.EU"} for German/Xetra stocks; (3) empty {} — enumerates the configured presets so the agent can pick one. For common known scan codes such as HIGH_LAST_VS_EMA50, HIGH_LAST_VS_EMA200, HIGH_VS_52W_HL, MOST_ACTIVE_USD, and HOT_BY_VOLUME, call this tool directly and reserve ibkr_scan_params for unfamiliar codes, regional uncertainty, or unsupported-code/location errors. Each row is enriched with last/prev_close/change/change_pct/volume/iv/week_52_high/week_52_low plus instrument_tags and data_type/feed_type/price_at/price_as_of/volume_phase/warning_details via per-row market-data subscriptions the daemon issues automatically (IBKR's scanner protocol returns only rank+symbol). instrument_tags flags known ETFs/leveraged ETPs that IBKR may still return from stock scans; when the user asks for non-ETF single-name ideas, drop rows tagged etf or leveraged_etp. Missing tags mean unknown, not confirmed common stock. Scanner enrichment can be the slowest step because it briefly subscribes to each returned row; use small limit values and stop after one weak/noisy scan instead of stacking rescue scans. Use min_price, min_volume, min_dollar_volume, exclude_penny, and require_live to suppress micro-cap/off-hours noise before the result reaches the agent. Nil fields mean the gateway didn't deliver the corresponding tick within the enrichment window — common off-hours, and IV is nil for symbols without actively-traded options. Ad-hoc rows are capped at 50.

Parameters:

NameTypeRequiredDescription
exchangestringnoad-hoc locationCode (e.g. "STK.US.MAJOR" or "STK.EU.IBIS") — required with type when no preset is given
exclude_pennybooleannodrop enriched rows below $5, equivalent to min_price at least 5
instrumentstringnoIBKR scanner instrument for ad-hoc scans; defaults to STK for US stocks, use STOCK.EU for European stock locations such as STK.EU.IBIS
limitintegernomax rows; preset default when omitted; ad-hoc capped at 50
min_dollar_volumenumbernodrop enriched rows whose last×volume dollar-volume is below this value; rows without last or volume fail this filter
min_pricenumbernodrop enriched rows whose last price is below this value; rows without last price fail this filter
min_volumeintegernodrop enriched rows whose current share volume is below this value; rows without volume fail this filter
presetstringnopreset name from ibkr_scan with no args (e.g. "top-movers"); omit for ad-hoc or list mode
require_livebooleannodrop rows whose quote context is off-hours, stale, previous-close-only, or otherwise not a usable live quote
typestringnoad-hoc scanCode (e.g. "HIGH_LAST_VS_EMA50", "HIGH_VS_52W_HL", "MOST_ACTIVE_USD") — required with exchange when no preset is given

ibkr_scan_params

Discover the scanner catalog this IBKR gateway supports: every scanCode (the type for ad-hoc ibkr_scan) and every locationCode (exchange), plus the instrument types each scanCode applies to. Use this before composing an ad-hoc scan — the catalog varies by gateway version, market-data permissions, and region. Pass instrument: "STK" to narrow scan_types to US stocks or instrument: "STOCK.EU" for European stocks; pass include_raw_xml: true only when you need a field not surfaced in the parsed result (the XML payload is ~200 KB).

Parameters:

NameTypeRequiredDescription
include_raw_xmlbooleannoinclude the gateway's raw XML payload (~200 KB); default false
instrumentstringnofilter scan_types to those valid for this instrument (e.g. "STK", "STOCK.EU", "OPT", "ETF"); empty returns all

ibkr_breadth

S&P 500 market-breadth readings for the risk-regime dashboard. Use for questions about the market's internals — "how many S&P names are above their 50-DMA?", "is this a narrow rally?", "what's the new-high/new-low spread?". S&P 500 constituents only — NDX, RUT, sector-specific, or single-stock breadth are NOT supported. Returns three readings every call: pct_above_50dma (the percentage of S&P 500 constituents trading above their 50-day SMA — the tactical signal), pct_above_200dma (the slower companion that catches cyclical tops cleanly), and new_highs_today/new_lows_today (constituent counts of names making fresh 52-week highs/lows), plus the derived net_new_highs_pct. The classic narrow-rally pattern — SPX near highs with net_new_highs_pct near zero or negative — fires when a few mega-caps carry the index while the median name is rolling over. IBKR does not redistribute S&P DJI's S5FI or the equivalent breadth indices on retail subscriptions, so the daemon computes all three locally from the 500 constituent daily closes pulled via IBKR's historical-bar feed (method: constituent-fanout-50/200dma-hl). A once-daily refresh post-close (16:35 ET) slides each name's 200-bar window forward and updates a 252-bar rolling max/min; readers see a cached snapshot. Cold start (no cache yet) takes ~60 min — IBKR's historical-data pacing limit caps the fan-out at ~6 names/min sustained, so the response carries state: "computing" until the cache is built. Pulling 200 bars per constituent instead of 50 doesn't cost more requests; the pacing limit is per-request, not per-bar, so the cold-start budget is unchanged. After cold-start the cache persists across daemon restarts and every subsequent call is instant. Threshold derivation (green/yellow/red) is intentionally left to the consumer; the spec calls those bands user-tunable. Suggested bands: 50-DMA — >55 green / 40-55 yellow / <40 with SPX at highs red. 200-DMA — >60 green / 40-60 yellow / <40 red (calibrated to the post-Mag-7 era; StockCharts' 70/30 default fires red far too often).

Parameters:

NameTypeRequiredDescription
history_daysintegernotrailing daily-series length (default 30)
timeout_msintegernoper-snapshot wait budget when the engine has a fresh value but the wire envelope is still being assembled (default 5000 ms); does not affect the multi-minute cold-start fan-out

ibkr_gamma

Dealer-gamma market-structure snapshot for SPY, SPX, or the default SPY+SPX view. Use for questions like "where is dealer gamma?", "did the signed profile find a zero-gamma crossing?", "is the modeled book long-gamma or short-gamma?", or "where are the largest gamma concentrations?" NOT for portfolio Greeks (use ibkr_positions) and NOT for options chains/quotes (use ibkr_chain / ibkr_quote). The ready result leads with summary: primary_statement, zero_gamma_status (crossing, none_in_window, mixed, mixed_degraded, unavailable), regime, confidence, not_advice, and per-index summaries. In combined scope there is no top-level combined zero-gamma price because SPY and SPX use different price scales; read summary.per_index.SPY and summary.per_index.SPX for per-underlying spot, zero, swept range, regime, and GEX leg counts. gamma_total_abs and top_strikes are sign-agnostic concentration/magnitude diagnostics. leg_count means legs with non-zero OI-weighted GEX; priced_leg_count means legs that priced/fit IV but may not have usable OI. Non-fatal data-quality issues are in warning_details with {code, scope, severity, message, impact, action}; raw warning tokens are not part of the JSON contract. By default profile arrays are stripped to keep MCP responses compact; set include_profiles: true only when charting the sweep. First call of a NY session may return status: "computing" with progress/ETA; set wait_ms to wait. The signed zero-gamma convention is a regime hint, not advice or a trade level.

Parameters:

NameTypeRequiredDescription
forcebooleannodiagnostics-only: ignore the cached result and start a fresh compute; default false
include_profilesbooleannoinclude full sweep profile arrays for charting; default false keeps the response compact for agents and tooling
scopestringnowhich underlying(s) to compute: 'spy+spx' (combined, the default — falls back to SPY-only on SPX entitlement/data gap); 'spy' (SPY-only); 'spx' (SPX-only, errors out if SPX unreachable). Omit for the default combined view. Mirrors the CLI's --only flag.
wait_msintegernoblock up to this many ms for the result; 0 (default) returns the current status immediately

ibkr_regime

Risk-regime snapshot — single-call, non-advisory answer for "how does the market regime look today?", "is this a risk-on or risk-off tape?", "are we close to stress thresholds?", or "give me the daily-check dashboard." Use this when the user wants the market's current evidence balance across equity vol (VIX/VIX3M + VVIX), credit (HYG/SPY + official HY/IG OAS), funding stress (CP/T-bill spread), FX carry proxy, dealer gamma, and S&P 500 breadth. NOT for a trade recommendation or probability forecast. The compact MCP response leads with summary (label, cluster-level evidence, indicator_evidence, punch_line, confidence, dominant_risks, not_advice) and composite raw + cluster counts, then the eight indicator rows. Per-row fields include raw measurements, status, band, band_reason, thresholds (heuristic + pending_backtest), as_of (label, freshness/source/time/date), streak, and per-scalar *_quality provenance. warning_details gives scoped prose for unavailable/stale/computing rows with {code, scope, severity, message, impact, action}; do not parse opaque error strings when this field is present. MOVE/rates-vol is intentionally absent until a verified IBKR contract/source exists; do not infer it from ETFs or futures. Methodology prose is omitted from MCP for compactness; use spec_doc or CLI ibkr regime --explain for full threshold notes. Gamma embeds the compact ibkr_gamma envelope with profiles stripped: in combined scope use envelope.result.summary, per_index.SPY, per_index.SPX, gamma_total_abs, and top_strikes; the signed γ-zero is a regime hint, not a precise level. Expect gamma/breadth to be computing on cold starts and optional fields_missing values when a secondary scalar missed the fetch budget or an official daily file is temporarily unavailable.

No parameters.

ibkr_size

Fixed-fractional position sizing pegged to live NLV. Pure math against the account snapshot — never proposes or executes an order. Pass an optional target to also get the R-multiple (reward:risk) and breakeven win rate.

Parameters:

NameTypeRequiredDescription
entrynumberyesplanned entry price per share, quote currency
fxnumbernoquote-currency units per 1 base-currency unit (default 1.0 for same-currency trades)
lotintegernoround shares down to this multiple (default 1; use 100 for one option contract's worth of stock)
risk_pctnumbernopercent of NLV to risk (default 1.0)
sidestringnotrade direction (default long)
stopnumberyesplanned stop price per share, quote currency
symbolstringyesticker the trade plan applies to (for reporting only)
targetnumbernooptional take-profit price; when set, response includes r (reward:risk multiple) and breakeven_win_rate