etrade-mcp

etrade-mcp

MCP server for E*TRADE that reads account balances, positions, transactions, and orders, with optional opt-in order placement via a two-step preview-confirm handshake.

Category
访问服务器

README

etrade-mcp

npm version License: MIT CI

MCP server for E*TRADE — OAuth 1.0a + VIP-TOTP auto-renew, account reads always-on, order placement strictly opt-in.

Talk to your E*TRADE account from Claude Code (or any MCP client): list accounts, check balances and positions, pull transactions and open orders — and, only if you turn it on, preview and place equity/option orders (including multi-leg spreads) through a code-enforced two-step handshake.

etrade-mcp demo

Is this for you?

  • You have (or can get) an E*TRADE brokerage account and an MCP-compatible AI client.
  • You want your assistant to read balances, positions, transactions, and orders directly, instead of pasting screenshots into a chat.
  • You may also want it to place orders — but only behind an explicit, separate opt-in, never by default.
  • You're fine getting your own E*TRADE developer API key. This project ships no credentials, no shared account, no proxy service — every install talks straight to E*TRADE with keys you own.

Probably not for you if you want a broker-agnostic tool (this wraps the E*TRADE Account + Order APIs specifically) or a "fully autonomous, no human review" trading bot — the write tools exist precisely so nothing reaches the market without a preview you can read first.

Safety model

