ib-gateway-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ib-gateway-mcpShow my account summary and open positions."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ib-gateway-mcp
An MCP server and Python library for the Interactive Brokers TWS API, built as a companion to gnzsnz/ib-gateway-docker.
Add one service next to your IB Gateway container, and any MCP client (Claude, Cursor, and others) gets what the gateway offers: contracts, market data, history, scanners, news, fundamentals, account and P&L, and orders. Orders sit behind safety rails.
Status: early development. Version 0.1.0 is not released yet: there is no PyPI package and no published container image (releases will go to PyPI as
ib-gateway-mcpand toghcr.io/aiordanescu/ib-gateway-mcp). Run it from a clone of the repository, or build the image with the Dockerfile. Beyond the offline test suite, it has been tested against a real IB Gateway (10.45): the order suite on a paper login, and the read-only suite on both paper and live accounts.
Why
As of September 2026, the MCP options for Interactive Brokers are either hosted services that stop short of placing orders, or community servers that each cover a slice of the TWS API, many of them read-only.
ib-gateway-mcp covers the TWS API broadly (70 tools; coverage maps every API request), runs on your own infrastructure next to your own gateway, and guards agent trading with safety rails that are on by default.
Related MCP server: ibkr-mcp-server
Features
TWS API coverage, through
ib_async2.1.0:contracts: symbol search, details, qualification, option chains, market rules
market data: snapshots, and streaming quotes (with generic ticks such as option statistics, shortability, ETF NAV), market depth, tick-by-tick data, 5-second and live-updating bars
historical bars and ticks, head timestamps, histograms, trading schedules
scanners, news (providers, headlines, articles, bulletins), Refinitiv fundamentals, Wall Street Horizon events
account summary and values, positions, portfolio, P&L, executions, open and completed orders
IBKR's option calculators and chain quotes with greeks
orders: MKT, LMT, STP, STP LMT, TRAIL, TRAIL LIMIT, REL, MIT, LIT, MOC, LOC, MIDPRICE, PEG MID and PEG MKT; brackets, OCA groups, combos (BAG); the Adaptive, TWAP, VWAP, Arrival Price, Percentage of Volume and Close Price algos; good-after and good-till times, all-or-none, hidden and iceberg orders; modify, cancel, cancel-all and option exercise
financial advisor (FA) logins: FA group configuration (read and replace), model-code orders, soft dollar tiers, family codes. Allocating one order across an FA group isn't supported yet.
not yet: order conditions, cash-quantity orders and the rarer order types and algos (list)
Toolsets: register only what you need. Three profiles:
readonly(default),trading,full. The tool list is large (thereadonlyprofile's 50 tools carry about 175,000 characters of descriptions and input schemas), so a narrowerIBKR_MCP_TOOLSETSleaves more of the model's context for the task.Safety rails for orders (see Safety): preview tokens, limits, rate limits, circuit breaker, audit log, and human confirmation for live orders.
Operational awareness: a health tool that reports gateway state plainly: connection lost or restored, API in read-only mode, waiting on login or 2FA.
Library plus server: an MCP server over stdio or streamable HTTP (bearer-token auth), and an importable async Python library.
Quick start with Docker
examples/docker-compose.yml runs ib-gateway-docker on a paper login next to this server, which it builds from the clone:
git clone https://github.com/aiordanescu/ib-gateway-mcp.git
cd ib-gateway-mcp/examples
umask 077 # secrets readable by their owner only
printf 'TWS_USERID=...\n' > .env
printf '%s' '<paper password>' > tws_password.txt
openssl rand -hex 32 > mcp_auth_token.txt
sudo chown 1000 tws_password.txt # Linux only: the gateway image's user
sudo chown 10001 mcp_auth_token.txt # Linux only: this image's user
docker compose up -d # builds the ib-gateway-mcp image firstCompose mounts secret files with their owner and mode from the host, hence the chown on Linux (Docker Desktop needs none). Run it on a host you do not share. The example publishes no gateway API port: the server reaches the gateway on the compose network, and a published API port would let any local process place orders around the safety rails.
Point an MCP client at http://127.0.0.1:8000/mcp with the header Authorization: Bearer <contents of mcp_auth_token.txt>. For Claude Code:
claude mcp add --transport http ib-gateway http://127.0.0.1:8000/mcp \
--header "Authorization: Bearer $(cat mcp_auth_token.txt)"To add the server to an existing ib-gateway-docker stack, copy the ib-gateway-mcp service (with build.context pointing at your clone), its secrets, and IB_HOST set to your gateway's service name. Inside the compose network the gateway listens on 4004 (paper) and 4003 (live).
No image is published yet, so Compose builds it from the clone; docker build -t ib-gateway-mcp:local . in the clone builds it on its own. Released images will be published as ghcr.io/aiordanescu/ib-gateway-mcp. The image runs as a non-root user (uid and gid 10001), serves streamable HTTP on port 8000 (/mcp), and has a Docker healthcheck on /healthz. The compose example runs it with a read-only root filesystem, no capabilities, and the audit log on a volume at /audit. /healthz (liveness) and /readyz (200 only while the gateway connection is up) are unauthenticated and return only {"state", "ready"}.
Running from source
Needs Python 3.12 or newer and uv. The package is not on PyPI yet, so run it from a clone:
git clone https://github.com/aiordanescu/ib-gateway-mcp.git
cd ib-gateway-mcp
uv sync
IB_HOST=127.0.0.1 IB_PORT=4002 uv run ib-gateway-mcp # stdio
openssl rand -hex 32 > mcp_auth_token.txt # HTTP on 127.0.0.1:8000
IBKR_MCP_AUTH_TOKEN_FILE=mcp_auth_token.txt uv run ib-gateway-mcp --transport http --port 8000HTTP always needs a bearer token of at least 32 characters. For a quick test on the loopback address only, IBKR_MCP_ALLOW_NO_AUTH=true serves it without one.
A stdio entry for an MCP client:
{
"mcpServers": {
"ib-gateway": {
"command": "uv",
"args": ["--directory", "/path/to/ib-gateway-mcp", "run", "ib-gateway-mcp"],
"env": { "IB_HOST": "127.0.0.1", "IB_PORT": "4002", "IBKR_MCP_PROFILE": "readonly" }
}
}
}The server starts even when the gateway is down and keeps reconnecting; tools then fail with not_connected and the reason (get_health explains it).
Configuration
Everything is set with environment variables. IB_* variables describe the gateway connection, IBKR_MCP_* the server's behaviour; other names (such as a bare PROFILE) are ignored. Secrets also take a _FILE variant (Docker secrets). A blank value (VAR=) counts as unset, so the default applies.
Variable | Default | Meaning |
|
| Gateway host ( |
|
| Gateway API port. In ib-gateway-docker's network: 4004 paper, 4003 live. |
|
| API client id; keep it stable and unique on the login. |
| Default account. Without it, a login that manages several accounts has no default, and calls must name one. | |
|
| Seconds per connection attempt. |
|
| Seconds per request. |
| Comma-separated accounts allowed besides the default; empty means only the default. | |
|
|
|
| Comma-separated toolsets; overrides the profile. | |
|
| Allow order tools on live (non-paper) accounts. |
|
| Ask a human (elicitation) before each live order, cancel or FA change. |
|
| Seconds a preview token stays valid. |
| Largest order notional, in the order's own currency (no FX conversion). While set, bond and event-contract orders are refused (their notional is not quantity x price). | |
| Largest order quantity. | |
| Comma-separated symbols orders may use; empty means any. | |
| Comma-separated security types ( | |
| Comma-separated order currencies ( | |
|
| Order rate limit. |
|
| Preview rate limit (each preview sends what-if checks to IBKR). |
|
| Consecutive IBKR rejections that halt order submission. |
|
| Allow |
| JSONL audit file; unset logs to the | |
|
| Open streams allowed. |
|
| Seconds without a read before a stream is cancelled. |
|
| 1 live, 2 frozen, 3 delayed, 4 delayed-frozen. |
|
| Allow |
|
|
|
|
| HTTP listen address ( |
|
| HTTP listen port. |
| Bearer token, at least 32 characters. Required for HTTP. | |
|
| Allow HTTP without a token, on a loopback address only. |
|
| Log level (logs go to stderr). The audit logger stays at INFO. |
Command-line flags (--transport, --host, --port, --profile, --toolsets, --log-level) override the environment.
Profiles and tools
Profile | Toolsets | Tools |
| ops, contracts, market_data, history, scanners, news, fundamentals, account, options | 50 |
| readonly + orders | 60 |
| trading + advisor, admin | 70 |
Every tool, with its parameters: docs/tools.md. Streams (subscribe_*) return a subscription id; get_subscription_data reads it, unsubscribe stops it, and streams nobody reads are cancelled after IBKR_MCP_SUBSCRIPTION_IDLE_TTL.
Safety
Read-only by default. The
readonlyprofile registers no order, advisor or admin tool. Every write path (orders, cancels, FA changes, admin settings) also passes the trading gate: the gateway is connected, a write toolset is enabled, the login's accounts are known and one of them is allowed, no live account is in scope unlessIBKR_MCP_ALLOW_LIVE=true, and the gateway's API is not read-only. For a deployment that must never trade, turn on the gateway's own Read-Only API setting too (READ_ONLY_API=yesin ib-gateway-docker): it's the only guarantee enforced by IBKR's software rather than this server.Paper unless told otherwise. Paper and live are told apart from the account ids (paper ids start with
D). Order tools refuse live accounts unlessIBKR_MCP_ALLOW_LIVE=true.Two-step orders. A
preview_*tool runs IBKR's what-if check (margin, commission) and the limits, and returns a token: a single-use, expiring key (192 random bits) to the exact order and account, which stay on the server.submit_ordertakes only the token and checks everything again.A human confirms live actions. With
IBKR_MCP_LIVE_CONFIRM=true(the default), submitting, cancelling or changing FA configuration on a live account asks the person at the client through MCP elicitation. The model can't answer for them. The question is built by the server; anything the model wrote into it (a model code, a tier or FA group name, a reason) is quoted and must be one line of plain text.Limits: notional, quantity, symbols, security types and currencies, order and preview rate limits, and a circuit breaker that halts submission after consecutive rejections until a human resets it; with an audit file it stays open across restarts.
get_healthshows the breaker. A notional check that had to use delayed, frozen or previous-close prices says so in the preview and in the confirmation.Audit log of every preview, submit, modify, cancel, exercise, FA change, billed snapshot, circuit-breaker reset, admin change (server log level, display group) and refusal at the trading gate (JSONL, no secrets). The server logs its safety configuration at start-up and warns about risky combinations. A failed write to the audit file is logged at ERROR and does not stop the order, so watch the logs, and keep the file on a volume the server's user can write (start-up already fails when it can't).
Caveats:
Clients without form elicitation can't confirm live orders, so live submits, cancels and FA changes are refused there (fail closed). Paper orders, cancels and FA changes never ask.
Resetting the circuit breaker always asks a human, on paper too, through
reset_circuit_breakerin the admin toolset (thefullprofile). Without elicitation or that toolset: with no audit file, restart the server; with one, stop the server, delete the.breaker.jsonfile next to the audit file (audit.breaker.jsonforaudit.jsonl), and start it again.The rails assume the model reaches the gateway only through this server. An agent that can open the gateway's API port itself, or restart this server and edit its files, can go around them; keep the API port unpublished and the server's host and volumes out of the agent's reach.
Paper logins see market data only with sharing. Enable market data sharing with the paper account in IBKR's settings, or use delayed data (
IBKR_MCP_MARKET_DATA_TYPE=3).Client ids matter. An API client can modify and cancel only the orders it placed itself.
IB_CLIENT_IDdefaults to 80; give every API client on the login (this server, other bots, notebooks) its own stable id.0is refused, because orders entered by hand in TWS bind to client 0.get_open_ordersmarks other clients' and manual orders as notmodifiable, andget_order_statusreads their status from IBKR each time.preview_cancel_all_orders(scope="global")is IBKR's global cancel: every working order on the login, including other API clients' and manual orders. It's refused unlessIBKR_MCP_ALLOW_GLOBAL_CANCEL=trueand the allowlist covers every managed account.Preview tokens live in memory; a restart invalidates them.
Troubleshooting
Orders fail with error 321, or the gateway shows "API client needs write access". The gateway's API is read-only:
get_healthreportsapi_read_only: trueand the trading gate stays closed. SetREAD_ONLY_API=noin ib-gateway-docker, or untick Read-Only API in the gateway's own settings (Configure > Settings > API > Settings, over VNC in ib-gateway-docker). IfREAD_ONLY_APIis alreadynoand the error persists, the gateway can still hold the old setting in its settings volume: setREAD_ONLY_API=yes, restart the gateway, then set it back tonoand restart it again. The server reconnects by itself after a gateway restart, which clearsapi_read_only; after a change in the gateway's settings alone, restart the server. While the API is read-only, IBKR also refusesget_completed_orders(error 321, at once), andget_open_ordersfor this server's own orders reads every client's orders and filters them, saying so innote.Quotes fail with error 10089 although delayed data is selected. IBKR offers the login no delayed data for that instrument either (IB Gateway 10.45 does this for some instruments on paper logins); historical bars can still work. Subscribe to the exchange's data, or share market data with the paper account.
Library
The services behind the tools are an async Python library:
import asyncio
from ib_gateway_mcp import ContractSpec, Gateway, Settings
from ib_gateway_mcp.models import OrderSpec, QuoteStreamData
async def main() -> None:
# Write access (orders, FA, admin) follows the toolsets, as for the server.
settings = Settings(ib_port=4002, profile="trading")
async with Gateway(settings) as gw:
await gw.wait_connected(timeout=15)
print(gw.ops.health().state)
spy = ContractSpec(symbol="SPY")
quotes = await gw.market_data.quotes([spy])
print(quotes.quotes[0].last)
preview = await gw.orders.preview_order(
OrderSpec(contract=spy, action="BUY", quantity=1, order_type="LMT", limit_price=1.00)
)
print(preview.summary, preview.what_if)
# result = await gw.orders.submit(preview.token)
sub = await gw.market_data.subscribe_quotes(spy)
async for data in gw.market_data.watch(sub.subscription_id, QuoteStreamData):
print(data.quote.last)
break
await gw.market_data.unsubscribe(sub.subscription_id)
asyncio.run(main())Services: gw.ops, gw.contracts, gw.market_data, gw.history, gw.scanners, gw.news, gw.fundamentals, gw.account, gw.options, gw.orders, gw.advisor, gw.admin. They take and return the pydantic models in ib_gateway_mcp.models and raise the errors in ib_gateway_mcp.errors (all derived from IbGatewayMcpError). Error messages are written for the MCP tools and name them where they point to a next step; docs/tools.md gives the service method behind each tool. Contract resolution (qualify, qualify_details, qualify_many) is shared by every service; gw.contracts has the lookups proper. The library applies the same account scope, trading gate and order rails as the server; gw.ib is a raw ib_async.IB escape hatch that bypasses them.
Development
uv sync
uv run ruff check . && uv run ruff format --check . && uv run mypy && uv run pytest
uv run python scripts/gen_docs.py # regenerate docs/tools.md after changing a toolUnit, MCP and end-to-end tests run against fakes (a mock ib_async.IB, and a fake TWS socket server on localhost) and never reach a real gateway. Two integration suites run only on demand, never in CI:
IB_HOST=... IB_PORT=... uv run pytest -m live_readonly: read-only probes of every read toolset.IB_HOST=... IB_PORT=... IB_ACCOUNT=DU... uv run pytest -m paper: order round trips; they refuse to run unless every account on the login is a paper account.
The contributor guide, with the architecture, the test tiers and the safety invariants every change keeps, is CLAUDE.md. See also CONTRIBUTING.md, SECURITY.md and CHANGELOG.md.
Disclaimer
This project is not affiliated with, endorsed by, or supported by Interactive Brokers. "Interactive Brokers", "IBKR", "IB Gateway" and "TWS" are trademarks of their owners and are used here only to name the software this project works with. Trading involves the risk of loss, and software that places orders can place wrong ones. Nothing here is investment advice. Use it at your own risk; the software comes with no warranty (see the license), and you are responsible for every order it places on your accounts.
License
Available Tools
50 toolscalculate_implied_volatilityImplied volatility calculatorARead-only
Compute an option's implied volatility from a given option price, with IBKR's model.
`contract` must be one option (sec_type OPT or FOP with symbol, expiry, strike and
right, or its con_id; futures options also need their exchange, e.g. CME). Returns
`implied_vol` as a decimal (0.25 = 25%) and the greeks at that volatility (delta,
gamma, vega, theta, dividend present value). Useful for what-if pricing: pass a
hypothetical option or underlying price. Nothing is stored or streamed.
Errors: invalid_request when the contract is not an option or no volatility fits the
prices (e.g. an option price below intrinsic value); not_found or ambiguous_contract
when the option cannot be resolved (get_option_chain lists expiries and strikes);
request_timeout when IBKR does not answer within 4 seconds; ib_api_error if IBKR
refuses (it may want market data permissions for the option and its underlying).
| Name | Required | Description | Default |
|---|---|---|---|
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| option_price | Yes | Option price per share (not multiplied by 100), e.g. 5.20. | |
| underlying_price | Yes | Underlying price to assume, e.g. the stock's current price. |
Output Schema
| Name | Required | Description |
|---|---|---|
| greeks | Yes | IBKR's full model output at that volatility: delta, gamma, vega, theta... |
| contract | Yes | The option the calculation ran for. |
| implied_vol | Yes | Implied volatility, annualized, as a decimal (0.25 = 25%). |
| option_price | Yes | Option price the volatility was implied from. |
| underlying_price | Yes | Underlying price the calculation assumed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint and openWorldHint already present, the description adds meaningful behavioral details: it promises 'nothing is stored or streamed,' describes the return format (decimal implied_vol plus greeks), and enumerates error scenarios including a 4-second timeout and potential market-data permission issues. This goes well beyond the annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with the one-line purpose first, followed by constraints, return behavior, usage context, and a compact error list. Every sentence carries information; the error list is internally organized with error-name to cause, so 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 three-parameter calculation tool with an output schema, this description is unusually complete: it specifies exact contract requirements, return format, usage scenario, non-persistence, timeout, and permission-related failures. The only minor omission is assumptions of the IBKR model, but that is a named model rather than a behavioral gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all three parameters (100% coverage), so the baseline is 3. The description enriches the contract parameter significantly by requiring sec_type OPT or FOP and adding that futures options need an exchange (e.g. CME), and it clarifies the meaning of option_price as per-share. This extra guidance justifies a score above baseline.
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 opens with a specific verb ('Compute') and resource ('option's implied volatility'), clarifies the input ('from a given option price'), and notes the IBKR model. It is clear and not tautological, but it does not explicitly contrast with the sibling calculate_option_price, so differentiation is left to the reader.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit context: it is 'useful for what-if pricing' and requires the contract to be a single option, with futures options needing an exchange. It also points to get_option_chain when an option cannot be resolved, but does not explicitly state when to prefer calculate_option_price, so some inference remains.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
calculate_option_priceOption price calculatorARead-only
Compute an option's theoretical price and greeks at a given volatility, with IBKR's model.
`contract` must be one option (sec_type OPT or FOP with symbol, expiry, strike and
right, or its con_id; futures options also need their exchange, e.g. CME). Returns
`option_price` per share (multiply by the contract multiplier for the premium) and
the greeks (delta, gamma, vega, theta, dividend present value). Useful for
scenarios: vary volatility or underlying_price.
Errors: invalid_request when the contract is not an option, volatility looks like a
percent (above 10), or IBKR computed no price; not_found or ambiguous_contract when
the option cannot be resolved; request_timeout when IBKR does not answer within 4
seconds; ib_api_error if IBKR refuses (e.g. missing market data permissions).
| Name | Required | Description | Default |
|---|---|---|---|
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| volatility | Yes | Annualized volatility as a decimal: 0.25 means 25% (not 25). | |
| underlying_price | Yes | Underlying price to assume, e.g. the stock's current price. |
Output Schema
| Name | Required | Description |
|---|---|---|
| greeks | Yes | IBKR's full model output at that price: delta, gamma, vega, theta... |
| contract | Yes | The option the calculation ran for. |
| volatility | Yes | Volatility the price assumes, as a decimal. |
| option_price | Yes | Theoretical option price, per share (unmultiplied). |
| underlying_price | Yes | Underlying price the calculation assumed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description adds substantial behavioral context: the pricing model is IBKR's, the return is per share with a multiplier caveat, errors are enumerated (invalid_request, not_found, ambiguous_contract, request_timeout with a 4-second limit, ib_api_error for missing permissions). This goes well beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the primary purpose, then moves logically through contract constraints, output format, use-case scenarios, and error handling. Every sentence adds operational value, and the error enumeration is compact rather than rambling.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the fact that an output schema exists, the description is complete: it covers contract requirements, output units and greeks, the multiplier adjustment, intended scenario use, and all realistic failure modes. An agent has everything needed to invoke 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 fully documents contract, volatility, and underlying_price. The description mostly restates the contract requirements and the decimal-volatility convention already present in the schema, adding limited new meaning beyond the percent-above-10 error behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (Compute), a precise resource (option's theoretical price and greeks), and the condition (at a given volatility, with IBKR's model). This clearly differentiates it from the inverse sibling calculate_implied_volatility, since this tool takes volatility as an input rather than solving for it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states clear context for use: pricing scenarios where you vary volatility or underlying_price. It provides detailed contract constraints and error conditions, but it does not explicitly say when NOT to use this tool or direct the agent to an alternative like calculate_implied_volatility, so it stops short of full exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_account_summaryAccount summaryARead-only
Return an account's headline balances: net liquidation, cash, buying power, margin.
Headline fields (in `base_currency`): net_liquidation, total_cash_value, settled_cash,
buying_power, available_funds, excess_liquidity, equity_with_loan_value,
gross_position_value, init/maint margin requirement, sma, cushion (fraction), leverage
and day_trades_remaining (-1 = unlimited). `values` holds every summary row,
including per-currency ledger rows (CashBalance, UnrealizedPnL... with currency BASE
for converted totals). IBKR refreshes the summary about every 3 minutes, and right
after trades. No market-data subscription needed.
Errors: invalid_request lists the valid tags when a tag is unknown.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Only return these tags in `values`, e.g. ['NetLiquidation', 'BuyingPower']. Omit for every row. The headline fields are always filled. | |
| account | No | IBKR account id, e.g. DU1234567. Omit to use the default account; list_accounts shows which accounts are allowed. |
Output Schema
| Name | Required | Description |
|---|---|---|
| sma | No | Special memorandum account (Reg T). |
| as_of | Yes | When this server read the values (UTC). |
| values | No | Every summary row (or the ones matching tags), including per-currency rows. |
| account | Yes | |
| cushion | No | Excess liquidity / net liquidation, as a fraction (0.25 = 25%). |
| leverage | No | Gross position value / net liquidation. |
| buying_power | No | What can be bought on margin now. |
| settled_cash | No | Settled cash (cash accounts). |
| base_currency | No | Currency the headline amounts are in. |
| available_funds | No | Equity with loan value minus initial margin. |
| init_margin_req | No | Initial margin requirement. |
| net_liquidation | No | Total account value (equity). |
| excess_liquidity | No | Equity with loan value minus maintenance margin; <0 risks liquidation. |
| maint_margin_req | No | Maintenance margin requirement. |
| total_cash_value | No | Cash, including unsettled. |
| day_trades_remaining | No | Day trades left under the pattern-day-trader rule; -1 means unlimited. |
| gross_position_value | No | Absolute market value of all positions. |
| equity_with_loan_value | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=true and openWorldHint=true. The description goes well beyond by specifying refresh cadence (~3 minutes and after trades), that no market-data subscription is required, that `values` contains every summary row including per-currency ledger rows, and the invalid_request error behavior listing valid tags. This is rich behavioral 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?
The description is dense but purposeful: purpose and field list come first, followed by structure, refresh, subscription, and error details. While somewhat long, each sentence contributes useful information. The structure could be slightly tightened with headings, but it's well organized.
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 tool with no required parameters and an existing output schema, the description covers purpose, exact fields, return structure, refresh behavior, subscription requirements, and error handling. An agent has everything needed to invoke 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 the schema already documents both `tags` and `account` with descriptive text. The description does not add parameter-level meaning beyond schema; its mention of 'headline fields are always filled' relates to behavior, not parameter semantics. 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 clearly states the verb and resource: 'Return an account's headline balances' and enumerates the specific fields returned. It doesn't explicitly contrast with sibling tools like get_account_values or get_portfolio, but the scope is precise enough to understand what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. The only contextual note is 'No market-data subscription needed,' which is a benefit, not a selection criterion. The description never says 'use this for headline balances' or names a sibling to avoid.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_account_valuesAccount valuesARead-only
Return the full key/value account data: every tag IBKR reports, per currency.
Use it for details the summary lacks (per-currency cash, accrued interest, segment
values with -C/-S suffixes, currency exchange rates...). Each row has the raw `value`
and, when numeric, `amount`. Values update about every 3 minutes or on change.
With `model_code` (financial advisors) the values of that model are fetched once.
Default limit 200, maximum 1000; `truncated` says whether more matched.
Errors: invalid_request lists the valid tags when a tag is unknown.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Only these tags (case-insensitive), e.g. ['CashBalance']. | |
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| account | No | IBKR account id, e.g. DU1234567. Omit to use the default account; list_accounts shows which accounts are allowed. | |
| currency | No | Only values in this currency, e.g. USD; BASE for converted totals. | |
| model_code | No | Financial-advisor model code, to scope the result to one model portfolio. Omit for the whole account (normal for non-advisor accounts). |
Output Schema
| Name | Required | Description |
|---|---|---|
| as_of | Yes | When this server read the values (UTC). |
| total | Yes | How many values matched the filters before the limit. |
| values | Yes | |
| account | Yes | |
| truncated | No | True when the result was cut to the limit. |
| model_code | No | Advisor model code, when one was given. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, but the description adds substantial behavioral context: values update every ~3 minutes or on change, default and maximum limits (200/1000), truncated flag semantics, repeated fetching behavior with model_code, and error behavior with invalid_request listing valid tags. These details go well beyond the annotations and schema, with no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well organized, leading with the core purpose, then use cases, update cadence, limits, and errors. Each sentence adds distinct information and none feel redundant with the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and the input schema already covers parameters, the description still provides essential behavioral context: cadence, limits/truncation, error handling, and use-case differentiation from get_account_summary. An agent has enough information to select and invoke the tool correctly in most scenarios.
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 baseline is 3. The description adds meaningful value on top: it explains the row structure (raw value and numeric amount), clarifies model_code fetches the model's values once, and connects the limit/truncation semantics. This lifts it above the baseline, though most parameter-level detail still comes from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Return the full key/value account data: every tag IBKR reports, per currency.' It also distinguishes this tool from the sibling summary tool, so an agent can reliably tell get_account_values apart from get_account_summary 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?
The description explicitly tells when to use this tool: 'Use it for details the summary lacks' and gives concrete examples such as per-currency cash, accrued interest, and segment values. It also references the alternative get_account_summary and explains special cases like model_code for financial advisors, giving clear contextual guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_completed_ordersCompleted ordersARead-only
List recently filled or cancelled orders, newest first, with IBKR's completion status.
IBKR decides how far back this reaches (the current and recent sessions). Use
get_executions for fill prices and commissions. Default limit 100, maximum 1000.
Errors: ib_api_error 321, at once, when the gateway's API is read-only (get_health:
api_read_only), which refuses this request; get_executions still lists recent fills.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| account | No | IBKR account id, e.g. DU1234567. Omit to use the default account; list_accounts shows which accounts are allowed. | |
| api_only | No | Only orders placed through the API (leave out manual TWS ones). |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | How many orders matched before the limit. |
| orders | Yes | |
| account | Yes | |
| truncated | No | True when the result was cut to the limit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses valuable behavioral traits: newest-first ordering, IBKR-limited historical range, default/maximum limits, and the specific error (ib_api_error 321) when the gateway is in read-only mode. It also notes that get_executions still works in that scenario. These details go well beyond the annotation's simple read-only flag.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the core purpose. Each sentence adds value: purpose, data-range limitation, alternative tool, and error behavior. Slight redundancy exists where the limit defaults were repeated from the schema, but the overall structure is tight and informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and the input schema fully documents all three optional parameters, the description covers everything needed for correct selection and invocation: what the tool returns, ordering, data-range constraints, default/cap values, an explicit alternative, and a failure mode. No critical gap remains for an agent to call this tool 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%, with each parameter (limit, account, api_only) already well described in the schema, including defaults, caps, and behavior. The description adds only minor redundancy ('Default limit 100, maximum 1000') without introducing new parameter semantics, so the baseline 3 is appropriate.
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 uses a specific verb+resource combination: 'List recently filled or cancelled orders, newest first, with IBKR's completion status.' This clearly identifies what the tool returns and its ordering, distinguishing it from get_executions (which reports fill prices) and get_open_orders (open orders). The scope is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly directs agents to 'Use get_executions for fill prices and commissions,' providing a clear alternative for a related but distinct need. It also explains the data-range limitation ('IBKR decides how far back this reaches') and the read-only error scenario with get_executions as a fallback, giving concrete guidance on when to choose this tool vs its sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_connection_infoConnection detailsARead-only
Return technical details of the API session: endpoint, client id, API versions.
Includes the negotiated server version, the API version range this client speaks,
whether open and completed orders were synced (`orders_synced`), when the session
started, and traffic counters. Works when disconnected too (the session fields are
then null).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| host | Yes | |
| port | Yes | |
| client_id | Yes | |
| connected | Yes | |
| bytes_sent | No | |
| messages_sent | No | |
| orders_synced | No | Whether this session loaded the open and completed orders. |
| bytes_received | No | |
| server_version | No | Negotiated TWS API server version. |
| connected_since | No | |
| ib_async_version | Yes | |
| messages_received | No | |
| client_version_range | Yes | API versions this client speaks, 'min..max'. |
| server_package_version | Yes | Version of ib-gateway-mcp. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description adds useful behavior beyond that: it lists what data is included and discloses that when disconnected the session fields are null. This gives the agent a realistic expectation of the result even in an offline state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the first sentence states the core purpose, and the second sentence efficiently enumerates the returned fields. No words are wasted, and every sentence adds meaningful information.
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 read-only tool with an output schema present, this description is complete. It explains the purpose, the returned content, and the edge case of being disconnected, so an agent has everything needed to select and invoke the tool 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?
The tool has no parameters, so there is no parameter semantics to clarify. The description appropriately focuses on what the tool returns instead, which is the correct use of description space here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return') and a specific resource ('technical details of the API session'), then lists concrete fields like endpoint, client id, and API versions. This clearly distinguishes it from sibling get_* tools such as get_user_info or get_server_time, so an agent can identify its purpose 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?
The description gives clear context by stating the tool returns session-level technical details and explicitly notes it 'works when disconnected too.' It does not name sibling alternatives or state when not to use it, but for a zero-parameter diagnostic tool this level of context is largely sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_contract_detailsContract detailsARead-only
Return IBKR's full contract details for every instrument a spec matches.
For each contract: identifiers (con_id, local symbol, trading class, multiplier),
long name (`contract.description`), industry and category, stock type, the
exchange time zone, trading and liquid (regular-hours) sessions for about the next
week with closed days, min tick, size increments, valid exchanges with their market
rule ids (same order; see get_market_rule), accepted order types, ISIN and other
security ids, the underlying of a derivative, and bond terms for bonds.
The contract may be partial: symbol + sec_type FUT + exchange lists every future expiry.
Derivatives are sorted by expiry, strike and right; `limit` defaults to 20 (cap 200),
`total` and `truncated` say how many matched. Broad option specs are slow and
throttled by IBKR: use get_option_chain for expiries and strikes, then look up single
options. Futures and indexes need their listing exchange (CME, CBOE...), not SMART;
set include_expired for expired futures. Errors: not_found for an unknown
instrument; invalid_request for combos (BAG).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | Distinct contracts IBKR matched before the limit. |
| contracts | Yes | |
| truncated | No | True when the result was cut to the limit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/openWorldHint annotations, the description discloses that partial contracts can match multiple instruments, derivatives are sorted by expiry/strike/right, limit defaults to 20 with a cap of 200, and total/truncated report match counts. It also surfaces throttling for broad option specs and names expected error types.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The text is dense but every sentence earns its place: purpose, output fields, matching behavior, performance caveats, and errors are arranged logically. It is front-loaded with the core purpose and returns info before moving into caveats and alternatives.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers what the tool returns, how partial specs behave, pagination semantics, performance considerations, exchange prerequisites, and error cases. With a rich input schema and output schema present, nothing essential for invoking the tool 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 schema already documents the parameters thoroughly. The description adds meaningful value on top: it explains partial-spec matching (e.g., symbol + sec_type FUT + exchange lists every future expiry), gives the concrete limit default/cap, and clarifies include_expired's role in a usage context.
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 opens with 'Return IBKR's full contract details for every instrument a spec matches,' a specific verb and resource. It then enumerates the concrete returned fields (identifiers, sessions, min tick, accepted order types, bond terms), making the scope unmistakable and clearly distinct from sibling tools like search_symbols or qualify_contract.
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 gives direct routing advice: for broad option specs, 'use get_option_chain for expiries and strikes, then look up single options.' It also warns that futures and indexes need their listing exchange rather than SMART, recommends include_expired for expired futures, and states that combos (BAG) are rejected with invalid_request. This is explicit when/how-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_depth_exchangesMarket depth exchangesARead-only
List the exchanges that offer market depth (level 2 order book), per security type.
Each row gives the exchange, security type, listing exchange and IBKR's depth service type (Deep or Deep2). Check it before subscribing to market depth. Depth itself needs a separate depth data subscription at IBKR; this list does not. The list is static and cached for the gateway session.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| exchanges | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the description only needs to add context. It does so by stating 'The list is static and cached for the gateway session' and 'this list does not' subscribe to depth. This helps the agent understand the data is not live and the tool has no side effects beyond returning a cached list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two tight sentences. The first sentence delivers the core purpose. The second adds field details, usage timing, the subscription distinction, and caching behavior—all without waste. Information is front-loaded and each sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters, a defined output schema, and readOnly/openWorld annotations, the description covers all essential context: what the tool returns, the fields in each row, when to use it, and its static/cached nature. No critical details are missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so the baseline is 4. No parameter explanation is needed, and the description correctly avoids inventing any. The description's field-level details (exchange, security type, listing exchange, depth service type) apply to the output, which the output schema 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 description begins with a specific action and resource: 'List the exchanges that offer market depth (level 2 order book), per security type.' It clearly differentiates from subscription tools by framing itself as a reference list to consult before subscribing. The title and description align without tautology.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: 'Check it before subscribing to market depth.' It also clarifies what this tool does not do: 'Depth itself needs a separate depth data subscription at IBKR; this list does not.' It implies the alternative (subscribe_market_depth) but does not name it explicitly, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_executionsExecutionsARead-only
List the account's executions (fills), newest first, with commission and realized P&L.
Covers the current trading day only (up to 7 days if the gateway's trade-log setting
allows); older trades are not available through the API. `commission` is null until
IBKR reports it (usually within seconds of the fill); realized_pnl is 0 for fills
that opened a position. Default limit 100, maximum 1000.
| Name | Required | Description | Default |
|---|---|---|---|
| side | No | Only buys (BUY) or sells (SELL). | |
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| since | No | Only executions at or after this time (ISO 8601; no zone = UTC). | |
| symbol | No | Only this symbol, e.g. AAPL. | |
| account | No | IBKR account id, e.g. DU1234567. Omit to use the default account; list_accounts shows which accounts are allowed. | |
| sec_type | No | Only this security type, e.g. STK or OPT. |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | How many executions matched before the limit. |
| account | Yes | |
| truncated | No | True when the result was cut to the limit. |
| executions | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only signal read-only and open-world behavior, so the description carries the burden of explaining field semantics. It adds valuable behavior: commission is null until IBKR reports it, realized_pnl is 0 for position-opening fills, and the default/maximum limit are concretely specified. This goes well beyond the annotations and introduces no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is organized into short, focused sentences: purpose first, then time coverage, then field semantics and limits. Every sentence earns its place, and there is no filler or redundant restatement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that the output schema exists and all parameter schemas are already descriptive, the description supplies the remaining contextual essentials: data availability window, null/zero value semantics, and limit behavior. An agent has enough information to select and invoke this tool 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?
All six parameters are already documented in the input schema, so the baseline is 3. The description adds the specific default limit of 100 and maximum of 1000, which the schema leaves unspecified, providing meaningful extra value for the limit parameter.
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 the exact resource ('executions (fills)') and the verb 'List', and it specifies ordering ('newest first') and the key returned fields ('commission and realized P&L'). This makes it clearly distinct from sibling order-status tools like get_open_orders and get_completed_orders.
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 gives clear context: it covers the current trading day only, with a possible 7-day extension depending on the gateway setting, and explicitly states that older trades are not available through the API. It does not name a sibling alternative, so it stops short of full when-to-use-vs-alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_fundamental_dataFundamental reportARead-only
Fetch a Refinitiv fundamentals report for a stock, as XML.
Deprecated by IBKR: reqFundamentalData was removed in TWS API 10.50. It still works on
IB Gateway stable (10.45); newer gateways may refuse it. Stocks only (sec_type STK).
Needs the Refinitiv (Reuters) fundamentals data subscription on the IBKR login.
Whitespace between XML tags is removed; long reports are cut at max_chars (default
50000, max 200000) with truncated=true, so prefer ReportSnapshot or ReportsFinSummary
over the large statement and ownership reports.
Errors: not_found (unknown stock, or IBKR has no such report for it, error
430), ambiguous_contract (give primary_exchange or con_id), ib_api_error 10358 (no
fundamentals subscription), invalid_request (not a stock), request_timeout (a newer
gateway may not answer at all). For key ratios without this report, use
subscribe_quotes with the fundamental_ratios generic tick.
| Name | Required | Description | Default |
|---|---|---|---|
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| max_chars | No | Longest XML report to return, in characters (at most 200,000); a longer report is cut and truncated is true. | |
| report_type | Yes | ReportSnapshot: company overview, key ratios, forecast summary. ReportsFinSummary: per-period EPS, revenue, dividends. ReportsFinStatements: income statement, balance sheet, cash flow (large). ReportsOwnership: holders (large). RESC: analyst estimates. CalendarReport: company calendar (often unavailable). |
Output Schema
| Name | Required | Description |
|---|---|---|
| xml | Yes | The report as XML (whitespace between tags removed). Not well-formed when truncated is true. |
| contract | Yes | The stock the report is about. |
| truncated | No | True when the result was cut to the limit. |
| report_type | Yes | The report type that was requested. |
| total_chars | Yes | Length of the whole report before truncation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses several non-obvious behaviors beyond the readOnlyHint annotation: deprecation and gateway compatibility, whitespace removal, truncation at max_chars with truncated=true, and a full error taxonomy including ib_api_error 10358 and request_timeout. This is rich behavioral context the annotations alone do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries load: core purpose first, then deprecation, subscription requirement, output behavior, error handling, and alternative tool. The structure is logical and front-loaded, and no sentence is 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 complex, deprecated, subscription-gated tool, the description covers return format, truncation, error conditions, prerequisites, and alternatives. Combined with the rich input schema and output schema, an agent has everything needed to call this correctly and handle failures.
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%, but the description adds real parameter-level value: it explains max_chars truncation behavior and default/max values, recommends smaller report types in relation to that limit, and tells the agent to resolve ambiguous_contract by supplying primary_exchange or con_id. This goes beyond what the schema states, though the schema already documents the parameters well.
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?
Opens with a specific verb-resource pair: 'Fetch a Refinitiv fundamentals report for a stock, as XML.' It explicitly names the data source (Refinitiv), the scope (stocks), and the output format (XML), and clarifies it is a read-only report tool, distinct from the many historical/subscription siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when/when-not guidance: stocks only (sec_type STK), requires the Refinitiv subscription, is deprecated on newer gateways, and for key ratios recommends subscribe_quotes with fundamental_ratios instead. It even advises preferring ReportSnapshot or ReportsFinSummary over the large report types, giving an agent actionable selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_head_timestampEarliest historical dataARead-only
Return the earliest date and time IBKR has historical data for an instrument.
Use it before long get_historical_bars requests, or when they come back empty, to
learn how far back the data goes for this `what_to_show`. Needs market-data
permissions for the instrument; counts toward IBKR's historical-data limits.
Errors: not_found (no such contract, or no data of that type).
| Name | Required | Description | Default |
|---|---|---|---|
| use_rth | No | True: regular trading hours only. False: include pre-market, after-hours and overnight data. | |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| what_to_show | No | Data the values are built from. TRADES (not for forex), MIDPOINT, BID, ASK, BID_ASK (counts double for pacing), ADJUSTED_LAST (split/dividend adjusted; end must be empty), HISTORICAL_VOLATILITY and OPTION_IMPLIED_VOLATILITY (stocks, indexes), REBATE_RATE and FEE_RATE (stock loan), YIELD_BID, YIELD_ASK, YIELD_BID_ASK, YIELD_LAST (bonds), AGGTRADES (crypto). | TRADES |
Output Schema
| Name | Required | Description |
|---|---|---|
| use_rth | Yes | |
| contract | Yes | |
| earliest | Yes | Earliest available data (UTC). |
| what_to_show | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description is not required to restate safety. It adds valuable behavior beyond the annotation: the tool 'Needs market-data permissions', 'counts toward IBKR's historical-data limits', and may fail with not_found for missing contracts or data types. This is useful operational context that annotations do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description has no filler: one sentence for the core result, one for usage context, and one for errors. The most important information is front-loaded, and every sentence earns its place by conveying permissions, rate-limit impact, or failure modes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich input schema (especially ContractSpec), the presence of an output schema, and readOnlyHint, the description covers what an agent needs: the purpose, when to call it, permission and pacing consequences, and the not_found error. Return-value details are already handled by the output schema, so nothing essential 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 contract, use_rth, and what_to_show in detail. The description adds only a loose tie to what_to_show ('for this what_to_show') and permission context, but it does not meaningfully expand parameter meaning beyond the schema. Baseline 3 is appropriate.
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 opens with a precise statement: 'Return the earliest date and time IBKR has historical data for an instrument.' This names a specific verb, resource, and result scope, and it clearly distinguishes the tool from siblings like get_historical_bars, get_histogram, and get_historical_ticks by its unique head-timestamp purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Use it before long get_historical_bars requests, or when they come back empty.' It also names the relevant alternative tool (get_historical_bars) and ties the call to the what_to_show parameter, so an agent can decide correctly without inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_healthGateway healthARead-only
Report whether the Interactive Brokers gateway connection is usable, and why not.
Call this first when another tool fails with not_connected or times out. It never
fails itself. `state` is one of:
- connected: everything works.
- connecting: a connection attempt is in progress.
- not_accepting: the gateway refused or ignored the connection (it is down, logged out,
or waiting for the user to approve 2FA). Retries run in the background.
- connectivity_lost: the gateway is up but cut off from IBKR's servers; usually heals.
- not_connected: stopped, or the connection dropped and a retry is pending.
`hint` explains what to do. `trading_enabled` says whether the trading gate is open
(order tools also need `circuit_open` false: after repeated IBKR rejections the
circuit breaker halts order submits until a human resets it). `api_read_only` means
the gateway's own settings reject orders. `is_paper` is true when the login only has
paper accounts. `market_data_type` is the data type requested for this session
(set_market_data_type changes it), and `subscriptions_used`/`subscriptions_max` show
how many streams are open. Pass probe=true to test the connection with a real
request (the state alone can lag behind a stalled socket).
| Name | Required | Description | Default |
|---|---|---|---|
| probe | No | Also send one request to the gateway (its clock) to prove the connection answers right now; the outcome is in `probe`. Takes up to IB_REQUEST_TIMEOUT. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | What is wrong and what to do, when not connected. |
| host | Yes | |
| port | Yes | |
| probe | No | Result of the live round trip; null unless probe=true was asked. |
| state | Yes | |
| accounts | No | Accounts this server may use (the allowlist). |
| is_paper | No | True when every managed account is a paper account (None: unknown). |
| client_id | Yes | |
| last_error | No | |
| circuit_open | No | True when the order circuit breaker tripped after consecutive IBKR rejections: submit_order refuses new orders, modifications and exercises until a human resets it (reset_circuit_breaker, admin toolset). Cancels still work. |
| api_read_only | No | The gateway rejected a request because its API is read-only (321). |
| orders_synced | No | Whether this session loaded the open and completed orders (skipped when no order toolset is enabled). Informational only: trading_enabled decides whether order tools work. |
| server_version | No | TWS API server version (when connected). |
| connected_since | No | |
| trading_enabled | Yes | Whether the trading gate is open right now: connected, accounts allowed, live trading permitted, API not read-only. Order submits are also refused while circuit_open is true. |
| market_data_type | No | Market data type requested for this session (live, frozen, delayed...). |
| circuit_threshold | No | Consecutive rejections that trip the breaker; null when disabled. |
| subscriptions_max | No | Subscription limit (IBKR_MCP_MAX_SUBSCRIPTIONS). |
| circuit_rejections | No | Consecutive IBKR order rejections since the last accepted order. |
| subscriptions_used | No | Open streaming subscriptions. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavior beyond the annotations: it never fails itself, enumerates all possible state values with meanings, explains circuit breaker behavior, api_read_only, paper accounts, market data type, subscription limits, and probe semantics. This goes far beyond readOnlyHint=true and openWorldHint=true with no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place by defining state semantics, related gates, and probe behavior. The lead sentence states the purpose immediately, and the state list is structured for quick agent parsing.
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 health-check tool with a rich output schema, the description covers when to call it, what each state means, what related fields like trading_enabled and api_read_only indicate, and how to force a live check. 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?
The single parameter probe is fully documented in the schema (100% coverage), so the baseline is 3. The description adds extra meaning by explaining why to use probe: the state alone can lag behind a stalled socket. This justifies the step above baseline.
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 opens with a specific verb and resource: 'Report whether the Interactive Brokers gateway connection is usable, and why not.' It clearly identifies this as a health/diagnostic tool and distinguishes it from sibling data-retrieval tools by positioning it as the first call when other tools fail.
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 tells the agent when to use it: 'Call this first when another tool fails with not_connected or times out.' It also explains when probe=true is appropriate. It does not explicitly contrast with get_connection_info or state when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_histogramPrice histogramARead-only
Return how trading volume was distributed over price levels during a period.
Each entry is a price and IBKR's count (traded volume) at that price, sorted by
price. Useful for volume-at-price, support/resistance and value-area questions.
Default limit 200 price levels, at most 1000; when there are more, the busiest levels
are kept and `truncated` is true. Needs market-data permissions for the instrument.
Errors: not_found (no data for the period), invalid_request (bad period).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| period | No | Look-back period: '<n> days|weeks|months|years', e.g. '3 days', '1 week', '1 month'. | 1 week |
| use_rth | No | True: regular trading hours only. False: include pre-market, after-hours and overnight data. | |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | How many price levels IBKR returned before the limit. |
| period | Yes | The period sent to IBKR, e.g. '1 week'. |
| entries | Yes | Sorted by price, lowest first. When truncated, the busiest price levels (highest count) are the ones kept. |
| use_rth | Yes | |
| contract | Yes | |
| truncated | No | True when the result was cut to the limit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only provide readOnlyHint=true, but the description goes far beyond: it discloses the default limit (200), maximum (1000), truncation behavior (busiest levels kept, `truncated` flag), the market-data permission requirement, and the possible error codes. This fully enriches the agent's understanding of the tool's behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each with a distinct job: purpose, output format and use cases, limits/truncation/permissions, and errors. No filler; the core purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and all parameters already well documented, the description covers all additional behavioral context an agent needs: truncation semantics, permissions, and error conditions. Nothing necessary for correct invocation 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%, giving a baseline of 3. The description adds meaningful value by specifying the default limit (200), the absolute cap (1000), and the 'busiest levels are kept' truncation behavior, which the schema leaves unspecified.
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: 'Return how trading volume was distributed over price levels during a period.' The description's focus on price-level volume counts distinguishes it from all sibling data tools, such as get_historical_bars or get_historical_ticks, even without naming them.
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 names three use cases: 'volume-at-price, support/resistance and value-area questions.' This gives an agent clear signals about when to select this tool, though it does not mention alternatives or specify when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_historical_barsHistorical barsARead-only
Return historical OHLCV bars for one instrument, oldest first.
Bars cover `duration` back from `end` (now when omitted). Intraday bar times are UTC;
daily, weekly and monthly bars carry the trading date. Default limit 1000 bars, at
most 10000; when there are more, the NEWEST are kept and `truncated` is true (request
a shorter duration or larger bars to see older ones).
Limits (IBKR): bars of 30 seconds or less reach back about 6 months, allow short
durations only (1 secs up to 1800 S, 5 secs up to 3600 S, 10/15 secs up to 14400 S,
30 secs up to 28800 S), and are paced at about 60 requests per 10 minutes, 5 per
contract and data type in 2 seconds, and no identical request within 15 s (this
server answers identical requests from a 15-second cache). Larger bars are not paced
that way; IBKR's guide for the longest duration: 1 min bars about 1 D, 3 mins 1 W,
30 mins 1 M, daily bars years. Needs market-data permissions for the instrument (the
same subscription as live quotes). IBKR keeps no data for expired options; expired
futures need include_expired in the contract.
Errors: not_found (no such contract, or no data in the range: check
what_to_show, use_rth and get_head_timestamp), invalid_request (bad duration or
bar size combination), rate_limit (pacing; retry after the stated time),
ib_api_error 162 (pacing, permissions), request_timeout (shorten the request).
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | End of the range, ISO 8601 (no offset means UTC). Omit for now. | |
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| use_rth | No | True: regular trading hours only. False: include pre-market, after-hours and overnight data. | |
| bar_size | No | Length of one bar, e.g. '5 secs', '1 min', '15 mins', '1 hour', '1 day'. | 1 hour |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| duration | No | How far back from end: '<n> S|D|W|M|Y', e.g. '1800 S', '5 D', '2 W', '6 M', '1 Y' (M means months). Words like '30 mins' also work. | 1 D |
| what_to_show | No | Data the values are built from. TRADES (not for forex), MIDPOINT, BID, ASK, BID_ASK (counts double for pacing), ADJUSTED_LAST (split/dividend adjusted; end must be empty), HISTORICAL_VOLATILITY and OPTION_IMPLIED_VOLATILITY (stocks, indexes), REBATE_RATE and FEE_RATE (stock loan), YIELD_BID, YIELD_ASK, YIELD_BID_ASK, YIELD_LAST (bonds), AGGTRADES (crypto). | TRADES |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | No | Requested end (UTC); null means now. |
| bars | Yes | Oldest first; when truncated, the newest bars are the ones kept. |
| total | Yes | How many bars IBKR returned before the limit. |
| use_rth | Yes | True when only regular trading hours are included. |
| bar_size | Yes | |
| contract | Yes | |
| duration | Yes | The duration sent to IBKR, e.g. '5 D' or '1800 S'. |
| truncated | No | True when the result was cut to the limit. |
| what_to_show | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and openWorldHint=true, and the description is consistent with those. It adds substantial behavioral context beyond the annotations: truncation behavior (newest kept, truncated flag), UTC vs trading-date time semantics, IBKR pacing limits (60 requests/10 min, 5 per contract/data type in 2s, 15s cache), data availability limits for expired contracts, and permission requirements. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized: first sentence states the core purpose, then range semantics, then limits/truncation, then IBKR pacing, then errors. It is longer than average, but every sentence carries operational information an agent needs. The error list is compact and actionable. Slight redundancy in the pacing section (multiple rate limits listed) but all are distinct constraints.
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 tool with 7 parameters, an output schema, and complex IBKR-specific constraints, the description covers all the critical operational context: range semantics, truncation, pacing, permissions, expired contracts, and error handling. The output schema exists so return values need not be described. The only minor gap is that it doesn't explicitly state the output format, but the output schema covers that.
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 all 7 parameters. The description adds value by explaining the interaction between duration and bar_size (e.g., 'bars of 30 seconds or less reach back about 6 months'), the meaning of the truncated flag relative to limit, and the end default ('now when omitted'). It doesn't restate every parameter but adds cross-parameter context that the schema lacks.
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 opens with a specific verb and resource: 'Return historical OHLCV bars for one instrument, oldest first.' This clearly distinguishes it from siblings like get_historical_ticks (ticks vs bars) and get_head_timestamp (timestamp only). The scope is explicit: one instrument, OHLCV bars, chronological order.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides extensive usage guidance: it explains how duration/end define the range, when truncation occurs and how to avoid it, IBKR pacing limits and duration reach, market-data permission requirements, and the include_expired caveat for futures. It also lists specific error conditions and remediation steps (check what_to_show, use_rth, get_head_timestamp). This is far beyond a minimal when-to-use statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_historical_newsHistorical headlinesARead-only
Return past news headlines about one instrument, newest first.
Each headline has provider_code and article_id for get_news_article, plus the
publication time (UTC). Works for stocks and other instruments IBKR tags news
with. Default limit 50, at most 300 (IBKR's cap per request); for more, move `end`
back to the oldest time returned. Needs a subscription to each provider searched
(see get_news_providers).
Errors: invalid_request for a provider the login is not subscribed to; not_found
when there are no headlines in the range (widen it); request_timeout when IBKR
does not answer within 4 seconds (retry with a narrower range).
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | End of the range, ISO 8601 (no time zone means UTC). Omit for now. | |
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| start | No | Start of the range, ISO 8601 (no time zone means UTC). Omit for none. | |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| provider_codes | No | Provider codes to search, e.g. ["BRFG", "DJNL"] (from get_news_providers). Omit for every subscribed provider. |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | No | End of the range asked for (UTC). |
| start | No | Start of the range asked for (UTC). |
| contract | Yes | |
| headlines | Yes | |
| truncated | No | True when the result was cut to the limit. |
| provider_codes | Yes | The providers that were searched. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnlyHint annotation by disclosing pagination behavior (default 50, max 300, move end back), subscription requirements, supported instrument types, UTC timestamps, and specific error conditions with recovery guidance. This is rich, actionable 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?
The description is dense but every sentence earns its place: purpose, return fields, supported instruments, limits, pagination, subscriptions, and errors. It is front-loaded with the core purpose and then systematically covers invocation-relevant details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 5-parameter schema, output schema, and read-only annotations, the description covers everything an agent needs to invoke this correctly: what is returned, how to paginate, provider requirements, and expected errors. Nothing important 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 is 3. The description adds value beyond the schema by specifying the exact default limit (50), the cap (300), the pagination technique using end, and the subscription-per-provider constraint.
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 opens with a specific verb and resource: 'Return past news headlines about one instrument, newest first.' It clearly distinguishes the tool from siblings like get_news_article and get_news_providers by explaining that headlines carry provider_code and article_id for use with get_news_article.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives practical workflow context: headlines reference get_news_article, provider codes come from get_news_providers, and subscription requirements are stated. It stops short of explicitly saying 'use this for historical news, not live news' or naming subscribe_news as the alternative, so it misses the top score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_historical_ticksHistorical ticksARead-only
Return individual historical trades, quote changes or midpoints (time and sales).
Give exactly one of `start` (ticks after it) or `end` (ticks before it). IBKR sends
at most 1000 ticks per request, with one-second timestamps, and may add a few to
finish the last second. When `truncated` is true there are probably more: page on
with start set to the last tick's time (or end set to the first tick's time); ticks
in that same second can repeat.
Needs market-data permissions for the instrument. Paced like small bars (about 60
requests per 10 minutes; BID_ASK counts double), so prefer get_historical_bars for
anything longer than minutes of activity.
Errors: not_found (no ticks in the range), invalid_request (both or neither
of start/end), rate_limit, ib_api_error 162 (pacing, permissions).
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Return the ticks up to this time (ISO 8601; no offset means UTC). | |
| count | No | How many ticks, 1-1000 (IBKR's maximum). | |
| start | No | Return ticks from this time on (ISO 8601; no offset means UTC). Give exactly one of start and end. | |
| use_rth | No | True: regular trading hours only. False: include pre-market, after-hours and overnight data. | |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| ignore_size | No | BID_ASK only: skip ticks where only the sizes changed. | |
| what_to_show | No | TRADES (price, size, exchange, conditions), BID_ASK (bid/ask and sizes; counts double for pacing) or MIDPOINT. | TRADES |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | No | Requested end (UTC), if given. |
| count | Yes | How many ticks were requested. |
| start | No | Requested start (UTC), if given. |
| ticks | Yes | |
| use_rth | Yes | |
| contract | Yes | |
| truncated | No | True when IBKR returned the full count, so more ticks probably exist: page on with start set to the last tick's time (or end set to the first tick's time). |
| what_to_show | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description adds substantial behavior beyond that: the 1000-tick cap, one-second timestamp granularity, possible repeated ticks in the same second, truncation-induced pagination guidance, and IBKR pacing limits. This is rich, non-obvious behavior the annotations do not cover.
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?
Every sentence earns its place: purpose first, then usage rules, then behavior quirks, pacing, and final error enumeration. Despite covering a lot, it stays focused and front-loaded, with no filler or restatement of schema descriptions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, the description need not explain the return shape. It covers error cases (not_found, invalid_request, rate_limit, ib_api_error 162), permissions, pagination, and the correct alternative tool. An agent has everything needed to call this tool safely and 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 schema documents each parameter. The description still adds meaningful interaction semantics: the exactly-one-of start/end constraint (reinforcement), pagination via setting start/end to boundary times, and the note that ticks in the same second can repeat, which affects how start/end should be used.
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?
Opens with a specific verb and resource: 'Return individual historical trades, quote changes or midpoints (time and sales).' This clearly identifies what the tool does and distinguishes it from bar-based history tools like get_historical_bars and from real-time subscription tools among its siblings.
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 instructs to give exactly one of start or end, then states when to prefer an alternative: 'prefer get_historical_bars for anything longer than minutes of activity.' It also adds prerequisites (market-data permissions) and pacing limits, giving an agent actionable selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_market_ruleMarket rulesARead-only
Return the price increments (tick ladder) of IBKR market rules.
A contract's valid price steps can depend on the price level and exchange: each rule
lists rows of (low_edge, increment), meaning prices from low_edge up to the next row's
low_edge move in steps of increment. Get the ids from get_contract_details; its
market_rule_ids line up with valid_exchanges. Use it to round limit prices correctly.
IBKR answers each rule within a second or not at all: ids it did not answer (probably
unknown) are listed in `missing_ids`; if none was answered the call fails with
not_found.
| Name | Required | Description | Default |
|---|---|---|---|
| market_rule_ids | Yes | Market rule ids from get_contract_details (market_rule_ids), e.g. [26, 239]. At most 20. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rules | Yes | |
| missing_ids | No | Ids IBKR did not answer within 1 second (probably unknown ids). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond annotations by disclosing that IBKR may omit some IDs (missing_ids), that unanswered rules are probably unknown, and that the call fails with not_found if none are answered. It also explains the semantics of the returned tick ladder, which is valuable 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?
The description is organized into three logically separated paragraphs: purpose, data format, and behavioral caveats. While slightly longer than strictly necessary, each sentence carries distinct information and the key purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and annotations cover read-only safety, the description fully addresses what an agent needs: the meaning of the tick ladder, how to source IDs, when to use it, and the specific failure modes (missing_ids, not_found). Nothing essential is omitted.
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?
Although the schema already describes market_rule_ids and its source, the description strengthens semantics by noting the relationship between market_rule_ids and valid_exchanges from get_contract_details. This adds useful context beyond a generic integer array, warranting above-baseline scoring.
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 opens with 'Return the price increments (tick ladder) of IBKR market rules,' a specific verb and resource. It further explains the structure of the data (low_edge, increment) and explicitly ties it to get_contract_details, distinguishing it from sibling 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?
The description explicitly states to get IDs from get_contract_details and says 'Use it to round limit prices correctly.' This gives clear when-to-use guidance and names the source tool, leaving no ambiguity about the workflow or the purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_news_articleNews articleARead-only
Return the full text of a news article, given its provider code and article id.
Take both from a headline (get_historical_news or a news subscription). HTML
articles are converted to plain text unless plain_text is false. Text longer than
max_chars (default 20000) is cut and truncated is true; total_chars gives the full
length. Binary articles (PDFs) are reported with article_type=binary and their
size, not returned. Needs a subscription to the provider.
Errors: ib_api_error with IBKR's message when the article is unknown or not
permitted; not_found when IBKR sends an empty article.
| Name | Required | Description | Default |
|---|---|---|---|
| max_chars | No | Longest article text to return, in characters (at most 200,000); a longer article is cut and truncated is true. | |
| article_id | Yes | Article id from the headline, e.g. BRFG$12345. | |
| plain_text | No | Convert HTML articles to plain text (fewer characters). | |
| provider_code | Yes | Provider code from the headline, e.g. BRFG. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | Why the text is missing or was converted. |
| text | No | The article; null for binary articles. |
| format | No | Whether text is plain text or HTML; null for binary articles. |
| truncated | No | True when the result was cut to the limit. |
| article_id | Yes | |
| total_chars | No | Length of the whole text before truncation. |
| article_type | Yes | text (plain text or HTML) or binary (a PDF, which is not returned). |
| binary_bytes | No | Approximate size of a binary (PDF) article, in bytes. |
| binary_base64 | No | The binary document, base64-encoded as IBKR sent it. Only for library callers that ask for it (``include_binary``); the MCP tool never returns it. |
| provider_code | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnly/openWorld annotations: it discloses HTML-to-plain-text conversion, truncation behavior with truncated and total_chars, binary article handling via article_type=binary, and the two error modes ib_api_error and not_found. This gives the agent a precise model of the tool's behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is front-loaded with the core purpose, followed by a compact paragraph of behavioral details and a final error list. Every sentence carries useful information; there is no filler or repetition of schema titles.
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 retrieval tool with an output schema, the description covers everything an agent needs to call it correctly: input provenance, content transformation, truncation, binary edge cases, subscription requirement, and expected errors. 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?
The schema already documents all four parameters at 100% coverage, so the baseline is 3. The description adds value by connecting provider_code and article_id to headline sources, explaining the max_chars default and truncation semantics, and noting the effect of plain_text for HTML articles.
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 opens with the specific operation: 'Return the full text of a news article, given its provider code and article id.' This clearly identifies the resource and inputs, and the mention of get_historical_news as the source of headers distinguishes this retrieval tool from headline-listing siblings.
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 says where to obtain the inputs ('Take both from a headline (get_historical_news or a news subscription)') and notes the prerequisite that the user needs a subscription to the provider. It does not enumerate exclusions or alternative retrieval tools, but the call context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_news_providersNews providersARead-only
List the news providers this IBKR login can use through the API (code and name).
Use the codes with get_historical_news, get_news_article and subscribe_news. Only
subscribed providers are listed; the free API feeds (BRFG Briefing.com General
Market Columns, BRFUPDN Briefing.com Analyst Actions, DJNL Dow Jones Newsletters)
must still be enabled in IBKR's market data subscriptions. Errors: not_found when
the login has none.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| providers | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint and openWorldHint; the description adds valuable behavior beyond them: only subscribed providers are returned, free API feeds require separate IBKR market-data subscriptions, and not_found is returned when the login has none. This explains filtering and failure behavior beyond what annotations 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?
The main verb and resource appear in the first sentence, followed by compact usage, subscription caveat, and error information. There is no filler or redundant restatement of the title or 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 zero-parameter, read-only list tool with an output schema, the description covers purpose, downstream consumers, subscription caveat, and error behavior. An agent has everything needed to call it correctly and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no parameters and schema coverage is 100%, so there are no parameter semantics to document; the 0-parameter baseline applies. The description's mention of returning 'code and name' is output-focused and does not need to compensate for any parameter gaps.
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 opens with a specific verb and resource: 'List the news providers this IBKR login can use through the API (code and name).' This unambiguously states what the tool returns and its scope, and it is clearly distinct from sibling news tools like get_news_article and subscribe_news.
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 provides clear downstream usage guidance: 'Use the codes with get_historical_news, get_news_article and subscribe_news,' and it explains the subscription limitation ('Only subscribed providers are listed'). It does not explicitly enumerate when not to use the tool, but the context and workflow are clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_open_ordersOpen ordersARead-only
List the account's working orders: status, filled/remaining quantity and prices.
`modifiable` is true only for orders this server placed (same API client id): only
those can be modified or cancelled with the order tools. Orders of other API clients
and manual TWS orders are shown for information. Filled and cancelled orders are
left out; see get_completed_orders. When the gateway's API is read-only (get_health:
api_read_only), IBKR refuses the request for this server's orders alone, so
include_other_clients=false reads every client's orders and keeps this server's;
`note` says so. Errors: ib_api_error 321, at once, if IBKR refuses open orders
altogether on a read-only API.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | IBKR account id, e.g. DU1234567. Omit to use the default account; list_accounts shows which accounts are allowed. | |
| include_other_clients | No | Also list orders placed by other API clients and manually in TWS (default). False lists only the orders this server placed. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | Set when the orders were read another way than asked: on a read-only gateway API, this server's own orders come from every client's list, filtered by client id. |
| as_of | Yes | When this server read the values (UTC). |
| orders | Yes | |
| account | Yes | |
| include_other_clients | Yes | Whether orders of other API clients and manual TWS orders were included. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint. The description adds essential behavioral detail: modifiable is true only for orders placed by this same server/client, other clients' orders are informational only, and IBKR can refuse the request on a read-only API with error 321 and a specific workaround. This is exactly the kind of context structured 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?
The description is dense but every sentence earns its place: scope and output fields, modifiability semantics, the completed-orders alternative, the read-only edge case, and the error code. The core purpose is front-loaded with no 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 read-only listing tool with no required parameters and an output schema present, the description covers all needed context: what is returned, what is excluded, which sibling to use instead, the read-only failure mode, and the fallback behavior. Nothing essential 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%, but the description still adds meaning beyond it: it explains the modifiable constraint tied to the API client and precisely what include_other_clients=false does under read-only gateway conditions. This goes well beyond the schema's one-line parameter descriptions.
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 opens with 'List the account's working orders' and specifies the returned fields: status, filled/remaining quantity, and prices. It explicitly contrasts with get_completed_orders by stating which order states are excluded, making it clearly distinguishable from the large sibling set.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states this tool shows working orders only, that filled/cancelled orders are excluded, and directs the agent to get_completed_orders for those. It also explains when include_other_clients=false is needed under a read-only API, giving concrete routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_option_chainOption chainARead-only
List the option expirations and strikes available on an underlying (no prices).
Returns one entry per trading class (e.g. SPX monthly and SPXW weekly), with its
multiplier, the exchanges listing it, all expirations (YYYYMMDD) and all strikes.
Strikes are the union across expirations: not every strike exists for every expiry,
so qualify_contract a specific option before quoting it. This is the cheap way to
explore options; it needs no market data subscription and has no pacing concerns.
For US stock and index options pass exchange SMART: IBKR lists a chain per options
exchange, and chains that differ slightly are not merged, so the full answer can be
long. Quotes and greeks come from the options and market_data tools.
Errors: not_found when the underlying is unknown or has no listed options (or none on
`exchange`); invalid_request when `underlying` is itself an option or combo (also when
given by the con_id of one).
| Name | Required | Description | Default |
|---|---|---|---|
| exchange | No | Only return chains listed on this exchange, e.g. SMART or CBOE. Omit for all exchanges (identical chains are merged anyway). | |
| underlying | Yes | The instrument the options are on: a stock (symbol, sec_type STK), an index (sec_type IND with its exchange, e.g. SPX on CBOE) or a future (sec_type FUT with exchange and contract month), or its con_id. | |
| fut_fop_exchange | No | For futures options: the exchange they trade on, e.g. CME. Omit to use the future's own exchange (for stocks and indexes: all exchanges). |
Output Schema
| Name | Required | Description |
|---|---|---|
| chains | Yes | |
| underlying | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/openWorldHint annotations, the description discloses important behavioral traits: strikes are the union across expirations and not every strike exists for every expiry, so qualify_contract must be used before quoting. It also covers exchange merging behavior, cost characteristics (no subscription, no pacing concerns), and specific error conditions (not_found, invalid_request). No contradiction with annotations found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded: it starts with the core purpose and the critical 'no prices' caveat, then covers output shape, usage notes, and errors in separate digestible blocks. Every sentence earns its place, and there is no 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?
Given the annotations already cover the read-only safety profile and an output schema exists, the description supplies all remaining essential context: underlying kinds, exchange behavior, subscription behavior, the need to call qualify_contract before quoting, and error conditions. Nothing important for selecting or invoking the tool 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 schema already documents all parameters richly, so the baseline is 3. The description adds operational meaning beyond the schema by recommending SMART for US stock/index underlyings and explaining why exchange-specific chains are not merged, which adds useful context beyond what the schema says.
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 states a specific verb and resource: 'List the option expirations and strikes available on an underlying (no prices).' The description goes further to distinguish the tool from pricing tools by explicitly saying 'no prices,' and explains it returns one entry per trading class with multiplier, exchanges, expirations, and strikes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear when-to-use guidance: 'This is the cheap way to explore options; it needs no market data subscription and has no pacing concerns.' It also tells callers to pass exchange SMART for US stocks/indexes because IBKR lists a chain per exchange and chains are not merged, and it routes quote/greek needs to the options and market_data tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_option_quotesOption chain quotesARead-only
Snapshot quotes and greeks for a slice of one option expiration (a mini chain).
Picks the chain for `expiration`, chooses strikes either in [strike_min, strike_max]
or the `strikes_around_atm` strikes nearest the underlying's price (taken from a
snapshot of the underlying), and returns for each option (both rights unless `right`
is set): bid/ask/last with sizes, volume, close, and IBKR's model greeks (implied_vol,
delta, gamma, vega, theta, und_price). Legs are sorted by strike, calls before puts.
`limit` caps the legs (strike and right pairs): default 20, max 40; `total` and
`truncated` say how many were selected (a range keeps the lowest strikes, ATM the
nearest). Strikes the chain lists but this expiration lacks are reported in
`skipped`, as are legs IBKR would not quote.
Market data: one snapshot per leg, using the connection's market data type (see
`market_data_type`; switch with set_market_data_type). Live quotes for US equity and
index options need IBKR's OPRA subscription for API use (plus the underlying's
exchange data; futures options need the futures exchange's data); without it, try
delayed data. Snapshots take a few seconds and up to about 11. For expiries and
strikes without quotes use get_option_chain; to stream one option use subscribe_quotes.
Errors: not_found (unknown underlying, expiration or strikes not listed, or no
underlying price: then pass strike_min/strike_max); invalid_request (bad arguments,
or several trading classes: pass trading_class); ib_api_error when no leg could be
quoted (the message names the subscription needed); subscription_limit when IBKR's
market-data lines are used up.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| right | No | C for calls, P for puts; omit for both. | |
| exchange | No | Exchange of the chain; default SMART, or the only exchange listed (futures options, e.g. CME). | |
| expiration | Yes | Expiration date as YYYYMMDD, e.g. 20261218 (from get_option_chain). | |
| strike_max | No | Highest strike to include; selects strikes by range. | |
| strike_min | No | Lowest strike to include; selects strikes by range. | |
| underlying | Yes | The instrument the options are on: a stock (symbol, sec_type STK), an index (sec_type IND with its exchange, e.g. SPX on CBOE) or a future (sec_type FUT with exchange and contract month), or its con_id. | |
| trading_class | No | Trading class when several list the expiration, e.g. SPXW (PM-settled weeklies) vs SPX. Default: the class named like the underlying. | |
| strikes_around_atm | No | Number of strikes nearest the underlying's current price (default 5). Not together with strike_min/strike_max. |
Output Schema
| Name | Required | Description |
|---|---|---|
| legs | Yes | One quote per option, by strike then right (C, P). |
| total | Yes | Legs (strike and right pairs) selected before the limit. |
| skipped | No | Selected legs without a quote: strike not listed for the expiry, or no data. |
| exchange | Yes | Exchange of the chain the legs were taken from. |
| truncated | No | True when the result was cut to the limit. |
| expiration | Yes | Expiration date, YYYYMMDD. |
| multiplier | No | Contract multiplier, e.g. 100. |
| underlying | Yes | The instrument the options are on. |
| trading_class | Yes | Trading class of the legs, e.g. SPX or SPXW. |
| market_data_type | No | Market data type this connection requests (see set_market_data_type). |
| underlying_price | No | Price the at-the-money strikes were chosen around (mid, else last or close). |
| underlying_quote | No | Snapshot of the underlying, taken to find the at-the-money strikes; null when strike_min/strike_max chose the strikes (each leg's greeks.und_price has it). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description aligns with that. It adds substantial behavioral context beyond the annotations: results are sorted by strike with calls before puts, limit defaults to 20 with max 40, skipped strikes/legs are reported, snapshots take a few seconds, and live quotes require specific IBKR data subscriptions. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well organized: main behavior first, then selection and output details, then market-data caveats and error mapping. Every paragraph earns its place, and the most decision-relevant information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 9 parameters, an output schema, and market-data dependencies, the description covers all essential context: return fields, selection semantics, truncation behavior, subscription requirements, latency expectations, error conditions, and sibling alternatives. Nothing an agent needs to invoke this 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?
Even with 100% schema coverage, the description adds meaning beyond the schema: it explains the range-vs-ATM selection tradeoff, that both rights are returned unless right is set, that limit caps leg pairs, and that a range keeps the lowest strikes while ATM keeps the nearest. This connects the parameters into a coherent selection model the schema 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?
The description names a specific verb ('Snapshot quotes and greeks') and a specific resource ('a slice of one option expiration (a mini chain)'), clearly distinguishing this from the broader get_option_chain and streaming subscribe_quotes siblings. It also specifies the two strike-selection modes, so an agent knows exactly what the tool returns and how to scope it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit routing guidance: use get_option_chain for expiries/strikes without quotes and subscribe_quotes for streaming a single option. It also notes the market_data_type dependency and when to pass trading_class. This tells the agent both when to use this tool and when to pick an alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_pnlAccount P&LARead-only
Return the account's live P&L: today's (daily), unrealized and realized, in base currency.
One-shot: subscribes to IBKR's P&L feed, waits a few seconds at most for the first
update (usually about a second), and cancels, so every call is a fresh reading and
nothing needs unsubscribing. Errors: request_timeout when IBKR sends nothing (right
after login, or an account without data); retry once before giving up.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | IBKR account id, e.g. DU1234567. Omit to use the default account; list_accounts shows which accounts are allowed. | |
| model_code | No | Financial-advisor model code, to scope the result to one model portfolio. Omit for the whole account (normal for non-advisor accounts). |
Output Schema
| Name | Required | Description |
|---|---|---|
| as_of | Yes | When this server read the values (UTC); IBKR refreshes P&L about every second. |
| account | Yes | |
| daily_pnl | No | P&L since the start of today's session. |
| model_code | No | |
| realized_pnl | No | Closed P&L today. |
| unrealized_pnl | No | Open-position P&L. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses the entire behavioral profile: one-shot subscription, wait time (a few seconds, usually about one), automatic cancellation, fresh reading per call, no need to unsubscribe, and error behavior (request_timeout after login or for data-less accounts, retry once). This is rich, non-obvious context that the agent needs to anticipate network behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose in the first sentence, then packs the behavioral contract into a compact second block. There is no filler, and every sentence covers a distinct aspect: purpose, subscription lifecycle, and error handling.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, so return values are covered there. The description provides the remaining context: base currency, P&L components, timing, one-shot semantics, and error behavior. 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%, with both parameters (account and model_code) already well documented. The description adds no additional parameter-specific meaning beyond what the schema provides, 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?
The description opens with a specific verb and resource: 'Return the account's live P&L: today's (daily), unrealized and realized, in base currency.' This precisely identifies what is returned and distinguishes the tool from per-position P&L (get_position_pnl) and account summaries. The scope is clear and immediately usable by an agent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: it is a one-shot snapshot that subscribes, waits for the first update, and cancels, so the agent knows it is not a continuous subscription and does not require explicit unsubscription. It also describes error handling and a retry. However, it does not explicitly name alternatives or state when-not-to-use, leaving the distinction from siblings like get_position_pnl to inference from the 'account's live P&L' phrase.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_portfolioPortfolioARead-only
List an account's positions with market price, market value and unrealized/realized P&L.
Values are in each position's currency and use IBKR's own valuation (no market-data subscription needed); IBKR refreshes them about every 3 minutes. For an account other than the default the call takes a moment longer, because IBKR streams portfolio data for one account at a time.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | IBKR account id, e.g. DU1234567. Omit to use the default account; list_accounts shows which accounts are allowed. |
Output Schema
| Name | Required | Description |
|---|---|---|
| as_of | Yes | When this server read the values (UTC). |
| items | Yes | |
| account | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint and openWorldHint provided by annotations, the description adds substantial extra behavioral context: values use IBKR's own valuation, require no market-data subscription, refresh about every 3 minutes, and a non-default account causes extra latency because IBKR streams one account at a time. These are meaningful operational traits an agent needs to set expectations, going well beyond the annotation flags.
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 sentences, each earning its place: the first defines the output, the second explains valuation and refresh behavior, the third warns about latency. Core purpose is front-loaded)Skip, and there is no filler or repetition of schema content.
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?
Despite being a simple tool with one optional parameter, the description covers what is returned, the valuation source, refresh cadence, and performance trade-offs. Since an output schema exists, return fields need no explanation. The one caveat about non-default accounts is exactly the kind of operational detail that helps an agent decide when to call it. Nothing essential 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 input schema fully documents the single optional 'account' parameter with a description including an example ID and instructions to omit it for the default account. Since schema coverage is 100%, the description need not repeat parameter details. The latency note for non-default accounts is behavior, not parameter semantics, so the baseline 3 is appropriate.
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 opens with 'List an account's positions with market price, market value and unrealized/realized P&L', stating a specific verb and resource. It clearly differentiates from siblings like get_positions (positions without valuation) and get_pnl (P&L summary without positions) by combining both. The wording is specific enough for an agent to select it without guessing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it by enumerating the returned data (positions + market value + P&L), but it never explicitly contrasts it with get_positions, get_pnl, or get_position_pnl, nor does it state conditions when an alternative would be better. The only usage note, about non-default accounts taking longer, is a performance caveat, not a routing guideline. This is adequate but leaves selection partially to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_position_pnlPosition P&LARead-only
Return the live P&L of one position: daily, unrealized, realized and market value.
Pass the position's con_id (from get_positions) for an exact match. Waits a few
seconds at most for IBKR's first update. Errors: not_found when the account has no
position and no P&L today in that contract; ambiguous_contract lists candidates;
invalid_request for a combo (BAG: ask per leg); request_timeout when IBKR sends nothing.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | IBKR account id, e.g. DU1234567. Omit to use the default account; list_accounts shows which accounts are allowed. | |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| model_code | No | Financial-advisor model code, to scope the result to one model portfolio. Omit for the whole account (normal for non-advisor accounts). |
Output Schema
| Name | Required | Description |
|---|---|---|
| as_of | Yes | When this server read the values (UTC); IBKR refreshes P&L about every second. |
| account | Yes | |
| contract | Yes | |
| position | No | Quantity held; 0 if closed today. |
| daily_pnl | No | P&L since the start of today's session. |
| model_code | No | |
| market_value | No | Current market value of the position. |
| realized_pnl | No | |
| unrealized_pnl | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and openWorldHint annotations, the description discloses useful runtime behavior: 'Waits a few seconds at most for IBKR's first update' and enumerates four distinct error modes with their triggers (not_found, ambiguous_contract, invalid_request, request_timeout). This gives the agent realistic expectations about latency and failure handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences, front-loaded with purpose, followed by the key input trick, the latency behavior, and a compact error list. Every sentence contributes meaning; there is no filler or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists (return values are covered there) and annotations declare read-only behavior, the description covers the remaining needs: what the tool does, how to identify the position, expected latency, and possible errors. For a read-only single-position query tool, nothing essential 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 is 3. The description adds value by instructing the agent to pass the position's con_id 'from get_positions' for an exact match, which is a workflow hint beyond the schema's generic ContractSpec description. It also clarifies combo handling with 'ask per leg'.
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 opens with a specific verb and resource: 'Return the live P&L of one position' and enumerates the components (daily, unrealized, realized, market value). This clearly distinguishes it from siblings like get_pnl (portfolio-level) and get_positions (positions list).
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 gives concrete usage guidance: pass the con_id from get_positions for an exact match, and it warns that combos (BAG) trigger invalid_request, implying an alternative approach per leg. However, it does not explicitly name alternative tools for aggregate P&L or when not to use this tool beyond the combo case, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_positionsPositionsARead-only
List an account's positions: contract, quantity (negative = short) and average cost.
Fast and always current (IBKR streams position changes). avg_cost includes
commissions and, for options and futures, the multiplier. For market value and
unrealized P&L use get_portfolio; for today's P&L of one position use
get_position_pnl. `contract.exchange` is not reported for positions; use the con_id
for follow-up calls. `model_code` (financial advisors) lists one model's positions.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | IBKR account id, e.g. DU1234567. Omit to use the default account; list_accounts shows which accounts are allowed. | |
| model_code | No | Financial-advisor model code, to scope the result to one model portfolio. Omit for the whole account (normal for non-advisor accounts). |
Output Schema
| Name | Required | Description |
|---|---|---|
| as_of | Yes | When this server read the values (UTC). |
| account | Yes | |
| positions | Yes | |
| model_code | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and openWorldHint annotations, the description reveals non-obvious behavioral traits: positions are streamed and always current, avg_cost includes commissions and multiplier, and contract.exchange is omitted, directing follow-up via con_id. These are valuable details not derivable from the schema or annotations.
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?
Five sentences with zero waste. The core purpose is front-loaded, followed by fast/current behavior, cost details, sibling routing, a caveat about exchange, and the model_code nuance. Every sentence contributes distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully equips an agent to select and invoke the tool: it states the resource, outputs, alternatives, an important data caveat, and parameter scoping. An output schema exists, so return-value documentation is not required, and no missing piece undermines a correct call.
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 are fully documented in the schema. The description adds a brief note about model_code meaning 'lists one model's positions', but this largely mirrors the schema's existing explanation. With the schema carrying the parameter burden, a baseline 3 is appropriate.
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 opens with a specific verb and resource: 'List an account's positions', and enumerates the key returned fields (contract, quantity, average cost). It further differentiates from siblings by naming get_portfolio and get_position_pnl for related but distinct data, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing guidance is provided: 'For market value and unrealized P&L use get_portfolio; for today's P&L of one position use get_position_pnl.' It also clarifies when model_code is appropriate, clearly stating the alternative behavior for financial-advisor accounts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_quotesQuote snapshotsARead-only
Get a one-time quote for up to 25 contracts: bid, ask, last, sizes, OHLC, volume.
Each quote also has `halted`, `market_data_type` (live, frozen, delayed or
delayed_frozen), `bbo_exchange` (expand it with get_smart_components) and, for
options, IBKR model greeks and implied volatility. Snapshots take up to about 11
seconds for quiet contracts. A contract with an open quote stream (subscribe_quotes)
is answered from the stream at no extra cost. Generic ticks (shortable shares,
fundamental ratios...) are not available as snapshots; use subscribe_quotes.
Contracts that fail are listed in `errors` (unknown or ambiguous contract, no market
data permission) while the others still get quotes; if all fail, the call fails.
Needs market data permissions for each exchange. Without them IBKR answers with
error 354, 10089 or 10168: call set_market_data_type with 'delayed' for free
15-20 minute delayed data (10089 with delayed already selected: IBKR has no delayed
data for that instrument on this login). Null prices mean IBKR sent no value.
| Name | Required | Description | Default |
|---|---|---|---|
| contracts | Yes | 1 to 25 instruments. A con_id alone is unambiguous; otherwise symbol and sec_type, plus expiry, strike and right for options. | |
| regulatory_snapshot | No | Request a regulatory (NBBO) snapshot. COSTS MONEY: IBKR bills about USD 0.01 per request for US stocks and ETFs without a live subscription. Refused (configuration_error) unless the server's operator allowed it. Leave false unless the user asked for it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | Contracts that got no quote, and why. |
| quotes | Yes | |
| notices | No | Things to know about the data (fees, missing data). |
| regulatory_snapshots | No | How many fee-bearing regulatory snapshots were requested. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint. The description adds substantial behavior: latency (~11 seconds), that open streams are reused at no cost, that missing permissions produce specific error codes (354, 10089, 10168), that null prices mean IBKR sent no value, and that partial failures still return quotes for valid contracts. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but each sentence contributes essential information: purpose, data fields, latency, stream reuse, exclusions, error handling, permissions, and null semantics. It is front-loaded with the primary action and then layers context. While not minimal, it avoids redundancy and is well-paragraphed, making it scannable.
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 tool with two parameters, a rich contract schema, and an output schema, the description covers all critical operational details: error codes and recovery, permission requirements, latency expectations, stream integration, and data availability limits. It also references related tools (get_smart_components, subscribe_quotes, set_market_data_type) to guide the agent. Nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: both parameters (contracts and regulatory_snapshot) are fully documented with constraints and cost warnings. The description adds little beyond the schema—it repeats the 25-contract cap and the cost of regulatory_snapshot, which are already in the schema. It does mention return fields (halted, market_data_type) but those are output, not parameters. Baseline 3 is appropriate since the schema carries the semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb+resource: 'Get a one-time quote for up to 25 contracts' and enumerates the exact data fields (bid, ask, last, sizes, OHLC, volume). It also distinguishes itself from subscribe_quotes by stating what snapshots do not include (generic ticks) and how they differ from streams, so an agent can tell them apart without inspecting 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?
Explicit guidance is provided: when to use subscribe_quotes instead ('Generic ticks ... are not available as snapshots; use subscribe_quotes'), how to expand bbo_exchange with get_smart_components, and the requirement for market data permissions with fallback instructions (set_market_data_type with 'delayed'). It also explains error behavior when contracts fail, so the agent knows how to handle partial failures.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scanner_parametersScanner parametersARead-only
Browse IBKR's market scanner catalogue to find valid inputs for run_scanner.
Sections:
- scan_codes: what a scan ranks by (e.g. TOP_PERC_GAIN, MOST_ACTIVE, HOT_BY_VOLUME),
with the instrument types each supports.
- instruments: instrument types (e.g. STK for US stocks, IND.US, FUT.US).
- locations: markets and exchanges (e.g. STK.US.MAJOR, STK.NASDAQ), nested via parent.
- filters: filter tags for run_scanner's `filters` (e.g. avgVolumeAbove), with
their value type and, for choice filters, the allowed values.
`query` matches codes and names (case-insensitive substring; for filters also the
filter group and category); `instrument` keeps only entries for that instrument
type. Default limit 50, at most 500; `total` says how many matched. The catalogue
is fetched once per gateway session, so the first call can take a few seconds.
Errors: not_found when nothing matches or the instrument type is unknown.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| query | No | Case-insensitive text to look for in codes and names, e.g. gain. | |
| section | Yes | What to list: scan_codes (what a scan ranks by), instruments (instrument types), locations (markets and exchanges) or filters (filter tags). | |
| instrument | No | Only entries that work with this instrument type, e.g. STK. |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | No | The substring filter applied, if any. |
| total | Yes | How many entries matched, before the limit. |
| filters | No | |
| section | Yes | |
| locations | No | |
| truncated | No | True when the result was cut to the limit. |
| fetched_at | Yes | When the catalogue was fetched from IBKR (UTC). |
| instrument | No | The instrument filter applied, if any. |
| scan_codes | No | |
| instruments | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark readOnly/openWorld, so the description adds real behavioral value: session-level caching, first-call latency, default limit and cap, total-count semantics, and not_found error behavior. All disclosed traits are consistent with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description front-loads its purpose, then organizes the remaining content into compact, scannable sections: catalogue sections, filtering behavior, limits, latency, and errors. No sentence is redundant or 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 read-only catalogue tool with an output schema and annotations, the description covers all four sections, query and instrument filtering, default and maximum limits, total counts, network/session latency, and error cases. 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 descriptions already document all four parameters, so this is a baseline-3 situation. The description still adds meaning beyond the schema by specifying the default limit (50), the cap (500), the total-count signal, and that query for filters also matches group and category.
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 action ('Browse'), a concrete resource ('IBKR's market scanner catalogue'), and its goal ('to find valid inputs for run_scanner'). The section list disambiguates it from scanner execution and from other data-listing siblings.
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 positions the tool as the catalogue look-up step before run_scanner, which is the main user of its output. It also tells the agent how to narrow results using query and instrument, so the right context-of-use is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_server_timeGateway server timeARead-only
Return the gateway's current time and how far this server's clock is from it.
Useful as a cheap round-trip check that the gateway answers requests, and before time-sensitive requests (historical data end times, order good-till times). IBKR reports whole seconds, so a skew under a second or two is normal.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| local_time | Yes | This server's clock when the answer arrived (UTC). |
| server_time | Yes | Time reported by the gateway. |
| skew_seconds | Yes | local_time minus server_time; IBKR reports whole seconds. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. The description adds useful behavioral context beyond that: IBKR reports whole seconds)Skip and that a skew under a second or two is normal, helping an agent interpret results correctly. No contradiction with annotations.
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: the first states what the tool returns, the second gives practical use cases, and the third provides a calibration caveat. Every sentence earns its place and is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parametersasi an output schema present, the description supplies exactly what an agent needs beyond structured metadata: purpose, use cases, and interpretation guidance. Nothing significant 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 has zero parameters and the schema coverage is 100%, so there is nothing for the description to clarify. As per baseline for zero-parameter tools, a 4 is appropriate.
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 ('Return') and a precise resource: the gateway's current time plus clock skew. This is unique among the sibling toolsebb and immediately tells an agent what the tool provides.
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?
Clear guidance on when to use the tool: as a cheap round-trip health check and before time-sensitive requests such as historical data end times or good-till times. It does not explicitly name alternatives or exclusions, but the context is strong enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_smart_componentsSMART componentsARead-only
Expand a SMART BBO exchange code into the exchanges behind it.
Quotes on SMART-routed contracts carry a `bbo_exchange` code; this lists the
exchanges it stands for, each with IBKR's single-letter code, which tells you where the
best bid and offer come from. The code only comes from market data (get_quotes needs
a market data subscription or delayed data). When IBKR returns no exchanges (e.g.
outside trading hours, or for a code not taken from a quote) the call fails with
not_found.
| Name | Required | Description | Default |
|---|---|---|---|
| bbo_exchange | Yes | The bbo_exchange code from a quote (get_quotes), e.g. '9c0001'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| components | Yes | |
| bbo_exchange | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds valuable behavioral context: the data source dependency (market data subscription), the failure mode (not_found), and the meaning of the returned codes. It doesn't detail the output schema, but an output schema exists, so that burden is reduced.
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 sentences, each earning its place: the core action, the data dependency and output meaning, and the failure condition. Front-loaded with the main verb and resource, no 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 single-parameter read-only tool with a full output schema, the description covers the source of the input, the failure mode, and the meaning of the output. Nothing an agent needs to decide whether to call it and what to expect 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 the parameter. The description adds context by explaining where the bbo_exchange code comes from (get_quotes) and giving an example ('9c0001'), which helps the agent understand the parameter's provenance and format beyond the schema's generic description.
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 ('Expand') and resource ('SMART BBO exchange code'), and explains the output: the exchanges behind the code with IBKR's single-letter codes. It clearly distinguishes itself from get_quotes (which produces the bbo_exchange code) and from other market-data 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?
The description explicitly says the bbo_exchange code comes from market data via get_quotes, and that a market data subscription or delayed data is required. It also states when the call fails (outside trading hours, or for a code not taken from a quote), giving the agent clear conditions for use and failure expectations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_subscription_dataRead subscriptionARead-only
Read the latest state of any subscription: quote, order book, ticks, bars, rows, news...
`data` depends on `kind`: quotes → `quote` (+ `extras`); depth → `bids`/`asks`;
tick_by_tick → `ticks`; realtime_bars and bars → `bars`; scanner → `rows`; news →
`headlines`; news_bulletins → `bulletins`; display_group → `current` and `updates`.
Time series (ticks, bars, headlines, bulletins, display group updates) come oldest
first, cut to the newest `limit` (default 100, max 5000) after `since`;
`data.truncated` is true when older ones were left out.
Stream snapshots also carry `active`, `error` and `notices` (IBKR messages such as
delayed data or a lost subscription). `stale` true means the gateway connection
dropped and values may be old. Each read keeps the subscription alive; one not read
for its idle time is cancelled and this tool then reports subscription_not_found.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| since | No | Only items (ticks, bars, headlines, bulletins, display group updates) after this time (ISO 8601, UTC if no zone). Pass the time of the last item you read to get only new ones. | |
| subscription_id | Yes | The id a subscribe_* tool returned (see list_subscriptions). |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | The snapshot; its fields depend on kind. |
| kind | Yes | |
| stale | No | True when the values may be old; see get_health. |
| created_at | Yes | |
| last_read_at | No | The previous read, before this one (UTC). |
| subscription_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and openWorldHint annotations, the description discloses substantial behavior: data shape depends on subscription kind, time series are ordered oldest-first and truncated by limit/since, stale indicates a dropped gateway connection, notices carry IBKR messages, and idle subscriptions get cancelled and surface as subscription_not_found. This goes well beyond what annotations or schema provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well organized: purpose first, then kind-dependent payload shapes, then time-series and truncation semantics, then lifecycle/staleness. Every sentence carries useful information and there is no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists, the description does not need to enumerate return fields; instead it covers the cross-cutting behaviors an agent must know: truncation, stale connections, IBKR notices, and subscription expiry. This is complete for a tool of this complexity.
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 meaningful parameter behavior: default limit of 100, max of 5000, ordering semantics, the meaning of truncated, and how `since` interacts with time-series data. This supplements the schema without redundantly restating it.
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 uses a specific verb ('Read') and resource ('the latest state of any subscription') and enumerates the data types it covers, which clearly distinguishes it from sibling historical/quote tools. It is immediately obvious what this tool does and which tool family it belongs to.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly frames this as reading the current state of an active subscription, with the keep-alive behavior making the use case concrete. It does not explicitly name alternative tools or exclusion cases, but the context is strong enough that an agent can infer when it applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_trading_scheduleTrading scheduleARead-only
Return an instrument's trading sessions (start, end, trading date) for recent days.
Times are in the exchange's time zone with the offset included, so holidays, early
closes and overnight sessions show up as they really were. For the upcoming
sessions, get_contract_details also lists trading and liquid hours. Counts toward
IBKR's historical-data limits.
Errors: not_found (no such contract, or no sessions in the range).
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last day to cover, ISO 8601 (no offset means UTC). Omit for now. | |
| use_rth | No | True: regular trading hours only. False: include pre-market, after-hours and overnight data. | |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| num_days | No | How many days of sessions, ending at end (1-30). |
Output Schema
| Name | Required | Description |
|---|---|---|
| end | No | End of the covered range. |
| start | No | Start of the covered range. |
| use_rth | Yes | True: regular hours only; false: including extended hours. |
| contract | Yes | |
| sessions | Yes | Oldest first. |
| time_zone | Yes | The exchange's time zone, as IBKR names it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description reveals that times are returned with the exchange's offset so holidays, early closes, and overnight sessions appear as they actually occurred. It also discloses a side effect on IBKR historical-data quota and lists the not_found error case. These details are not present in the annotations and materially shape invocation expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the purpose is in the first sentence, followed by one behavioral paragraph, one limit note, and one error line. Every sentence adds distinct value—timezone handling, data limits, and failure modes—with no 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 needs only the behavioral and error context, which it supplies. It explains timezone formatting, rate-limit implications, the not_found error, and the relevant sibling alternative. No key operational detail an agent needs before calling appears to be 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?
All four parameters already carry prose descriptions in the schema (100% coverage), so the baseline is 3. The description does not add parameter-specific guidance beyond restating the 'recent days' notion that maps to end/num_days. No extra meaning is missing.
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 opens with a specific verb and resource: 'Return an instrument's trading sessions (start, end, trading date) for recent days.' It clearly defines the output contents and timeframe, and distinguishes itself by naming get_contract_details as a related alternative for upcoming sessions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The sentence 'For the upcoming sessions, get_contract_details also lists trading and liquid hours' gives the agent a concrete alternative when future-looking hours are needed. It also flags that the call counts toward historical-data limits, a practical consideration. However, it never explicitly says when not to use this tool or states a hard branching rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_infoUser infoARead-only
Return details about the logged-in IBKR user: the white-branding id, if any.
The id identifies an introducing broker's white-labelled platform; it is empty for
most direct IBKR clients.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| white_branding_id | No | White-branding id of the user's broker, if any (empty for most users). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as readOnly and openWorld. The description adds useful behavioral context beyond those hints: the white-branding id can be empty for most direct IBKR clients, implying the return value is not always populated. This helps the agent interpret results without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is only two sentences and front-loads the core action ('Return details about the logged-in IBKR user') before explaining the white-branding id. Every sentence adds meaningful context, with no filler or repetition of the 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 no-parameter, read-only tool with an output schema and annotations, the description fully covers what an agent needs to know: what is returned, the meaning of the returned field, and the empty-value case. There are no obvious gaps for correct invocation or result interpretation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so the baseline is 4. The description adds no parameter-specific semantics, but none are needed. It correctly focuses on the tool's output and meaning instead.
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 opens with a specific verb and resource: 'Return details about the logged-in IBKR user.' It then pinpoints the key content (white-branding id) and distinguishes it from account summaries or connection info by emphasizing the user identity and white-label context. This makes the tool's purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description establishes clear context for use: it is for retrieving details about the logged-in IBKR user, specifically the white-branding id. It also clarifies when the value will be empty, which helps an agent decide whether this tool is relevant. It does not explicitly name alternatives, but the context is sufficient given the tool's unique role.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_wsh_eventsWSH corporate eventsARead-only
List Wall Street Horizon corporate events: earnings dates, dividends, splits, meetings.
Also shareholder and board meetings, conferences and more (get_wsh_metadata lists
the event types). Give a contract, event_types, a raw filter_json, or
fill_portfolio/fill_watchlist; narrow by start_date/end_date. Returns at most `limit`
events (default 50, max 100); each event is the JSON object WSH sends (event type
tag, dates, company, details), and `request` shows what was asked of IBKR.
truncated=true means more events may exist: narrow the dates to page through them.
The WSH metadata is requested automatically first, as IBKR requires. Needs a Wall
Street Horizon corporate event data subscription (paid) on the IBKR login; without
it IBKR answers with an ib_api_error.
Errors: not_found (no events match: widen the dates or check event_types),
invalid_request (unknown event type, bad filter_json, dates in the wrong order,
nothing to ask for), account_not_allowed (fill_portfolio on a login with accounts
outside the allowlist).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| contract | No | The company (usually a stock). Alone it returns all its event types; add event_types to narrow them. | |
| end_date | No | Last day to include (YYYY-MM-DD). | |
| start_date | No | First day to include (YYYY-MM-DD). | |
| event_types | No | WSH event type tags from get_wsh_metadata, e.g. wshe_ed (earnings date), wshe_bod (board meeting). | |
| filter_json | No | A raw WSH filter: a JSON object (or its text), e.g. {"watchlist": ["8314"], "wshe_ed": "true"}. Overrides contract and event_types; dates, fill flags and limit still apply. | |
| fill_portfolio | No | Also include the instruments held in the login's portfolio (WSH fillPortfolio). Refused when the login has accounts outside this server's allowlist. | |
| fill_watchlist | No | Also include the login's watchlist instruments (WSH fillWatchlist). | |
| fill_competitors | No | Also include the competitors of the selected companies (WSH fillCompetitors); not enough on its own. |
Output Schema
| Name | Required | Description |
|---|---|---|
| notes | No | Remarks about how the arguments were used. |
| total | Yes | How many events IBKR returned, before the limit. |
| events | Yes | One object per event, as WSH describes it (event type tag, dates, company and event-specific data). Missing numbers are null. |
| request | Yes | What was asked of IBKR. |
| contract | No | The instrument asked about, if any. |
| truncated | No | True when the result was cut to the limit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnlyHint=true and openWorldHint=true, and the description adds substantial behavior beyond them: the exact return shape (raw WSH JSON plus a request echo), truncated pagination semantics with remediation advice, the automatic metadata fetch IBKR requires, the paid-subscription failure mode (ib_api_error), and a full error-code map with causes and fixes. No contradiction with the read-only annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but dense — roughly 180 words covering scope options, return format, pagination, prerequisites, and errors for a 9-parameter tool with documented failure modes. It is front-loaded with purpose and follows a logical progression from purpose to inputs to behavior to errors; every sentence earns its place even though it is not as terse as the highest-scoring examples.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity — 9 parameters, pagination, subscription requirements, and multiple error cases — the description leaves nothing an agent needs for correct invocation: what to pass, how paging works, what the response contains, what subscription is required, and how to interpret failures. The output schema covers return-value structure, so the brief mention of the JSON shape is sufficient.
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 real value: concrete default (50) and maximum (100) for limit, which the schema only vaguely calls 'the tool's default' and 'capped'. It also ties error conditions to specific parameters (dates in the wrong order, unknown event type, bad filter_json), helping the agent diagnose invocation mistakes.
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 opens with a specific verb and resource — 'List Wall Street Horizon corporate events' — followed by concrete examples (earnings dates, dividends, splits, meetings). It explicitly differentiates from the nearest sibling by pointing to get_wsh_metadata for the event-type list, so an agent can tell the two tools apart 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?
The description clearly states the invocation modes ('Give a contract, event_types, a raw filter_json, or fill_portfolio/fill_watchlist'), the narrowing parameters, and the subscription prerequisite. It gets close to explicit when/when-not guidance via the error section ('not_found... widen the dates or check event_types'), but it never names a same-purpose alternative to prefer, which is the only step short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_wsh_metadataWSH metadataARead-only
Describe the Wall Street Horizon (WSH) event calendar: event types and filter fields.
Use it to build get_wsh_events queries: `event_types` lists the event type tags
(wshe_ed is the earnings date, for example) and `metadata_json` holds the full
description, filtered by `query` and cut at max_chars (default 30000, max 200000).
The metadata is fetched once and then served from this server's cache (`cached`).
Needs a Wall Street Horizon corporate event data subscription (paid) on the IBKR
login; without it IBKR answers with an ib_api_error. not_found means nothing matched
`query`.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Only return the parts of the metadata mentioning this text (case-insensitive), e.g. 'earnings' or 'wshe_ed'. Omit for everything. | |
| max_chars | No | Longest JSON to return, in characters (at most 200,000); longer JSON is cut and truncated is true. |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | No | The filter applied to the metadata, if any. |
| cached | Yes | True when served from this server's cache instead of a new request. |
| truncated | No | True when the result was cut to the limit. |
| fetched_at | Yes | When the metadata was fetched from IBKR (UTC). |
| event_types | No | Event type tags (wshe_...) found in the returned metadata; pass them as event_types to get_wsh_events. |
| total_chars | Yes | Length of the full (filtered) JSON before truncation. |
| metadata_json | Yes | The metadata as compact JSON (only the parts mentioning query, when given). Not valid JSON when truncated is true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide readOnlyHint and openWorldHint, so the description carries more weight. It discloses the caching behavior ('fetched once and then served from this server's cache'), the subscription requirement with the resulting ib_api_error, and the meaning of not_found. These are valuable behavioral details not present in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with purpose, but it repeats some schema details (default 30000, max 200000) and weaves parameter behavior into the usage sentence. It is a few sentences longer than strictly necessary, but each sentence carries useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity, two optional parameters, and an output schema, the description is largely complete. It covers purpose, usage context, caching, prerequisites, and error semantics. Minor gaps such as refresh behavior for the cache are not critical for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description mostly restates what the schema already says about query filtering and max_chars truncation, and even the example 'wshe_ed is the earnings date' appears in the schema. It adds slight context by linking event_types and metadata_json to get_wsh_events, but does not meaningfully enhance parameter understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Describe the Wall Street Horizon (WSH) event calendar: event types and filter fields.' It clearly distinguishes this metadata tool from its data-fetching sibling get_wsh_events by explicitly framing it as the assistant for building get_wsh_events queries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage guidance: 'Use it to build get_wsh_events queries,' directly naming the alternative tool and the scenario in which this tool is appropriate. It also specifies prerequisites (paid subscription) and the failure mode without it, which helps an agent decide whether to call the tool at all.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_accountsAccounts in scopeARead-only
List the IBKR accounts this server may use, and which one is the default.
Account-scoped tools use `default_account` when called without an account. If it is
null, the login manages several accounts and you must pass one explicitly. Paper
accounts start with D. Accounts outside the server's allowlist are only counted
(`other_managed_accounts`), never named, and cannot be used.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| accounts | Yes | |
| default_account | No | Account used when none is given; None means pass one explicitly. |
| other_managed_accounts | No | How many more accounts this login manages outside the allowlist. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds valuable behavioral context: the default_account behavior, the null case, paper account naming convention (D prefix), and the restriction that non-allowlisted accounts are only counted and never named. This goes beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the first sentence states the core purpose, and subsequent sentences add essential behavioral details without redundancy. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless read-only tool with an output schema, the description covers everything an agent needs: what the tool returns, how to interpret the default_account field, and the constraints on account usage. The output schema presumably details the return structure, so the description need not repeat it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema provides no parameter semantics. The description compensates by explaining the output's key fields (default_account, other_managed_accounts) and their implications, which is the relevant semantic content for a parameterless tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists IBKR accounts the server may use and identifies the default. It distinguishes itself from sibling account-related tools by focusing on account scope rather than account values or summaries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains when to use this tool: to determine which account to pass to account-scoped tools, especially when default_account is null. It also clarifies that accounts outside the allowlist cannot be used, providing clear guidance for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_subscriptionsList subscriptionsARead-only
List every open subscription of every kind: quotes, depth, ticks, bars, scans, news...
For each: its id, kind, key, contract, parameters, when it was created and last
read, when it will be cancelled for being idle (`idle_expires_at`), and `stale`
(true while the gateway connection is down). Also shows capacity: subscriptions
used out of the server maximum, and market depth and tick-by-tick streams used out
of IBKR's limits, plus the connection's current market data type.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| max | Yes | IBKR_MCP_MAX_SUBSCRIPTIONS. |
| used | Yes | |
| depth_max | Yes | |
| depth_used | Yes | |
| idle_ttl_s | Yes | |
| subscriptions | Yes | |
| market_data_type | No | What later market data requests on this connection get. |
| tick_by_tick_max | Yes | |
| tick_by_tick_used | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and openWorldHint, so the description only needs to add interpretive context. It does: idle expiration via `idle_expires_at`, `stale` while the gateway connection is down, and capacity relative to server and IBKR limits. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core scope in the first sentence and then organizes details logically: per-subscription fields, idle/stale behavior, then capacity and connection type. Every sentence adds useful information without 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?
Given the tool has no parameters and an output schema exists, the description covers everything an agent needs to invoke it correctly and interpret the result: which subscriptions are included, what fields appear, staleness semantics, and capacity limits. 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?
The tool has zero parameters and an empty input schema, so there is no parameter meaning for the description to augment. The baseline of 4 applies; the description sensibly devotes its space to the response contents instead.
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 opens with 'List every open subscription of every kind,' giving a specific verb, resource, and scope, followed by concrete kinds: quotes, depth, ticks, bars, scans, news. This makes the tool's purpose unmistakable and clearly distinct from lower-level retrieve or subscribe 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?
The description makes the usage context clear: this is the tool for an overview of all open subscriptions and their state, including capacity and staleness. It does not explicitly name a per-subscription alternative or give when-not conditions, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qualify_contractQualify contractARead-only
Resolve a contract spec to exactly one IBKR contract and return it with its con_id.
Use it to check a spec before quoting or ordering, or to turn a symbol into a con_id;
later calls can then pass just the con_id. The returned `description` is the long name
(e.g. APPLE INC) to confirm it is the intended instrument.
If several contracts match (e.g. a stock listed on two exchanges, or an option spec
without trading class), the call fails with ambiguous_contract and the message lists
up to 20 candidates with their con_ids: retry with the right con_id or more fields
(primary_exchange, currency, trading_class...). An unknown spec fails with not_found;
a combo (BAG) with invalid_request (qualify each leg by con_id instead).
| Name | Required | Description | Default |
|---|---|---|---|
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. |
Output Schema
| Name | Required | Description |
|---|---|---|
| right | No | |
| con_id | Yes | IBKR contract id (None if not yet qualified). |
| strike | No | |
| symbol | Yes | |
| currency | No | |
| exchange | No | |
| sec_type | Yes | |
| combo_legs | No | |
| multiplier | No | |
| description | No | |
| local_symbol | No | |
| trading_class | No | |
| primary_exchange | No | |
| last_trade_date_or_contract_month | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/openWorldHint annotations, the description discloses specific failure modes (ambiguous_contract with up to 20 candidates, not_found, invalid_request for combos) and explains the returned `description` field. This gives the agent a precise model of tool behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core purpose, then covers failure modes in two short paragraphs. No wasted words or redundant detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Combined with the rich schema and output schema, the description covers the main use case, return value, and error recovery steps. It doesn't explicitly mention alternatives like search_symbols, but the scope is well-defined and practically complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema is already rich (100% coverage via ContractSpec and field descriptions). The tool description adds targeted guidance about con_id being unambiguous and what to provide for options, which complements rather than repeats the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Resolve') and resource ('contract spec to exactly one IBKR contract') and explains the output (con_id). It clearly differentiates from siblings like get_contract_details and search_symbols by focusing on resolution to a single contract.
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 before quoting/ordering and to turn a symbol into a con_id, and states not to use it for BAG combos (qualify legs by con_id instead). It doesn't name alternative siblings such as search_symbols, but the context is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_scannerRun a market scanARead-only
Run an IBKR market scan once and return the ranked instruments, best first.
Example: top % gainers among US listed stocks above $5 is scan_code=TOP_PERC_GAIN,
instrument=STK, location_code=STK.US.MAJOR, above_price=5. Find other scan codes,
locations and filter tags with get_scanner_parameters. Each row has the rank
(1 = top) and the contract (with con_id, for quotes or orders).
Limits: at most 50 rows. IBKR allows 10 scanner subscriptions at a time; a run
uses one for a moment and always releases it. Scans need market data permissions
for the exchanges scanned.
Errors: not_found when nothing matches right now (loosen the filters, or the
market may be closed); ib_api_error with IBKR's message for an unknown scan code,
location or filter; subscription_limit when 10 scanner subscriptions are open.
| Name | Required | Description | Default |
|---|---|---|---|
| rows | No | How many rows to return (1-50). | |
| filters | No | More filters as tag: value, with tags from get_scanner_parameters section="filters", e.g. {"avgVolumeAbove": 100000}. | |
| scan_code | Yes | What to rank by, e.g. TOP_PERC_GAIN or MOST_ACTIVE. | |
| instrument | No | Instrument type, e.g. STK (US stocks) or FUT.US. | STK |
| above_price | No | Only prices above this. | |
| below_price | No | Only prices below this. | |
| above_volume | No | Only volume above this. | |
| location_code | No | Market or exchange, e.g. STK.US.MAJOR or STK.NASDAQ. | STK.US.MAJOR |
| market_cap_above | No | Only market capitalization above this. | |
| market_cap_below | No | Only market capitalization below this. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | |
| as_of | Yes | When the rows arrived (UTC). |
| scan_code | Yes | |
| truncated | No | True when the result was cut to the limit. |
| instrument | Yes | |
| location_code | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safe-read nature is covered. The description adds substantial behavioral context beyond that: the 50-row limit, the 10-subscription cap and the fact that a run temporarily uses and releases a subscription, the market-data permission requirement, and a detailed error taxonomy (not_found, ib_api_error, subscription_limit). This is exactly the kind of operational nuance 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?
The description is organized into clear sections: purpose, example, output shape, limits, permissions, and errors. Every sentence contributes information needed to call the tool correctly or interpret results, and there is no filler or redundancy. It is longer than a one-liner, but the length is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 10 parameters, no enums, and relies on external knowledge (scan codes, locations, filters), the description is complete: it explains how to discover valid values, what the output contains, what the limits are, what permissions are needed, and what errors to expect. The presence of an output schema further reduces the need to describe return values in prose. Nothing essential is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 per the rubric. The description adds value beyond the schema by giving a concrete composition example (scan_code=TOP_PERC_GAIN, instrument=STK, location_code=STK.US.MAJOR, above_price=5) and by pointing to get_scanner_parameters for valid values. This helps the agent understand how multiple parameters combine, even though each individual parameter is already documented in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Run an IBKR market scan once and return the ranked instruments, best first.' The word 'once' clearly distinguishes it from the sibling subscribe_scanner, and the example further pins down what the tool does. It also tells the agent what each row contains, making the output expectation clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly directs users to get_scanner_parameters for discovering valid scan codes, locations, and filter tags, which is a clear alternative for parameter selection. It also states 'once', implying a one-shot operation versus ongoing subscription, but it does not explicitly name subscribe_scanner as the alternative for continuous scanning. The guidance is strong but not fully explicit about when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_symbolsSearch symbolsARead-only
Find instruments by ticker prefix or company name (IBKR's symbol search).
Returns up to `limit` matches (default 16, IBKR rarely sends more): each with its
con_id, symbol, sec_type, primary exchange, currency, name (`description`) and the
derivative types listed on it (OPT, FUT, WAR...). Use it to discover a symbol or its
con_id, then call qualify_contract or get_contract_details for the exact contract.
Limits: discovery only, not exhaustive (no options or futures months in the results;
use get_option_chain or get_contract_details for those). IBKR allows about one search
per second, so back-to-back searches are spaced out. Errors: not_found when nothing
matches; request_timeout when IBKR did not answer within 4 seconds.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of items to return. Omit for the tool's default; larger values are capped. The result's truncated flag says whether more were available. | |
| pattern | Yes | The first letters of a ticker (e.g. 'AAP') or a word from the company or instrument name (e.g. 'apple'). |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | Yes | How many matches IBKR returned before the limit. |
| matches | Yes | |
| pattern | Yes | |
| truncated | No | True when the result was cut to the limit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, lowering the bar, but the description adds substantial behavioral detail: default and typical limit of 16 matches, the truncated flag, exact fields returned, per-second rate spacing, and specific error cases (not_found, request_timeout with a 4-second threshold). This goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: the first line states the core function, the second explains return shape and next steps, and the third covers limits, rate behavior, and error semantics. It is front-loaded with the most important information and contains no 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 search/discovery tool with read-only and open-world annotations, this description is complete. It covers what the tool returns, what it does not return, how to handle rate limits, what errors to expect, and how to proceed after discovery. An agent has everything needed to invoke it correctly and interpret results.
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 meaning beyond the schema by explaining the default limit behavior, that IBKR rarely sends more than 16, and that the result's truncated flag indicates additional matches. The pattern parameter is already well described in the schema, so the description does not need to repeat it.
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: find instruments by ticker prefix or company name. It also distinguishes this tool from siblings by positioning it as the discovery step before qualify_contract or get_contract_details, and by noting it is not exhaustive for options/futures months unlike get_option_chain. This makes the tool's scope unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: use it to discover a symbol or con_id, then switch to qualify_contract or get_contract_details. It also names exclusions (no options/futures months, use get_option_chain or get_contract_details) and warns about the one-search-per-second IBKR rate limit, so an agent knows how to sequence calls.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_market_data_typeSet market data typeAIdempotent
Switch the whole gateway connection between live, frozen, delayed and delayed-frozen data.
Applies to every market data request made afterwards (get_quotes and new streams),
for every tool, and is kept across reconnects. Use 'delayed' when quotes fail with
error 354, 10089 or 10168 (no live market data subscription). With live selected,
IBKR still falls back to delayed data where it can (each quote says which it got).
Delayed data has no market depth and no tick-by-tick data. Open streams keep what
they had until you unsubscribe and subscribe again.
| Name | Required | Description | Default |
|---|---|---|---|
| data_type | Yes | live (real-time, needs a subscription), frozen (last live values after the close), delayed (15-20 minutes old, free for most exchanges) or delayed_frozen (last delayed values). |
Output Schema
| Name | Required | Description |
|---|---|---|
| code | Yes | TWS API code: 1 live, 2 frozen, 3 delayed, 4 delayed-frozen. |
| note | Yes | |
| previous | No | |
| data_type | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: the setting persists across reconnects, applies globally to all tools, and affects only future requests (open streams are unaffected until resubscribed). It also discloses limitations of delayed data (no market depth, no tick-by-tick). This is strong supplementary context, though it doesn't mention any authentication or rate-limit requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: the core action and scope appear in the first sentence, followed by practical usage guidance and limitations. Every sentence earns its place, and the structure moves from what the tool does, to when to use it, to what to expect. No filler or repetition of schema content.
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 configuration tool with a full enum schema and an output schema, the description is complete. It covers the global scope, persistence across reconnects, error-code triggers, fallback behavior, and limitations of delayed data. An agent has everything needed to decide when to call this tool and what to expect from it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the single data_type parameter with enum values and per-value explanations. The description adds meaning by explaining the practical implications of each mode (e.g., delayed is 15-20 minutes old, frozen is last live values after close) and by clarifying that the choice applies globally. This goes beyond the schema's basic enum descriptions, earning above the baseline 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?
The description opens with a specific verb ('Switch') and a precise resource ('the whole gateway connection'), and enumerates the four data modes. It clearly distinguishes this tool from the many get_/subscribe_ siblings by stating it applies to every subsequent market data request, so an agent can tell it apart 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?
The description gives explicit when-to-use guidance: use 'delayed' when quotes fail with specific error codes (354, 10089, 10168) due to no live subscription. It also explains the behavioral consequence of choosing live (IBKR falls back to delayed where possible) and notes that open streams keep their data until resubscribed, which helps an agent decide when to call this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscribe_barsStream live barsARead-only
Load recent bars of any size and keep the newest bar updating live.
First loads `duration` of history (like get_historical_bars), then IBKR updates the
last bar and appends new ones as time passes. get_subscription_data returns the
bars oldest first (the newest 100 by default; the server keeps up to 5000). One
stream per contract and parameter set: subscribing again returns the same handle.
Counts against IBKR's historical data pacing (about 60 requests per 10 minutes;
error 162 on a violation) and needs market data permissions. Stop it with
unsubscribe.
Errors: not_found if IBKR has no bars for the period (try a longer duration or
use_rth=false), ib_api_error 321 if IBKR rejects the combination of bar size,
duration and what_to_show (the message names the field).
| Name | Required | Description | Default |
|---|---|---|---|
| use_rth | No | True: regular trading hours only. False: include pre-market, after-hours and overnight data. | |
| bar_size | Yes | Length of one bar, 5 secs or more, e.g. '5 secs', '1 min', '1 hour'. | |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| duration | No | How much history to load first: a number and a unit, S (seconds), D, W, M or Y, e.g. '3600 S', '1 D', '2 W'. | 1 D |
| what_to_show | No | Data the values are built from. TRADES (not for forex), MIDPOINT, BID, ASK, BID_ASK (counts double for pacing), ADJUSTED_LAST (split/dividend adjusted; end must be empty), HISTORICAL_VOLATILITY and OPTION_IMPLIED_VOLATILITY (stocks, indexes), REBATE_RATE and FEE_RATE (stock loan), YIELD_BID, YIELD_ASK, YIELD_BID_ASK, YIELD_LAST (bonds), AGGTRADES (crypto). | TRADES |
Output Schema
| Name | Required | Description |
|---|---|---|
| key | Yes | What it streams for: the contract id plus parameters. |
| kind | Yes | What streams: quotes, depth, tick_by_tick, realtime_bars, bars, scanner, news_bulletins, news or display_group. |
| contract | No | The instrument, when there is one. |
| created_at | Yes | |
| idle_ttl_s | Yes | Seconds without a read before it is cancelled. |
| deduplicated | No | True when an identical stream was already open and its handle was returned instead of opening a second one. |
| subscription_id | Yes | Handle for get_subscription_data and unsubscribe. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are readOnlyHint and openWorldHint, and the description adds substantial behavioral context: one stream per contract/parameter set, server retains up to 5000 bars with the newest 100 returned, pacing violations produce error 162, and rejected combinations yield error 321 with the offending field named. This goes well beyond the annotations and helps an agent predict side effects and failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient: it opens with the core behavior, then covers lifecycle, constraints, and errors in a logical order. Every sentence adds operational information, so the length is justified.
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 subscription tool with an output schema, the description covers the full lifecycle (subscribe, retrieve via get_subscription_data, stop via unsubscribe), plus limits, permissions, and error handling. It gives agents all necessary operational context to use the tool 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 parameters are already described. The description adds the stream is unique per contract and parameter set, ties duration to the initial history size, and links bar_size, duration, and what_to_show to error 321, giving a semantic relationship not present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it loads recent bars and keeps the newest one updating live, with specific verbs and a resource. It references get_historical_bars for the initial history, but does not explicitly contrast with sibling subscribe_realtime_bars, though the live-updating behavior is distinct enough.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use the tool: when you need a history load followed by live bar updates, and it points to get_subscription_data for retrieval and unsubscribe for stopping. It also gives preconditions (market data permissions) and constraints (pacing, 60 requests per 10 minutes, error 162), but does not name alternatives like subscribe_realtime_bars for other bar use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscribe_market_depthStream market depthARead-only
Start streaming the order book (Level II market depth) of one contract.
get_subscription_data returns `bids` and `asks` as levels (position 0 is the best
price) with price, size and market maker or venue. IBKR allows only 3 depth
streams at a time by default; this server refuses a 4th (unsubscribe one first).
One depth stream per contract: subscribing again returns the same handle with its
original rows and smart_depth. Needs live data (not available when
set_market_data_type chose delayed) and a Level II (depth of book) subscription
for the exchange; get_depth_exchanges lists exchanges that offer depth. Errors:
309 (depth limit), 10092 (no depth for this contract and exchange), 354 (no
subscription).
| Name | Required | Description | Default |
|---|---|---|---|
| rows | No | Price levels per side of the book. | |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| smart_depth | No | Aggregate the book across all exchanges (each level names its venue). False shows the book of the contract's exchange only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| key | Yes | What it streams for: the contract id plus parameters. |
| kind | Yes | What streams: quotes, depth, tick_by_tick, realtime_bars, bars, scanner, news_bulletins, news or display_group. |
| contract | No | The instrument, when there is one. |
| created_at | Yes | |
| idle_ttl_s | Yes | Seconds without a read before it is cancelled. |
| deduplicated | No | True when an identical stream was already open and its handle was returned instead of opening a second one. |
| subscription_id | Yes | Handle for get_subscription_data and unsubscribe. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations (readOnlyHint: true, openWorldHint: true) cover safety, but the description adds valuable behavioral context beyond them: the depth limit and server refusal, the idempotent resubscription behavior ('One depth stream per contract: subscribing again returns the same handle with its original rows and smart_depth'), and the prerequisites for live data and Level II subscription. Error codes (309, 10092, 354) further disclose failure modes. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: purpose in the first sentence, data shape reference, limits, idempotency, prerequisites, and error codes. It is front-loaded with the core action and structured as a compact paragraph followed by error list, maximizing information per word.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that the tool has an output schema and rich annotations, the description fully covers the calling context: prerequisites (live data, Level II subscription), capacity limits, idempotency, and error handling. It also references the sibling get_depth_exchanges and get_subscription_data, completing the mental model for an agent deciding to use this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema describes all three parameters (contract, rows, smart_depth) with high detail, including defaults and constraints, so schema coverage is 100%. The description adds no new parameter-level meaning beyond noting that rows and smart_depth persist when resubscribing, which is more behavioral than semantic. A baseline 3 is appropriate since the schema does the heavy lifting.
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 opens with 'Start streaming the order book (Level II market depth) of one contract,' giving a specific action, resource, and scope. It distinguishes itself from sibling streaming tools like subscribe_quotes and subscribe_bars by naming the exact data type (order book depth) and later referencing get_subscription_data as the counterpart that reads the stream.
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?
Provides explicit when-to-use and constraints: 'IBKR allows only 3 depth streams at a time by default; this server refuses a 4th (unsubscribe one first),' and 'Needs live data (not available when set_market_data_type chose delayed) and a Level II (depth of book) subscription.' It also routes the user to get_depth_exchanges to find eligible exchangeshare and lists error codes for troubleshooting, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscribe_newsStream news headlinesARead-only
Stream live news headlines for one instrument, or a provider's whole feed.
Give a contract for headlines about that instrument (from provider_code, or every
subscribed provider), or only a provider_code for that provider's broad tape (all
its headlines, e.g. BRF for Briefing Trader, BZ for Benzinga, FLY for The Fly;
each needs its own subscription). Returns a handle; read the headlines (oldest
first, the newest 200 kept) with get_subscription_data(subscription_id) and fetch
a full story with get_news_article. Uses one market data line. Stop it with
unsubscribe; it is cancelled after idle_ttl_s seconds without a read.
Errors: invalid_request without a contract or provider_code, or when a contract is
given with a provider the login is not subscribed to (see get_news_providers);
ib_api_error when IBKR refuses the stream (no news permission for that provider).
| Name | Required | Description | Default |
|---|---|---|---|
| contract | No | The instrument whose headlines to stream (a con_id alone is unambiguous). Omit to stream a provider's whole feed instead. | |
| provider_code | No | Provider code. With a contract: only this provider's headlines (default: every subscribed provider). Without a contract: that provider's whole feed (broad tape), e.g. BRF, BZ or FLY. |
Output Schema
| Name | Required | Description |
|---|---|---|
| key | Yes | What it streams for: the contract id plus parameters. |
| kind | Yes | What streams: quotes, depth, tick_by_tick, realtime_bars, bars, scanner, news_bulletins, news or display_group. |
| contract | No | The instrument, when there is one. |
| created_at | Yes | |
| idle_ttl_s | Yes | Seconds without a read before it is cancelled. |
| deduplicated | No | True when an identical stream was already open and its handle was returned instead of opening a second one. |
| subscription_id | Yes | Handle for get_subscription_data and unsubscribe. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses the subscription lifecycle: it returns a handle, keeps the newest 200 headlines, requires reads via get_subscription_data, consumes one market data line, cancels after idle_ttl_s, and reports specific error conditions. This is exactly the kind of behavioral context agents need.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well structured: purpose first, then invocation modes, consumption, teardown, and errors. Every sentence carries operational meaning, and the most important decision — contract versus provider_code — is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers setup, consumption, story retrieval, unsubscription, retention limits, resource usage, and failure modes. Given the output schema exists and the annotations are present, nothing essential is missing for an agent to call and manage this subscription 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% and the schema descriptions already explain contract and provider_code. The description adds value by giving concrete provider examples, noting that each provider feed needs its own subscription, and linking errors to provider subscription status via get_news_providers.
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 states a specific action and resource: 'Stream live news headlines for one instrument, or a provider's whole feed.' The two modes, instrument-specific versus provider-wide feed, are clear and help distinguish this from related news tools such as get_historical_news, get_news_article, and subscribe_news_bulletins.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly explains when to pass a contract versus only a provider_code, gives concrete examples, and names downstream tools for reading, fetching stories, and unsubscribing. It does not explicitly contrast with subscribe_news_bulletins or historical news, but the 'live' qualifier and references to alternatives make the intended usage inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscribe_news_bulletinsStream IBKR bulletinsARead-only
Stream IBKR's system bulletins: notices and exchanges becoming unavailable or available.
Returns a handle; read the bulletins with get_subscription_data(subscription_id)
(each has type news, exchange_unavailable or exchange_available, the message and the
exchange). There is one bulletin stream per gateway connection, so calling this
again returns the same handle, and all_messages only counts the first time. Stop it
with unsubscribe; it is cancelled after idle_ttl_s seconds without a read.
| Name | Required | Description | Default |
|---|---|---|---|
| all_messages | No | Also send the bulletins already issued today, not only new ones. |
Output Schema
| Name | Required | Description |
|---|---|---|
| key | Yes | What it streams for: the contract id plus parameters. |
| kind | Yes | What streams: quotes, depth, tick_by_tick, realtime_bars, bars, scanner, news_bulletins, news or display_group. |
| contract | No | The instrument, when there is one. |
| created_at | Yes | |
| idle_ttl_s | Yes | Seconds without a read before it is cancelled. |
| deduplicated | No | True when an identical stream was already open and its handle was returned instead of opening a second one. |
| subscription_id | Yes | Handle for get_subscription_data and unsubscribe. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint/openWorldHint annotations, the description discloses critical behaviors: one stream per gateway connection, repeated calls return the same handle, all_messages only counts on first call, and auto-cancellation after idle_ttl_s seconds. This is rich, non-obvious context that materially affects how an agent should invoke and manage the subscription.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: purpose, return-handle usage, event types, stream identity semantics, and cancellation. It is front-loaded with the core purpose and uses compact phrasing without unnecessary 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?
Given the simple input schema, rich annotations, and existing output schema, the description covers everything an agent needs to invoke and consume this tool correctly: what it returns, how to read it, how to stop it, and its unusual single-stream behavior. Nothing essential 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 schema already documents the single optional parameter with 100% coverage. The description adds valuable nuance by linking all_messages to the first-call-only behavior of the stream, which is not present in the schema. This exceeds the baseline but is still limited to one parameter.
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: 'Stream IBKR's system bulletins' and specifies the content type ('notices and exchanges becoming unavailable or available'). It clearly distinguishes this from sibling tools like subscribe_news by focusing on system bulletins rather than news articles.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear lifecycle guidance: returns a handle, read via get_subscription_data, stop via unsubscribe, and notes idle cancellation. It does not explicitly contrast with subscribe_news, but the resource and behavior are clear enough that an agent can infer when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscribe_quotesStream quotesARead-only
Start streaming live top-of-book quotes for one contract (read with get_subscription_data).
Returns a subscription handle. get_subscription_data(subscription_id) then returns
the current quote (bid/ask/last, sizes, OHLC, volume, greeks for options), the
requested generic tick values under `extras`, and IBKR notices. There is one quote
stream per contract: subscribing again returns the same handle (`deduplicated`
true), adding any new generic ticks to it. Each stream uses one of the login's
market data lines (100 by default); streams nobody reads for `idle_ttl_s` seconds
are cancelled, and unsubscribe frees the line at once.
Needs market data permissions (see set_market_data_type for delayed data). If IBKR
refuses the stream right away (354, 10089, 10168, 10197), the call fails with the
reason; later problems show in the data as `active: false` and `error`.
| Name | Required | Description | Default |
|---|---|---|---|
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| generic_ticks | No | Extra fields to stream: option_volume, option_open_interest, historical_volatility, avg_option_volume, implied_volatility (these five for stocks: the underlying's option statistics), index_future_premium, misc_stats (13/26/52-week high/low, average volume), mark_price, auction, rt_volume (time & sales, VWAP), shortable (short availability and shares), fundamental_ratios (needs a Refinitiv subscription), trade_count, trade_rate, volume_rate, rt_trade_volume, rt_historical_volatility, dividends, futures_open_interest, last_rth_trade, bond_factor_multiplier, short_term_volume (3/5/10-minute volume), ipo_prices, and for ETFs etf_nav_bid_ask, etf_nav_last, etf_nav_close, etf_nav_high_low, etf_nav_frozen_last (IBKR's intraday NAV of the fund). |
Output Schema
| Name | Required | Description |
|---|---|---|
| key | Yes | What it streams for: the contract id plus parameters. |
| kind | Yes | What streams: quotes, depth, tick_by_tick, realtime_bars, bars, scanner, news_bulletins, news or display_group. |
| contract | No | The instrument, when there is one. |
| created_at | Yes | |
| idle_ttl_s | Yes | Seconds without a read before it is cancelled. |
| deduplicated | No | True when an identical stream was already open and its handle was returned instead of opening a second one. |
| subscription_id | Yes | Handle for get_subscription_data and unsubscribe. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint and openWorldHint annotations, the description discloses one-stream-per-contract deduplication, the market data line quota, idle-timeout cancellation, immediate vs deferred error reporting with specific IBKR error codes, and the data shape available via get_subscription_data. This is rich, non-obvious behavioral context that materially helps an agent manage the subscription lifecycle.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient: three short paragraphs front-load the core action and handle, then cover deduplication, resource limits, lifecycle cancellation, permissions, and failure modes. Every sentence contributes useful information, and no filler or repetition is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich output schema and annotations, the description is complete for correct invocation and management of the subscription. It covers what the stream returns, how to read it, deduplication semantics, market data line usage, idle cancellation, permissions, and both immediate and deferred error behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% description coverage for both contract and generic_ticks. The tool description adds value beyond the schema by explaining that requested generic ticks appear under `extras` and that resubscribing with new generic ticks extends the same stream rather than creating a new one.
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 opens with a precise verb and resource: 'Start streaming live top-of-book quotes for one contract.' It clearly differentiates the tool from snapshot, historical, market-depth, and tick-by-tick siblings, and immediately names the companion get_subscription_data for reading the stream.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong operational context: use it for live per-contract top-of-book quotes, pair it with get_subscription_data, and be aware of market data permissions and delayed-data routing. However, it never names rival subscription tools such as subscribe_realtime_bars, subscribe_tick_by_tick, or subscribe_market_depth, nor states when one would prefer this tool over them, so the usage guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscribe_realtime_barsStream 5-second barsARead-only
Start streaming 5-second OHLCV bars for one contract into a ring buffer.
A new bar arrives every 5 seconds; get_subscription_data returns them oldest first
with open, high, low, close, volume, VWAP and trade count. Only 5-second bars exist;
for other sizes use subscribe_bars. One stream per contract, what_to_show and
use_rth: subscribing again returns the same handle. Uses a market data line and
counts against IBKR's historical data pacing. Needs market data permissions; TRADES
is not available for forex (use MIDPOINT). Errors 420 and 162 mean IBKR refused the
request (invalid for the contract, or pacing). Stop it with unsubscribe.
| Name | Required | Description | Default |
|---|---|---|---|
| use_rth | No | True: regular trading hours only. False: include pre-market, after-hours and overnight data. | |
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| buffer_size | No | How many of the newest bars the server keeps (720 = one hour). | |
| what_to_show | No | Build bars from TRADES, MIDPOINT, BID or ASK prices. | TRADES |
Output Schema
| Name | Required | Description |
|---|---|---|
| key | Yes | What it streams for: the contract id plus parameters. |
| kind | Yes | What streams: quotes, depth, tick_by_tick, realtime_bars, bars, scanner, news_bulletins, news or display_group. |
| contract | No | The instrument, when there is one. |
| created_at | Yes | |
| idle_ttl_s | Yes | Seconds without a read before it is cancelled. |
| deduplicated | No | True when an identical stream was already open and its handle was returned instead of opening a second one. |
| subscription_id | Yes | Handle for get_subscription_data and unsubscribe. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations declare readOnlyHint=true and openWorldHint=true, so the safety profile is already known. The description adds valuable behavioral context beyond the annotations: the ring buffer semantics, the 5-second cadence, the oldest-first return order, the one-stream-per-contract deduplication (subscribing again returns the same handle), the market data line consumption, and the pacing implications. It also discloses that TRADES is not available for forex. This is rich behavioral disclosure that goes well beyond what annotations provide, though it doesn't detail the exact output schema structure (which is covered by the output schema).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and information-dense, with every sentence earning its place. It front-loads the core action ('Start streaming 5-second OHLCV bars') before diving into details. The structure flows logically: what it does, what you get, how it differs from alternatives, deduplication behavior, resource implications, permissions, and error handling. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a subscription tool with an output schema, annotations, and 100% schema coverage, the description is complete. It covers the subscription lifecycle (start, retrieve via get_subscription_data, stop via unsubscribe), the data cadence, the ring buffer semantics, the deduplication behavior, resource consumption, permissions, forex caveat, and error codes. An agent has everything it needs to decide whether to call this tool and how to interpret the result. The output schema covers the return structure, so the description doesn't need to.
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 all four parameters (contract, use_rth, buffer_size, what_to_show) with descriptions. The tool description adds some context beyond the schema: it explains that buffer_size relates to the ring buffer, that what_to_show=TRADES is not available for forex (use MIDPOINT), and that use_rth affects whether pre-market/after-hours data is included. However, most of the parameter semantics are already in the schema, so the description's incremental contribution is moderate. Baseline 3 is appropriate.
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 ('Start streaming'), a precise resource ('5-second OHLCV bars for one contract'), and the delivery mechanism ('into a ring buffer'). It also distinguishes itself from the sibling subscribe_bars by explicitly noting that only 5-second bars exist and other sizes should use subscribe_bars. This is a clear, specific, and well-differentiated purpose statement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: it names the alternative (subscribe_bars) for other bar sizes, states the one-stream-per-contract behavior, and gives concrete conditions for when to use MIDPOINT instead of TRADES for forex. It also mentions error codes 420 and 162 as indicators of IBKR refusal, which helps an agent decide whether to retry or switch approaches. This is comprehensive usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscribe_scannerStream a market scanARead-only
Keep a market scan running so its ranking follows the market; returns a handle.
Takes the same arguments as run_scanner. Read the current rows with
get_subscription_data(subscription_id): rows (best first), updated_at, no_matches
(nothing qualifies right now) and error. Stop it with unsubscribe; it is also
cancelled after the idle time in idle_ttl_s without a read. The same scan asked
for twice returns the existing handle (deduplicated=true).
Limits: at most 50 rows; IBKR allows 10 scanner subscriptions at a time.
Errors: ib_api_error when IBKR rejects the scan (check the codes with
get_scanner_parameters); subscription_limit when no slot is free.
| Name | Required | Description | Default |
|---|---|---|---|
| rows | No | How many rows to return (1-50). | |
| filters | No | More filters as tag: value, with tags from get_scanner_parameters section="filters", e.g. {"avgVolumeAbove": 100000}. | |
| scan_code | Yes | What to rank by, e.g. TOP_PERC_GAIN or MOST_ACTIVE. | |
| instrument | No | Instrument type, e.g. STK (US stocks) or FUT.US. | STK |
| above_price | No | Only prices above this. | |
| below_price | No | Only prices below this. | |
| above_volume | No | Only volume above this. | |
| location_code | No | Market or exchange, e.g. STK.US.MAJOR or STK.NASDAQ. | STK.US.MAJOR |
| market_cap_above | No | Only market capitalization above this. | |
| market_cap_below | No | Only market capitalization below this. |
Output Schema
| Name | Required | Description |
|---|---|---|
| key | Yes | What it streams for: the contract id plus parameters. |
| kind | Yes | What streams: quotes, depth, tick_by_tick, realtime_bars, bars, scanner, news_bulletins, news or display_group. |
| contract | No | The instrument, when there is one. |
| created_at | Yes | |
| idle_ttl_s | Yes | Seconds without a read before it is cancelled. |
| deduplicated | No | True when an identical stream was already open and its handle was returned instead of opening a second one. |
| subscription_id | Yes | Handle for get_subscription_data and unsubscribe. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, the description discloses lifecycle details: deduplicated handles, idle TTL cancellation, the 50-row cap, IBKR's 10-subscription limit, and specific error types. This is rich behavioral context for a streaming tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized: purpose first, then reading data, stopping, deduplication, limits, and errors. Every sentence adds useful operational information without 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?
Given the output schema exists and parameters are fully documented, the description covers the remaining usage-critical aspects: subscription lifecycle, how to retrieve data, cancellation, deduplication, limits, and error handling. Nothing needed for correct invocation 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 every parameter is already documented. The description adds matching-argument context with run_scanner and a row limit note, but it does not need to repeat parameter meanings; 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 starts with a specific action and resource: 'Keep a market scan running so its ranking follows the market; returns a handle.' It clearly distinguishes this subscription tool from a one-shot scanner by referencing run_scanner's arguments while emphasizing the persistent handle returned.
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 gives clear workflow guidance: read results with get_subscription_data(subscription_id), stop with unsubscribe, and be aware of idle-time cancellation. It references run_scanner only for argument compatibility, not explicit when-not-to-use, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscribe_tick_by_tickStream tick-by-tick dataARead-only
Start recording every trade, quote change or midpoint of one contract into a ring buffer.
get_subscription_data returns the buffered ticks oldest first (use its `since` and
`limit` to page). Times are when the tick reached this server (UTC). IBKR allows
only about 3 tick-by-tick streams at a time; this server refuses more. One stream
per contract and tick_type: subscribing again returns the same handle. Needs live
data and a market data subscription for the instrument (not available with delayed
data); errors 10189 and 10190 mean IBKR refused it or its limit is reached. Stop it
with unsubscribe.
| Name | Required | Description | Default |
|---|---|---|---|
| contract | Yes | The instrument. A con_id alone is unambiguous; otherwise give symbol and sec_type, plus expiry, strike and right for options. | |
| tick_type | Yes | Last: trades reported to the consolidated tape. AllLast: every trade including odd lots and off-exchange prints. BidAsk: every change of the best bid or ask. MidPoint: every change of the midpoint. | |
| buffer_size | No | How many of the newest ticks the server keeps for you to read. | |
| ignore_size | No | BidAsk only: skip updates that change only a size. |
Output Schema
| Name | Required | Description |
|---|---|---|
| key | Yes | What it streams for: the contract id plus parameters. |
| kind | Yes | What streams: quotes, depth, tick_by_tick, realtime_bars, bars, scanner, news_bulletins, news or display_group. |
| contract | No | The instrument, when there is one. |
| created_at | Yes | |
| idle_ttl_s | Yes | Seconds without a read before it is cancelled. |
| deduplicated | No | True when an identical stream was already open and its handle was returned instead of opening a second one. |
| subscription_id | Yes | Handle for get_subscription_data and unsubscribe. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and openWorldHint=true, so the safety profile is already known. The description adds valuable behavioral context beyond that: the ring-buffer semantics, oldest-first retrieval via get_subscription_data, UTC timestamps, the ~3-stream IBKR limit, deduplication of identical subscriptions, and the 10189/10190 error meanings. It does not contradict the annotations. A small gap is that it doesn't describe the exact shape of the returned handle or the buffered tick records, but the output schema likely covers that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph that front-loads the core action and then layers constraints and usage guidance in logical order. Every sentence earns its place: the ring-buffer behavior, the read path, the timestamp semantics, the IBKR limit, the deduplication, the data requirements with error codes, and the stop command. No filler or repetition of schema content.
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 subscription tool with a rich output schema and 100% parameter coverage, the description covers everything an agent needs to invoke it correctly: what it does, how to read the data, the limits, the deduplication, the prerequisites, the error codes, and how to stop it. The sibling list shows related subscription tools, and this description clearly differentiates subscribe_tick_by_tick from subscribe_bars, subscribe_quotes, and subscribe_realtime_bars by naming the tick-level granularity and the ring-buffer read path.
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 all four parameters well. The description adds meaningful context beyond the schema: it explains the ring-buffer lifecycle (buffer_size relates to how many newest ticks are kept), the deduplication behavior tied to tick_type, and the error conditions tied to the contract's data subscription. It doesn't restate the schema's parameter docs, which is appropriate. The only reason it's not a 5 is that the description doesn't add much about ignore_size or the exact contract resolution nuances, but the schema already covers those.
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 opens with a specific verb and resource: 'Start recording every trade, quote change or midpoint of one contract into a ring buffer.' It clearly distinguishes this from sibling subscription tools by naming the exact data granularity (tick-by-tick) and the ring-buffer behavior. The title 'Stream tick-by-tick data' is reinforced, not merely restated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use context: it names the companion get_subscription_data for reading buffered ticks, explains the IBKR limit of ~3 streams and that the server refuses more, and states the one-stream-per-contract/tick_type deduplication behavior. It also tells the agent to stop it with unsubscribe and warns about live-data/market-data-subscription requirements with specific error codes. This is comprehensive routing and prerequisite guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsubscribeUnsubscribeAIdempotent
Cancel one subscription, or all of them, and free their IBKR market data lines.
Pass either `subscription_id` or `all=true`. Works for every kind of subscription
(quotes, depth, tick-by-tick, bars, scanners, news, bulletins, display groups).
Subscriptions belong to the server, not to one client: `all=true` also stops streams
that other clients of this server opened.
| Name | Required | Description | Default |
|---|---|---|---|
| all | No | Cancel every subscription of every kind. | |
| subscription_id | No | The id a subscribe_* tool returned (see list_subscriptions). |
Output Schema
| Name | Required | Description |
|---|---|---|
| cancelled | Yes | |
| remaining | Yes | Subscriptions still open. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal mutation and idempotency, but the description adds important non-obvious behavior: unsubscribing frees market data lineshare and 'all=true' also stops streams opened by other clients of the same server. It does not contradict any annotation, and the server-wide side effect is valuable context the agent could not infer from the schema.
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: what it does, how to invoke it, and the critical all=true caveat. No fluff, no repetition of the schema, and the most important decision (which parameter to use) is front-loaded in the second sentence.
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 and annotations covering idempotency and world effects, the description is largely complete for correct invocation. It covers single vs. all scopebinary behavior and the server-wide consequenceholistic. The main gaps are the unspecified behavior when both or neither parameter is supplied, but these are minor against an otherwise solid definition.
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. The description adds value by framing the two parameters as mutually exclusive alternatives and by explicitly tying 'works for every kind of subscription' to the cancellation scope. That goes slightly beyond the schema's per-parameter descriptions.
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 opens with a specific action and resource: 'Cancel one subscription, or all of them', followed by the consequence of freeing IBKR market data lines. It makes the tool's scope explicit and distinguishes it from the many subscribe_* and list_subscriptions siblings.
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 states the two invocation modes ('Pass either subscription_id or all=true') and clarifies when all=true is the right choice, including the cross-client side effect. It does not explicitly discuss what happens if both are passed or neither is provided, but there are no competing cancellation tools to distinguish between.
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.
50 tool updates
v0.1.0- First observed
calculate_implied_volatility - First observed
calculate_option_price - First observed
get_account_summary - First observed
get_account_values - First observed
get_completed_orders - First observed
get_connection_info - First observed
get_contract_details - First observed
get_depth_exchanges - First observed
get_executions - First observed
get_fundamental_data - First observed
get_head_timestamp - First observed
get_health - First observed
get_histogram - First observed
get_historical_bars - First observed
get_historical_news - First observed
get_historical_ticks - First observed
get_market_rule - First observed
get_news_article - First observed
get_news_providers - First observed
get_open_orders - First observed
get_option_chain - First observed
get_option_quotes - First observed
get_pnl - First observed
get_portfolio - First observed
get_position_pnl - First observed
get_positions - First observed
get_quotes - First observed
get_scanner_parameters - First observed
get_server_time - First observed
get_smart_components - First observed
get_subscription_data - First observed
get_trading_schedule - First observed
get_user_info - First observed
get_wsh_events - First observed
get_wsh_metadata - First observed
list_accounts - First observed
list_subscriptions - First observed
qualify_contract - First observed
run_scanner - First observed
search_symbols - First observed
set_market_data_type - First observed
subscribe_bars - First observed
subscribe_market_depth - First observed
subscribe_news - First observed
subscribe_news_bulletins - First observed
subscribe_quotes - First observed
subscribe_realtime_bars - First observed
subscribe_scanner - First observed
subscribe_tick_by_tick - First observed
unsubscribe
TDQS
Scored across 50 tools
Every tool targets a distinct resource and action; even the many get_* tools (account_summary vs account_values, positions vs portfolio, historical_bars vs historical_ticks) are carefully separated by purpose and data. Streaming versions (subscribe_*) are clearly differentiated from one-shot snapshots (get_*), so there is no real ambiguity.
All tool names follow a consistent snake_case verb_noun pattern: get_, subscribe_, set_, list_, run_, calculate_, qualify_, search_, and unsubscribe. The verb reflects the access mode and the noun the resource, making the naming scheme predictable and uniform across all 50 tools.
At 50 tools, this is far above the '16-25 feels heavy' range and well into the 'too many' category. While each tool is individually distinct and the breadth of IBKR justifies many of them, several niche or deprecated tools (e.g., get_wsh_metadata, get_depth_exchanges, get_fundamental_data) add bulk and make the surface difficult for an agent to navigate efficiently.
The tool set is heavily tilted toward reading account state, market data, news, and subscriptions, but it completely lacks order placement, modification, and cancellation tools—the core of a trading gateway. get_open_orders even references 'order tools' that do not exist here, so any agent attempting an actual trade workflow will hit a dead end.
Maintenance
Related MCP Connectors
Connect any MCP client to MetaTrader 4/5 to read prices, manage positions, and place trades.
Trade across 22+ exchanges and brokers from any MCP-capable AI agent, no install required.
Hosted MCP for stocks, options, Greeks, brokers, order previews, alerts, and workflows.
Trade 16 crypto exchanges + MetaTrader 5 from your AI assistant via one MCP connection.
Related MCP Servers
- FlicenseCqualityCmaintenanceAn MCP server that provides an interface for the Interactive Brokers API via the ib_async library. It enables users to manage accounts, access real-time and historical market data, and execute or monitor trades through TWS or IB Gateway.331-
- AlicenseNot gradedqualityDmaintenanceMCP server for Interactive Brokers that exposes portfolio data, market quotes, trading, and analysis to any MCP-compatible AI client, with support for EU investors and safety-gated trading.1MIT
- FlicenseBqualityDmaintenanceMCP server for Interactive Brokers via IB Gateway, enabling read access to account data and trading capabilities for paper accounts.11-
- AlicenseBqualityCmaintenanceA read-only-by-default MCP server for Interactive Brokers that exposes account, positions, PnL, market data, and trade history from a local TWS/IB Gateway session, with optional trading capabilities.15MIT