Skip to main content
Glama
etoro-mcp

etoro-mcp

etoro-mcp

MCP server for the eToro public API: market data, balances, portfolio, trade history, watchlists, alerts, investor rankings, user statistics, social feeds, and — behind explicit opt-in gates — trading, watchlist/alert mutations, and social posting. Coverage is organised into toolsets; only the toolsets you select are registered, and write tools are not registered at all unless their gate is enabled — a client connected to the default configuration cannot see or call them.

Features

  • Read-first by design — 62 read tools across eleven of the twelve toolsets (the social toolset is write-only); the 43 write tools exist only when their gate is set — 5 trading tools behind ETORO_MCP_ENABLE_TRADING, the other 38 (watchlist, alert, social, and notification mutations) behind ETORO_MCP_ENABLE_WRITES.

  • Demo environment by default — trading tools call the demo endpoint group unless ETORO_ENV=real is set.

  • Toolset selection — register only what you need via ETORO_MCP_TOOLSETS; unknown names fail startup rather than serving a partial tool set.

  • Trimmed responses — tools return the fields an investor acts on (prices, units, P&L, timestamps), not raw API dumps; list tools are bounded by a limit parameter or by explicit range parameters (min_date/max_date/count) on the time-series tools.

  • Credentials stay in the environment — keys travel only in the x-api-key/x-user-key headers, and error messages never echo header or credential values.

  • Rate-limit aware — HTTP 429 responses are retried once, honouring Retry-After, re-sending the same x-request-id so a retried order cannot fill twice.

Related MCP server: eToro MCP Server

Toolsets

Select toolsets with ETORO_MCP_TOOLSETS (comma-separated; all selects every toolset). Without it, the trading core is registered:

Toolset

Default

Covers

market

✓

Instrument search and details, candles, rates, closing prices, exchanges, instrument types, stock industries

account

✓

Profile, balances (aggregated, by account type, history), cash transactions

trading

✓

Portfolio, P&L, order status, eligibility and cost estimates; gated order/position writes

history

✓

Closed-trade history

watchlists

✓

Own/public/curated watchlists and recommendations; gated watchlist mutations

alerts

✓

Price alerts; gated alert mutations

rankings

Investor rankings, presets, tags, sector/industry summaries

users

User search, profiles, portfolios, performance and copier statistics

feeds

News, following, for-you, instrument, and user feeds; posts and comments

social

Gated posting, comments, replies, reactions, polls, and media upload

clubs

eToro Club dashboard

notifications

Notifications; gated mark-read

Tools

Read tools (registered whenever their toolset is selected)

Toolset

Tool

Description

market

search_instruments

Search instruments by ticker symbol and return candidate matches (contains-matching, so verify the symbol)

market

get_instrument_details

Display data for instruments by id: name, symbol, type, exchange

market

get_candles

OHLCV candles for one instrument (nine intervals, up to 1000 bars)

market

get_closing_prices

Latest official closing prices per instrument

market

get_rates

Real-time bid/ask quotes for instruments

market

list_exchanges

Exchanges (id and description) for resolving exchangeId values

market

list_instrument_types

Instrument types (stocks, crypto, ETFs, ...) by id

market

list_stock_industries

Stock industries (id and name) for resolving stocksIndustryId values

account

get_profile

The authenticated user's identity and the scopes their keys carry

account

get_aggregated_balances

Current balances aggregated across the user's accounts

account

get_balances_by_type

Current balances for every account of one account type

account

get_balance

Current balance of one specific account

account

get_balance_history

Daily balance snapshots over a date range

account

list_cash_transactions

Transactions of a cash account, newest pages first

trading

get_portfolio

Aggregated portfolio: account totals plus one aggregate per instrument

trading

get_portfolio_breakdown

Position-level snapshot: open positions and pending orders

trading

get_pnl

Portfolio snapshot with unrealized P&L per position

trading

get_order

Look up an order's status by order id or reference id

trading

get_close_order_info

Look up a close order's status by its order id

