Skip to main content
Glama
questrade-mcp

questrade-mcp

by agustinsacco

Questrade MCP

A read-only Model Context Protocol server for Questrade. It covers Questrade's whole read API: accounts, balances, positions, activities, executions, orders, symbols, quotes, option chains with Greeks, candles and markets. It adds technical analysis and portfolio reports across accounts, and keeps responses small enough that a model can page through years of activity without flooding its context.

Not affiliated with Questrade. Read-only by design: no tool places, changes or cancels orders.

What it can do

Area

Tools

What you get

Context

qt_get_context, qt_list_accounts

sign-in state and command, accounts, default account, server time

Balances

qt_get_balances

cash, market value, equity, buying power; per currency and combined; start of day

Positions

qt_list_positions

quantity, cost, price, value, open/day P&L, currency, weight; totals per currency

Activity

qt_list_activities

trades, dividends, deposits, withdrawals, interest, fees, FX; any date range; filters; totals

Fills and orders

qt_list_executions, qt_list_orders, qt_get_order

fills with commission and fees; order history and one order in full

Symbols and quotes

qt_search_symbols, qt_get_symbols, qt_get_quotes, qt_list_markets

tickers to IDs, fundamentals (P/E, EPS, yield, 52-week range), live quotes with change, market hours

Options

qt_get_option_chain, qt_get_option_quotes

expiries, strikes near the money, IV and Greeks

Price history

qt_get_candles

stats, ASCII chart and OHLCV rows, 1 minute to 1 year candles

Analysis

qt_compare_symbols, qt_analyze_technicals, qt_screen_watchlist

% change and drawdown, RSI, SMA 50/200, VWAP, Bollinger Bands, screens

Reports

qt_run_report

portfolio summary, allocation, dividend income, activity summary (below)