This is a tool that can, if you ask it to, put real orders into a real brokerage account. The safety properties below are enforced in code (src/mcp.ts, src/orders.ts, src/order-store.ts, src/tools/), not just written down:

  • Read-only unless you opt in. etrade_preview_order, etrade_preview_spread, etrade_place_order, and etrade_cancel_order are only registered with the MCP server when ETRADE_ALLOW_ORDERS=1 is set. Without it, the server can read accounts, balances, positions, transactions, and orders — and cannot create, modify, or cancel anything.
  • Two-step preview → place, enforced server-side. etrade_place_order accepts only a previewId (plus confirm: true) from a recent etrade_preview_order / etrade_preview_spread call. It replays the exact envelope that was previewed — there is no code path that lets a place call carry raw, un-previewed order parameters.
  • Previews are single-use and short-lived. Each previewId is consumed on first use and expires ~3 minutes after issue (mirroring E*TRADE's own preview window); a second attempt or a stale one is rejected and you have to re-preview.
  • Explicit confirmation. etrade_place_order and etrade_cancel_order both require confirm: true — a Zod literal(true), re-checked again in the handler.
  • Sandbox and prod can't cross. A preview minted while the server is running against ETRADE_ENV=sandbox is refused if you try to place it against a prod server, and vice versa.
  • No bulk or irreversible operations. One order per call. There is no "cancel all" or "liquidate everything" tool.
  • Ambiguous outcomes are never silently retried. If E*TRADE's place/cancel response comes back without a clear success or an explicit error (a network timeout, an odd payload), the tool reports the outcome as UNKNOWN and tells you to check etrade_list_orders before doing anything else — it never auto-retries a place, which could double an order.
  • Order shaping is validated before anything reaches E*TRADE — quantity/action/price-field combinations, E*TRADE's own coupling rules (e.g. MARKET orders must be GOOD_FOR_DAY, extended-hours orders must be LIMIT, all-or-none needs 300+ shares), and, for spreads, that every leg is a distinct contract on the same underlying. Bad input fails locally with a specific message instead of round-tripping to E*TRADE first.
  • Not LIMIT-only. To be precise about what the code does and doesn't do: MARKET, LIMIT, STOP, and STOP_LIMIT are all supported order price types — this package does not force limit-only discipline on you. If you want that discipline, enforce it in whatever is calling these tools.

Your keys, your account, your risk. This is not investment advice, and nothing here is a recommendation about what to trade. You are responsible for every order this places.

Quickstart

etrade-mcp needs its own E*TRADE developer API key and a one-time OAuth login before it can do anything — there is no bundled or shared credential (see Getting an E*TRADE developer key below).

1. Get sandbox credentials at developer.etrade.com (see below).

2. Log in once. E*TRADE's OAuth authorize step is an interactive browser login, but the CLI that drives it runs straight from npm — no clone needed:

ETRADE_ENV=sandbox ETRADE_SANDBOX_API_KEY=<your-key> ETRADE_SANDBOX_API_KEY_SECRET=<your-secret> \
  npx -y --package=etrade-mcp etrade-mcp-auth

--package=etrade-mcp is required here: a bare npx etrade-mcp runs the package's default bin (etrade-mcp, the MCP server itself), not this non-default etrade-mcp-auth bin — the --package=<name> form is npx's way of installing one package and running a different named bin from it. bunx --package=etrade-mcp etrade-mcp-auth works the same way if you're on Bun.

This opens (prints) an E*TRADE authorize URL, and once you approve it and paste back the 5-digit verifier, writes an access token to ~/.config/etrade-mcp/tokens.sandbox.json (0600 permissions). See Auth model & token lifecycle for renewal and the other auth CLIs. (Contributing, or want to run from source instead? git clone the repo — see Testing.)

3. Register the published server with your MCP client — reads are always on; writes need the explicit opt-in:

claude mcp add etrade \
  --env ETRADE_ENV=sandbox \
  --env ETRADE_SANDBOX_API_KEY=<your-key> \
  --env ETRADE_SANDBOX_API_KEY_SECRET=<your-secret> \
  -- npx -y etrade-mcp

bunx -y etrade-mcp works the same way if you're on Bun. The credential env vars sign requests; the actual session token comes from the file step 2 wrote to disk. To also enable order placement, add --env ETRADE_ALLOW_ORDERS=1 and register it as a separate, deliberately-named server (e.g. etrade-trade) so the read-only server can stay registered without the write surface attached — see Tools below.

Once you've validated the flow against sandbox, repeat with a production key (ETRADE_ENV=prod, ETRADE_PROD_API_KEY / ETRADE_PROD_API_SECRET) — ETRADE_ENV defaults to prod, so a bare install targets your real account unless you explicitly opt into sandbox.

Getting an E*TRADE developer key

E*TRADE's API is not a shared or public API — every consumer needs their own key, scoped to their own account. This project ships no credentials of any kind.

  1. Sandbox key (start here): request one at developer.etrade.com. Sandbox targets E*TRADE's canned test data — it validates the request/response shape, not real fills or real account data.
  2. Production key: once you're happy against sandbox, request a production key at the same site. Order placement specifically requires signing E*TRADE's API Developer Agreement and completing a User Intent Survey.
  3. Put the resulting consumer key + secret in your environment — a local .env in the clone, your shell profile, or your MCP client's --env flags — under the names in the Environment variables table below.

Auth model & token lifecycle

E*TRADE uses OAuth 1.0a (not OAuth2): a 3-legged flow — request a token, a human authorizes it in a browser, exchange a short verifier code for an access token. This package implements that directly (oauth-1.0a + HMAC-SHA1 request signing), no vendor SDK:

  • npx -y --package=etrade-mcp etrade-mcp-auth (or, from a clone, bun run auth) — the interactive one-shot: fetches a request token, prints the E*TRADE authorize URL, waits for you to open it and log in, and reads back the 5-digit verifier E*TRADE shows you.
  • etrade-mcp-auth-start / etrade-mcp-auth-finish <verifier> (both via npx -y --package=etrade-mcp <bin>, or from a clone bun run auth:start / bun run auth:finish <verifier>) — the same flow split in two for scripting: auth-start prints just the authorize URL and stashes the pending request token; auth-finish (verifier as an argument, or ETRADE_VERIFIER) completes it later.

The resulting access token is written to ~/.config/etrade-mcp/tokens.<env>.json with 0600 permissions.

Expiry. E*TRADE access tokens expire at midnight US Eastern (there is no refresh token) and go idle after about 2 hours without an API call.

  • npx -y --package=etrade-mcp etrade-mcp-renew (or, from a clone, bun run renew) tries E*TRADE's browser-free renew_access_token endpoint first. If the token has only gone idle (not past the midnight-ET hard expiry), this reactivates the same token with zero browser interaction — exit code 0 means it worked, exit code 3 means the token is past saving and you need the full etrade-mcp-auth browser flow again.
  • Past midnight ET, only the full 3-legged browser flow can mint a new token — an E*TRADE platform limit (no refresh tokens), not something this package can route around. Re-run etrade-mcp-auth (or the etrade-mcp-auth-start/etrade-mcp-auth-finish pair) once a day.

Optional: VIP TOTP (2FA code) helper

E*TRADE's 2FA is Symantec VIP Access. If you provision a VIP soft-token credential (e.g. via the vipaccess CLI's provision command) you get a base32 secret. Store it as ETRADE_TOTP_SECRET and npx -y --package=etrade-mcp etrade-mcp-totp (or, from a clone, bun run totp) prints the current 6-digit code — RFC 6238 TOTP generated locally with node:crypto only (no network call, no third-party TOTP dependency) — so you don't need your phone during the browser login step.

