florinel-chis

etoro-mcp

Community florinel-chis
Updated

MCP server for the eToro public API — 105 tools across 12 selectable toolsets with gated trading and social writes

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 writetools are not registered at all unless their gate is enabled — a client connected to the defaultconfiguration cannot see or call them.

Features

  • Read-first by design — 62 read tools across eleven of the twelve toolsets (the socialtoolset is write-only); the 43 write tools exist only when their gate is set — 5 tradingtools behind ETORO_MCP_ENABLE_TRADING, the other 38 (watchlist, alert, social, andnotification mutations) behind ETORO_MCP_ENABLE_WRITES.
  • Demo environment by default — trading tools call the demo endpoint group unlessETORO_ENV=real is set.
  • Toolset selection — register only what you need via ETORO_MCP_TOOLSETS; unknown namesfail 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 byexplicit 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-keyheaders, and error messages never echo header or credential values.
  • Rate-limit aware — HTTP 429 responses are retried once, honouring Retry-After, re-sendingthe same x-request-id so a retried order cannot fill twice.

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 servestreamable HTTP at /mcp instead.

Warning: the HTTP endpoint has no authentication — anyone who can reach the port cancall every registered tool with your API keys' privileges. The server thereforerefuses to bind a non-loopback --host unless --allow-remote is also passed; only usethat flag behind an authenticated reverse proxy or an otherwise-restricted network (such asthe 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 areenvironment-bound, so a demo key against real (or vice versa) fails at the API rather thantrading the wrong account.
  • Write tools are hidden behind two independent gatesETORO_MCP_ENABLE_TRADING fororder/position writes and ETORO_MCP_ENABLE_WRITES for everything else (watchlists, alerts,notifications, social). Gated tools are never registered, not merely rejected, so MCP clientscannot discover or call them.
  • The HTTP transport is unauthenticated: anyone who can reach the port can call everyregistered tool — read balances and positions always, and place or close orders when tradingis 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 anotherwise-restricted network (the stdio transport has no such exposure).
  • upload_media reads local JPEG/PNG files and returns a public CDN URL for them — anextra privilege class beyond the API keys themselves. It is therefore triple-gated: thesocial 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 arerejected, file content must actually be JPEG/PNG, and the 8 MB limit is checked before thefile 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 retryre-sends the same id, so a rate-limited retry cannot double-fill.) Poll fill status withget_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 furtherback; use a coarser interval (e.g. OneWeek) for deeper history.
  • The API enforces per-group rate quotas (order execution 20 requests/60 s; market data120/60 s; portfolio and most other groups 60/60 s; eligibility and cost estimates 20/60 seach). Each tool's description names its quota; 429s are retried once, honouringRetry-After.
  • Trading leveraged products is risky. Use at your own risk, and test everything against ademo 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 thein-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.

MCP Server · Populars

MCP Server · New

    ronak-create

    FableCut

    Zero-dependency browser video editor that AI agents can drive — JSON timeline, MCP + REST, live-reloading UI

    Community ronak-create
    runesleo

    Polymarket Toolkit

    CLI + AI Skills workflow for profiling Polymarket traders from an address

    Community runesleo
    ohad6k

    Emulo

    Mine your Claude Code and Codex logs into a local you.md agent profile.

    Community ohad6k
    vshulcz

    deja-vu

    Memory layer for coding agents: search, MCP recall, auto-context, secret redaction, stats, share and sync over the session logs Claude Code, Codex and opencode already write. One zero-dep binary.

    Community vshulcz
    Wh1isper

    mcp-email-server

    IMAP and SMTP via MCP Server

    Community Wh1isper