19 tools, 2 resources (questrade://guide, questrade://limitations) and 3 prompts (portfolio_review, dividend_report, research_symbol). Every tool, parameter and default is listed in docs/TOOLS.md, which is generated from the server.

Reports

qt_run_report works across all active accounts (or one), and every result states its basis:

Report

Source

Period

portfolio_summary

live balances; each account's total in CAD and USD at Questrade's rate

now

allocation

live positions combined by symbol, weights within each currency, by security type

now

dividend_income

dividend activities by symbol and by month

any range (default year to date)

activity_summary

activities by type and currency, net deposits per account, commissions

any range (default year to date)

How it handles Questrade's API

Questrade behaviour

Handling

Activities allow about a month per request

Any range is split into 30-day requests, back to back with no overlap, and cached briefly

Times need an ISO offset and Questrade works in Eastern time

Tools take YYYY-MM-DD (a Toronto day) or a full date-time; offsets follow DST

Positions carry no currency

Added from symbol details, so totals and weights never mix CAD and USD

Tools take numeric symbol IDs

Tools also accept exact tickers (XEQT.TO, AAPL); unknown ones get a pointer to qt_search_symbols

Candles stop at 2000 per request

Defaults per interval stay under it; a warning says when a range was cut

Each refresh token works once

Rotation is shared safely between processes (see Sign in)

Rate limits (X-RateLimit-Reset)

429s wait for the reset (at most 10 s) and retry; 5xx and network errors back off

What Questrade's API cannot do

See questrade://limitations:

  • No trading for personal apps (and this server never trades).

  • No tax lots, realized gains or tax slips: use Questrade's statements for tax filing.

  • No watchlists and no streaming through this server.

  • Quotes follow the account's market-data subscription and can be delayed.

Related MCP server: Webull MCP Server

Install

Node.js 20 or later. Agents get two things on top of the server:

  • the questrade-portfolio skill (skills/questrade-portfolio/SKILL.md), which covers first steps, sign-in, the tools and the rules;

  • the sign-in command, which the server puts into its connector description, qt_get_context (auth.signIn) and every auth error, with this machine's real path and host name.

pi / Phosphor: one command

pi install git:github.com/agustinsacco/questrade-mcp

pi installs the npm dependencies. The package's extension registers the questrade MCP server for every session (codemode exposure), and the skill joins every session's skill index. Phosphor can also install it from Settings → Skills & extensions. Until someone signs in, each new session shows:

Questrade is not signed in on <host>. In a terminal there, run: node <package>/bin/questrade-mcp.js login

A questrade entry in mcp.json takes precedence over the package's registration.

Claude Code and other clients: setup

git clone https://github.com/agustinsacco/questrade-mcp && cd questrade-mcp && npm install
node bin/questrade-mcp.js setup

setup looks for pi and Claude Code, shows each change and asks first:

  • pi: pi install <this folder>.

  • Claude Code: claude mcp add --scope user questrade …, plus a link at ~/.claude/skills/questrade-portfolio.

It then runs login and check. Re-running it skips whatever is already set up, and --yes accepts every step without asking. For other clients (Claude Desktop, Cursor, …) it prints the config entry to add:

{ "mcpServers": { "questrade": { "command": "node", "args": ["/path/to/questrade-mcp/bin/questrade-mcp.js"] } } }

Clients without skills can read the same guide from the questrade://guide resource. Credentials stay on the machine that runs the server, so sign in on each machine where it runs.

Sign in

node bin/questrade-mcp.js login
  1. Log in at https://my.questrade.com and open App Hub → API Centre. Activate API access the first time.

  2. Open your personal app (register one if needed), click New manual authorization, then Generate new token.

  3. Paste the token at the hidden prompt. It is never printed.

login exchanges the token right away, so a mistyped or already-used token is caught immediately. Tokens are stored outside the repository in ~/.config/questrade-mcp/credentials.env, mode 600 (override with QUESTRADE_CREDENTIALS_FILE). Running servers pick up a new token on their next call. Other commands:

  • check verifies the login and lists the accounts.

  • secrets list shows which keys are set, never their values.

  • logout forgets the tokens. To revoke access on Questrade's side too, remove the authorization in the API Centre.

See credentials.env.example.

Token lifecycle. Access tokens last about 30 minutes, and each refresh token works once:

  • Every server process reads the current access token from the credentials file.

  • A refresh runs under a lock file and re-reads the file first, so when several processes (one per agent session) need a new token at once, only one spends the refresh token and the rest reuse its result.

  • A 401 on a token another process already replaced reuses the new one.

  • While a server runs it refreshes every 25 minutes, which keeps the chain alive. A manually generated token expires after 7 days if unused, so after a longer stretch with no server running, sign in again.

  • Writes are atomic (temp file, fsync, rename, chmod 600).

Configuration

Variable

Default

Meaning

QUESTRADE_ACCOUNT_ID

auto

Default account. Otherwise the only active account; with several, tools ask for accountId

QUESTRADE_MCP_TOOLSETS

all

Comma list: context,accounts,market,analysis,reports

QUESTRADE_MCP_MAX_RESPONSE_CHARS

60000

Hard cap per tool result (trailing list items are dropped, with a note)

QUESTRADE_MCP_MAX_RANGE_DAYS

3660

Longest activity/execution/order range one call may fetch

QUESTRADE_MCP_CACHE_TTL_MS

60000

Cache for account data, ranges and candles

QUESTRADE_MCP_MAX_CONCURRENCY

4

Concurrent Questrade requests

QUESTRADE_MCP_TIMEOUT_MS / QUESTRADE_MCP_MAX_RETRIES

30000 / 3

Per request

QUESTRADE_MCP_NO_KEEPALIVE

off

Skip the 25-minute refresh while the server runs

QUESTRADE_MCP_LOG_LEVEL

info

debug, info, warn, error, silent (stderr only)

QUESTRADE_MCP_HTTP_HOST / _PORT / _PATH

127.0.0.1 / 8788 / /mcp

HTTP transport

QUESTRADE_MCP_ALLOWED_HOSTS

loopback

Host/Origin allow-list for HTTP

QUESTRADE_MCP_HTTP_TOKEN

—

Bearer token for HTTP (credentials file); required off loopback

QUESTRADE_CREDENTIALS_FILE

~/.config/questrade-mcp/credentials.env

Credentials file (QUESTRADE_TOKEN_FILE, the 1.x name, still works)

Use it

Ask things like "what's my allocation across TFSA and RRSP?", "how much did I get in dividends last year, by month?", "show my trades in XEQT this year", or "compare XEQT.TO, VFV.TO and AAPL over 3 years". The prompts give ready-made versions: portfolio_review, dividend_report (year) and research_symbol (symbol).

Streamable HTTP (one server for several clients)

node bin/questrade-mcp.js serve --http                      # http://127.0.0.1:8788/mcp
QUESTRADE_MCP_HTTP_HOST=100.x.y.z QUESTRADE_MCP_ALLOWED_HOSTS=myhost,100.x.y.z node bin/questrade-mcp.js serve --http

Off loopback the server refuses to start without QUESTRADE_MCP_HTTP_TOKEN, and clients send Authorization: Bearer <token>. Host and Origin headers are validated against DNS rebinding. GET /healthz reports liveness.

Response design

  • Pagination everywhere. Lists use page/pageSize (default 20, max 100); reports and candles use offset/limit. Every response says hasMore and gives nextPage/nextOffset.

  • Summary by default. detail: "summary" returns key fields and clips long text; "full" returns every field Questrade sends.

  • Compact JSON. Nulls, empty strings and empty lists are dropped.

  • A hard budget. Results above QUESTRADE_MCP_MAX_RESPONSE_CHARS are trimmed, never silently.

  • Totals cover all rows even when only a page of rows is returned.

  • Errors are tool results (isError: true) whose text names the fix: Questrade's own message and code, the account choices when one is needed, unknown tickers, auth problems with the command to run.

MCP practices followed

  • Official TypeScript SDK v2 (@modelcontextprotocol/server), spec 2026-07-28, serving 2025-era clients from the same factory over stdio and Streamable HTTP.

  • Zod input schemas with per-field descriptions and bounds; arguments are validated before handlers run.

  • Tool annotations on every tool: readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true.

  • Server instructions, resources for the guide and limitations, and user-invoked prompts.

  • stdout carries only JSON-RPC; logs go to stderr with secrets redacted.

  • Toolsets for least privilege; no tool accepts or reveals credentials.

Security

  • Read-only: no order placement, cancellation or any other write.

  • Credentials live only in the mode-600 credentials file on the machine that runs the server. They are never in MCP arguments, logs or tool results. login and secrets set read them with echo off.

  • Agents are told never to ask for a token in the chat, and never to run login themselves.

  • HTTP binds to loopback unless a bearer token is set.

Development

npm test          # unit + end-to-end over both transports against a fake Questrade (no network)
npm run smoke     # live, with your credentials: every tool once, against the default account
npm run docs      # regenerate docs/TOOLS.md (a test fails when it is out of date)
npm run inspect   # MCP Inspector

The fake Questrade (test/helpers/fake-questrade.js) behaves like the real one where it matters:

  • one-use refresh tokens, and only the latest access token works;

  • the 31-day activity limit (error 1003);

  • { code, message } errors and rate limits.

The token tests run six real processes at once to prove only one spends the refresh token.

Migrating from 1.x

2.0 matches wave-mcp: the same SDK, CLI, install paths and response design. Tool names follow its list_/get_ convention:

1.x

2.0

qt_get_accounts

qt_list_accounts (or qt_get_context)

qt_get_positions

qt_list_positions

qt_get_transactions

qt_list_activities

qt_get_orders

qt_list_orders

qt_lookup_symbol

qt_search_symbols

qt_get_quotes, qt_get_candles, qt_get_balances, qt_compare_symbols, qt_analyze_technicals, qt_screen_watchlist

same names; symbols may also be tickers

Account tools no longer fall back silently to the first account: set QUESTRADE_ACCOUNT_ID or pass accountId. Times may be plain dates. src/main.js is now bin/questrade-mcp.js, and the credentials file gains the current access token, so several processes can share it.

wave-mcp, an MCP server for Wave accounting, works the same way: it installs the same way, signs in the same way, and has the same CLI and response design.

License

MIT

Available Tools

11 tools
qt_analyze_technicalsB

Calculate technical indicators (RSI, SMAs, VWAP, Bollinger Bands) for a given symbol over a timeframe.

NameRequiredDescriptionDefault
endTimeYes
intervalNo
symbolIdYes
startTimeYes

TDQS

B3.1/5.0
Behavior2/5

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

No annotations are provided, so the description must carry the full burden of behavioral disclosure. It states the action but does not disclose whether this is read-only, requires permissions, has rate limits, or what happens with insufficient data. It adds no traits beyond the stated calculation.

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 a single concise sentence with no filler. It front-loads the verb and resource, making the purpose immediately clear.

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

Completeness2/5

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

For a four-parameter tool with no output schema and no annotations, this description is too sparse. It does not describe the return shape, interval options, or time format requirements, so an agent may call it with incorrect or incomplete inputs.

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

Parameters2/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 maps 'symbol' and 'timeframe' to symbolId and startTime/endTime, but it does not explain the 'interval' parameter or time string formats. Several parameters remain undocumented by both schema and description.

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 ('Calculate') and names the resource ('technical indicators') with explicit indicator list (RSI, SMAs, VWAP, Bollinger Bands). It clearly distinguishes this from sibling tools like qt_get_candles, which fetch raw price data, and qt_compare_symbols, which compare symbols.

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 alternatives. It does not mention qt_get_candles for raw data or any exclusions, so an agent must infer the use case from the name and description alone.

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

qt_compare_symbolsC

Compare performance of multiple symbols with normalized chart

NameRequiredDescriptionDefault
endTimeYes
intervalNo
startTimeYes
symbolIdsYes

TDQS

C2.7/5.0
Behavior2/5

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

With no annotations, the description carries the full disclosure burden, but it only names the operation and the 'normalized chart' output concept. It does not explain how normalization works, what the output format is, symbol limits, or whether this is a read-only analysis, leaving significant behavioral uncertainty.

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 front-loaded sentence with no filler; every word earns its place. It is not penalized more here because the missing detail is accounted for in other dimensions.

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

Completeness2/5

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

The tool has four parameters, no output schema, and no annotations, and sits among ten related siblings, yet the description gives no return type, no comparison methodology, and no constraints on symbols or time ranges. An agent cannot reliably decide versus siblings or predict the output.

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

Parameters2/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 adds meaning only for symbolIds ('multiple symbols') and vaguely implies time via 'performance', but startTime/endTime formats and the interval enum are left entirely to the schema, which itself has no descriptions.

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 uses a specific verb ('Compare') and resource ('performance of multiple symbols'), and adds a distinctive detail ('normalized chart') that separates it from sibling tools that fetch quotes/candles or analyze technicals. It does not explicitly name a sibling alternative, so it falls just short of a 5.

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?

There is no guidance on when to choose qt_compare_symbols over qt_get_candles, qt_analyze_technicals, or qt_screen_watchlist. The sentence only states the action; it does not give conditions, prerequisites, or exclusions.

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

qt_get_accountsA

Get all Questrade accounts

NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations, the description carries the burden. 'Get' signals a read-only operation and 'all' implies no filtering, but it does not disclose authentication/session requirements, rate limits, or whether the response is a flat list. This is acceptable but shallow.

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 a single sentence with no filler, and the key verb/resource appears first. It is appropriately sized for a simple zero-parameter tool.

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?

For a zero-parameter list, the description is a minimum viable summary, but there is no output schema or annotation to clarify what an account object looks like or whether prerequisites exist. More context would improve call confidence.

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 parameters, so the schema is trivially covered. The description's 'all' clarifies no filtering is available or needed, matching the empty schema. Baseline 4 applies.

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 names a specific verb ('Get') and resource ('all Questrade accounts'), and the scope ('all') distinguishes it from sibling tools that retrieve positions, balances, quotes, orders, etc. This is a clear, non-tautological statement of function.

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?

There is no explicit statement of when to use this tool or exclusions, but the resource name and sibling list imply it is for retrieving the account list, not positions, balances, or quotes. This is implied usage rather than explicit guidance, so a 3.

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

qt_get_balancesC

Get account balances

NameRequiredDescriptionDefault
accountIdNo

TDQS

C2.6/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, but it only says "Get account balances." While "Get" implies a read-only operation, it does not disclose whether an omitted accountId returns all balances, what authorization is expected, or what the response contains.

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 extremely concise and front-loaded, with no filler or redundant phrasing. However, it is so minimal that it may be under-specified rather than deliberately efficient, though purely as a concise statement it works.

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

Completeness2/5

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

Given no annotations, no output schema, and a single undocumented parameter, the description is not complete enough for an agent to understand behavior, response shape, or accountId handling. The statement only provides enough surface-level information to know what resource the tool acts on.

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

Parameters1/5

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

The schema exposes a single optional accountId parameter, and the description adds no meaning beyond the property name. With 0% schema description coverage, the description should clarify how accountId is used or what happens when it is omitted, but it does not.

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 "Get account balances" clearly identifies the action (get) and resource (account balances), making it distinguishable from sibling tools like qt_get_positions or qt_get_quotes. It is not a tautology, though it does not elaborate on the exact scope of 'balances' or whether it covers all accounts or a single specified account.

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 provides no guidance on when to choose this tool over its siblings, such as qt_get_accounts or qt_get_positions. There is no mention of intended scenarios, exclusions, or how the optional accountId affects the call.

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

qt_get_candlesC

Get historical candle data with ASCII chart

NameRequiredDescriptionDefault
endTimeYes
intervalNo
symbolIdYes
startTimeYes

TDQS

C2.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 carries the full burden of behavioral disclosure. It only adds 'with ASCII chart' as an output behavior; it does not disclose read-only status, authentication needs, default interval behavior, timezone handling, pagination, limits, or error behavior. This is insufficient for a tool with no annotation support.

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, front-loaded sentence with no wasted words. It efficiently communicates the core action and a notable output feature. However, it is so minimal that it leaves out important operational detail, so it does not earn a 5.

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

Completeness2/5

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

Given four parameters, no output schema, no annotations, and 0% schema description coverage, the description is far too sparse to enable confident invocation. It fails to explain timestamp formats, what happens when interval is omitted, possible output variants, or how the ASCII chart is rendered. An agent would have to guess at several important invocation details.

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

Parameters1/5

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

Schema description coverage is 0%, and the description mentions none of the four parameters by name. The agent gets no additional meaning about symbolId, startTime, endTime, or interval beyond their raw names. The description does nothing to compensate for the schema's complete lack of parameter documentation.

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 clearly states a specific verb ('Get'), a specific resource ('historical candle data'), and even indicates the output style ('with ASCII chart'). It is easy to understand what the tool does. However, it does not explicitly differentiate itself from siblings such as qt_get_quotes or qt_analyze_technicals, leaning on the term 'candles' to imply the distinction.

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?

There is no guidance about when to use this tool versus related siblings. The description does not mention that qt_get_quotes is better for current prices, or that qt_analyze_technicals might be a better choice for analysis. An agent receives no contextual decision-making support.

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

qt_get_ordersB

Get read-only orders for an account, optionally filtered by state and date range.

NameRequiredDescriptionDefault
endTimeNo
accountIdNo
startTimeNo
stateFilterNo

TDQS

B3.1/5.0
Behavior3/5

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

With no annotations, the description must carry the burden of behavioral disclosure. It does state that the operation is read-only and that filters are optional, which are useful traits. However, it does not mention authentication needs, date format expectations, default behavior, or what happens when optional parameters are omitted.

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 sentence that front-loads the core purpose and remains free of filler. It is appropriately concise, though it sacrifices some useful detail for brevity.

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

Completeness2/5

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

Given four unannotated parameters and no output schema, the description is too sparse to fully support correct invocation. It does not explain parameter formats, required vs optional behavior, output shape, or error cases, leaving significant gaps for an agent relying solely on this definition.

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. It adds meaning by saying filters are by 'state and date range', which maps to stateFilter, startTime, and endTime; 'for an account' implies accountId. However, it does not clarify date formats, enum semantics, or default values.

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 clearly identifies the resource as 'orders' and the action as 'Get', with the scope being 'for an account'. It distinguishes its subject matter from sibling tools like qt_get_positions and qt_get_balances by naming the specific resource type, though it does not explicitly contrast itself with them.

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 explicit guidance on when to use this tool instead of siblings. It implies the tool is for retrieving orders and optionally filtering, but there are no exclusions, prerequisites, or alternative tool references.

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

qt_get_positionsC

Get current positions for an account

NameRequiredDescriptionDefault
accountIdNo

TDQS

C2.4/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 does not state whether this is a read-only operation (likely implied by 'Get') or what the response looks like. It also does not mention if it provides real-time data, historical positions, or if it requires authentication. The description is too minimal to be transparent.

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 short sentence that is concise and front-loaded. It is not verbose, but its brevity sacrifices necessary detail. It earns a 4 for efficiency, but loses a point for lack of completeness.

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

Completeness2/5

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

Given it's a simple tool with one parameter and no output schema, the description is extremely sparse. It does not explain what positions are, how the accountId is used, or the nature of the response. An agent would have limited understanding of how to use this correctly, especially with no annotations to fall back on.

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

Parameters2/5

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

Schema description coverage is 0%, meaning the schema provides no descriptions. The description only mentions 'accountId' implicitly by saying 'for an account', but does not explain its format, requiredness, or how to obtain it. Since the schema has one parameter with no description, the tool description should at least clarify the parameter's role, which it barely does.

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

Purpose3/5

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

The description 'Get current positions for an account' clearly states the verb 'Get' and the resource 'positions', with the scope being 'for an account'. It is somewhat generic but does identify a distinct purpose from siblings like qt_get_balances or qt_get_orders. However, it doesn't specify what a 'position' is in this context (e.g., holdings, open trades), which could cause ambiguity.

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?

There is no guidance on when to use this tool versus alternatives. It does not mention prerequisites (e.g., need an account ID) or differentiate from qt_get_balances (which may also relate to account holdings). The sibling list suggests multiple financial data tools, but the description provides no context for choosing this one.

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

qt_get_quotesA

Get read-only real-time quotes for one or more symbol IDs.

NameRequiredDescriptionDefault
symbolIdsYes

TDQS

A3.7/5.0
Behavior3/5

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

With no annotations provided, the description carries the full behavioral burden. It explicitly labels the operation 'read-only', which is a key safety indicator, but it does not disclose output format, data freshness guarantees, error behavior, or any rate limits.

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 sentence that front-loads the core action and scope, with no filler or redundant information. Every word contributes meaning.

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?

The tool is simple, with one parameter, and the description covers purpose and input. However, with no output schema and no annotations, the return value structure and underlying data source are left undefined, leaving some ambiguity for an agent expecting quote fields.

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. It clarifies that 'symbolIds' refers to symbol identifiers and supports 'one or more', complementing the schema's array constraints. It does not explain how to obtain or resolve symbol IDs.

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?

Description states a specific verb ('Get'), a precise resource ('real-time quotes'), and the input scope ('one or more symbol IDs'). This clearly differentiates it from sibling tools such as qt_get_candles, qt_get_accounts, and qt_lookup_symbol.

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 'real-time' qualifier implies use for current market data as opposed to historical data from qt_get_candles, but there is no explicit statement of when to use or avoid this tool, and no alternatives are named. Usage must be inferred.

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

qt_get_transactionsC

Get historical transactions/activities for an account

NameRequiredDescriptionDefault
endTimeYes
accountIdNo
startTimeYes

TDQS

C2.7/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. 'Get' and 'historical' imply a read-only operation, but the description does not state authentication requirements, date-range semantics, pagination, or what response shape to expect.

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 sentence with no filler and the key verb is front-loaded. It is concise, though slightly vague with 'transactions/activities'.

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

Completeness2/5

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

Given the large sibling set, no output schema, and no parameter documentation, the description is too thin for an agent to confidently select and invoke the tool. It needs more context about parameter behavior, result shape, and how this differs from related data tools.

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

Parameters2/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 loosely maps to the parameters via 'historical' (startTime/endTime) and 'account' (accountId), but it does not explain time format, whether the range is inclusive, or how accountId behaves when omitted.

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 uses a specific verb ('Get') and identifies the resource ('historical transactions/activities') and scope ('for an account'). It is not a tautology and clearly conveys the tool's core function, but it does not explicitly distinguish it from sibling tools like qt_get_orders or qt_get_candles.

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 provides no guidance on when to use this tool versus alternatives, no exclusions, and no context about prerequisites. An agent cannot tell from the description why it should choose this over qt_get_orders or other sibling tools.

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

qt_lookup_symbolC

Search for a stock symbol ID

NameRequiredDescriptionDefault
prefixYes

TDQS

C2.3/5.0
Behavior2/5

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

With no annotations, the description carries the full burden of explaining behavior. It only says 'search', without covering prefix matching semantics, case sensitivity, number of matches, or data source. It is not misleading, but it is seriously under-informative.

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

Conciseness2/5

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

One short sentence with no filler, but it is under-specified rather than appropriately concise. It leaves out essential semantic content that the tool name does not supply.

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

Completeness2/5

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

For a one-parameter tool with no output schema, the description should at least state what the prefix means and what a successful lookup returns. It does neither, so an agent lacks enough information to invoke it correctly and interpret the result.

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

Parameters2/5

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

The schema provides only a string type and no description, and schema coverage is 0%. The description never explicitly explains that 'prefix' is the text used to search, though the parameter name makes that inference easy. This is minimal added meaning.

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

Purpose3/5

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

The description names a concrete action and object ('search for a stock symbol ID'), so the basic purpose is identifiable. However, it is close to a restatement of the tool name and does not clarify what kind of result is returned or how it differs from sibling symbol-related tools.

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 on when to call this tool versus alternatives like qt_compare_symbols or qt_get_quotes. There are no conditions, prerequisites, or exclusions, so the agent must guess from the name.

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

qt_screen_watchlistC

Screen a list of symbols against technical criteria (e.g. maxRsi, mustBeAbove200Sma).

NameRequiredDescriptionDefault
endTimeYes
criteriaNo
intervalNo
startTimeYes
symbolIdsYes

TDQS

C2.7/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions screening against criteria but doesn't state whether this is a read-only operation, whether it fetches live data, how results are returned, or any side effects. For a screening tool that likely performs computation over time series, the lack of behavioral context is a notable gap.

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 sentence that is reasonably concise and front-loads the core purpose. It includes useful examples of criteria. However, it could be slightly more structured by separating the purpose from parameter details, but it is not overly verbose.

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

Completeness2/5

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

Given the tool has 5 parameters, a nested criteria object, no output schema, and no annotations, the description is incomplete. It doesn't explain the time range parameters, the interval enum, or how the criteria interact (e.g., AND vs OR). An agent would need to infer too much to call this tool correctly.

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

Parameters2/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 undocumented parameters. It only mentions two example criteria (maxRsi, mustBeAbove200Sma) and doesn't explain the meaning of startTime, endTime, interval, symbolIds, or the other criteria fields. The nested criteria object is left mostly unexplained, and the time range semantics are not described.

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 ('Screen') and resource ('a list of symbols') against technical criteria, with concrete examples (maxRsi, mustBeAbove200Sma). It is clear what the tool does, though it doesn't explicitly differentiate from siblings like qt_analyze_technicals or qt_compare_symbols, which could overlap in purpose.

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 on when to use this tool versus alternatives. Sibling tools like qt_analyze_technicals and qt_compare_symbols likely perform similar technical analysis, but the description doesn't explain the distinction or when to prefer one over the other. The context is implied by the name and description but not explicit.

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. 11 tool updatesv1.0.0
    • First observedqt_analyze_technicals
    • First observedqt_compare_symbols
    • First observedqt_get_accounts
    • First observedqt_get_balances
    • First observedqt_get_candles
    • First observedqt_get_orders
    • First observedqt_get_positions
    • First observedqt_get_quotes
    • First observedqt_get_transactions
    • First observedqt_lookup_symbol
    • First observedqt_screen_watchlist

TDQS

B3.2/5.0

Scored across 11 tools

Disambiguation4/5

Most tools target distinct resource types: accounts, positions, balances, quotes, orders, candles, transactions, and symbol lookup. The slight overlap is among compare_symbols, analyze_technicals, and screen_watchlist, but their descriptions differentiate normalized charting, indicator calculation, and criteria-based screening well enough.

Naming Consistency5/5

Every tool uses the qt_ prefix and follows a clear verb_noun pattern, such as qt_get_accounts, qt_lookup_symbol, and qt_screen_watchlist. Although verbs vary beyond get, the convention is consistent and predictable across the entire set.

Tool Count5/5

With 11 tools, the server is well-scoped for Questrade data retrieval and analysis. Each tool serves a distinct purpose, and the count is appropriate for covering account data, market data, historical candles, and technical screening without unnecessary bloat.

Completeness4/5

The toolset covers account information, positions, balances, orders, quotes, candles, transactions, symbol lookup, comparisons, and technical analysis. It appears intentionally read-only, so order placement/cancellation is absent, but for market data and analysis workflows the coverage is strong with only minor gaps.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables querying portfolio data, positions, balances, quotes, price history, orders, and account activity through the Questrade API.
    70 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables MCP clients to read Webull account balances, positions, orders, stock quotes, historical bars, and US option market data, with live equity trading available only as an explicitly enabled opt-in.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables read-only access to Finary portfolio data, including profiles, organizations, institution connections, portfolios, and transactions, through MCP.
    5
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients to securely access read-only Psagot Trade account and market information through authenticated HTTP endpoints. It exposes only read-only tools, with no trade-submission capabilities.
    -