Optional: browser auto-fill for the login page

npx -y --package=etrade-mcp etrade-mcp-login-fill (or, from a clone, bun run login:fill; reads ETRADE_LOGIN_USERNAME / ETRADE_LOGIN_PASSWORD) drives a Chromium-family browser already open on E*TRADE's login page over the Chrome DevTools Protocol (CDP_PORT, default 9333), filling the username and password fields with trusted input events. It fills only those two fields — never the 2FA/verifier step — and never prints the credential values, only their lengths. It's a building block for your own re-auth automation, not a turnkey unattended login.

Tools

Read (always registered)

Tool Description
etrade_list_accounts List all E*TRADE accounts for the authenticated user.
etrade_get_balance Cash balance, buying power, and NAV for one account.
etrade_get_portfolio Current positions for one account.
etrade_list_transactions Transactions for one account in a date range.
etrade_get_transaction Detail for a single transaction.
etrade_list_orders Orders for one account. status=OPEN shows working orders; status=EXECUTED confirms a fill before placing a paired stop.
etrade_snapshot Fan-out snapshot across all accounts: balances + positions (+ optional recent transactions).

Write (only registered when ETRADE_ALLOW_ORDERS=1)

Tool Description
etrade_preview_order Step 1 (single leg). Validates an equity or single-option order and returns E*TRADE's own cost/commission estimate plus a previewId. Nothing is sent to market.
etrade_preview_spread Step 1 (multi-leg). Validates a 2–4-leg option spread (verticals, calendars, straddles) on one underlying, priced on the net (NET_DEBIT/NET_CREDIT/NET_EVEN), and returns the net cost estimate plus a previewId.
etrade_place_order Step 2. Sends the order. Accepts only a previewId + confirm: true, and replays the exact previewed order — executes both single-leg and spread previews.
etrade_cancel_order Cancels an open order by orderId + confirm: true. An order already routed to or filled at market can't be cancelled.

Equities, single options, and multi-leg option spreads (2–4 legs, e.g. a defined-risk vertical) are all supported — a spread is one E*TRADE SPREADS order whose legs fill as a unit at the net price, distinct from placing separate single-leg orders. The API has no native bracket/OCO/contingent order type — a "stop attached to an entry" is done client-side: place the entry, confirm the fill with etrade_list_orders, then place the stop as its own order.

accountIdKey (used across every account-scoped tool) is the obfuscated key etrade_list_accounts returns — not the plain account number.

Environment variables