trading

check_trading_eligibility

Per-instrument trading rules: leverage, sizing mode, SL/TP bounds

trading

get_trading_cost_estimate

Estimate the costs of a hypothetical open order without placing it

history

list_trading_history

Closed trades since a given date

watchlists

list_watchlists

The authenticated user's watchlists with their items

watchlists

get_watchlist

A single watchlist owned by the authenticated user, by id

watchlists

get_default_watchlist

Items of the authenticated user's default watchlist

watchlists

get_public_watchlists

Another user's public watchlists by their numeric user id

watchlists

get_curated_lists

eToro's curated investment lists available to the user

watchlists

get_market_recommendations

Personalized market recommendations for the authenticated user

alerts

list_price_alerts

The active price alerts on the account

rankings

list_ranking_presets

Names of all publicly available ranking presets

rankings

get_rankings_by_preset

Investor ranking rows for a named preset

rankings

get_investor_rankings

A filtered, sorted page of investor ranking rows

rankings

get_investor_ranking_row

The full ranking row for a single investor

rankings

bulk_ranking_rows

Ranking rows for several investors in one call

rankings

list_ranking_tags

The catalog of ranking tags with resolved names

rankings

get_ranking_universe_by_sector

The ranking universe aggregated by sector or industry

users

search_users

Search public investors with performance and risk filters

users

get_user_profile

Public profile and account summary for one or more users

users

get_user_portfolio

A user's live public portfolio: open positions and copy trades

users

get_user_performance

A user's full monthly and yearly gain history

users

get_user_daily_performance

A user's day-by-day or aggregated gain over a date range

users

get_user_trade_info

A user's trading statistics for a period (copy-trading due diligence)

users

get_gain_timeseries

An investor's gain time-series at daily, monthly, or yearly resolution

users

get_asset_allocation_history

A portfolio's daily asset-allocation breakdown over time

users

get_market_exposure_history

A portfolio's daily directional market exposure per instrument

users

get_copier_stats

An investor's live copier count and assets-under-management tier

users

get_copiers_info

Anonymised info about the people copying your portfolio

users

search_portfolios

Search trader portfolios or Smart Portfolios by free text

users

get_top_assets

A user's top assets ranked by impressions-based score

feeds

get_news_feed

The eToro news feed (editorial and market-news posts)

feeds

get_following_feed

Posts from users the authenticated user follows

feeds

get_for_you_feed

The personalised For You feed for the authenticated user

feeds

get_instrument_feed

The discussion feed for one instrument (market)

feeds

get_user_feed

The posts published by one user

feeds

get_saved_feed

The posts the authenticated user has saved

feeds

get_pinned_posts

The posts a user has pinned to their profile

feeds

get_post

A single post by its UUID, with an inline comments preview

feeds

list_post_comments

The top-level comments on a post

feeds

list_comment_replies

The replies nested under one comment

feeds

list_post_shares

Who shared a post (plain reshares and quote shares)

clubs

get_club_dashboard

The eToro Club dashboard for the authenticated user

notifications

list_notifications

The account's in-app notifications, newest data first

Trading write tools (registered only when ETORO_MCP_ENABLE_TRADING is set)

Toolset

Tool

Description

trading

create_order

Place an order to open a position — not idempotent: every call places a new order

trading

cancel_order

Cancel a pending (not yet executed) order

trading

close_position

Close an open position, fully or partially, at market

trading

cancel_close_order

Cancel a pending close order before it executes

trading

modify_position_sltp

Edit an open position's stop-loss and/or take-profit

Other write tools (registered only when ETORO_MCP_ENABLE_WRITES is set)

Toolset

Tool

Description

watchlists

create_watchlist

Create a new watchlist

watchlists

rename_watchlist

Rename a watchlist

watchlists

delete_watchlist

Delete a watchlist

watchlists

add_watchlist_items

Add items to a watchlist

watchlists

remove_watchlist_items

Remove items from a watchlist

watchlists

update_watchlist_items

Reorder items within a watchlist

