Skip to main content
Glama
bholzer

tastytrade-mcp

by bholzer

tastytrade-mcp

MCP server for the tastytrade brokerage API, built in TypeScript on the official @tastytrade/api SDK. Runs over stdio.

This is a rebuild of the earlier Python tastytrade_mcp server with a deliberately leaner surface: single-tenant, env-var auth, no database, and only tools backed by real API endpoints.

Setup

No clone, no build — npx installs straight from this repo and compiles automatically on first run. You need Node 20+ and SSH access to this GitHub repo (the same git@github.com key you use for pushing).

  1. Create an OAuth client and a personal-grant refresh token at my.tastytrade.com → Manage → API Access. You need the client secret and the refresh token (access tokens are generated and refreshed automatically).

  2. Put the secrets in your environment (shell profile, or a gitignored .env loaded by direnv — never in a file you commit):

    export TASTYTRADE_CLIENT_SECRET="..."
    export TASTYTRADE_REFRESH_TOKEN="..."
  3. Register with your MCP client.

    Project .mcp.json (Claude Code) — safe to commit. .mcp.json supports ${VAR} environment-variable expansion, so the file holds only references; values are read from the environment Claude Code was launched in. If a variable is missing, the config fails to load rather than silently sending an empty secret:

    {
      "mcpServers": {
        "tastytrade": {
          "command": "npx",
          "args": ["-y", "git+ssh://git@github.com/bholzer/tastytrade-mcp.git"],
          "env": {
            "TASTYTRADE_CLIENT_SECRET": "${TASTYTRADE_CLIENT_SECRET}",
            "TASTYTRADE_REFRESH_TOKEN": "${TASTYTRADE_REFRESH_TOKEN}",
            "TASTYTRADE_ENVIRONMENT": "${TASTYTRADE_ENVIRONMENT:-production}"
          }
        }
      }
    }

    ⚠️ Don't use claude mcp add --scope project --env TASTYTRADE_CLIENT_SECRET=... — that writes the literal secret value into .mcp.json, which is exactly the file that gets committed. Write the ${VAR} form by hand as above.

    One-liner (Claude Code, user scope). claude mcp add defaults to local/user config (~/.claude.json), which never leaves your machine, so passing values directly is acceptable there:

    claude mcp add tastytrade \
      --env TASTYTRADE_CLIENT_SECRET="$TASTYTRADE_CLIENT_SECRET" \
      --env TASTYTRADE_REFRESH_TOKEN="$TASTYTRADE_REFRESH_TOKEN" \
      -- npx -y git+ssh://git@github.com/bholzer/tastytrade-mcp.git

    Claude Desktop. claude_desktop_config.json does not support ${VAR} expansion — you have to paste the values in. That file is local-only (not committed), but be aware the secrets sit in plaintext on disk.

    The first launch takes ~30s while npm clones and compiles; after that it starts from cache. To pin a specific version, append a tag or commit: ...tastytrade-mcp.git#v1.0.0.

Updating

npx caches the install. To pick up new commits:

npx clear-npx-cache    # then the next launch re-installs from HEAD

(Or pin to tags and bump the tag in your config.)

Running from a local checkout (development)

claude mcp add tastytrade \
  --env TASTYTRADE_CLIENT_SECRET="$TASTYTRADE_CLIENT_SECRET" \
  --env TASTYTRADE_REFRESH_TOKEN="$TASTYTRADE_REFRESH_TOKEN" \
  -- node /path/to/tastytrade-mcp/dist/index.js

Environment variables

Variable

Required

Description

TASTYTRADE_CLIENT_SECRET

yes

OAuth client secret

TASTYTRADE_REFRESH_TOKEN

yes

OAuth personal-grant refresh token

TASTYTRADE_ENVIRONMENT

no

production (default) or sandbox (cert environment)

TASTYTRADE_SCOPES

no

OAuth scopes, default read trade

Tools (18)

System

  • health_check — verify credentials, report environment and customer.

Accounts & portfolio

  • get_accounts — list accounts.

  • get_balances — cash, net liq, buying power, margin usage.

  • get_positions — open positions, filterable by symbol/underlying, optional marks.

  • get_transactions — transaction history with date/symbol/type filters and paging.

  • get_net_liq_history — historical net liquidating value (1dall).

  • get_margin_requirements — margin/buying-power requirements report.

Market data

  • search_symbols — symbol search.

  • get_instrument — full instrument definition (tick size, streamer symbol, …) for equities, options, futures, future options, crypto.

  • get_market_metrics — IV rank/percentile, liquidity, beta, earnings/dividend dates.

  • get_option_chain — nested option chain with expiration/DTE/strike/type filters; returns an expiration summary when unfiltered to keep responses small.

  • get_quotes — live bid/ask, last trade, OHLC summary, and Greeks (for options) via the dxLink websocket streamer. Accepts equity, OCC option, futures, and future-option symbols.

Trading

  • create_order — 1–4 leg orders for any instrument type. Dry-run by default: returns the preview (buying-power effect, fees, warnings) without placing anything; requires explicit dry_run: false to submit.

  • list_orders — order history or live working orders.

  • get_order — single order status.

  • cancel_order — cancel one order.

  • replace_order — modify price/type/TIF of a working order.

  • cancel_all_orders — cancel every working order in an account (optionally one underlying).

Differences from the Python server

  • OAuth only (the v7 JS SDK no longer supports session login as a client config). Sandbox use requires a cert-environment OAuth client instead of sandbox username/password.

  • Dropped: multi-user database mode, encrypted token storage, shortcuts, and tools that had stub/fake implementations (fake streaming endpoints, correlation analysis, opportunity scanning). The persistent "emergency state" machinery is replaced by the real cancel_all_orders action.

  • set_stop_loss / set_take_profit are expressible through create_order (order_type: "Stop" / "Limit" with closing legs).

Development

npm run watch   # incremental compile
npm start       # run the built server