Skip to main content
Glama
PatrickSUDO

firstrade-mcp-server

by PatrickSUDO

firstrade-mcp-server

A Model Context Protocol server that gives an LLM (Claude, or any other MCP host) read/write access to a Firstrade brokerage account: live positions, balances, quotes, option chains/greeks, order history, and — if you choose to enable it — order placement (stocks, single-leg options, and two-leg option spreads).

Built on top of the community firstrade Python package, which reverse-engineers Firstrade's internal api3x web API. This project is not affiliated with, endorsed by, or supported by Firstrade.

⚠️ Read this before you use it

  • Firstrade has no official public trading API. This server (like the firstrade package it depends on) works by driving the same private endpoints the Firstrade web app uses, authenticated with your real login. That is very likely outside the spirit — and possibly the letter — of Firstrade's Terms of Service around automated / unauthorized access. Your account could be flagged, rate-limited, or suspended. Use at your own risk, on an account you're prepared to lose access to.

  • The order-placement tools (place_stock_order, place_option_order, place_option_spread) send real orders with real money. There is no simulated/paper mode. This is enforced server-side, not just by convention: place_* is disabled unless FT_ALLOW_LIVE_ORDERS=true is set in .env, and every call additionally requires a confirm_token minted by the matching preview_* tool for the identical order — a mismatched or missing token is rejected before anything is sent. See Live order safety model.

  • This is a personal tool the author built for their own workflow and is sharing as-is. It is not a product, has no support SLA, and comes with no warranty of any kind (see LICENSE). Nothing here is investment advice.

  • Options trading requires an appropriately approved options level on your Firstrade account (e.g. naked calls need Level 2+ margin approval) — the broker enforces this server-side and will reject anything you're not approved for.

If any of that gives you pause, it should — read it twice before you put real credentials in .env.

Related MCP server: Alpaca API MCP Server

What it does

Tool

Purpose

get_account_position

Live stock + option positions, all accounts

get_account_balance

Equity, cash, buying power

get_account_history

Transaction history (fills, dividends, interest, transfers) — presets or a custom date range

get_orders

Open/filled/cancelled orders, with the Firstrade order id

get_single_quote / get_watchlist_quote

Real-time quote(s)

get_option_chain

Broker's own option chain; omit the expiration to list available expirations

get_option_greeks

Broker-computed delta/gamma/theta/vega/rho + IV for a chain

preview_stock_order / place_stock_order

Stock orders — buy, sell, sell_short, buy_to_cover; limit/market/stop/stop-limit/trailing

preview_option_order / place_option_order

Single-leg option orders — buy_to_open, sell_to_open, sell_to_close, buy_to_close

preview_option_spread / place_option_spread

Two-leg option spreads (debit or credit), priced by net price

cancel_order

Cancel an open order by id

Every place_* tool has a matching preview_* tool that runs the identical request in dry-run mode. The intended usage pattern for an LLM host is: always preview first, show the user the preview, only place after explicit confirmation — and the server enforces this, it doesn't just document it (see below).

Live order safety model

place_stock_order, place_option_order, and place_option_spread are gated by two independent checks, both server-side:

  1. Kill switch. They refuse to run unless FT_ALLOW_LIVE_ORDERS=true is set in .env. Unset (the default) or anything else, and every place_* call returns an error without touching the network — preview_* still works, so you can wire this up and see previews before ever flipping the switch.

  2. Preview→place confirmation token. Every preview_* call mints a one-time confirm_token bound to the exact order arguments (symbol, side, quantity, price, duration, etc.), valid for 10 minutes. The matching place_* call must pass that token back unchanged. A missing token, an expired token, or a token minted for different order arguments (e.g. the LLM previewed 10 shares but tries to place 100) is rejected before the order reaches Firstrade. Tokens live in-process only — a server restart invalidates every pending preview.

This closes the gap where "preview first" was only a docstring instruction an LLM host could skip or a permissions layer could bypass; now placing an order that was never (or differently) previewed is impossible at the code level.

