eToro MCP Server
Click on "Deploy 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., "@eToro MCP Servershow me my current portfolio and PnL"
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.
eToro MCP Server (unofficial)
Talk to your eToro account from Claude. Ask about your portfolio in plain language, check prices and costs, and — only if you choose to turn it on — place orders that you approve one by one.
Disclaimer. This project is not affiliated with, endorsed by or supported by eToro. "eToro" is a trademark of its owner. Nothing here is financial advice. Trading — especially with leverage or CFDs — can lose money, and software that lets an AI act on a brokerage account can lose it faster. Read the safety model, start on the demo environment, and check eToro's API terms before automating anything.
What it does
MCP is the standard way to give Claude tools. This server gives Claude a set of tools that talk to the eToro Public API with your own keys, so instead of opening the app and clicking around you can just ask:
You say | What happens |
"How is my portfolio doing? What are my biggest positions?" | Claude reads your positions, balances and profit and loss, and summarises them. |
"How are the traders I copy performing?" | One compact summary per copied trader, with their positions available on request. |
"What would it cost to buy 50 dollars of AAPL, and can my account even do that?" | Live price, the settlement types and leverage your account is offered, and an estimate of the fees. |
"What if I had bought 1,000 dollars of AAPL in January with a stop at 170?" / "How would investing 100 dollars every two weeks have done over two years?" | A simulation on eToro's past price candles ( |
"Find popular investors with moderate risk who trade mostly tech, and show me one's stats." | Searches investors by performance, risk and what they hold ( |
"How did my balance change over the last three months? What went through my cash account?" |
|
"Show my closed trades since January." | Your trade history, filtered by date. |
"Find the Apple instrument and tell me how it did over the last year." | Searches by name, then reads the price candles and summarises them (first open, last close, high, low, change). |
"Prepare a purchase of 20 dollars of AAPL on my demo account." | Claude prepares the order (instrument, size, costs, environment) and your browser opens an approval page with the exact action. You press Execute there; Claude cannot. Then it follows the order. |
"Prepare closing that position." / "Add a stop loss at 780 to it." / "Prepare cancelling that pending order." | Same: Claude proposes, you execute on the page. |
"Tell me when AAPL reaches 350." / "Move that alert to 340." / "Delete the alert." | Price alerts: Claude lists them and prepares creating, changing or deleting one; you execute on the page. An alert only notifies you: it places no order and moves no money. |
"Add these instruments to my Tech watchlist." | Creates and edits watchlists (no money involved). |
24 read tools, 12 prepare-only write tools and one gated transfer tool; see Tools.
Safe by default. It starts read-only and on eToro's demo environment. The tools that can move money are not even registered until you switch them on, real money needs a second switch, and Claude can only prepare an action: you execute it yourself on a local approval page, never Claude. Size caps, a rate limit and an audit log apply on top. Your keys stay on your machine (OS keychain, password manager or a protected file) and are never shown to Claude. Details in the safety model.
Related MCP server: eToro Portfolio Connector
TL;DR: install in two minutes
You need an eToro API key pair; a Read key on the Demo environment is enough to start (how to get one).
Claude Desktop
Download
etoro-mcp-server-<version>.mcpbfrom the latest release (or build it:npm ci && npm run mcpb:pack).Double-click it, or drag it into Settings → Extensions. Claude Desktop shows a red warning that the extension gets access to your computer and that Anthropic has not verified the developer: that is expected for an independent project, and you can check where the file came from.
Paste your API key and user key, leave Use the REAL environment and Enable write tools off. The keys go to your OS keychain.
Start a chat and ask: "Check my eToro connection." Then try "How is my portfolio doing?"
Claude Code
git clone https://github.com/slemos/etoro-mcp-server.git && cd etoro-mcp-server && npm ci && npm run build
claude mcp add etoro -- node "$(pwd)/dist/index.js" # reads ETORO_API_KEY / ETORO_USER_KEY from your environmentOther MCP clients and safer ways to hand over the keys (keychain, password manager, protected file) are in Install and Securing your setup.
Why you can trust it
An AI that can touch a brokerage account deserves more scrutiny than most code, so the project treats security as a feature, and checks it automatically on every change:
Check | What it proves | Runs |
Tests | Logic, the prepare → you-execute flow, caps and blocked paths, against a mocked eToro API and an in-memory MCP client | every push and pull request |
SAST (CodeQL, | No known vulnerability patterns in the TypeScript source | every push and pull request, weekly |
Dependency audit ( | The few production dependencies have no known high-severity advisories | same, plus weekly |
Secret scan (Gitleaks) | No keys or tokens in the repository or its history | same |
Dynamic security checks ( | The built server, run as a real process with the network cut off, exposes only the tools each permission switch allows, refuses a non-eToro base URL, rejects hostile arguments before any request, cannot be made to call another API path, and never leaks the keys into results, logs or the audit trail | every CI run and release |
OpenSSF Scorecard | An independent score of the repository's security practices (protected | on every push to |
Protected | Nobody, the owner included, can push to | always |
Build provenance + checksums + SBOM | A release file was built by this repository's workflow from the tagged commit, after everything above passed | every release |
Details and the threat model are in SECURITY.md.
Where it stands (v0.8.0). Early software, tried against a live eToro demo account from Claude Desktop: the connection check, portfolio, positions, PnL, balances, trade history, instrument lookup and text search, rates, candles, eligibility, cost estimates and watchlist listing, the prepare → you-execute flow for opening an order and changing a stop loss, and the action history page with the daily counter. Closing and cancelling from Claude Desktop, watchlist changes and transfers are covered by tests but not yet exercised live (the demo script has closed positions), and nothing has been run with real money. Start on demo.
This server and eToro's official MCP server
eToro publishes its own MCP server (https://mcp.public-api.etoro.com, described at https://mcp.public-api.etoro.com/skill). This project is independent of it and not affiliated with eToro. The two solve overlapping problems differently, and you can install both: their tool names do not collide.
eToro's official server | This server | |
Publisher and support | eToro | An independent open-source project (MIT) |
Where it runs | Remote, hosted by eToro; your credentials go in the connection headers | Local, on your machine; credentials from your keychain, a password manager or a protected file |
Authentication | API key pair or OAuth | API key pair |
Coverage | Read and write tools plus a generic route catalogue ( | A fixed, reviewed route allowlist; no trader profiles yet |
Who executes a trade | Claude: | You: Claude prepares, and only the Execute button on a local page sends anything |
What enforces the approval step | Its documentation describes it as an instruction to the model (show the confirmation, get an explicit yes); it does not describe a server-side human confirmation | The server: no tool Claude can call executes anything, and the HTTP client refuses a write without the permission that button issues |
Size limits, history | Not described in its documentation | Per-order, per-session and per-day caps; a searchable local history |
Extras | Instrument overview, trader profiles | Candles with summaries, what-if simulations and backtests, a pre-close estimate |
As of October 2026, from its public documentation and our own tests on a demo account: in one Claude Code session the official server's prepare-trade and place-trade flow placed an order after a plain "yes". In an earlier test of this project, a session declined to call the tool that executed. We did not isolate why; whether a model calls an execute tool is its own decision, and a gate that depends on it is only as strong as that decision.
Which to use. Use the official server for the widest coverage and for OAuth, if you accept that the model can place orders once you approve in chat. Use this one if you want the approval to be enforced outside the model, local control of your keys, spending limits and a record of what you did. If you only read data, either works. Whichever you choose, start on demo, give the key only the permissions it needs, and keep real-money access off until you have decided you want it.
Safety model
Layer | Default | What it does |
Environment |
| Keys and routes target eToro's demo environment unless you set |
Write tools | off |
|
Real-money writes | off | On |
Transfers | off | The internal-transfer tool needs |
Claude proposes, you execute | always | Every change (orders, closes, cancels, transfers, watchlists) is an |
The approval page | always | Served on |
Size caps | 100 USD / order, 500 USD / session, 1000 USD / day |
|
Daily limits | 1000 USD and 25 writes per day, per environment |
|
Rate brake | 5 writes / minute |
|
Route allowlist | fixed | The HTTP client can only call the routes in |
Environment guard | always | Before any trading preview the server reads the key's scopes ( |
Idempotency | always | Each prepared action has its own |
Tool annotations | always | Read and write tools are separate and carry MCP annotations ( |
Secrets | — | Never in tool inputs, results, errors or the audit log. |
Also strongly recommended on the eToro side: create a Read key unless you need to trade, restrict it by IP, and set an expiry. Keys are separate for Demo and Real, so a demo key can never touch real money.
See SECURITY.md for the threat model and how to report a vulnerability.
History and daily limits
Everything Claude prepares, and what you do with it (execute, reject, let it expire), is recorded in a local SQLite file (ETORO_HISTORY_DB, private to your user, never containing keys or approval links). It has three jobs:
Look back. Ask Claude "what did I do this week?" (
etoro_get_action_history), or ask it to open the history (etoro_open_history): a page in your browser with a search box (words, tickers, order or position ids), filters for date, environment, action and status, the detail of each action with eToro's answer and its timeline, today's use of the daily limits, and a CSV download. The page listens on127.0.0.1only, uses a secret address that expires after an hour, is read-only and has no JavaScript. Nothing in it can change or delete the history.Hold the daily limits.
ETORO_MAX_DAILY_USDandETORO_MAX_DAILY_WRITESare checked and reserved in one database transaction when you press Execute, so two server processes cannot both spend the same allowance, and a restart does not reset it.Survive restarts. An action that was waiting when the server stopped is shown as expired, and one that was executing is shown as failed with a note to check eToro.
The file is a plain SQLite database; you can open it with any SQLite tool, and deleting it only erases the record (and resets the day's counters).
Install
Claude Desktop (MCPB bundle)
Get
etoro-mcp-server-<version>.mcpbfrom the GitHub release, or build it:npm ci && npm run mcpb:pack.Open it with Claude Desktop (double-click, or drag it into Settings → Extensions).
Fill in the form: API key, user key, and leave Use the REAL environment off to start on demo. Keys are stored in your OS keychain.
Leave Enable write tools off until you have tried the read tools.
Claude Desktop shows a red warning before installing: the extension runs with your user's access to your computer, and any developer information shown "has not been verified by Anthropic". That is the case for any extension from outside Anthropic's own directory, and this bundle is also not signed with a code-signing certificate; see Verifying a release for how to check where it came from. Some organisations restrict which extensions may be installed; if yours does, ask your administrator or build from source.
Claude Code
git clone https://github.com/slemos/etoro-mcp-server.git && cd etoro-mcp-server
npm ci && npm run buildExport your keys in your shell profile or secret manager (do not paste them into chat or commit them), then register the server. A project-scoped .mcp.json can reference them without containing them:
{
"mcpServers": {
"etoro": {
"command": "node",
"args": ["/absolute/path/to/etoro-mcp-server/dist/index.js"],
"env": {
"ETORO_API_KEY": "${ETORO_API_KEY}",
"ETORO_USER_KEY": "${ETORO_USER_KEY}",
"ETORO_ENV": "demo"
}
}
}
}Or from the CLI: claude mcp add etoro -- node /absolute/path/to/etoro-mcp-server/dist/index.js (the server reads ETORO_API_KEY / ETORO_USER_KEY from the environment Claude Code runs in). Check with claude mcp list.
Any other MCP client
It is a standard stdio server: run node dist/index.js with the environment variables below. With npx once published: npx -y etoro-mcp-server.
Getting eToro API keys
Use a verified eToro account.
In eToro go to Settings → Trading → API Key Management → Create New Key.
Choose the environment (Demo first), the permission (Read, or Write only if you want to trade) and, ideally, an IP allowlist and an expiry. SMS verification is required.
You get an API key (
x-api-key) and a user key (x-user-key). Treat both like passwords.
Reference: Authentication.
Securing your setup
The server needs two secrets (the API key and the user key). How you hand them over matters as much as what the server does with them. Anyone who gets the pair can read your account, and with a Write key can trade on it.
On the eToro side (always): create a Read key unless you really need to trade; keep Demo and Real keys separate (eToro's documentation says a key serves one environment, but a key can carry scopes for both — etoro_check_connection shows them, and strict key scope — on by default for real, off for demo, configurable with ETORO_STRICT_KEY_SCOPE — makes the server refuse such keys for trading); restrict the key by IP address; set an expiry; revoke it at once if it may have leaked. etoro_check_connection shows the key's scopes and warns when a read-only server holds a Write key.
On your side: keep the secrets out of config files and shell history. Pick the first option that your client allows:
Option | Where the secret lives | Use it with |
MCPB bundle ( | OS keychain, managed by the host | Claude Desktop |
| OS keychain or password manager; the config only holds the command | Any client, manual setup |
| A file readable only by you (the server refuses it otherwise) | Any client, manual setup |
Plain | Your shell or a config file in clear text | Quick local tests only |
Avoid putting the keys directly in claude_desktop_config.json, in claude mcp add -e ETORO_API_KEY=... (stored in clear text in ~/.claude.json and in your shell history), or in a committed .mcp.json. Set exactly one source per key; the server refuses ambiguous setups.
*_CMD takes a command line that prints the secret on one line. It is split into words (quotes are honored) and run without a shell: no pipes, no expansion. It runs with your privileges, so treat it like the command of the server itself. *_FILE accepts ~/... paths; on macOS and Linux the file must not be accessible to group or others (chmod 600).
Recipes
macOS Keychain (prompts for the value without echoing it):
security add-generic-password -U -s etoro-mcp-server -a api-key -w
security add-generic-password -U -s etoro-mcp-server -a user-key -w"env": {
"ETORO_API_KEY_CMD": "security find-generic-password -s etoro-mcp-server -a api-key -w",
"ETORO_USER_KEY_CMD": "security find-generic-password -s etoro-mcp-server -a user-key -w",
"ETORO_ENV": "demo"
}When macOS asks whether security may read the item, prefer Allow over Always Allow: with "Always Allow", any program you run that calls security can read it without asking.
Linux (libsecret): secret-tool store --label="eToro API key" service etoro-mcp-server key api-key (same for user-key), then ETORO_API_KEY_CMD="secret-tool lookup service etoro-mcp-server key api-key".
Password managers: any CLI that prints the secret works, for example op read "op://Private/eToro/api-key" (1Password, with biometric unlock), pass show etoro/api-key, or bw get password etoro-api-key (Bitwarden, needs an unlocked session).
A protected file:
mkdir -p ~/.config/etoro-mcp && chmod 700 ~/.config/etoro-mcp
( umask 077; printf "API key: "; read -rs v; echo; printf '%s' "$v" > ~/.config/etoro-mcp/api-key )
( umask 077; printf "User key: "; read -rs v; echo; printf '%s' "$v" > ~/.config/etoro-mcp/user-key )
# then: ETORO_API_KEY_FILE=~/.config/etoro-mcp/api-key ETORO_USER_KEY_FILE=~/.config/etoro-mcp/user-keyWindows: use the MCPB bundle (keys go to the host's credential store), or a password manager CLI through *_CMD.
What this does not protect against
The server runs as you. Another program running as your user can read what you can read, including the keychain items you allow and files with your permissions. Prompt injection is a separate risk, covered by the write-tool safeguards above. Use IP restrictions and short expiries so that a leaked key is worth little.
Verifying what you install
Building from source is small and auditable (npm ci uses the committed lockfile). Release bundles are built by GitHub Actions from the tagged commit, after tests and security checks pass.
Verifying a release
Each release attaches the bundle, a SHA256SUMS file and an SBOM (*.sbom.cdx.json, CycloneDX). The bundle is not code-signed with a certificate; its provenance is attested instead, which proves it was produced by this repository's release workflow:
shasum -a 256 -c SHA256SUMS --ignore-missing
gh attestation verify etoro-mcp-server-<version>.mcpb --repo slemos/etoro-mcp-serverIf you would rather not trust a binary at all, build it yourself (npm ci && npm run mcpb:pack) and compare the result with the release.
Configuration
All settings are environment variables (see .env.example). The server does not read a .env file by itself: export the variables, or load a git-ignored .env with Node's flag, e.g. node --env-file=.env dist/index.js (Node 22.13+, which the history database needs).
Variable | Default | Description |
| — (required) | Public API key ( |
| — (required) | User key ( |
|
|
|
| unset |
|
|
| Register the write tools. Needs a key with Write permission. |
|
| Second switch required for write tools when |
|
| Register the internal-transfer tool (real only, needs both switches above). |
|
| Refuse trading previews when the key can also write in the other environment. On real it means the key must be real-only; on demo it would mean the key must not be able to trade real money. Set it explicitly to override either default. |
|
| Open the approval page in your default browser when an action is prepared. If it cannot be opened, the address is in the server's log (stderr). |
|
| Put the approval page's address in the tool result. That lets Claude see it, and with browser tools open it: meant for scripts ( |
|
| Max exposure (amount × leverage) or transfer amount per action. |
|
| Max total exposure executed until the server restarts. |
|
| Local brake on executed writes (eToro also rate-limits). |
|
| Max total exposure (and transfers) executed per calendar day, per environment. Counted in the history database: it survives restarts and is shared by every server process. A request that clearly fails at eToro (a 4xx answer) gives its share back; a timeout or network error does not, because the order may exist. |
|
| Max executed writes (orders, closes, stop-loss changes, watchlist changes...) per calendar day, per environment. |
|
| IANA time zone (for example |
| your data folder | Path of the SQLite file with the action history and the daily ledger (macOS |
|
| How long a prepared action waits for you on the approval page. |
|
| Output size cap per tool result. Above it, arrays are shortened to their first N items (the result stays valid JSON and lists each array's real length). |
|
| Log each HTTP call to eToro (method, path, query names, status, duration) to stderr. Never logs keys, headers or bodies. |
| unset | Append JSON-lines audit events to this file (also logged to stderr). |
|
| Must be |
Tools
24 read tools (always available) and 12 write tools that only prepare (+1 gated transfer tool). Full parameters and the eToro routes they use are in docs/TOOLS.md.
Tool | Kind | Purpose |
| read | Verify the keys authenticate, show their scopes (demo/real, read/write), and prove which account (demo or real) the data comes from |
| read | Aggregated portfolio snapshot |
| read | Open positions (ids, units), pending orders, credit |
| read | Unrealized PnL and portfolio details |
| read | Balances across your eToro accounts |
| read | Closed trades since a date |
| read | Status of one order |
| read | Resolve exact tickers / ids to instruments |
| read | Find instruments by name or partial text ("apple", "S&P 500") |
| read | Historical price candles (1m to 1w) for a window, with a summary: first open, last close, high, low, % change, volume |
| read | Find investors by performance and risk filters (period, risk score, copiers, instrument held...), compact public stats per investor |
| read | One investor's public data by username: profile, statistics over a period, copiers, gain history and live portfolio. Free text they wrote is flagged as untrusted |
| read | Day-by-day total balance between two dates, with a summary (start, end, change, lowest, highest) |
| read | Movements of one of your cash accounts, newest first, paginated |
| read | What-if on past prices: a long or short with leverage, stop loss and take profit, followed over a window of candles (entry, exit and why, result in USD and %, worst and best moments). Places nothing |
| read | Backtest |
| read | Bid/ask for instruments |
| read | Settlement types, leverage, limits per instrument |
| read | What-if cost breakdown for an order |
| read | Your active price alerts, with which way the price has to move to reach each target and how far |
| read | Your watchlists |
| read | Where a prepared action stands (waiting, executed with eToro's answer, rejected, expired, failed); also finds actions from earlier sessions |
| read | Search the local history (text, ids, dates, environment, action, status) and see today's use of the daily limits |
| read | Open a read-only page in your browser to search, filter and export the history |
| write (preview) | Validate + preview an order, open its approval page; returns |
| write (preview) | Preview closing all/part of a position: instrument, direction, current price, rough result, what stays open |
| write (preview) | Preview changing the stop loss / take profit of an open position (new rates, trailing, or removing them) |
| write (preview) | Preview cancelling a pending order |
| write (preview) | Preview cancelling a pending close order (the position stays open) |
| write (preview, gated) | Preview an internal transfer (real + opt-in only) |
| write (preview) | Propose creating, changing the target of, or deleting a price alert (no order, no money); you execute them on the page |
| write (preview) | Propose watchlist changes (no money involved); you execute them on the page |
Example: a guarded order
You: Prepare a purchase of 50 USD of AAPL as a CFD on my demo account.
Claude: [etoro_prepare_open_position] → preview: BUY AAPL (id 1001) | $50.00 | 1x | cfd | mkt | DEMO,
eligibility, estimated costs, actionId 6b1c… (nothing sent; your browser opens the approval page)
You: (review the page, press Execute) → the server sends the order to eToro
Claude: [etoro_get_action_status] → executed, eToro's orderId
Claude: [etoro_get_order] → status of the ordereToro answers an order with "accepted for processing", not "filled": follow the order with etoro_get_order.
Trying an order on the demo environment
npm run demo:order runs the whole flow through the real server on eToro's demo (virtual money) environment: connection and environment check, instrument lookup, eligibility, preview with cost estimate, your confirmation in the terminal, execution, and following the order until it has a position.
npm run demo:order -- --symbol AAPL --amount 50 # buy $50 on demo, keep the position
npm run demo:order -- --symbol AAPL --amount 50 --close # ... and close it afterwards (asks again)
npm run demo:order -- --symbol AAPL --amount 20 --settlement cfd
npm run demo:order -- --close-position 123456789 # close an open demo position by id
npm run demo:order -- --symbol AAPL --amount 50 -y 2>&1 | tee demo-order.log # no questions, output to a logThe script forces ETORO_ENV=demo whatever your environment says, stops unless the connection check proves the key reaches your demo account, and asks in the terminal before sending anything; your "yes" (or -y) is what it uses to press Execute on the approval page for you. -y (or --yes) answers yes to the questions — the order and, with --close, the close — so you can pipe the output to a log (use 2>&1 to include the server's audit lines). Without a terminal and without -y it refuses to start instead of hanging. Use a key with demo Write permission. After a fill it prints the new position's settlement (cfd or real) with its settlementTypeID and isSettled. --settlement real on an account that is only offered CFDs is refused at the preview.
Known limitations
Very large responses are shortened. A big portfolio (many positions or copy-trading mirrors) can exceed the output cap; the server then keeps the first N items of each array and says how many there really were. Prefer narrower tools or raise
ETORO_MAX_RESPONSE_CHARS.Responses are passed through as eToro sends them. The shapes come from eToro's reference pages and from a live demo account (see "Where it stands" above); the actions listed there have been tried live and the rest only through tests. If a field is missing or renamed, please open an issue with the (redacted) response shape (
--verbose --maskin the smoke script produces one that is safe to paste).etoro_get_instrumentsis an exact lookup (ticker or id); useetoro_search_instrumentsfor names. ETF tickers on eToro carry an exchange suffix such asEXMPL.L.Claude cannot execute, by design. Claude's own rules keep it from executing financial transactions, so the server never asks it to: it prepares, you press Execute on the approval page. That needs a browser on the same computer (or
ETORO_SHOW_APPROVAL_URL=trueto read the address from the log or result); without a screen, nothing can be executed.Prepared actions live in memory. They are forgotten when the server restarts (for example when Claude Desktop restarts it), and expire after
ETORO_CONFIRM_TTL_SECONDS.Prompt injection is a real risk for any tool-using agent: do not let Claude read untrusted content (web pages, emails, documents) in the same session in which it can prepare real orders, and read the approval page carefully before pressing Execute. If Claude has browser tools, keep
ETORO_SHOW_APPROVAL_URLoff so it never sees the page's address.No streaming/WebSocket data, no copy-trading actions, no OAuth (API key pair only).
Eligibility to use the API and the instruments available depend on your account and jurisdiction. In particular, depending on jurisdiction some accounts can only open CFDs, not real shares:
settlementType: "real"is then rejected by eToro (seen on a demo account that was offered only CFDs).etoro_prepare_open_positionreads the eligibility answer first and refuses a settlement type the account is not offered, before anything can be confirmed.Two instruments for some stocks. eToro lists a regular-trading-hours instrument (symbol ending in
.RTH) next to the 24/5 one for some stocks. The preview shows the exact symbol and instrument id, and warns on.RTH; passinstrumentIdwhen in doubt.
Development
npm ci
npm run typecheck
npm test # unit + end-to-end tests with a mocked eToro API (no network, no keys)
npm run build # tsc → dist/
node scripts/smoke.mjs # launch the built server over stdio and list tools (dummy keys)
npm run security:check # runs the built server with the network cut off: permission switches, hostile inputs, secret redaction
npm run mcpb:pack # esbuild bundle → server/index.js, then etoro-mcp-server.mcpb
npm run pack:dev # throwaway etoro-mcp-server-dev.mcpb, versioned <version>-dev.<n>, to try changes in Claude DesktopWith your own keys in a git-ignored .env, npm run smoke:live (or node scripts/smoke.mjs --live with the variables exported) runs etoro_check_connection and a few read tools and prints only the shape of the responses (never values), which is a safe first check. In a client, ask Claude to run etoro_check_connection to confirm the keys work and which mode the server is in.
Debugging options for the script (all run the real server over stdio):
Option | Effect |
| Only verify the connection and the environment ( |
| Print each tool's full output. It contains your real account data: keep it private. |
| Same, but every value is replaced by a placeholder ( |
| Call a single tool, e.g. |
| Sets |
| Launch another entry point, e.g. |
src/
config.ts env parsing, switches, caps
endpoints.ts the complete route allowlist (read vs write)
client.ts HTTP client: auth headers, idempotency ids, 429 retry, redaction, policy checks
approval/ proposals (limits, status), the local approval page (server, renderer, browser opener), the write permission
audit.ts JSON-lines audit trail
tools/ read.ts, write.ts, common.ts
test/ vitest, including MCP client ↔ server tests over an in-memory transportContributing
Issues and pull requests are welcome — see CONTRIBUTING.md. Security issues: see SECURITY.md.
License
Available Tools
11 toolsetoro_check_eligibilityCheck eToro trading eligibilityARead-onlyIdempotent
What the demo account may do with instruments: available settlement types (real/cfd), leverage values, buy/sell and partial-close permissions, minimum position amounts, stop-loss/take-profit limits. Computes only; places nothing. Provide instrumentIds and/or symbols (max 100 combined).
| Name | Required | Description | Default |
|---|---|---|---|
| symbols | No | ||
| instrumentIds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnlyHint, idempotentHint, destructiveHint and openWorldHint, so the safety profile is known. The description still adds genuine value by stating 'Computes only; places nothing' and by describing the returned decision fields (settlement types, permissions, limits), which no output schema provides. It does not, however, cover auth scope or any per-call limits beyond input count.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense clause stating what is returned, followed by a short constraint sentence and a short input instruction. Strongly front-loaded with the payload description and no filler. Slightly run-on list inside the first clause, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and 0% schema description coverage, the description must explain both returns and inputs, and it does so competently for a two-parameter read tool. Remaining gaps are minor: behavior when neither parameter is given, and the 'demo account' scoping, which could confuse an agent unsure whether it applies to live accounts.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the parameter burden and largely does: it explains that instrumentIds and symbols are alternatives ('and/or') and imposes a 'max 100 combined' limit that is stricter and more useful than the schema's per-array maxItems of 100. It does not explain symbol format or what happens when neither is supplied.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description enumerates exactly what the tool returns for a given instrument set (settlement types, leverage, buy/sell and partial-close permissions, minimums, SL/TP limits), which is far more specific than a restatement of the name. It is clearly distinct from the portfolio/pnl/balances siblings. It lacks an explicit verb ('check'), but the resource and scope are unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the tool reports what an account may trade, and 'Computes only; places nothing' signals a pre-trade query. However, there is no explicit when-to-use framing, no prerequisites, and no alternative sibling is named or excluded, so an agent must infer the context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
etoro_get_balancesGet eToro balancesBRead-onlyIdempotent
Aggregated balances across the user's eToro accounts (trading, cash, ...), expressed in a display currency. Not environment-specific: it reports the account the key belongs to.
| Name | Required | Description | Default |
|---|---|---|---|
| accountTypes | No | Comma-separated filter: Trading, Cash, Options, Crypto, MoneyFarm, Spaceship, Plaee. | |
| displayCurrency | No | ISO 4217 code used for totals. | USD |
| includeSubAccounts | No | ||
| includeZeroBalances | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description usefully adds that balances are aggregated in a display currency and that the tool reports the account the key belongs to (not environment-specific), which is real context beyond annotations, but it says nothing about response shape or currency-conversion behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with the core purpose front-loaded and no filler. Slightly terse given the tool's scope, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-required-parameter read tool with annotations covering safety, the description is adequate on purpose but incomplete: it omits the meaning of unfiltered calls (all account types?), pagination, and the shape of the aggregated result. With no output schema present, a bit more disclosure would help.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 50%: accountTypes and displayCurrency are documented, while includeSubAccounts and includeZeroBalances have no description in either the schema or the description. The description mentions no parameter at all, so it fails to compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('aggregated balances across the user's eToro accounts') and clarifies scope with 'trading, cash, ...'. It hints at differentiation from portfolio siblings via 'Not environment-specific', but never names a sibling like etoro_get_portfolio, so an agent must still infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance and no named alternative among the many portfolio/PnL siblings. The only routing clue is the negative statement that it is not environment-specific, which does not tell the agent when to prefer this over etoro_get_portfolio or etoro_get_portfolio_breakdown.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
etoro_get_instrumentsFind eToro instrumentsARead-onlyIdempotent
Look up instruments by exact ticker symbols or by instrument ids, or list by type. Returns instrumentId, symbol, displayName, type and exchangeId. Free-text name search is not supported; ETF listings use exchange suffixes (for example CSPX.L). Provide symbols or instrumentIds, not both.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | ||
| symbols | No | Exact tickers, e.g. ['AAPL', 'CSPX.L']. | |
| pageSize | No | ||
| instrumentIds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly/idempotent/openWorld/non-destructive, so the safety profile is covered. The description adds genuinely useful behavior beyond that: the lack of free-text search, the exchange-suffix convention for ETFs with a concrete example (CSPX.L), and the return field list (no output schema exists, so this is the only source).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with no filler, front-loaded with the core action before the constraints. The return-field list and the 'not both' rule each carry weight, though the sentences are packed tightly enough that a little breathing room would help readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return shape itself, and it covers the input modes and mutual-exclusion rule. Remaining gaps are minor: it never says what happens when no parameters are supplied (full listing?) or how pageSize pagination behaves.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 25% (just 'symbols'), so the description does meaningful compensation: it clarifies symbols are exact tickers, contrasts symbols vs instrumentIds, explains the ETF suffix format, and notes only one of the two should be supplied. pageSize and the type enum values are left to the schema, which documents them adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('look up instruments') and enumerates the three lookup modes (exact symbols, instrument ids, or by type). Also names the returned fields (instrumentId, symbol, displayName, type, exchangeId), so an agent knows exactly what it gets. Clearly distinct from the sibling portfolio/order/rate tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete operating constraints: free-text name search is not supported, and symbols/instrumentIds should not be combined. These are real usage rules that steer the caller. It does not name an alternative tool, but none of the siblings overlaps this lookup function, so the guidance is effectively complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
etoro_get_orderLook up an eToro orderARead-onlyIdempotent
Status and execution details of one order, found by orderId (returned when an order is placed) or by referenceId. Provide exactly one.
| Name | Required | Description | Default |
|---|---|---|---|
| orderId | No | ||
| referenceId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds provenance context ('orderId returned when an order is placed') but says nothing about behavior on a missing order, pagination, or rate limits, so it adds only modest value beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence naming the return content, followed by a terse clause on key selection and the exactly-one constraint. Nothing is redundant and no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read-only lookup with no output schema, the description covers what is returned at a summary level and how to identify the order. It does not sketch the shape of 'status and execution details' or error behavior, which is the only real gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the parameter burden, and it does: it explains what orderId is (returned when an order is placed), that referenceId is an alternative identifier, and that exactly one must be supplied. It omits type/format constraints (positive integer, string length), keeping it short of a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Status and execution details of one order') and names the lookup keys, so the agent knows it fetches a single order rather than a list. The resource is distinct from every sibling (portfolio, pnl, balances, rates, watchlists), though the description never explicitly contrasts itself with them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives useful invocation guidance — use either orderId or referenceId and 'Provide exactly one' — which tells the agent how to call it. However, it says nothing about when this tool is appropriate versus other order- or history-related siblings such as etoro_get_trade_history, so usage context is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
etoro_get_pnlGet eToro account PnLARead-onlyIdempotent
Unrealized profit/loss and portfolio details of the demo account (positions, mirrors, pending orders and orders to open/close).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), so the bar is lower, and the description still adds two useful pieces of context: that it targets the demo account specifically and exactly which data classes are returned. It stops short of noting any auth, rate-limit, or freshness/valuation caveats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the subject (unrealized P/L) comes first and the enumeration is compactly parenthesized. Every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and no output schema, the description must convey what comes back, and it does enumerate the returned data classes. The remaining gap is the absence of sibling differentiation, which matters given three other portfolio-style tools in the same family.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate and the baseline of 4 applies. The parenthetical clarifies what the (parameterless) response covers, which is a reasonable substitute.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource and result: unrealized P/L plus portfolio details, with an explicit enumeration of contents (positions, mirrors, pending orders, orders to open/close). It is clear what the tool returns, but it never distinguishes itself from close siblings like etoro_get_portfolio, etoro_get_portfolio_breakdown, or etoro_get_balances, which an agent must choose between.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only scoping signal is 'demo account', which implies a context but is not framed as a when-to-use rule. No alternatives are named and no conditions for choosing this over the other portfolio/balance tools are given, leaving selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
etoro_get_portfolioGet eToro portfolio snapshotARead-onlyIdempotent
Aggregated snapshot of the demo account: account totals, open positions grouped by instrument, and copy-trading mirrors. For individual open positions with their position ids and pending orders use etoro_get_portfolio_breakdown. Reference: https://api-portal.etoro.com.
| Name | Required | Description | Default |
|---|---|---|---|
| pnlLevel | No | Profit/loss detail to include. | Pnl |
| instrumentIds | No | Restrict the snapshot to these instrument ids. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description usefully scopes the call to the 'demo account' and sketches the aggregation shape, but discloses nothing about pagination, latency, or auth requirements beyond the API reference link.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, all front-loaded: what it returns first, the sibling alternative second, the reference link last. No filler or restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of describing the return shape, and it does so adequately (totals, positions grouped by instrument, mirrors). The 'demo account' framing answers an important scope question, though the absence of any note on the aggregate-vs-breakdown trade-offs for filtering remains a small gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so pnlLevel and instrumentIds are already documented in the schema, including the enum values and maxItems constraint. The description adds no additional meaning about these filters, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('aggregated snapshot of the demo account') and enumerates exactly what the payload contains: account totals, open positions grouped by instrument, and copy-trading mirrors. It explicitly contrasts itself with the sibling etoro_get_portfolio_breakdown, so an agent can distinguish the two without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names an alternative and the condition that selects it ('For individual open positions with their position ids and pending orders use etoro_get_portfolio_breakdown'), which is genuine routing guidance. It does not, however, say when to prefer this aggregated view over other sibling reads like etoro_get_pnl or etoro_get_balances, which overlap in scope.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
etoro_get_portfolio_breakdownGet eToro positions and pending ordersARead-onlyIdempotent
Open positions (with position ids and units), pending orders and available credit for the demo account. Position ids from here are what etoro_prepare_close_position needs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish the safe-read profile (readOnlyHint, idempotentHint, destructiveHint=false). The description then adds behavior the annotations cannot convey: the data is scoped to the demo account and the response carries position ids and units that are consumable downstream. It does not mention pagination or result size limits, but the added account scoping is meaningful context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. Content is front-loaded (what is returned first, then the downstream-id note), and every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must convey what comes back, and it does list the three main return groups plus the demo-account scope. It stops short of describing field-level detail or ordering, which is acceptable for a read-only breakdown tool but leaves some minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a no-parameter tool applies. The description correctly spends no words on arguments and instead characterizes the returned data.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the concrete resources returned: open positions (with ids and units), pending orders, and available credit. That is specific enough for an agent to know what it gets, but it never explicitly distinguishes itself from likely overlapping siblings such as etoro_get_portfolio or etoro_get_balances.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives one real usage hook — the position ids are the inputs that etoro_prepare_close_position needs — which is genuinely useful workflow guidance. However, there is no statement of when to prefer this over etoro_get_portfolio, etoro_get_balances, or etoro_get_pnl, so selection among siblings is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
etoro_get_ratesGet eToro bid/ask ratesARead-onlyIdempotent
Current bid and ask for up to 100 instruments by id. Prices are eToro's quotes, not necessarily the underlying venue's.
| Name | Required | Description | Default |
|---|---|---|---|
| instrumentIds | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint, idempotentHint, destructiveHint=false), so the description's added value is the caveat that these are eToro's own quotes rather than the underlying venue's prices, which is genuinely decision-relevant for an agent. It does not discuss failure behavior for unknown ids or rate limits, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no waste, with the core operation stated first and the important quote-source caveat second. Both sentences earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully names the returned fields (bid and ask) and the quote provenance, so an agent knows what comes back. Only minor gaps remain around id validity and error behavior for a tool this simple and well-annotated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the single instrumentIds parameter, so the description must carry the load. It conveys the id-based array and the 100-item ceiling, matching the schema's maxItems, but adds no clarification on id format, ordering, or error handling for invalid ids.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (current bid and ask) plus a scope limit (up to 100 instruments by id), which separates it from sibling lookups like etoro_get_instruments or etoro_get_trade_history. It stops short of naming an alternative sibling explicitly, so it is clear but not fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use or when-not-to-use guidance, nor any pointer to etoro_get_instruments as the source of the ids this tool requires. The 'by id' phrasing implies a prerequisite lookup, but the routing decision is left entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
etoro_get_trade_historyGet eToro closed tradesARead-onlyIdempotent
Closed trades of the demo account since a date, with open/close rates, net profit and fees. Paginated.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| minDate | Yes | Start date, YYYY-MM-DD. | |
| pageSize | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive, and open-world behavior. The description adds useful operation-specific context: it is limited to the demo account, returns closed trades with open/close rates, net profit and fees, and is paginated. It still does not explain pagination behavior or authentication needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no wasted words. The core purpose, scope, return fields, and pagination caveat are front-loaded and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only listing tool with no output schema and rich safety annotations, the description covers the key facts an agent needs: demo-account scope, closed trades only, date filtering, returned fields, and pagination. It remains incomplete on pagination details and lacks sibling routing, but overall it is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is low at 33%, with only minDate documented. The description adds some semantic value: 'since a date' clarifies minDate as a start date, and 'Paginated' signals that page/pageSize exist and matter. However, it does not explain page or pageSize behavior, defaults, or limits, so the two undocumented parameters remain underspecified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States specific verb+resource ('Get eToro closed trades'), scope ('demo account since a date'), and returned fields. It distinguishes closed trades from generic portfolio/PnL siblings implicitly through 'closed trades' and 'open/close rates, net profit and fees', but does not explicitly say how it differs from tools like etoro_get_pnl.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use or when-not-to-use guidance, and no alternative sibling is named. The description only implies usage by specifying 'closed trades of the demo account since a date', leaving the agent to infer context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
etoro_get_trading_costsEstimate eToro trading costsARead-onlyIdempotent
What-if cost breakdown (markup, market spread, transaction fee, overnight and weekend fees, stamp duty) for a hypothetical order. Computes only; places nothing. Amounts are in USD. For closing, pass the position ids.
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | open | |
| symbol | No | ||
| leverage | No | ||
| amountUsd | No | ||
| orderType | No | mkt | |
| positionIds | No | ||
| transaction | No | buy | |
| instrumentId | No | ||
| settlementType | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/openWorld, so the bar is lower, yet the description adds real value: it confirms nothing is placed, enumerates the fee components computed (markup, spread, transaction, overnight/weekend, stamp duty), and specifies amounts are in USD. It omits any statement about return shape or latency, but the added context is solid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the purpose and the compute-only guarantee, then the currency unit and the closing hint. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter tool with zero schema descriptions and no output schema, the description is thin: it names the output fee components and currency but leaves nearly all input semantics undocumented, so an agent must infer which parameters pair with which action (open vs close) and what values are valid.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 9 parameters, so the description carries the full burden. It only clarifies one parameter ('For closing, pass the position ids') and never explains action, symbol, leverage, amountUsd, orderType, transaction, instrumentId, or settlementType — enums and defaults exist in the schema but no semantics are added.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — a what-if cost breakdown for a hypothetical order — and immediately clarifies 'Computes only; places nothing', which cleanly separates it from the read-only portfolio/pnl/balance siblings and from any order-placement flow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'what-if ... hypothetical order' framing plus 'Computes only; places nothing' tells the agent this is for estimation rather than execution, and 'For closing, pass the position ids' gives a concrete conditional. It stops short of naming an alternative tool or stating exclusions explicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
etoro_list_watchlistsList eToro watchlistsCRead-onlyIdempotent
The user's watchlists with their items (instrument ids).
| Name | Required | Description | Default |
|---|---|---|---|
| itemsPerPage | No | ||
| includeBuiltin | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is covered. The description adds some value by stating that items are returned as instrument ids, but it does not explain pagination behavior, whether built-in watchlists are included, or other operational details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single noun phrase rather than a structured sentence, so it is terse but under-specified. It is not front-loaded with a clear verb or usage context, leaving important information absent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With two undocumented parameters, no output schema, and no usage guidance, the description is too thin for an agent to call the tool confidently. It states the broad return content but omits parameter meanings, pagination, and the role of built-in watchlists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for both itemsPerPage and includeBuiltin, and the description does not mention either parameter. The definition gives an agent no way to understand the two inputs beyond their bare names and defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific resource (the user's watchlists) and what each contains (items / instrument ids), so an agent can tell it is a read/list tool for watchlists. It lacks an explicit verb, but the title supplies 'List' and no sibling tool covers watchlists, making the purpose clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this tool, when to avoid it, or how it relates to the portfolio and instrument siblings. The agent must infer its usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v0.1.0- First observed
etoro_check_eligibility - First observed
etoro_get_balances - First observed
etoro_get_instruments - First observed
etoro_get_order - First observed
etoro_get_pnl - First observed
etoro_get_portfolio - First observed
etoro_get_portfolio_breakdown - First observed
etoro_get_rates - First observed
etoro_get_trade_history - First observed
etoro_get_trading_costs - First observed
etoro_list_watchlists
TDQS
Scored across 11 tools
etoro_get_portfolio, etoro_get_portfolio_breakdown, etoro_get_pnl, and etoro_get_balances all return overlapping portfolio/account data. Descriptions attempt to differentiate (e.g., aggregated vs. breakdown), but an agent could still misselect among the portfolio tools. Other tools are clearly distinct.
All tools use the etoro_ prefix followed by a consistent snake_case verb_noun pattern (get_, check_, list_). No deviation in style or casing.
11 tools is a reasonable count for a read-focused trading API surface. It is not excessive, but the absence of any execution tools makes the set feel slightly under-scoped relative to the platform's purpose.
Major gaps: no tools to place orders, cancel orders, or close positions, despite etoro_check_eligibility and etoro_get_trading_costs implying trading workflows. The description of etoro_get_portfolio_breakdown references etoro_prepare_close_position, which is not present, creating a dead end. Watchlists are read-only.
Maintenance
Related MCP Connectors
- FensoryOAuthcom.fensory
Trading MCP server for AI agents, with live market data, account reads and controlled execution.
Agentic brokerage access to a US brokerage account: quotes, orders, positions, cash and documents.
Unified financial infrastructure connecting AI agents directly to trade live/demo brokerage accounts, Web3 non-custodial wallets, real-time market data across equities, ETFs, crypto, forex, options, DeFi swaps, and prediction markets, institutional research feeds, and algorithmic strategy backtesters.
MCP server for OpenMM — exposes market data, account, trading, and strategy tools to AI agents
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides secure access to Trading 212 Public API through MCP, enabling Claude Desktop users to manage portfolios, execute trades, and analyze market data using natural language commands.-
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server that connects Claude to your eToro account, enabling queries about your portfolio, P\&L, balances, watchlists, live prices, and price history.MIT
- AlicenseNot gradedqualityAmaintenanceMCP server for Interactive Brokers that provides account, portfolio, market data, and risk analysis tools to MCP hosts like Claude Desktop, enabling natural language queries about positions, market regime, and position sizing without placing orders.8MIT
- FlicenseNot gradedqualityBmaintenanceA local-first MCP server that connects Claude Code to your Robinhood account, enabling read-only portfolio insights, tax analysis, and natural language queries, with optional human-in-the-loop trading actions.-