Variable Required Purpose
ETRADE_ENV optional sandbox or prod. Defaults to prod.
ETRADE_SANDBOX_API_KEY / ETRADE_SANDBOX_API_KEY_SECRET for ETRADE_ENV=sandbox Your E*TRADE sandbox consumer key/secret.
ETRADE_PROD_API_KEY / ETRADE_PROD_API_SECRET for ETRADE_ENV=prod Your E*TRADE production consumer key/secret.
ETRADE_ALLOW_ORDERS optional Set to 1 to register the write tools (preview/place/cancel). Anything else, or unset, is read-only.
ETRADE_VERIFIER optional Verifier code for etrade-mcp-auth-finish (or pass it as a CLI argument).
ETRADE_TOTP_SECRET optional Base32 VIP TOTP secret, for etrade-mcp-totp.
ETRADE_LOGIN_USERNAME / ETRADE_LOGIN_PASSWORD optional Used only by etrade-mcp-login-fill's browser automation.
CDP_PORT optional Debug port for etrade-mcp-login-fill's browser automation. Defaults to 9333.

Why this exists

There are a handful of independent E*TRADE MCP servers already on GitHub, mostly small, Python-based projects with a handful of stars or fewer. None of them are published to npm, so none are npx-installable — every one requires cloning and a Python toolchain (uvx/pip). The most established of them, davdunc/mcp_etrade, is a good reference point:

etrade-mcp (this project) davdunc/mcp_etrade
Runtime TypeScript on Node/Bun Python 3.11+
Install npx -y etrade-mcp (published to npm) uvx --from git+... (not on npm/PyPI)
Order safety Code-enforced two-step preview → place, single-use ~3-min previewId, sandbox/prod isolation Order validation via risk-guardrail tools
Multi-leg option spreads Yes (2–4-leg SPREADS) Not documented
2FA helper Built-in VIP TOTP generator + optional CDP login-fill Not documented
Watch lists / R-multiple risk sizing No Yes

This project's focus is narrower and deeper on one thing — a safe, well-tested order-placement handshake, installable in one command — rather than a broader feature surface. If you want watch lists or built-in position-sizing math, mcp_etrade covers ground this one doesn't.

Testing

bun test                          # Unit tests (fast, no network)
bun run test:integration          # Manual: requires a valid sandbox token on disk

# Opt-in, PREVIEW-ONLY order smoke (never places an order) — run with the market closed:
ETRADE_RUN_INTEGRATION=1 ETRADE_RUN_ORDER_PREVIEW=1 \
  ETRADE_TEST_ACCOUNT_KEY=<accountIdKey> ETRADE_TEST_SYMBOL=AAPL \
  bun test src/__tests__/integration.test.ts

# Opt-in, PREVIEW-ONLY multi-leg SPREAD smoke (never places) — validates the SPREADS
# envelope against the live preview endpoint. Defaults to a SOXX Jul-17 $630/$660 call
# vertical; override the contract with the ETRADE_TEST_SPREAD_* vars:
ETRADE_RUN_INTEGRATION=1 ETRADE_RUN_ORDER_SPREAD_PREVIEW=1 \
  ETRADE_TEST_ACCOUNT_KEY=<accountIdKey> \
  [ETRADE_TEST_SPREAD_SYMBOL=SOXX ETRADE_TEST_SPREAD_EXPIRY=2026-07-17 \
   ETRADE_TEST_SPREAD_LONG_STRIKE=630 ETRADE_TEST_SPREAD_SHORT_STRIKE=660] \
  bun test src/__tests__/integration.test.ts

src/index.ts also exports the client/auth/order-shaping/token/TOTP layer directly, so you can use this as a library instead of (or alongside) the MCP server — see the file's header comment for what is and isn't included.

Dependencies

Four runtime dependencies: @modelcontextprotocol/sdk, oauth-1.0a, zod, dotenv. No database, no external service beyond E*TRADE's own API.

License

MIT © 2026 Stephen Blatt

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选