Two more things worth knowing:

  • duration on stock orders defaults to gt90 (Firstrade's ~90-day GTC), which the confirm-token flow forces you to see in the preview before it can be sent. Pass duration="day" explicitly if you don't want a resting GTC order.

  • If your login has more than one Firstrade account, order/quote/cancel tools refuse to guess which one you mean — set FT_ACCOUNT_NUMBER in .env.

See docs/option-order-api.md for the reverse-engineered schema of Firstrade's single-leg and multi-leg option order endpoints (error codes, field validation behavior, GTC vs day-only constraints), discovered via the probe scripts in tools/.

Prerequisites

  • Python 3.12+

  • uv (recommended; plain pip install -e . also works)

  • A Firstrade account, and an authenticator app if you want headless session refresh (see below)

Setup

git clone https://github.com/PatrickSUDO/firstrade-mcp-server.git
cd firstrade-mcp-server
uv sync
cp .env.example .env
# edit .env: fill in FT_USERNAME, FT_PASSWORD, FT_PIN, FT_EMAIL
# leave FT_ALLOW_LIVE_ORDERS unset until you've reviewed the safety model below

First login (interactive)

Firstrade requires 2FA (OTP or authenticator MFA) on every fresh login. Run this once to establish a session:

uv run python3 tools/ft_setup.py step1
# → sends an OTP / prompts for your authenticator code
uv run python3 tools/ft_setup.py step2 <CODE>

This saves session cookies to ~/.local/share/firstrade-session. server.py reuses that saved session on every tool call, so you don't re-auth per request.

Optional: headless session refresh

Firstrade sessions expire periodically. If you set FT_TOTP_SECRET in .env (the seed your authenticator app was set up with — not the 6-digit code), the server self-heals automatically: it detects a dead session (401) and re-runs the login + TOTP flow without a human typing anything. You can also trigger this manually:

uv run python3 tools/ft_setup.py auto

Without FT_TOTP_SECRET, a dead session falls back to the manual step1 / step2 <code> flow above.

Register with an MCP host

Claude Code:

claude mcp add firstrade-server -- uv --directory /absolute/path/to/firstrade-mcp-server run server.py

Generic mcp.json / host config:

{
  "mcpServers": {
    "firstrade-server": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/firstrade-mcp-server", "run", "server.py"]
    }
  }
}

Credentials are read from firstrade-server/.env at startup — you don't need to (and shouldn't) put them in the MCP host config.

Security notes

  • No credentials are hardcoded anywhere in the source. server.py and tools/ft_setup.py both load FT_* values from a local .env file that is git-ignored.

  • FT_TOTP_SECRET, if you set it, is your authenticator's full seed — not a 6-digit code. Anyone with it (or with your .env) can mint valid login codes for your account indefinitely, no phone required. Treat .env like a password, not a config file: chmod 600 it, don't sync it anywhere shared.

  • The saved session (~/.local/share/firstrade-session) and the transient login-flow state (~/.local/share/firstrade-session-tmp/) hold live cookies / tokens. Both are written with 0600/0700 perms and kept out of /tmp (which is world-readable on most multi-user machines). ft_setup.py also never prints raw tokens/cookies to stdout — only redacted shapes — since a failed headless re-auth surfaces its tail through the MCP error channel.

  • uv.lock is committed and firstrade is pinned to an exact version, not a floating >=. This wraps an unofficial, reverse-engineered API client that runs against a live brokerage account — bump it deliberately, after testing, not automatically on uv sync.

  • tools/probe-out/ (raw API responses captured while reverse-engineering the option order schema) is git-ignored too — even though account numbers in those responses are masked by Firstrade itself, it's still your own live session output.

  • Review .gitignore before you fork/extend this and make sure your own .env, session cache, and any new debug-output directories stay out of git.

License

MIT. Provided as-is, for personal/educational use. Not investment advice. Not affiliated with Firstrade.

Available Tools

15 tools
cancel_orderA

Cancel an open order by order_id (e.g. 'G42621-1569').

Args: order_id: The order ID returned by place_stock_order or place_option_order.

Returns JSON with cancellation result.

ParametersJSON Schema
NameRequiredDescriptionDefault
order_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses that the tool acts on open orders, requires a specific order id, and returns a JSON cancellation result. However, it does not mention irreversibility, failure conditions for already-filled or already-cancelled orders, or permission requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and well-structured: action sentence, Args block, and Returns note. Every sentence adds necessary information with no filler or redundancies.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter cancellation tool, the description covers the action, eligibility ('open order'), parameter provenance, and response format. A small gap remains around error behavior and irreversibility, but the presence of an output schema reduces the need to explain return structure in detail.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description fully compensates for the single parameter. It explains that order_id is the ID returned by place_stock_order or place_option_order and provides a realistic example, adding meaning well beyond the schema's simple string type.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Cancel'), the resource ('an open order'), and the identifying key ('order_id'), with a concrete example format. This distinguishes it from sibling placement/preview/get tools without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context by specifying that the order_id comes from place_stock_order or place_option_order, which tells the agent what prerequisite needs to exist. It does not explicitly enumerate when not to use the tool, but the verb 'Cancel' and the 'open order' restriction make the intended scenario clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_account_balanceA

