MCP server for the eToro public API: market data, account state, and gated trading, watchlist, and social tools.
Strong foundation with 16 well-named tools, comprehensive descriptions (avg 180 chars), and complete JSON Schema definitions for all parameters. All tools follow verb_noun naming (get_, list_, create_, update_, delete_). Descriptions are detailed and include API endpoints, rate limits, and return field documentation. However, output schemas are not formally documented in the tool definitions, responses are described in prose rather than as structured JSON Schema. Error handling guidance is minimal; most tools lack recovery hints. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk classifications in the metadata.
Create a price alert on an instrument. The alert fires when the market bid price reaches ``target_price`` (in the instrument's quote currency). Returns the created alert with its ``alertId`` (UUID) for later update or deletion. Quota: 60 requests per 60 seconds (shared default pool).
Permanently delete a price alert. Fails with HTTP 404 when no alert with ``alert_id`` exists on the account. Quota: 60 requests per 60 seconds (shared default pool).
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).
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).
Output schemas not formally documented. Tool descriptions include prose field lists (e.g., 'Returns gcid, realCid, demoCid...') but no JSON Schema definitions for response objects. LLMs cannot reliably extract or chain response fields without structured schemas.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk classifications. create_price_alert, update_price_alert, delete_price_alert are marked WRITE/DESTRUCTIVE but lack formal annotations to guide agent behavior.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
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).
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).
Get the eToro Club dashboard for the authenticated user. Returns the loyalty-programme dashboard in five sections. ``clubs`` lists every tier (name is one of Internal, Bronze, Silver, Gold, Platinum, PlatinumPlus, Diamond) with its display ``rank`` and the ``minRealizedEquity``/``maxRealizedEquity`` thresholds (realized equity in the account currency; null when unbounded). ``manager`` holds the account manager's name, email, and calendar booking URL. ``downgradeRisk`` reports ``isAtRisk`` plus ``daysUntilDowngrade`` (present only when at risk). ``offers`` groups club offers into ``current`` (available at the user's tier), ``next`` (unlocked at the next tier), and ``static`` (eligible across specific tiers); offer ``status`` is one of Pending, Available, Reserved, Claimed, Expired, Claim Cancelled, Inventory Order Cancelled. ``webinars`` splits into ``upcoming`` (with ``joinUrl``) and ``previous`` (with ``recordUrl``); ``startTime`` is an ISO 8601 UTC timestamp. Quota: 60 requests per 60 seconds (shared default pool).
Get the feed of posts from users the authenticated user follows. Paginate with limit and offset. Each post carries id (UUID), owner (id, username), text, created/updated (ISO 8601 UTC), type (Default, Share, MarketEvent, Trade, Order, Copy, Poll, Article), tagged instrument symbols, attachments, commentsCount, likesCount, and sharedCount; Share posts embed the shared original post and Poll posts embed the poll options. Shares the feeds read quota of 60 requests per 60 seconds.
Get the personalised For You feed for the authenticated user. Paginate with limit and offset. Posts may carry a reason explaining why they were selected (type 'followed-user' or 'instrument-trending' plus a sourceId). Each post carries id (UUID), owner (id, username), text, created/updated (ISO 8601 UTC), type (Default, Share, MarketEvent, Trade, Order, Copy, Poll, Article), tagged instrument symbols, attachments, commentsCount, likesCount, and sharedCount; Share posts embed the shared original post and Poll posts embed the poll options. Shares the feeds read quota of 60 requests per 60 seconds.
Get the discussion feed for one instrument (market). market_id is the numeric instrument ID (as a string) used across the market-data tools. Paginate with limit and offset. Each post carries id (UUID), owner (id, username), text, created/updated (ISO 8601 UTC), type (Default, Share, MarketEvent, Trade, Order, Copy, Poll, Article), tagged instrument symbols, attachments, commentsCount, likesCount, and sharedCount; Share posts embed the shared original post and Poll posts embed the poll options. Shares the feeds read quota of 60 requests per 60 seconds.
Get the eToro news feed (editorial and market-news posts). Paginate with limit and offset. Each post carries id (UUID), owner (id, username), text, created/updated (ISO 8601 UTC), type (Default, Share, MarketEvent, Trade, Order, Copy, Poll, Article), tagged instrument symbols, attachments, commentsCount, likesCount, and sharedCount; Share posts embed the shared original post and Poll posts embed the poll options. Shares the feeds read quota of 60 requests per 60 seconds.
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).
List cash-account transactions (deposits, withdrawals, fees, interest).
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).
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).
Change the target price of an existing price alert. Returns the updated alert. Fails with HTTP 404 when no alert with ``alert_id`` exists on the account. Quota: 60 requests per 60 seconds (shared default pool).
Minimal error recovery guidance. Tools lack descriptions of failure modes and recovery steps. E.g., delete_price_alert states 'Fails with HTTP 404 when no alert exists' but does not suggest how the agent should respond (retry, list alerts, ask user).
list_cash_transactions description is minimal (27 chars). Lacks detail on what 'cash-account transactions' includes, expected return fields, and when to call it vs. other balance tools.
Feed tools (get_news_feed, get_following_feed, get_for_you_feed, get_instrument_feed) share identical pagination and response structure but lack explicit documentation of the distinction between them. LLMs may conflate similar names.