watchlists

set_default_watchlist

Set a watchlist as the selected default

watchlists

change_watchlist_rank

Change a watchlist's display position

alerts

create_price_alert

Create a price alert on an instrument

alerts

update_price_alert

Change the target price of an existing price alert

alerts

delete_price_alert

Permanently delete a price alert

notifications

mark_notifications_read

Mark all in-app notifications as read

social

create_post

Create a discussion post on the authenticated user's feed

social

create_poll_post

Create a poll post with 2 to 4 answer options

social

update_post

Edit the authenticated user's own post in-place

social

delete_post

Soft-delete the authenticated user's own post

social

pin_post

Pin one of the authenticated user's own posts to their profile

social

unpin_post

Remove the authenticated user's pin from a post

social

create_comment

Create a top-level comment on a post

social

update_comment

Edit the authenticated user's own comment in-place

social

delete_comment

Soft-delete the authenticated user's own comment

social

create_reply

Create a reply nested under an existing comment

social

update_reply

Edit the authenticated user's own reply in-place

social

delete_reply

Soft-delete the authenticated user's own reply

social

share_post

Share an existing post, as a plain reshare or a quote share

social

upload_media

Upload a JPEG or PNG image (max 8 MB) for use as an attachment; requires ETORO_MCP_UPLOAD_DIR and reads only inside it

social

like_post

Like a post

social

unlike_post

Remove a like from a post

social

like_comment

Like a comment on a post

social

unlike_comment

Remove a like from a comment

social

like_reply

Like a reply (a nested answer to a comment)

social

unlike_reply

Remove a like from a reply

social

save_post

Bookmark a post

social

unsave_post

Remove a post from the saved bookmarks

social

follow_post

Subscribe to notifications on a post

social

unfollow_post

Unsubscribe from notifications on a post

social

vote_poll

Cast a vote on a poll option

social

remove_poll_vote

Remove a vote from a poll option

Configuration

All configuration comes from environment variables — no config files, no flags carrying secrets.

Variable

Default

Purpose

ETORO_API_KEY

— (required)

eToro API key, sent as the x-api-key header

ETORO_USER_KEY

— (required)

eToro user key, sent as the x-user-key header

ETORO_ENV

demo

demo or real — which trading endpoint group tools call. eToro keys are environment-bound, so a mismatched key fails at the API

ETORO_MCP_TOOLSETS

trading core (see table above)

Comma-separated toolset names; all selects every toolset. Unknown names fail startup with the list of valid names

ETORO_MCP_ENABLE_TRADING

off

true/1/yes registers the trading write tools: order placement/cancel, position close, stop-loss/take-profit edits

ETORO_MCP_ENABLE_WRITES

off

true/1/yes registers all other write tools: watchlist/alert mutations, notification mark-read, social posting and reactions

ETORO_MCP_UPLOAD_DIR

— (unset)

The only directory upload_media may read images from. Unset (the default) leaves upload_media unregistered, so the server can never read local files. Paths and symlinks resolving outside the directory are rejected

Getting started

Run straight from the repository with uv:

uvx --from git+https://github.com/florinel-chis/etoro-mcp etoro-mcp

The server speaks stdio by default; pass --transport http --host 127.0.0.1 --port 8000 to serve streamable HTTP at /mcp instead.

Warning: the HTTP endpoint has no authentication — anyone who can reach the port can call every registered tool with your API keys' privileges. The server therefore refuses to bind a non-loopback --host unless --allow-remote is also passed; only use that flag behind an authenticated reverse proxy or an otherwise-restricted network (such as the Docker port-mapping below).

MCP client configuration

Add the server to your MCP client's configuration (the exact file location depends on the client):

{
  "mcpServers": {
    "etoro": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/florinel-chis/etoro-mcp", "etoro-mcp"],
      "env": {
        "ETORO_API_KEY": "your-api-key",
        "ETORO_USER_KEY": "your-user-key",
        "ETORO_ENV": "demo"
      }
    }
  }
}