Get account equity, cash, and balance overview for all accounts.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description is the sole source for behavioral disclosure. It only says 'Get,' which implies a read operation, but it doesn't state the operation is read-only, mention any authentication or rate-limit requirements, or describe side effects or data volume. For a tool acting across all accounts, this lack of behavioral note is a significant gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The entire description is one concise sentence with no filler. It front-loads the action and resource, and every word contributes to understanding what the tool returns. There is no redundancy or unnecessary background, making it efficiently structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with no parameters and a declared output schema, the description covers the essential purpose. It names the output (equity, cash, balance overview) and scope (all accounts). The output schema exists, so return details need not be restated. It is sufficient for an agent to invoke the tool correctly, though a brief note on account scope or expected data could push it to 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and a schema coverage of 100% (vacuously). The description doesn't need to explain parameter meaning because there are none. Per the rubric, a zero-parameter tool gets baseline 4, and the description correctly avoids adding pointless parameter info.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Get' and identifies a precise resource: 'account equity, cash, and balance overview for all accounts.' This distinguishes it from siblings like get_account_position (positions) or get_account_history (history), so an agent can tell which tool handles overall balances.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus its many siblings (get_account_position, get_account_history, get_orders, etc.). There is no mention of when this is the right choice or when another tool would be better, leaving the agent with 13 alternatives and no decision aid.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_account_historyA

Get transaction history (fills, dividends, interest, transfers).

Args: date_range: today|1w|1m|2m|mtd|ytd|ly|cust. Use "ly" for the trailing year, or "cust" with custom_from/custom_to for an explicit window. custom_from: Window start, "YYYY-MM-DD". Required when date_range="cust"; supplying it also implies "cust" so the range arg can be left alone. custom_to: Window end, "YYYY-MM-DD". Defaults to custom_from when omitted.

Returns JSON keyed by account number.

ParametersJSON Schema
NameRequiredDescriptionDefault
custom_toNo
date_rangeNo1m
custom_fromNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral load: 'Get transaction history' implies read-only retrieval, and 'Returns JSON keyed by account number' states output shape. It does not mention pagination, auth, or side effects, but those are minimal concerns for a history lookup.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is tight, scannable, and uses a clear Args list. It would be slightly improved by a concrete example, but the structure serves an agent well.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the core invocation contract (what it does, what the parameters mean, what the response shape is). Missing details like pagination or date range boundaries are minor for a simple read-only history endpoint, and no annotations exist to contradict or supplement.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides no parameter descriptions (0% coverage), but the free-text description documents all three parameters, includes allowed values for date_range, states when custom_from is required, and explains custom_to's default. This fully compensates for the structured schema gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb and resource ('Get transaction history') and enumerates included transaction types (fills, dividends, interest, transfers). It does not explicitly contrast with sibling tools like get_orders or get_account_balance, but the scope is easy to infer.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Documents parameter usage including enum values, the required condition for custom_from when date_range='cust', and the default for custom_to. However, it gives no explicit guidance on when to choose this tool over siblings such as get_orders or get_option_chain.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_account_positionA

Get current stock and options positions for all accounts.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries the full burden of behavioral disclosure. It conveys that this is a read operation returning current positions across all accounts locked account scope. However, it does not disclose potential limitations such as pagination, data freshness, or whether it returns both realized and unrealized positions. This is adequate for a simple getter but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One concise sentence with no filler. It conveys scope, resource, and recency in a single line.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters and an output schema present, the description is largely complete. It tells the agent this is a read operation ('Get current') covering positions across all accountscars. It could optionally note the absence of filtering, but the word 'all accounts' already conveys that. The output schema covers return structure, so no return description is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parametersaine schema, so the description doesn't need to explain parameters. The baseline for 0 params is 4, and the description, while brief, does clarify the scope of what is returned ('for all accounts'), which is the only semantic ambiguity that could exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Get') and names a precise resource: current stock and options positions, scoped to all accounts. This clearly distinguishes it from siblings like get_account_balance (balances vs. positions) and get_account_history (historical activity vs. current positions), so an agent can tell them apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to use this tool versus alternatives. There is no explicit mention of trade-offs, prerequisites, or scenarios where another tool would be more appropriate. The context is implied by the verb and resource, but no direct usage guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_option_chainA

Get the broker's own option chain for a stock symbol.

Args: symbol: Underlying ticker, e.g. 'NVDA'. exp_date: Expiration as 'YYYYMMDD' (or 'YYYY-MM-DD'). Omit to list the available expiration dates instead of returning a chain. strike_min / strike_max: Optional inclusive strike filter (0 = no bound). Full chains on NVDA/MU/CRWD exceed the MCP result-size cap (~100-140k chars); pass a band around spot (e.g. ±15%) to keep the payload small.

