tastytradeDeveloper Docs
Legacy ↗

MCP Server

The tastytrade MCP server gives AI agents structured access to the tastytrade API through the Model Context Protocol. It exposes the API as MCP Tools, Resources, and Prompts, and gates order submission behind a dry-run-first confirmation flow.

Self-hosted and open source. You run it yourself. The source is at github.com/tastytrade/tastytrade-mcp. There is no tastytrade-hosted endpoint to connect to.

The default endpoint is production. With no environment configured, the server connects to the production API, where every account the supplied credentials can reach is a real brokerage account and every order moves real money, immediately and irreversibly. Set TASTYTRADE_ENV=sandbox for an environment with no real money in it, and TASTYTRADE_READ_ONLY=1 to withhold every write and destructive tool.

Production is the default deliberately: the sandbox does not serve market data, and a default endpoint that cannot quote would teach operators to override it without reading why.

Why an MCP server (vs. calling the REST API directly)

Trading APIs are unforgiving — wrong quantity, wrong account, or wrong symbol costs real money. The MCP server adds guardrails enforced server-side, so an agent cannot skip them:

  • Tools — direct API actions (get a quote, place an order, cancel an order…).
  • Resources — documentation bundles and computed account views the agent reads instead of stitching several tool calls together.
  • Prompts — pre-composed tool-call plans (LLMs follow plans more reliably than they compose them).
1

LLM clients

“Sell a 30-delta SOFI put and show my portfolio theta”

Interfaces

Claude Code
Cursor
Gemini CLI
Custom agents
requestanswer
2

tastytrade MCP Server

The bridge

Model Context Protocol
Tool registry
REST + DXLink router
Order validation

84 tools · one protocol

Translates plain language into API calls, then returns a plain-language answer. OAuth-scoped, dry-run safety checks.

API callsdata
3

tastytrade APIs

tastytrade API + DXLink
Market data · quotes, chains, greeks
Trading · orders, fills
Accounts · balances, positions
Watchlists, alerts & history
How the tastytrade MCP server connects LLM clients to your brokerage

Install

Clone-and-build is the supported install. Nothing is published to npm, and there is no published container image.

git clone https://github.com/tastytrade/tastytrade-mcp.git
cd tastytrade-mcp
npm ci
npm run build

Requires Node.js 22 or newer. The repo includes a Dockerfile that builds an image locally — note that a stdio server must be started with docker run -i, or the container exits immediately and looks like a crash.

Credentials

Authentication is environment-only; there is no interactive login flow. Create an OAuth client and refresh token out of band (see the OAuth2 guide, or my.tastytrade.com → Manage → My Profile → API), then supply three variables:

VariableRequired
TASTYTRADE_CLIENT_IDyes
TASTYTRADE_CLIENT_SECRETyes
TASTYTRADE_REFRESH_TOKENyes

Sandbox credentials are a separate OAuth application and are not interchangeable with production ones. A sandbox refresh token cannot mint an access token against production, or vice versa — and the failure is uninformative: every tool call returns auth_failed with nothing saying why.

The server does not auto-load a .env file. Export the variables yourself, or pass them through your MCP client's env block.

Choosing an environment

VariableEffect
TASTYTRADE_ENVproduction (default) or sandbox. Unset means production.
TASTYTRADE_API_URLExplicit base URL; wins over TASTYTRADE_ENV.
TASTYTRADE_READ_ONLY1 withholds and refuses all 14 write and destructive tools.
MAX_ORDER_NOTIONAL_USDCeiling on an order's buying-power impact (default 50000).

A TASTYTRADE_ENV the server cannot read — a typo like sandbx — resolves to the sandbox and says so, on the principle that a failed instruction must not land in the same place as an unset default. TASTYTRADE_READ_ONLY fails closed the same way.

Three surfaces announce the active environment: a stderr startup banner, the instructions field of the MCP initialize result (the only signal the agent itself can read), and an environment member on every order and dry-run result, so a transcript is evidence of where an order actually went.

What the sandbox cannot do