Or run the Docker image (build it first, see below):

{
  "mcpServers": {
    "etoro": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "ETORO_API_KEY", "-e", "ETORO_USER_KEY", "-e", "ETORO_ENV", "etoro-mcp"],
      "env": {
        "ETORO_API_KEY": "your-api-key",
        "ETORO_USER_KEY": "your-user-key",
        "ETORO_ENV": "demo"
      }
    }
  }
}

Docker

docker build -t etoro-mcp .

# stdio (for MCP client configs)
docker run -i --rm -e ETORO_API_KEY -e ETORO_USER_KEY etoro-mcp

# streamable HTTP at http://127.0.0.1:8000/mcp
# (-p 127.0.0.1:8000:8000 keeps the unauthenticated endpoint off external interfaces;
#  --host 0.0.0.0 refers to interfaces inside the container and is required for the
#  port mapping to work, hence --allow-remote — the host-side bind stays loopback-only)
docker run --rm -p 127.0.0.1:8000:8000 -e ETORO_API_KEY -e ETORO_USER_KEY \
  etoro-mcp --transport http --host 0.0.0.0 --port 8000 --allow-remote

Safety

  • Trading tools call the demo endpoint group unless ETORO_ENV=real is set. Keys are environment-bound, so a demo key against real (or vice versa) fails at the API rather than trading the wrong account.

  • Write tools are hidden behind two independent gates — ETORO_MCP_ENABLE_TRADING for order/position writes and ETORO_MCP_ENABLE_WRITES for everything else (watchlists, alerts, notifications, social). Gated tools are never registered, not merely rejected, so MCP clients cannot discover or call them.

  • The HTTP transport is unauthenticated: anyone who can reach the port can call every registered tool — read balances and positions always, and place or close orders when trading is enabled — using your API keys' privileges. The server refuses non-loopback binds unless --allow-remote is passed; only use that flag behind an authenticated proxy or an otherwise-restricted network (the stdio transport has no such exposure).

  • upload_media reads local JPEG/PNG files and returns a public CDN URL for them — an extra privilege class beyond the API keys themselves. It is therefore triple-gated: the social toolset, ETORO_MCP_ENABLE_WRITES, and ETORO_MCP_UPLOAD_DIR must all be set, and it reads only inside that directory (paths and symlinks resolving outside it are rejected, file content must actually be JPEG/PNG, and the 8 MB limit is checked before the file is read).

  • create_order is not idempotent across calls: each call mints a fresh x-request-id, which is the order's idempotency key, so calling it twice places two orders. (The 429 retry re-sends the same id, so a rate-limited retry cannot double-fill.) Poll fill status with get_order before treating an order as filled — an accepted order can still be rejected.

  • Candle history is capped at roughly 1000 bars per interval with no way to page further back; use a coarser interval (e.g. OneWeek) for deeper history.

  • The API enforces per-group rate quotas (order execution 20 requests/60 s; market data 120/60 s; portfolio and most other groups 60/60 s; eligibility and cost estimates 20/60 s each). Each tool's description names its quota; 429s are retried once, honouring Retry-After.

  • Trading leveraged products is risky. Use at your own risk, and test everything against a demo account first.

Development

uv sync
uv run pytest
uv run ruff check .

Tests are hermetic: all HTTP is mocked with respx and the server is exercised through the in-memory FastMCP client. No credentials or network access are needed to run them. A manual, read-only smoke check against a real demo account lives at scripts/smoke.py.

License

MIT — see LICENSE.

Available Tools

29 tools
check_trading_eligibilityA
Read-only

Per-instrument trading rules: leverage, sizing mode, SL/TP bounds.

Provide instrument_ids and/or symbols (at least one, at most 100 combined). For each instrument returns the minimum position exposure (USD), max units per order, whether opening/closing/partial closes/ market-if-touched orders/trailing stop-loss are allowed, whether units are whole or fractional, whether sizing must be by units, by amount, or either, and per settlement type and direction the valid leverage values, minimum position amount (USD), and stop-loss/take-profit percentage bounds. Call before create_order to pick valid parameters. Rate limit: dedicated 20 requests/60s quota.