Returns JSON: {"items": [{exp_date, day_left, exp_type}, ...]} when exp_date is omitted, else the chain for that expiration (filtered if bounds given).

ParametersJSON Schema
NameRequiredDescriptionDefault
symbolYes
exp_dateNo
strike_maxNo
strike_minNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the transparency burden and does so effectively. It explains the data returned in both modes, the impact of optional parameters, and the operational constraint about large option chains exceeding the MCP response cap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the primary action and uses a compact 'Args' section. No wasted words; every sentence adds operational value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given four parametersanged, no annotations, and no output schema, the description covers all parameters, both invocation modes, the exact return shape when listing expirations, and the critical size-cap warning. An agent has enough context to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0% description coverage, but the description fully compensates by explaining symbol, exp_date behavior, and the role of strike_min/strike_max, including numeric filtering semantics and defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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: 'Get the broker's own option chain for a symbol.' This clearly identifies what the tool returns and is distinct enough from sibling quote/order/greeks tools, though it does not explicitly name an alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives concrete usage rules: omit exp_date to list expirationstar, and use strike_min/strike_max to avoid response-size issues. It does not, however, compare against sibling tools such as get_option_greeks, so it stops short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_option_greeksA

Get broker-computed greeks (delta/gamma/theta/vega/rho, IV) for an option chain.

Prefer this over locally derived greeks when sizing or comparing legs.

Args: symbol: Underlying ticker, e.g. 'TSLA'. exp_date: Expiration as 'YYYYMMDD' (or 'YYYY-MM-DD'). Get valid dates from get_option_chain with exp_date omitted. strike_min / strike_max: Optional inclusive strike filter (0 = no bound); full greeks on liquid names exceed the MCP result-size cap.

Returns JSON {"chains": [{strike, cp, side, symbol, iv, delta, gamma, rho, theta, vega}, ...]}. Illiquid strikes report "--" rather than a number.

ParametersJSON Schema
NameRequiredDescriptionDefault
symbolYes
exp_dateYes
strike_maxNo
strike_minNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries safety/behavioral info: returns broker-computed data, applies a strike-cap workaround, and reports '--' for illiquid strikes. It doesn't mention data freshness or auth, but this is a read-only query and the main quirks are covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with a clear verb and greeks list, then a short routing note scan and sample return schema. Every sentence contributes; slightly dense but efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Enough to invoke correctly: parameters, formats, optional filters, behavior for illiquid strikes, return shape, and a pointer to get_option_chain for valid expiration dates. Missing only rare edge-case/error behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Adds substantial meaning beyond the bare schema: ticker format example, date format guidance, where to get valid dates, optional strike_min/max semantics with 0 meaning no bound, and why you'd filter (size cap).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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: 'Get broker-computed greeks ... for an option chain', and enumerates exactly which Greeks and IV are returned. It is easy to distinguish from sibling tools such as get_option_chain or quote tools, and it even contrasts itself with locally derived greeks.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells the agent to prefer this over locally derived greeks when sizing/comparing legs artists, and points to get_option_chain for valid expiration dates. It doesn't fully spell out when to choose alternative MCP tools, but the condition is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_ordersA

List orders and their status (open / filled / cancelled) for all accounts.

Each entry carries the Firstrade order id (e.g. 'G42621-1601'), which is the authoritative link between a fill and the GTC ladder it came from. Use this to see resting GTC orders, detect dead orders, and attribute fills to a plan.

Args: per_page: Orders per page. 0 (default) returns all.

Returns JSON keyed by account number.

ParametersJSON Schema
NameRequiredDescriptionDefault
per_pageNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the behavioral disclosure burden. It adds meaningful behavior: returns data for all accounts, is keyed by account number, and explains the authoritative order-id link. It does not discuss auth or side effects, but 'List' and the JSON-return note make the read-only nature reasonably clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose and keeps the most important behavioral details early. The illustrative use cases are slightly expansive but earn their place by explaining why the order id matters, making the description informative without being bloated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter list tool with an output schema present, the description is complete: it states scope (all accounts), statuses returned, the return keying scheme, and the meaning of per_page. It omits trivial details like sorting and pagination limits, which are not essential for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain parameters. It fully explains per_page: 'Orders per page. 0 (default) returns all.' This adds non-obvious behavior (0 means all) beyond the schema's type and default, giving an agent everything needed to use the only parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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 orders and their status (open / filled / cancelled) for all accounts.' This clearly distinguishes it from order-mutation siblings like cancel_order and place_stock_order, and from position/balance quote tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives concrete usage context: 'Use this to see resting GTC orders, detect dead orders, and attribute fills to a plan.' It does not explicitly name when-not-to-use alternatives, but the context is clear enough for an agent to recognize this as the order-listing tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_single_quoteB