The sandbox does not serve market data — /market-data and /market-metrics return HTTP 502 — so quotes, quote snapshots, market metrics, historical dividends and earnings reports all fail there. Everything else works: instruments, option chains, futures, accounts, balances, positions, transactions, orders, and the dry-run and submission paths. The sandbox also resets every 24 hours, clearing trades, transactions and positions.

Connecting a client

The server speaks MCP over stdio: the client launches it as a subprocess. What is constant across clients is the command (node), the absolute path to dist/index.js, and the environment variables.

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "tastytrade": {
      "command": "node",
      "args": ["/absolute/path/to/tastytrade-mcp/dist/index.js"],
      "env": {
        "TASTYTRADE_ENV": "sandbox",
        "TASTYTRADE_CLIENT_ID": "…",
        "TASTYTRADE_CLIENT_SECRET": "…",
        "TASTYTRADE_REFRESH_TOKEN": "…"
      }
    }
  }
}

Every value in that object is a string, "1" included. Name the environment explicitly rather than relying on the default, so the block cannot mean something different from what it says.

Claude Code writes the file for you:

claude mcp add tastytrade \
  -e TASTYTRADE_CLIENT_ID=… \
  -e TASTYTRADE_CLIENT_SECRET=… \
  -e TASTYTRADE_REFRESH_TOKEN=… \
  -- node /absolute/path/to/tastytrade-mcp/dist/index.js

-s project writes a shareable .mcp.json instead — which makes it the wrong place for a client secret or refresh token.

Other clients (Cursor, Zed, Continue among them) keep their own config file and do not all use the same key; check your client's documentation.

Tool surface

84 tools — 70 read-only, 2 write, 12 destructive. Read-only tools are auto-approvable; every tool carries MCP annotations (readOnlyHint / destructiveHint / idempotentHint) so clients render the right approval UI.

Five tools require a confirmation token — the five that submit or change an order: tastytrade_place_order, tastytrade_edit_order, tastytrade_replace_order, tastytrade_place_complex_order and tastytrade_edit_complex_order. Each takes a single-use confirmation_token minted by its own dry_run_* tool, valid for 60 seconds and bound to a hash of the submitted arguments and of the request target — so you cannot dry-run one share and submit a thousand, or pre-flight against one endpoint and submit to another.

The other seven destructive tools carry no token and have no dry-run. They are tastytrade_cancel_order, tastytrade_cancel_complex_order, tastytrade_delete_quote_alert, and the four watchlist mutators (tastytrade_update_watchlist, tastytrade_delete_watchlist, tastytrade_add_watchlist_symbol, tastytrade_remove_watchlist_symbol). Of those seven only the two cancels touch orders; the other five move no money. They act on the first call, and each says so in its own description.

Safety model

In order of how much they protect you:

  1. Dry-run-first confirmation — the five order-submitting tools will not act without a token from their own dry-run (above). It covers those five and none of the other destructive tools.
  2. Pre-submit sanity checks — per-leg quantities against the account's own published order-size ceilings, a notional cap on buying-power impact (MAX_ORDER_NOTIONAL_USD, default $50,000), and a refusal to send orders into frozen or closing-only accounts. Every result names the checks that did not run, so an empty warning list can never be mistaken for a completed check.
  3. Credential-destination guard — the refresh token and client secret are only sent to a recognised tastytrade host over an encrypting channel. An unrecognised host stops the server rather than warning about it.
  4. Rate limiting — tastytrade's own published per-second, per-endpoint ceilings plus a 50/sec global cap, charged once per call. See Rate limits and backoff.
  5. Bounded, attributed output — everything the broker wrote is nested under an upstream member and marked as untrusted external content, bounded in size and stripped of display-hostile codepoints, so it cannot impersonate the server's own fields.

Verify it starts

Two JSON-RPC lines on stdin prove the server starts and lists its tools. Neither call reaches tastytrade, so this works before the credentials are right:

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
  | node dist/index.js | cut -c1-200

Startup diagnostics go to stderr, because stdout carries the MCP protocol and nothing else. A client writes stderr to its own server log — that log is where to look when a client reports the server failed to start.

See also