Inputs: symbols, instrument_ids. Returns: object

get_aggregated_balancesA
Read-only

Get current balances aggregated across the user's accounts.

Calls GET /api/v1/balances. Returns totalBalance (in display_currency) plus one entry per account with its native-currency balance, the converted displayBalance, and the exchangeRate used. Account types: Trading, Cash, Options, Crypto, MoneyFarm, Spaceship. Amounts are numbers in the stated currency. Rate limit: 60 requests per 60 seconds (default shared quota).

Inputs: account_types, display_currency, include_zero_balances, include_equity_details. Returns: object

get_balanceA
Read-only

Get the current balance of one specific account.

Calls GET /api/v1/balances/{accountType}/{accountId}. Account types: Trading, Cash, Options, Crypto, MoneyFarm, Spaceship. Returns the account's balance in its native currency plus the displayBalance converted into display_currency. With include_equity_details, Trading accounts also report available buying power, frozen cash, current PnL, and used margin. Rate limit: 60 requests per 60 seconds (default shared quota).

Inputs: account_id (required), account_type (required), display_currency, include_zero_balances, +1 more. Returns: object

get_balance_historyA
Read-only

Get daily balance snapshots over a date range.

Calls GET /api/v1/balances/history (or the {accountType} / {accountType}/{accountId} variant when narrowed). Dates are YYYY-MM-DD; the default range is the last 30 days, history covers at most the last 12 months, and a single range spans at most 365 days — the API answers 404 when no data exists for the range. Each snapshot carries total cash, invested amount, PnL, and balance, both in native currencies and converted into display_currency. Rate limit: 60 requests per 60 seconds (default shared quota).

Inputs: to_date, from_date, account_id, account_type, +1 more. Returns: object

get_balances_by_typeA
Read-only

Get current balances for every account of one account type.

Calls GET /api/v1/balances/{accountType}. Account types: Trading, Cash, Options, Crypto, MoneyFarm, Spaceship. Returns totalBalance (in display_currency) and per-account balances in their native currency alongside the converted displayBalance. Rate limit: 60 requests per 60 seconds (default shared quota).

Inputs: account_type (required), account_ids, display_currency, include_zero_balances, +1 more. Returns: object

get_candlesA
Read-only

Get OHLCV candles for one instrument.

Returns {"instrumentId": int, "interval": str, "candles": [{"time": ISO-8601 period start, "open": float, "high": float, "low": float, "close": float, "volume": float}]}. Prices are in the instrument's quote currency; the newest bar can be the still-forming session.

History depth is capped at about 1000 bars per interval — there is no way to page further back in time (no from/to parameters exist), so at OneDay one request covers roughly four years; use a coarser interval such as OneWeek for deeper history. 'direction' only changes ordering: asc and desc return the same most-recent window, oldest-first vs newest-first. An unknown instrument id yields no candle data and this tool raises an error rather than returning an empty series.

Rate limit: shares the market-data pool of 120 requests per 60 seconds.

Inputs: instrument_id (required), count, interval, direction. Returns: object

get_close_order_infoA
Read-only

Look up a close order's status by its order id.

Same status codes as get_order (1 Received … 10 RejectedPartiallyFilled); positionsToClose and positionExecutions show which positions closed and at what price. Returns HTTP 404 if the close order does not exist. Rate limit: shares a 60 requests/60s pool with get_order.

Inputs: order_id (required). Returns: object

get_closing_pricesA
Read-only

Get the latest official closing prices per instrument.

The API returns closing prices for every instrument in one response; this tool filters to 'instrument_ids' when given and truncates to 'limit'. Returns {"results": [{"instrumentId": int, "officialClosingPrice": float, "daily"/"weekly"/"monthly": {"price": float, "date": ISO-8601}}]} — daily is the previous trading day's close, weekly the previous week's, monthly the previous month's. A price of -1 with date 0001-01-01 means no data for that period.