Get real-time quote for a stock symbol.

ParametersJSON Schema
NameRequiredDescriptionDefault
symbolYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool gets a real-time quote but does not disclose any behavioral traits such as data source, latency, rate limits, or whether the quote is delayed. It also does not describe the return format, though an output schema exists. The description adds minimal behavioral context beyond the basic action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that is front-loaded with the verb and resource. It is appropriately sized for a simple tool with one parameter, though it could add a bit more context without becoming verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no nested objects) and the presence of an output schema, the description is mostly adequate. However, with no annotations and 0% schema description coverage, the description could have provided more context about the symbol format or the nature of the real-time quote. It is minimally complete but leaves some gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the undocumented 'symbol' parameter. The description mentions 'stock symbol' in the text, which adds some meaning to the parameter, but it does not provide format examples, validation rules, or clarify that the symbol must be a ticker like 'AAPL'. This is a minimal compensation for the schema gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get') and resource ('real-time quote for a stock symbol'), which clearly identifies the tool's function. It does not explicitly differentiate from sibling tools like get_watchlist_quote, but the 'single' in the name and 'for a stock symbol' provide enough distinction for basic selection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving a real-time quote for a single stock symbol, which is clear context. However, it does not explicitly state when to use this tool versus alternatives like get_watchlist_quote or get_option_chain, nor does it mention any exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_watchlist_quoteA

Get real-time quotes for multiple symbols (comma-separated, e.g. 'AAPL,NVDA,MU').

ParametersJSON Schema
NameRequiredDescriptionDefault
symbolsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It explicitly states the real-time nature and the comma-separated multiple-symbol format. Since this is a read-only lookup, there are no destructive side effects to disclose; error handling and response fields are 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The entire description is a single, information-dense sentence. It states the purpose and gives the exact input format and an example with no unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is operationally simple: one required parameter, no nested objects, and an output schema is available. The description covers the only real ambiguity—how to format symbol lists—so the agent has enough to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the parameter 'symbols' had almost no meaning beyond being a string. The description fully compensates by explaining the comma-separated format and providing the 'AAPL,NVDA,MU' example, which is exactly the semantic an agent needs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a clear verb ('Get') and resource ('real-time quotes for multiple symbols'), and even supplies a comma-separated example. This immediately differentiates it from the close sibling get_single_quote, which is for a single quote.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly communicates the use case: retrieving multiple quotes in one call. It does not explicitly mention when to avoid it or compare it to get_single_quote, but the symbol-format context is strong enough that an agent can infer the right selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

place_option_orderA

Place a real option order (dry_run=False). Requires FT_ALLOW_LIVE_ORDERS=true in .env AND a confirm_token from preview_option_order called with these exact same arguments — the server rejects the order otherwise, it does not just rely on the caller having "meant to" preview first.

Args: option_symbol: OCC format symbol (e.g. 'AAPL250620C00150000'). order_type: buy_to_open | sell_to_close | sell_to_open | buy_to_close ('buy' = buy_to_open, 'sell' = sell_to_open; to exit a long option you MUST use sell_to_close, otherwise Firstrade treats it as opening a short and rejects with ref 1103). contracts: Number of contracts. confirm_token: Token returned by preview_option_order for this exact order. price_type: limit | market | stop | stop_limit duration: day | day_ext | gt90 price: Limit price per contract (required for limit orders). stop_price: Stop trigger price (required for stop/stop_limit orders).

Returns JSON with order confirmation. This sends a real order to Firstrade.

ParametersJSON Schema
NameRequiredDescriptionDefault
priceNo
durationNoday
contractsYes
order_typeYes
price_typeNolimit
stop_priceNo
confirm_tokenYes
option_symbolYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the full burden. It discloses the real-money side effect ('This sends a real order to Firstrade'), the FT_ALLOW_LIVE_ORDERS environment requirement, the mandatory token validation, and the specific rejection risk for sell_to_close semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The critical 'real order' and prerequisite information is front-loaded, and the argument list is dense but organized. Every sentence contributes operational information, with no filler or repeated schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a high-risk live-order tool with 8 parameters, no annotations, and an output schema, the description gives the caller everything needed to invoke it correctly: prerequisites, token workflow, order-type edge cases, and price requirements.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, and the description compensates fully by documenting all 8 parameters, including OCC symbol format, order_type meanings with a must-use caveat, confirm_token provenance, price_type values, duration values, and required price/stop_price conditions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Place a real option order (dry_run=False)', stating a specific verb, resource, and mode. It clearly distinguishes itself from the preview/simulation siblings by emphasizing that this is a live order.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit required workflow: obtain confirm_token from preview_option_order with the exact same arguments, and warns that the server rejects otherwise. It does not explicitly name the alternative tool for dry-runs or spread orders, but the real-vs-preview distinction is strongly implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

