etrade-mcp
Click on "Install 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., "@etrade-mcpshow me my account balances"
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.
etrade-mcp
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.

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.
Related MCP server: IBKR MCP
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, andetrade_cancel_orderare only registered with the MCP server whenETRADE_ALLOW_ORDERS=1is 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_orderaccepts only apreviewId(plusconfirm: true) from a recentetrade_preview_order/etrade_preview_spreadcall. 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
previewIdis 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_orderandetrade_cancel_orderboth requireconfirm: true— a Zodliteral(true), re-checked again in the handler.Sandbox and prod can't cross. A preview minted while the server is running against
ETRADE_ENV=sandboxis refused if you try to place it against aprodserver, 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_ordersbefore 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.
MARKETorders must beGOOD_FOR_DAY, extended-hours orders must beLIMIT, 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, andSTOP_LIMITare 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-mcpbunx -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.
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.
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.
Put the resulting consumer key + secret in your environment — a local
.envin the clone, your shell profile, or your MCP client's--envflags — 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 vianpx -y --package=etrade-mcp <bin>, or from a clonebun run auth:start/bun run auth:finish <verifier>) — the same flow split in two for scripting:auth-startprints just the authorize URL and stashes the pending request token;auth-finish(verifier as an argument, orETRADE_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-freerenew_access_tokenendpoint 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 code0means it worked, exit code3means the token is past saving and you need the fulletrade-mcp-authbrowser 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 theetrade-mcp-auth-start/etrade-mcp-auth-finishpair) 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 |
| List all E*TRADE accounts for the authenticated user. |
| Cash balance, buying power, and NAV for one account. |
| Current positions for one account. |
| Transactions for one account in a date range. |
| Detail for a single transaction. |
| Orders for one account. |
| Fan-out snapshot across all accounts: balances + positions (+ optional recent transactions). |
Write (only registered when ETRADE_ALLOW_ORDERS=1)
Tool | Description |
| Step 1 (single leg). Validates an equity or single-option order and returns E*TRADE's own cost/commission estimate plus a |
| Step 1 (multi-leg). Validates a 2–4-leg option spread (verticals, calendars, straddles) on one underlying, priced on the net ( |
| Step 2. Sends the order. Accepts only a |
| Cancels an open order by |
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 |
| optional |
|
| for | Your E*TRADE sandbox consumer key/secret. |
| for | Your E*TRADE production consumer key/secret. |
| optional | Set to |
| optional | Verifier code for |
| optional | Base32 VIP TOTP secret, for |
| optional | Used only by |
| optional | Debug port for |
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:
|
| |
Runtime | TypeScript on Node/Bun | Python 3.11+ |
Install |
|
|
Order safety | Code-enforced two-step preview → place, single-use ~3-min | Order validation via risk-guardrail tools |
Multi-leg option spreads | Yes (2–4-leg | 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.tssrc/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
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/sblattj/etrade-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server