Rate limit: shares the market-data pool of 120 requests per 60 seconds.

Inputs: limit, instrument_ids. Returns: object

get_curated_listsA
Read-only

Get eToro's curated investment lists available to the user.

Each list carries uuid, name, description, and the instrument IDs it contains (resolve them via the market-data tools). Dedicated quota of 60 requests per 60 seconds.

Inputs: limit. Returns: object

get_default_watchlistA
Read-only

Get the items of the authenticated user's default watchlist.

Returns items with itemId (instrument or person ID), itemType ('Instrument' or 'Person'), itemRank (position in the list), symbol and displayName when market metadata is included, and itemAddedDate (ISO 8601). Shares the watchlist read quota of 60 requests per 60 seconds.

Inputs: limit, items_per_page. Returns: object

get_instrument_detailsA
Read-only

Get display data for instruments by id: name, symbol, type, exchange.

Returns {"results": [{"instrumentId": int, "displayName": str, "symbol": str, "instrumentTypeId": int, "exchangeId": int, "stocksIndustryId": int, "priceSource": str, "isInternalInstrument": bool}]}. isInternalInstrument true means the instrument is restricted from public trading. Use search_instruments to resolve a ticker to an instrumentId first.

Rate limit: shares the market-data pool of 120 requests per 60 seconds.

Inputs: instrument_ids (required). Returns: object

get_market_recommendationsA
Read-only

Get personalized market recommendations for the authenticated user.

Returns responseType and instrumentIds — the recommended instrument IDs, resolvable via the market-data tools. Dedicated quota of 60 requests per 60 seconds.

Inputs: limit. Returns: object

get_orderA
Read-only

Look up an order's status by order_id or reference_id (exactly one).

Status ids: 1 Received, 2 Placed, 3 Filled, 4 Rejected, 5 PartiallyFilled, 6 PendingCancel, 7 Canceled, 8 Expired, 9 CanceledPartiallyFilled, 10 RejectedPartiallyFilled. A filled order lists its positions under positionExecutions (positionId, state, remaining units, execution price and fees). Rates are absolute instrument prices; timestamps ISO 8601. Rate limit: shares a 60 requests/60s pool with get_close_order_info.

Inputs: order_id, reference_id. Returns: object

get_pnlA
Read-only

Account P&L: portfolio snapshot with unrealized P&L per position.

Returns credit (available trading balance, USD), bonusCredit, the account-level unrealizedPnl (sum across open positions, account currency), and open positions each carrying an unrealizedPnl figure in the account currency, plus mirror summaries with closedPositionsNetProfit. Total P&L = sum of position unrealizedPnl (own and mirror positions) + sum of mirror closedPositionsNetProfit. Rate limit: shares a 60 requests/60s pool with get_portfolio and get_portfolio_breakdown.

Inputs: limit. Returns: object

get_portfolioA
Read-only

Aggregated portfolio: account totals plus one aggregate per instrument.

Account totals are in the account currency (usually USD): accountAvailableCash, accountFrozenCash, accountCurrentPnl, accountTotalUsedMargin, accountBalance, and accountTotalValue (= available cash + used margin + current P&L). Each instrument aggregate carries net units (positive = long, negative = short), average open rate and leverage, margin, exposure, and unrealized return (accountCurrencyReturn) in the account currency. Filters narrow the instrument aggregates only — account totals ignore them. Rate limit: shares a 60 requests/60s pool with get_portfolio_breakdown and get_pnl.

Inputs: limit, mirror_ids, instrument_ids, conversion_mode. Returns: object

get_portfolio_breakdownA
Read-only

Position-level portfolio snapshot: open positions and pending orders.