place_option_spreadA

Place a real two-leg option spread (dry_run=False). Requires FT_ALLOW_LIVE_ORDERS=true in .env AND a confirm_token from preview_option_spread called with these exact same arguments — the server rejects the order otherwise, it does not just rely on the caller having "meant to" preview first.

Same arguments as preview_option_spread, plus confirm_token. DAY order only; 7AM–4PM ET window. Returns JSON with order confirmation. This sends a real order to Firstrade.

ParametersJSON Schema
NameRequiredDescriptionDefault
symbol1Yes
symbol2Yes
net_priceYes
contracts1No
contracts2No
limit_typeYes
transaction1Yes
transaction2Yes
confirm_tokenYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly warns this sends a real order to Firstrade, requires a live-order environment flag, and that the server enforces the preview-token requirement rather than trusting caller intent. It also discloses the order window and return type, giving strong transparency for a mutating action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loaded with the most important fact: this places a real order. It avoids fluff and covers prerequisites, constraints, and return behavior. The only slight redundancy is stating the real-order nature twice, but the repetition serves as a safety emphasis and does not meaningfully hurt clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a high-complexity live-order tool, the description covers the critical context: live environment requirement, preview-token precondition, server-side enforcement, tradeable hours, order type, and confirmation return. It does not enumerate parameter values or error cases, but the pointer to preview_option_spread and the existence of an output schema fill in some of the remaining gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% coverage across 9 parameters, and the description does not directly explain symbol1, transaction1, transaction2, limit_type, net_price, or contracts1/contracts2. It does add meaningful context by saying the arguments are the same as preview_option_spread plus confirm_token, and it explains that confirm_token comes from a prior preview call. This helps but delegates most parameter interpretation to a sibling tool rather than standing alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool places a real two-leg option spread and explicitly distinguishes it from a dry run with 'dry_run=False' and 'This sends a real order to Firstrade.' It names the resource (option spread), the action (place), and the live nature of the operation, making it unmistakable versus preview_option_spread.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit preconditions: FT_ALLOW_LIVE_ORDERS=true in .env and a confirm_token from preview_option_spread called with the exact same arguments. It also specifies the DAY-only restriction, the 7AM–4PM ET window, and notes the server will reject the order if the preview requirement is not met. This is clear when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

place_stock_orderA

Place a real stock order (dry_run=False). Requires FT_ALLOW_LIVE_ORDERS=true in .env AND a confirm_token from preview_stock_order called with these exact same arguments — the server rejects the order otherwise, it does not just rely on the caller having "meant to" preview first.

Args: symbol: Ticker symbol (e.g. 'NVDA'). order_type: buy | sell | sell_short | buy_to_cover quantity: Number of shares. confirm_token: Token returned by preview_stock_order for this exact order. price_type: limit | market | stop | stop_limit | trailing_stop_dollar | trailing_stop_percent duration: day | day_ext | overnight | gt90 (gt90 ≈ GTC, 90-day) price: Limit price (required for limit/stop_limit orders). stop_price: Stop trigger price (required for stop/stop_limit orders).

Returns JSON with order confirmation. This sends a real order to Firstrade.

ParametersJSON Schema
NameRequiredDescriptionDefault
priceNo
symbolYes
durationNogt90
quantityYes
order_typeYes
price_typeNolimit
stop_priceNo
confirm_tokenYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It clearly discloses that this sends a real order to Firstrade, that it requires a confirm_token, and that the server enforces the preview requirement. It could add more about side effects (e.g., irreversible, funds affected), but the core behavioral traits are well covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with a clear opening warning, then a compact parameter list. It is slightly long but every line earns its place by adding necessary usage detail. The front-loaded warning about live orders is appropriately placed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (8 params, live order side effects, no annotations), the description covers prerequisites, parameter semantics, and the preview-token requirement. It mentions returns JSON with order confirmation, and an output schema exists. Minor gaps: no explicit statement about reversibility or error cases, but the description is largely complete for safe invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does: it explains each parameter's meaning, provides examples for symbol, enumerates valid values for order_type, price_type, and duration, and clarifies conditional requirements for price and stop_price. This is strong compensation, though it doesn't detail the exact return JSON structure.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Place'), a specific resource ('real stock order'), and immediately distinguishes itself from preview_stock_order by noting dry_run=False. It also names the sibling preview_stock_order explicitly, making the tool's role clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states the prerequisite (FT_ALLOW_LIVE_ORDERS=true) and the mandatory precondition (confirm_token from preview_stock_order with exact same arguments). It also explains the server rejects otherwise, which tells the agent when this tool is appropriate and what must happen before calling it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

