schwab-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., "@schwab-mcpWhat's my account balance?"
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.
schwab-mcp
A local MCP server exposing the Charles Schwab Individual Trader API (accounts, quotes, orders, transactions) as MCP tools, built on schwabdev.
See CLAUDE.md for architecture/conventions.
Setup
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
cp .env.example .env
# fill in SCHWAB_CLIENT_ID, SCHWAB_CLIENT_SECRET, SCHWAB_REDIRECT_URI
python scripts/authorize.py # one-time interactive browser loginRe-run scripts/authorize.py whenever the refresh token expires (every 7
days, per Schwab's policy).
Related MCP server: Schwab MCP Server
Connecting to Claude Desktop
Claude Desktop launches MCP servers as a separate process without your
shell's environment, so pass credentials explicitly via env rather than
relying on .env discovery. Edit (or create)
~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"schwab": {
"command": "/Users/edhac/Workspace/schwab-mcp/.venv/bin/python",
"args": ["-m", "schwab_mcp.server"],
"env": {
"SCHWAB_CLIENT_ID": "your-client-id",
"SCHWAB_CLIENT_SECRET": "your-client-secret",
"SCHWAB_REDIRECT_URI": "https://127.0.0.1",
"SCHWAB_TOKEN_PATH": "~/.schwab-mcp/tokens.db"
}
}
}
}Then fully quit and reopen Claude Desktop. Run scripts/authorize.py
manually first (Claude Desktop can't complete the interactive browser login
itself) — the server will raise a clear error on startup if the token db is
missing or the refresh token has expired, telling you to do this.
Available Tools
10 toolscancel_orderA
Cancel a live (working/pending) order in one Schwab account.
SAFETY CRITICAL / two-step confirmation flow. This tool NEVER cancels an order on the first call:
With confirm=False (the default, and how this must always be called the first time), the current order's details are fetched from Schwab (NOT cancelled) so the user can see exactly what they're about to cancel. You MUST show these details to the user in full and obtain their explicit confirmation before calling this tool again.
Only after the user has explicitly confirmed should this tool be called again with the same order_id and confirm=True. Only then is the order actually cancelled with Schwab.
Args: account_number: The plain Schwab account number as shown to the user (not the internal account hash). order_id: The Schwab order id to cancel. confirm: Must be False (default) for the initial lookup call, and True only on a follow-up call after the user has explicitly confirmed. Never default this to True.
Returns: If confirm is False: the current order's details, not cancelled. If confirm is True: confirmation that the order was cancelled.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | ||
| order_id | Yes | ||
| account_number | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly states that the tool NEVER cancels on the first call, that confirm=False fetches details without cancelling, and that confirm=True is required for actual cancellation. It also warns about the safety-critical nature and the need to show details to the user.
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 with clear sections, a safety warning, and a bulleted flow. It is somewhat long but every sentence earns its place given the safety-critical nature. The front-loaded warning and step-by-step explanation are appropriate for the 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's complexity (two-step confirmation, safety-critical), the description is complete. It covers the workflow, parameter semantics, return behavior for both confirm values, and the required user confirmation step. No output schema exists, but the description explains what is returned in each mode.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains account_number as the plain Schwab account number (not internal hash), order_id as the Schwab order id, and confirm with its default and the two-step semantics. It doesn't describe the exact format of order_id or account_number beyond that, but it adds significant meaning beyond the bare 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 ('Cancel') and resource ('a live (working/pending) order in one Schwab account'), and distinguishes it from siblings like get_order and list_orders by emphasizing it is the cancellation tool. It also clarifies the two-step confirmation flow, which makes its 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 explicitly explains when to call the tool (first call with confirm=False to fetch details, second call with confirm=True after user confirmation) and what not to do (never default confirm to True). It also implies the alternative of using get_order for viewing details, and provides a clear safety-critical workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_accountA
Get one Schwab account's details (balances, and optionally positions).
Args: account_number: The plain Schwab account number as shown to the user (not the internal account hash). include_positions: If True, also include the account's current positions.
Returns: A single account detail object.
| Name | Required | Description | Default |
|---|---|---|---|
| account_number | Yes | ||
| include_positions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It usefully clarifies that account_number is the plain user-visible number (not internal hash) and that include_positions controls position inclusion. However, it omits error behavior, auth requirements, and the exact structure of the returned object.
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 well-structured, with no redundant content. The purpose is front-loaded and the arg/return format is standard.
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 2-parameter, no-output-schema tool, the description provides the essential operational details but leaves the return object's contents (beyond balances/positions) unspecified. Since no annotations or output schema exist, this is a notable gap for an agent deciding if the tool yields enough information.
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?
Both parameters are given meaningful context beyond the schema: account_number's required format is clarified, and include_positions' effect is stated. This fully compensates for the 0% schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb (Get), resource (one Schwab account's details), and scope (balances and optionally positions). It distinguishes itself from list_accounts by specifying 'one' account, and from quote/order/transaction tools by the resource type.
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 siblings like list_accounts. The description implies single-account retrieval but never names alternatives or exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_orderA
Get the full details of one order in one Schwab account.
Read-only; does not place, modify, or cancel anything.
Args: account_number: The plain Schwab account number as shown to the user (not the internal account hash). order_id: The Schwab order id to look up.
Returns: A single order object.
| Name | Required | Description | Default |
|---|---|---|---|
| order_id | Yes | ||
| account_number | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and explicitly states 'Read-only; does not place, modify, or cancel anything,' which is the critical behavioral disclosure for a trading-related tool. It also states the return is 'a single order object,' though it does not discuss failure modes or auth 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 well-organized, with the verb, resource, and scope front-loaded. The labeled Args and Returns sections make each piece easy to parse, and every sentence contributes purpose, behavioral safety, parameter meaning, or return shape.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter read tool with no output schema, the description provides the return type, read-only guarantee, and full parameter semantics. An agent has enough information to invoke the tool correctly; the only minor gap, explicit sibling routing, is already covered by the clear scoping language.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the Args section must supply the meaning, and it does. It clarifies that account_number is the plain account number as shown to the user and not the internal account hash, and it identifies order_id as the Schwab order id to look up. Both parameters are meaningfully documented beyond their bare titles.
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 uses a specific verb ('Get'), a singular resource ('one order'), and a scoping qualifier ('in one Schwab account'), which clearly separates it from list_orders and other siblings. The read-only line further clarifies what the tool does not do.
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 scopes the operation to retrieving a single known order by account and order id, which implies when it should be used. It does not explicitly contrast it with list_orders or name exclusions, 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.
get_quoteA
Get a real-time quote for a single symbol.
Args: symbol: The ticker symbol to quote (e.g. "AAPL").
Returns: A dict with a single key (the requested symbol) mapping to that symbol's quote data.
| Name | Required | Description | Default |
|---|---|---|---|
| symbol | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the behavioral burden. It does disclose that the quote is real-time and describes the return structure as a dict with one key per symbol. However, it does not mention error behavior, quote data fields, or any operational caveats.
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 well-structured with separate Args and Returns sections. Every sentence adds value, and the 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 simple one-parameter read tool, the description covers the purpose, parameter semantics, and return shape. The only notable gap is that 'quote data' is not expanded into specific fields, and no output schema exists to fill that 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 only defines 'symbol' as a string, but the description adds meaningful semantics: 'The ticker symbol to quote (e.g. "AAPL").' This fully compensates for the 0% schema description coverage and gives the agent a concrete example.
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: 'Get a real-time quote for a single symbol.' The 'single symbol' scope clearly distinguishes it from the sibling get_quotes, and the purpose is immediately understandable.
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 'single symbol' phrasing implies when this tool is appropriate, and the sibling name get_quotes suggests the alternative, but the description never explicitly says 'for multiple symbols use get_quotes.' The guidance is left to inference rather than being stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_quotesA
Get real-time quotes for multiple symbols in a single call.
Args: symbols: List of ticker symbols to quote (e.g. ["AAPL", "MSFT"]).
Returns: A dict keyed by each requested symbol, mapping to that symbol's quote data.
| Name | Required | Description | Default |
|---|---|---|---|
| symbols | Yes |
TDQS
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 quotes are real-time and specifies the return shape as a dict keyed by requested symbol, which is meaningful behavioral context. It does not mention auth or rate limits, but for a simple read-only quote fetcher this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with the main purpose, and uses a clear Args/Returns structure. Every sentence adds value; the example is useful and not redundant.
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 tool with no output schema and no annotations, the description is complete: it explains what the tool does, what the argument means, and what the return value looks like. Nothing essential 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 0%, so the description must compensate. It fully documents the only parameter: a list of ticker symbols, with an example (['AAPL', 'MSFT']). This adds all needed meaning beyond the raw array-of-strings 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 uses a specific verb and resource: 'Get real-time quotes for multiple symbols in a single call.' The plural scoping directly distinguishes it from the sibling get_quote without any ambiguity.
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 phrase 'multiple symbols in a single call' implies the appropriate use case, and the sibling name get_quote makes the alternative inferable. However, it never explicitly says when to use get_quotes versus get_quote or notes any exclusions, so the guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_transactionA
Get full details for a single transaction on one Schwab account.
Args: account_number: The plain Schwab account number as shown to the user (not the internal account hash). transaction_id: The Schwab transaction id to fetch.
Returns: A single transaction object.
| Name | Required | Description | Default |
|---|---|---|---|
| account_number | Yes | ||
| transaction_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It communicates a read-style operation via 'Get' and states the return shape, but it does not mention error behavior, permissions, or what 'full details' includes. This is adequate for a simple fetch 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in one sentence, and the Args and Returns sections each add necessary information with no filler. Every line 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 tool with only two required parameters and no output schema, the description gives enough to invoke it correctly and understand the result is a single transaction object. It could be slightly stronger by referencing list_transactions for multi-transaction needs, but that is not essential.
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 provides only bare string types with 0% coverage, so the description must compensate. It does, especially for account_number, clarifying that the value must be the user-facing plain number rather than the internal account hash, and it identifies transaction_id as Schwab's transaction id.
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, 'Get full details for a single transaction on one Schwab account,' uses a specific verb and resource and clearly scopes the operation. The word 'single' distinguishes it from sibling tools like list_transactions, and 'transaction' distinguishes it from get_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 makes the use case clear: you need full details for one transaction on one account. It does not explicitly name alternatives or state when-not-to-use, such as pointing to list_transactions for multiple transactions, but the single-transaction phrasing provides sufficient context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_accountsA
List every Schwab account linked to this API app, with balances.
Args: include_positions: If True, each account also includes its current positions (symbol, quantity, market value, cost basis, etc.) in addition to balances.
Returns: A list of per-account detail objects, one per linked account.
| Name | Required | Description | Default |
|---|---|---|---|
| include_positions | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It clearly states the tool lists accounts and optionally includes positions, and it describes the return shape. However, it does not disclose potential latency, pagination, auth requirements, or whether balances are real-time or delayed.
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 purpose is in the first sentence, and the parameter explanation is concise. 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 simple list tool with one optional boolean parameter and an output schema, the description is largely complete. It explains the return value and the parameter. Minor gaps: no mention of pagination or data freshness, but these are not critical for a list-accounts tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It does: it explains include_positions with concrete examples of what positions include (symbol, quantity, market value, cost basis). This adds real meaning beyond the bare boolean 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 ('List') and resource ('every Schwab account linked to this API app') and adds the balance detail, which distinguishes it from get_account (single account) and other siblings. It is 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this is the tool for listing all linked accounts, and the include_positions parameter clarifies an optional behavior. However, it does not explicitly state when to prefer this over get_account or other alternatives, 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.
list_ordersA
List orders entered for one Schwab account within a time window.
Read-only; does not place, modify, or cancel anything.
Args: account_number: The plain Schwab account number as shown to the user (not the internal account hash). from_entered_time: Start of the entered-time window (ISO-8601 datetime string). to_entered_time: End of the entered-time window (ISO-8601 datetime string). max_results: Optional cap on the number of orders returned. status: Optional order status filter (e.g. "FILLED", "CANCELED", "WORKING").
Returns: A list of order objects, most recent first.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | ||
| max_results | No | ||
| account_number | Yes | ||
| to_entered_time | Yes | ||
| from_entered_time | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and handles it well. It discloses read-only behavior, the entered-time window semantics, return ordering ('most recent first'), and a critical input constraint: the plain account number rather than the internal hash.
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: a one-sentence purpose, a behavioral warning, an Args block, and a Returns line. Each element adds necessary information without padding, and the parameter details are organized for quick 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?
Given the tool's moderate complexity and absent annotations/schema descriptions, the description covers all essential invocation details: account scope, time-window parameters, optional filters, input formats, read-only safety, and return ordering. An agent has enough to call it correctly without further inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description fully compensates by explaining all five parameters. It defines account_number format, ISO-8601 expectations for from/to times, max_results as an optional cap, and status with concrete examples.
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: 'List orders entered for one Schwab account within a time window.' It clearly establishes the plural, windowed scope and explicitly contrasts with mutating tools by saying it does not place, modify, or cancel anything, which distinguishes it from place_order and cancel_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 gives clear context: use this to retrieve orders for a single account within an entered-time window, and the explicit read-only note tells the agent not to use it for mutations. It does not explicitly name sibling alternatives like get_order or list_transactions, so it falls just 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.
list_transactionsA
List transactions for one Schwab account within a date range.
Args: account_number: The plain Schwab account number as shown to the user (not the internal account hash). start_date: Start of the date range, inclusive (ISO-8601 date or datetime string). end_date: End of the date range, inclusive (ISO-8601 date or datetime string). types: Required Schwab transaction-type filter, e.g. "TRADE", "DIVIDEND_OR_INTEREST". symbol: Optional ticker symbol to further filter transactions.
Returns: A list of transaction objects.
| Name | Required | Description | Default |
|---|---|---|---|
| types | Yes | ||
| symbol | No | ||
| end_date | Yes | ||
| start_date | Yes | ||
| account_number | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of behavioral disclosure. It states the operation and return type but is silent on pagination, ordering, error behavior, authorization prerequisites, or rate limits. The read-only nature is not explicitly disclosed.
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 with a one-sentence summary followed by an Args section and a Returns line. Every line earns its place and adds information not present in the input 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?
Given the tool has 5 parameterschery, no annotations, and no enum constraints, the description covers all required and optional parameters plus the return shape. It omits minor operational details like pagination and error handling, but the presence of an output schema reduces the need for describing return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the docstring must compensate, and it does thoroughly. It explains each parameter in plain terms, including the account_number nuance (plain number vs internal hash), inclusive ISO-8601 dates, required types filter with examples, and optional symbol filtering.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb and resource: 'List transactions for one Schwab account within a date range.' This clearly distinguishes the tool from siblings like get_transaction (single transaction) and list_orders (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?
The description implies when to use the tool through its scope ('one Schwab account', 'date range'), but it does not explicitly mention alternatives or provide exclusion conditions, such as using get_transaction for a single transaction. It provides clear context but no direct routing between siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
place_orderA
Preview or place a live order in one Schwab account.
SAFETY CRITICAL / two-step confirmation flow. This tool NEVER submits a live order on the first call:
With confirm=False (the default, and how this must always be called the first time for any new order), the order is only sent to Schwab's preview/dry-run endpoint, which validates and prices it WITHOUT submitting it to the market. The response contains the proposed order and Schwab's preview details. You MUST show these details to the user in full and obtain their explicit confirmation before calling this tool again.
Only after the user has explicitly confirmed should this tool be called again with the exact same order and confirm=True. Only then is the live order actually submitted to Schwab.
Args: account_number: The plain Schwab account number as shown to the user (not the internal account hash). order: The order object per Schwab's order schema (orderType, session, duration, orderStrategyType, price, orderLegCollection with instruction/quantity/instrument, etc.). confirm: Must be False (default) for the initial preview call, and True only on a follow-up call after the user has explicitly confirmed. Never default this to True.
Returns: If confirm is False: preview details and no order placed. If confirm is True: the submitted order's id and status.
| Name | Required | Description | Default |
|---|---|---|---|
| order | Yes | ||
| confirm | No | ||
| account_number | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure, and it does so thoroughly. It explicitly states that the tool NEVER submits a live order on the first call, explains the dry-run endpoint behavior, and describes the different return outcomes for confirm=False versus confirm=True.
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 lengthy but every sentence serves a safety-critical purpose. The key warning and two-step flow are front-loaded before parameter details, and the structure makes the conditional behavior easy to follow.
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, the lack of an output schema, and the absence of annotations, the description provides a complete picture: what happens on preview, what happens on confirmation, return values, and required user confirmation. Nothing essential to calling 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 description coverage is 0%, but the description compensates fully. It clarifies that account_number is the plain Schwab account number rather than the internal hash, explains the order object's key fields, and defines the confirm parameter's meaning, default, and safety implications.
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: 'Preview or place a live order in one Schwab account.' It clearly differentiates the tool from sibling order-management tools like list_orders and cancel_order by focusing on order submission rather than retrieval or cancellation.
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 defines the two-step confirmation flow: call with confirm=False first to preview, show the user the details, and only call with confirm=True after explicit user confirmation. This is a clear, unambiguous usage protocol that leaves no room for misinvocation.
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.
10 tool updates
v0.1.0- First observed
cancel_order - First observed
get_account - First observed
get_order - First observed
get_quote - First observed
get_quotes - First observed
get_transaction - First observed
list_accounts - First observed
list_orders - First observed
list_transactions - First observed
place_order
TDQS
Scored across 10 tools
Each tool maps to a unique resource-action pair: accounts list/get, quotes single/batch, orders list/get/place/cancel, transactions list/get. The only similar pair is get_quote vs get_quotes, but the singular/batch distinction is explicit and clear.
Tool names follow a consistent verb_noun pattern: list_* for collections, get_* for single items, and place_/cancel_ for state-changing order actions. This makes the API surface predictable and easy to navigate.
Ten tools is well-scoped for a brokerage server, covering accounts, market quotes, orders, and transactions without redundancy or bloat. Each tool earns its place and the count matches the domain breadth.
Core brokerage workflows are covered: account lookup, quoting, order placement/cancellation, and transaction history. Minor gaps exist, such as order modification/replacement, but the primary agent-facing operations are present and workable.
Maintenance
Related MCP Connectors
Multi-tenant FastMCP server for Charles Schwab brokerage data, monetized via DPYC Tollbooth
MCP server for OpenMM — exposes market data, account, trading, and strategy tools to AI agents
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
MCP server exposing the Backtest360 engine API as tools for AI agents.
Related MCP Servers
- FlicenseNot gradedqualityFmaintenanceA Model Context Protocol server that enables AI assistants like Claude to securely interact with Charles Schwab accounts and market data through the official Schwab API.75-
- AlicenseAqualityDmaintenanceA read-only MCP server that provides access to Charles Schwab account data and market information, including portfolio positions, real-time quotes, options chains, price history, and account balances through AI assistants.9MIT
- FlicenseAqualityDmaintenanceMCP server for the tastytrade brokerage API, providing tools for account management, market data, and order execution.18-
- AlicenseAqualityCmaintenanceRead-only MCP server for Interactive Brokers that exposes market data, positions, and account info as MCP tools.8MIT