Returns credit (available trading balance, USD), bonusCredit, open positions (positionID, instrumentID, isBuy — true long / false short, leverage, amount = invested margin in USD, units, openRate, openDateTime ISO 8601, stop-loss/take-profit rates as absolute prices, mirrorID — 0 = manual position, non-zero = copy trading), pending market-if-touched orders (pendingOrders), pending market opens (ordersForOpen), and pending closes (ordersForClose), plus copy-trading mirror summaries. Cheaper than get_pnl — no unrealized P&L fields. Rate limit: shares a 60 requests/60s pool with get_portfolio and get_pnl.

Inputs: limit. Returns: object

get_profileA
Read-only

Get the authenticated user's identity and the scopes their keys carry.

Calls GET /api/v1/me. Returns gcid (global customer id), realCid and demoCid (real/demo account customer ids), username, first/last name when set, playerLevel (1 Bronze, 2 Platinum, 3 Gold, 4 Internal, 5 Silver, 6 PlatinumPlus, 7 Diamond) with its name, and the OAuth scopes granted to the credentials — useful to verify keys and to see which endpoint groups are accessible. Rate limit: 60 requests per 60 seconds (default shared quota).

Inputs: no named parameters. Returns: object

get_public_watchlistsA
Read-only

List another user's public watchlists by their numeric user ID.

Returns the same shape as list_watchlists: watchlistId, name, watchlistType, totalItems, watchlistRank, and up to items_per_watchlist items each. Shares the watchlist read quota of 60 requests per 60 seconds.

Inputs: user_id (required), limit, items_per_watchlist. Returns: object

get_ratesA
Read-only

Get real-time bid/ask quotes for instruments.

Recommended before placing an order. Returns {"results": [{"instrumentId": int, "bid": float (sell price), "ask": float (buy price), "lastExecution": float, "conversionRateBid": float, "conversionRateAsk": float (instrument currency to USD), "date": ISO-8601 quote timestamp}]}.

Rate limit: shares the market-data pool of 120 requests per 60 seconds.

Inputs: instrument_ids (required). Returns: object

get_trading_cost_estimateA
Read-only

Estimate the costs of a hypothetical open order without placing it.

Takes the same arguments as create_order (exactly one of symbol/instrument_id, exactly one of amount/units/contracts) and returns the cost breakdown: one entry per cost type (markup, marketSpread, transactionFee, overnightFee, overWeekendFee, sdrt) with an amount and currency, plus the quote timestamp (ISO 8601). Rate limit: dedicated 20 requests/60s quota.

Inputs: transaction (required), units, amount, symbol, +7 more. Returns: object

get_watchlistA
Read-only

Get a single watchlist owned by the authenticated user, by ID.

Items are paginated with page_number (zero-based) and items_per_page. Returns the watchlist's metadata plus its items: itemId, itemType ('Instrument' or 'Person'), itemRank, symbol, and itemAddedDate (ISO 8601). Shares the watchlist read quota of 60 requests per 60 seconds.

Inputs: watchlist_id (required), page_number, items_per_page. Returns: object

list_cash_transactionsA
Read-only

List transactions of a cash account, newest pages first.

Calls GET /api/v1/money/accounts/cash/{accountId}/transactions. Paginated by cursor: pass pagination.nextPageToken from one call as page_token to fetch the next page; nextPageToken null (or hasNext false) means the last page. Amounts are decimal strings in ISO 4217 currencies; postedAt is an ISO 8601 timestamp. transactionType is one of card, internalTransfer, bankTransfer, balanceAdjustment; direction is debit or credit; status is one of failed, authorized, settled, rejected, returned, expired, unknown. Rate limit: 60 requests per 60 seconds (default shared quota).

Inputs: account_id (required), limit, page_token. Returns: object

list_exchangesA
Read-only

List exchanges (id and description) for resolving exchangeId values.

Returns {"results": [{"exchangeId": int, "description": str}]}.

Rate limit: shares the market-data pool of 120 requests per 60 seconds.

Inputs: limit, exchange_ids. Returns: object

list_instrument_typesA
Read-only

List instrument types (stocks, crypto, ETFs, ...) by id.

Resolves instrumentTypeId values returned by other market-data tools. Returns {"results": [{"instrumentTypeId": int, "description": str}]}.