preview_option_orderA

Preview an option order WITHOUT sending it (dry_run=True). Always call this first.

Args: option_symbol: OCC format symbol (e.g. 'AAPL250620C00150000'). order_type: buy_to_open | sell_to_close | sell_to_open | buy_to_close ('buy' = buy_to_open, 'sell' = sell_to_open; to exit a long option you MUST use sell_to_close, otherwise Firstrade treats it as opening a short and rejects with ref 1103). contracts: Number of contracts. price_type: limit | market | stop | stop_limit duration: day | day_ext | gt90 price: Limit price per contract (required for limit orders). stop_price: Stop trigger price (required for stop/stop_limit orders).

Returns JSON with order preview confirmation data, plus "confirm_token": pass that token unchanged to place_option_order (with the identical order arguments) to actually send it. The token expires in 10 minutes and works once.

ParametersJSON Schema
NameRequiredDescriptionDefault
priceNo
durationNoday
contractsYes
order_typeYes
price_typeNolimit
stop_priceNo
option_symbolYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully discloses the crucial behavior: it is a dry run that does not send the order, the returned token is single-use, expires in 10 minutes, and must be passed to the placement tool with identical arguments. It even documents broker-specific rejection behavior (ref 1103).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but efficient: every sentence contributes purpose, parameter semantics, or workflow behavior. The token flow and the critical sell_to_close warning earn their place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers all seven parameters despite zero schema descriptions, specifies required conditions, explains return value and token usage, and gives a concrete error-code warning. Nothing needed for correct invocation is left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries full responsibility for parameter meaning. It explains the OCC symbol format, enumerates allowed values for order_type, price_type, and duration, clarifies aliases, and states which prices are required for which order types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Preview') and resource ('option order') and immediately clarifies it does NOT send the order (dry_run=True). This distinguishes it from place_option_order and preview_stock_order without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: 'Always call this first,' and explains that the returned confirm_token must be passed to place_option_order with identical arguments to actually send. It also gives a concrete exclusion warning about when Firstrade rejects sell orders unless sell_to_close is used, which routes the agent away from a common mistake.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

preview_option_spreadA

Preview a two-leg option spread WITHOUT sending it (dry_run=True). Always call this first.

Args: symbol1 / symbol2: OCC symbols of the two legs (e.g. 'NVDA261120C00270000'). transaction1 / transaction2: buy_to_open | sell_to_open | sell_to_close | buy_to_close per leg (e.g. debit call spread = leg1 buy_to_open lower strike, leg2 sell_to_open higher strike). limit_type: 'debit' (you pay net_price) or 'credit' (you receive net_price). net_price: Net limit price per spread. contracts1 / contracts2: Contracts per leg (default 1 each).

Notes: complex orders are DAY only (no GTC) and accepted by Firstrade only 7AM–4PM ET (ref 1110 otherwise). Returns JSON preview plus "confirm_token": pass that token unchanged to place_option_spread (with the identical arguments) to actually send it. The token expires in 10 minutes and works once.

ParametersJSON Schema
NameRequiredDescriptionDefault
symbol1Yes
symbol2Yes
net_priceYes
contracts1No
contracts2No
limit_typeYes
transaction1Yes
transaction2Yes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral disclosure burden and does so well: it states no order is sent, result contains a JSON preview plus confirm_token, the token expires in 10 minutes and works once, and complex orders are DAY-only with a 7AM–4PM ET window (ref 1110). This goes far beyond a generic 'previews an order' statement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The statement is front-loaded with the core purpose ('Always call this first') and then compactly lists parameters and operational constraints. No filler or repetition; the density is justified by the complexity of option spreads.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description tells the agent everything needed to invoke it correctly and handle the result: required arguments, transaction types, limit_type semantics, the confirm_token handoff, expiration, and Firstrade hours restriction. With no annotations and a bare schema, this is a fully self-sufficient description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has only parameter names and titles with zero descriptions, yet the docstring compensates fully: it explains OCC symbols, enumerates valid transaction values, defines limit_type, gives an example of debit call spreads, and notes default contract counts. Every schema parameter is meaningfully explained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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: 'Preview a two-leg option spread WITHOUT sending it (dry_run=True).' It also says 'Always call this first,' which unambiguously frames the tool's role in the order workflow and distinguishes it from the actual send step (place_option_spread).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly instructs that this tool should always be called first warnx and that the returned confirm_token must be passed unchanged to place_option_spread with identical arguments. This gives the agent a clear when-to-use rule and names the follow-up tool. It also states the dry_run behavior so users know no order is sent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

preview_stock_orderA

Preview a stock order WITHOUT sending it (dry_run=True). Always call this first.

Args: symbol: Ticker symbol (e.g. 'NVDA'). order_type: buy | sell | sell_short | buy_to_cover quantity: Number of shares. price_type: limit | market | stop | stop_limit | trailing_stop_dollar | trailing_stop_percent duration: day | day_ext | overnight | gt90 (gt90 ≈ GTC, 90-day) price: Limit price (required for limit/stop_limit orders). stop_price: Stop trigger price (required for stop/stop_limit orders).

Returns JSON with order preview confirmation data, plus "confirm_token": pass that token unchanged to place_stock_order (with the identical order arguments) to actually send it. The token expires in 10 minutes and works once.

ParametersJSON Schema
NameRequiredDescriptionDefault
priceNo
symbolYes
durationNogt90
quantityYes
order_typeYes
price_typeNolimit
stop_priceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It clearly states the order is not sent (dry_run=True), and discloses the token's expiry (10 minutes) and single-use nature. It also specifies required parameters for certain order types, which is critical for correct invocation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description front-loads the purpose and mandatory usage instruction, then organizes parameters in a compact Args list with inline allowed values. It avoids redundancy and includes only necessary details about the token flow. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with an output schema, the description covers all required guidance: prerequisites, parameter semantics, conditional fields, and the handoff to place_stock_order. No gaps exist that an agent would need to fill.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 0% schema description coverage, the description meticulously documents each parameter with allowed values (e.g., order_type: buy/sell/sell_short/buy_to_cover; price_type: limit/market/...; duration: day/day_ext/overnight/gt90). It also explains the conditional requirements for price and stop_price based on price_type, adding meaning far beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Preview a stock order WITHOUT sending it'. This is distinct from siblings like place_stock_order or preview_option_order. The dry_run=True clarification adds precision. Clear and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs 'Always call this first' and explains that the returned confirm_token must be passed to place_stock_order to actually send the order. This workflow guidance clearly differentiates when to use this tool versus the placement tool, and its scope (stock orders) is implied.

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.

  1. 15 tool updatesv0.1.0
    • First observedcancel_order
    • First observedget_account_balance
    • First observedget_account_history
    • First observedget_account_position
    • First observedget_option_chain
    • First observedget_option_greeks
    • First observedget_orders
    • First observedget_single_quote
    • First observedget_watchlist_quote
    • First observedplace_option_order
    • First observedplace_option_spread
    • First observedplace_stock_order
    • First observedpreview_option_order
    • First observedpreview_option_spread
    • First observedpreview_stock_order

TDQS

A4/5.0

Scored across 15 tools

Disambiguation5/5

Each tool targets a distinct responsibility: account data, quotes, option chains/greeks, order preview vs. placement, and cancellation. The preview/place pairs are clearly separated by the confirm_token workflow, and even the two option-order tools (single vs. spread) are distinct in scope.

Naming Consistency4/5

The set follows a clear verb-first pattern: get_* for reads, preview_*/place_* for order flows, and cancel_order. Minor inconsistency exists between get_single_quote and get_watchlist_quote, which could be more uniformly get_quote/get_quotes, but the intent remains obvious.

Tool Count4/5

15 tools is at the upper edge of reasonable, but the count is justified by the trading domain: separate preview/place pairs for stocks, options, and spreads plus account data. Could be slightly consolidated (e.g., one quote tool), but it is not bloated.

Completeness4/5

The set covers the core brokerage workflow well: quotes, positions, balances, history, option chains/greeks, order preview/placement for stocks/options/spreads, and cancellation. Missing order modification/replacement, but cancel+recreate covers most needs.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    Enables AI assistants to interact with Interactive Brokers trading accounts to retrieve market data, check positions, and place trades. Includes pre-configured IB Gateway and handles OAuth authentication automatically.
    14
    518
    215
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables trading and portfolio management through the Alpaca API, allowing users to place orders, manage positions and watchlists, access market data, and retrieve account information through natural language.
    40
    3
    ISC
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to securely interact with Charles Schwab accounts through OAuth authentication, providing access to account balances, real-time market quotes, options chains, transaction history, order management, and comprehensive market data.
    1
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables LLMs to retrieve real-time stock and options market data through the E\*TRADE API using natural language. It features secure OAuth 1.0 authentication, persistent token management, and comprehensive support for stock quotes, options chains, and Greeks.
    2
    -