Rate limit: shares the market-data pool of 120 requests per 60 seconds.

Inputs: limit, instrument_type_ids. Returns: object

list_price_alertsA
Read-only

List the active price alerts on the account.

Returns up to limit alerts, each with its alertId (UUID), instrumentId, symbol (e.g. AAPL), targetPrice (trigger level in the instrument's quote currency), currentPrice (market bid when the alert was created or last updated), and ISO 8601 UTC createdAt/updatedAt timestamps. Quota: 60 requests per 60 seconds (shared default pool).

Inputs: limit. Returns: object

list_stock_industriesA
Read-only

List stock industries (id and name) for resolving stocksIndustryId values.

Returns {"results": [{"industryId": int, "name": str}]}.

Rate limit: shares the market-data pool of 120 requests per 60 seconds.

Inputs: limit, industry_ids. Returns: object

list_trading_historyA
Read-only

List closed trades since a given date.

Returns trades closed on or after min_date for the configured environment (demo or real account). Each trade includes position and order ids, instrument id, direction (isBuy), leverage, units, invested amount and fees in the account currency, open/close rates in the instrument's quote currency, and ISO 8601 open/close timestamps. Paginate with page and limit. Quota: 60 requests per 60 seconds (shared default pool).

Inputs: min_date (required), page, limit. Returns: object

list_watchlistsA
Read-only

List the authenticated user's watchlists with their items.

Each watchlist carries watchlistId, name, watchlistType (one of Static, Dynamic, RecentlyInvested, Default), totalItems, isDefault, isUserSelectedDefault, watchlistRank (display order), and up to items_per_watchlist items with itemId (instrument or person ID), itemType ('Instrument' or 'Person'), itemRank, and itemAddedDate (ISO 8601). Shares the watchlist read quota of 60 requests per 60 seconds.

Inputs: limit, include_builtin, items_per_watchlist. Returns: object

search_instrumentsA
Read-only

Search instruments by ticker symbol and return candidate matches.

Matching is contains/prefix, NOT exact: searching 'AAPL' also returns variants such as 'AAPL.24-7' and 'AAPL.EUR'. Always verify that the candidate's internalSymbolFull exactly equals the symbol you want before using its instrumentId. Instrument ids are immutable (they survive rebrands and ticker changes), so they are safe to cache.

Returns {"totalItems": int, "results": [{"instrumentId": int, "internalSymbolFull": str, "displayName": str, "isCurrentlyTradable": bool}]}.

Rate limit: shares the market-data pool of 120 requests per 60 seconds.

Inputs: query (required), limit. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 29 tools

    Disambiguation5/5

    Each tool targets a distinct resource or action, with clear descriptions. Even similar tools like get_balance, get_aggregated_balances, and get_balances_by_type are well-differentiated by scope. No overlapping purposes.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern (e.g., get_balance, list_watchlists, search_instruments), using lowercase with underscores. No mixing of conventions.

    Tool Count3/5

    29 tools is on the high side for a single server, exceeding the 'heavy' threshold of 16-25. While each tool serves a specific endpoint, the count may overwhelm an agent. However, the domain is complex enough to justify most tools.

    Completeness2/5

    Several critical operations are missing, such as create_order, cancel_order, create/delete/update watchlists, and manage price alerts. The server provides many read operations but lacks corresponding write/delete actions, leading to dead ends for common trading workflows.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      C
      maintenance
      MCP server for the Trading 212 API. Provides 28 tools for portfolio management, trading, pies, dividends, market data, and analytics.
      28
      125 PyPI
      10
      MIT
    • F
      license
      A
      quality
      D
      maintenance
      A security-hardened MCP server that wraps the eToro public API, enabling AI assistants to trade, access market data, manage portfolios, and interact with social feeds via 34 tools.
      6
      -
    • A
      license
      A
      quality
      D
      maintenance
      MCP server for the tastytrade brokerage API, providing tools for account management, market data, and order execution.
      18
      MIT