Docs

MCP server: connect Claude, ChatGPT and AI agents to MetaTrader 5

Connect Claude (claude.ai, Desktop, Code), ChatGPT and other AI agents to your MetaTrader 5 accounts through the fxapis MCP server: sign in, choose read-only or trading per account, revoke any time. Setup per client, the tool reference, and the safety model.

fxapis runs a hosted Model Context Protocol (MCP) server. Add it to an AI app, sign in to fxapis, and the assistant can read your MetaTrader 5 accounts, positions, orders and history. If you allow it, it can also trade.

https://api.fxapis.com/mcp

There is nothing to install. The MT5 terminals run in our EU cloud, as for every fxapis call.

An app you allow to trade trades real money

Connect read-only first, and try trading on a broker demo account. Trading is off unless you turn it on when you sign in. It applies only to the accounts you pick, and it needs two-factor. Claude still asks you before every trade. Read the Safety model before allowing a live account.

How it works

  • Sign in, no key to copy. The first time the app uses fxapis, it opens fxapis's sign-in page. You choose what it may do:
    • Read access: accounts, positions, orders, deals, figures and quotes. This is always included.
    • Trading: off by default. Turn it on per account: everything the app changes — opening, closing, stops, cancelling, bringing online, taking offline — is limited to the accounts you pick. It needs two-factor turned on; your session already proved it at sign-in, so there is no code to enter here. You can also set a maximum order size and a number of orders a day.
  • Revoke any time. Every app you connect is listed on the API keys page under Connected apps, with when it was last used. Revoke ends its access on its very next request. Removing someone from the workspace, or changing their role, revokes the apps they connected.
  • The same rules as the REST API. A connected app acts through the ordinary /v1 endpoints with exactly what you chose. Workspace isolation, rate limits, plan limits, idempotency and our trading kill switch all apply. Each tool call counts as one or two API calls on your plan.
  • API keys still work for scripts and unattended agents: send Authorization: Bearer fx_live_… or X-API-Key. See Agents with an API key.
  • Deliberately missing: connecting an MT5 account and managing keys. Connecting takes the broker password, which must never pass through an AI model. Do both in the console.

Under the hood:

  • the server speaks Streamable HTTP, stateless, in both the 2026-07-28 and the 2025 protocol revisions;
  • sign-in is OAuth 2.1 with PKCE, as the MCP authorization spec asks, discovered from https://api.fxapis.com/.well-known/oauth-protected-resource/mcp;
  • initialize and tools/list answer without signing in. A tool call without a credential gets 401 with a WWW-Authenticate challenge that points the app at the sign-in.

Connect your app

Claude (claude.ai and Claude Desktop)

On any Claude plan:

  1. Open Customize → Connectors → Add custom connector. On Team and Enterprise, an Owner adds it under Organization settings → Connectors.
  2. Remote MCP server URL: https://api.fxapis.com/mcp. Leave the OAuth client fields empty: Claude registers itself.
  3. Click Connect, and sign in to fxapis in the window that opens. Choose read-only or trading, then allow it.

Connectors you add on claude.ai are also in the Claude desktop app.

Claude Code

claude mcp add --transport http fxapis https://api.fxapis.com/mcp

Then run /mcp, choose fxapis, and Authenticate: your browser opens fxapis's sign-in.

Or install the fxapis plugin. It adds the server, a safe-trading skill and a hook that confirms every trade:

/plugin marketplace add FXapis/fxapis-claude-plugins
/plugin install fxapis@fxapis

ChatGPT

In ChatGPT, turn on Settings → Apps → Advanced settings → Developer mode (on the plans OpenAI offers it on). Then Create app:

  • MCP server URL: https://api.fxapis.com/mcp
  • Authentication: OAuth

Sign in to fxapis when ChatGPT asks.

Cursor, VS Code and other clients

Any client that supports MCP's OAuth sign-in connects with the URL alone. fxapis accepts sign-in return addresses for Claude, ChatGPT, and apps on your own computer (http://localhost and http://127.0.0.1). Clients that return to a custom scheme, such as cursor:// or vscode://, are not accepted yet: use an API key with them.

To test from a terminal with the MCP Inspector:

npx @modelcontextprotocol/inspector https://api.fxapis.com/mcp

Agents with an API key

For an agent that runs unattended, create a key just for it, with the fewest scopes that do the job:

The agent should…Scopes
Report on accounts, positions and historyaccounts:read, trading:read, history:read
…and bring accounts online or take them offlineadd accounts:write
…and manage risk: close, move stops, cancel — never openadd trading:reduce
…and open new positionsadd trading:execute

Send it as Authorization: Bearer fx_live_…, or as X-API-Key: fx_live_… for clients that only offer that header.

Claude Code, with a key:

claude mcp add --transport http fxapis https://api.fxapis.com/mcp --header "Authorization: Bearer $FXAPIS_KEY"

Cursor (~/.cursor/mcp.json):

{ "mcpServers": { "fxapis": { "url": "https://api.fxapis.com/mcp", "headers": { "Authorization": "Bearer ${env:FXAPIS_KEY}" } } } }

VS Code (.vscode/mcp.json):

{
  "inputs": [{ "type": "promptString", "id": "fxapis-key", "description": "fxapis API key", "password": true }],
  "servers": { "fxapis": { "type": "http", "url": "https://api.fxapis.com/mcp", "headers": { "Authorization": "Bearer ${input:fxapis-key}" } } }
}

OpenAI API (Responses). Put this in the request's tools:

{ "type": "mcp", "server_label": "fxapis", "server_url": "https://api.fxapis.com/mcp", "authorization": "fx_live_…", "require_approval": "always" }

Anthropic API (Messages). Use mcp_servers: [{ "type": "url", "url": "https://api.fxapis.com/mcp", "name": "fxapis", "authorization_token": "fx_live_…" }], with an mcp_toolset tool for fxapis, as Anthropic's MCP connector documentation describes.

Every config is also in fxapis-mcp-examples.

Revoking access

  • A connected app: on the API keys page, under Connected apps, choose Revoke.
    • Its access ends on its next request, its sign-in can no longer be refreshed, and any sign-in still in progress is cancelled.
    • Owners and admins see and revoke everyone's connected apps. Members see their own.
  • A key: revoke it on the same page. It is refused from its next request.

Tools

Arguments are snake_case. Account ids are the fxapis UUIDs from list_accounts, not MT5 logins. Volumes and prices are strings ("0.10", "1.08450").

Results are small by design:

  • one line for the model, plus the data once as compact JSON;
  • response_format: "detailed" adds every field the API has;
  • lists answer { items, next_cursor, total } 25 at a time; pass next_cursor back as cursor.

Answer a question in one call

ToolWhat it doesScope
get_account_overviewAn account's state, environment, balance, equity, and its largest positions with total P/Laccounts:read, trading:read
get_symbol_snapshotA symbol's specification, live quote, whether the market is open, and the margin for a volumeaccounts:read, trading:read

Read-only

ToolWhat it doesScope
get_workspacePlan, its limits and features, and whether trading is switched offaccounts:read
get_usageThis month's usage against the planaccounts:read
list_accountsAccounts with id, login, server, state and environment (demo or live)accounts:read
get_accountOne account and its last-read balance and equityaccounts:read
get_account_statusJust the state — poll it after bring_accounts_onlineaccounts:read
get_account_figuresBalance, equity, margin and margin level; fresh: true asks the terminalaccounts:read
list_positionsOpen positions as last observedtrading:read
list_instrumentsMarkets named once (XAUUSD, US30…)any
search_broker_serversThe exact MT5 server for a brokeraccounts:read
list_account_instrumentsEach instrument's symbol on an account's broker; query narrows itaccounts:read
get_market_hoursWhether a market is open now, and when it opens or closesaccounts:read
get_quotesLive bid and ask for up to 20 symbolstrading:read
list_ordersOrders, newest first, by account, state, symbol and timetrading:read
get_orderOne order and the broker's answer; optionally its dealstrading:read
list_dealsThe broker's deal history for an accounthistory:read
list_multi_account_ordersRecent multi-account orderstrading:read
get_multi_account_orderOne multi-account order, account by accounttrading:read
calculateMargin or profit, as the broker computes it; opens nothingtrading:read

Account lifecycle

ToolWhat it doesScope
bring_accounts_onlineStarts and logs in accounts; poll get_account_statusaccounts:write
take_account_offlineStops the terminal; positions and stops stay at the brokeraccounts:write

Trading

These are marked destructiveHint: true, so Claude and other careful clients ask before each one. Each requires an idempotency_key: a fresh UUID per action, and the same one only to retry that action. With it, a retried order is never a second order, and a retried close is never an opposite position.

ToolWhat it doesScope
place_market_orderOpens a position at markettrading:execute
place_pending_orderA limit, stop or stop-limit ordertrading:execute
close_positionCloses a position in whole or in parttrading:reduce
modify_positionMoves or removes a stop loss or take profittrading:reduce
cancel_orderCancels a pending ordertrading:reduce
place_multi_account_orderThe same trade on many accountstrading:execute
cancel_multi_account_orderCalls one off before anything is senttrading:reduce

A connected app that was not allowed to trade, and calls a trade tool, gets 403 with WWW-Authenticate: Bearer error="insufficient_scope", scope="… trading:execute". The app then asks you to sign in again, and the sign-in page opens with Trading selected.

Errors

A failure comes back as an MCP tool error (isError: true) whose text starts with the API's own error code, followed by the message, any details, what to do next and the request id:

ORDER_UNRESOLVED (HTTP 503): Something went wrong and we do not know yet whether the order was sent. We are confirming it with the broker. Do not resend it.
details: [{"orderId":"5b0e7c1a-2f4d-4a8e-9c3b-1d6f0e2a7b94","state":"unknown","retryable":false}]
Next step: Do NOT resend this order. Its outcome is unknown and it may be live at the broker. Poll get_order with the orderId in details until it leaves `unknown`, and tell the user.
requestId: 3f8a1c92-7b4e-4d81-a2f6-0c5e9b3d7a14

The same code, status, message, request id and next step are in the result's _meta under com.fxapis/error, for programs.

The codes that matter most to an agent:

CodeMeaning for the agent
ORDER_UNRESOLVEDThe outcome is unknown and the order may be live. Never resend; poll get_order
SEND_FAILEDNothing reached the broker. Retry with the same idempotency_key
ORDER_REJECTEDThe broker refused it; nothing was opened. Tell the user the reason
MISSING_SCOPEThis connection does not allow it. Ask the user; do not look for another way
KEY_LIMIT_EXCEEDEDA limit chosen for this connection or key refuses it; details say which
ACCOUNT_NOT_READY / NO_RUNTIMEBring the account online, wait for ready, then retry
RATE_LIMITEDWait retryAfterSeconds, then retry once
TRADING_DISABLEDTrading is switched off for the account or workspace. Do not retry

Every code and its next step: error codes in the skill.

Safety model

An agent is a new kind of caller. It can misread a request, act on text planted in a web page, or loop. The protections, from strongest to weakest:

  1. What you allowed. Enforced by the API on every call, whatever the model decides:

    • a connected app's choices on the sign-in page: read-only, or trading on the accounts you picked, within the size and daily limits you set;
    • a key's scopes and limits.

    A read-only connection cannot trade. A trading connection cannot change anything on an account you did not pick: it cannot open, close, move stops on or cancel orders there, or bring that account online or take it offline. It can still read every account in the workspace.

  2. Two-factor for trading. Letting an app trade needs two-factor turned on; signing in with it already proved it, so nothing more is asked at consent.

  3. Demo accounts. fxapis has no simulated market. Broker demo accounts are how you test.

  4. Your plan's limits and rate limits. Closing is never refused for billing.

  5. Your app's confirmations. Trading tools are marked destructive, so Claude asks before each trade. The Claude Code plugin makes that a rule, and refuses live accounts until you allow them.

  6. The tool descriptions and the skill. They tell the model to confirm every trade and never to resend an unresolved order. That shapes behaviour; it does not enforce anything. Points 1 and 2 do.

Every order an agent places is recorded like any other, with the key or connected app that placed it. Tool calls are logged with the tool name, the workspace and the outcome, never the arguments.

Directories

Claude's and ChatGPT's app directories do not list tools that execute financial transactions. So:

Example prompts

  • "Which of my MT5 accounts are online, and what positions are open on each?"
  • "What was my realised profit on EURUSD this week on the Vantage demo account?"
  • "How much margin would 0.5 lots of XAUUSD need on account 2?"
  • "Bring all my accounts online, then tell me when they are ready."
  • "Move the stop loss on my gold position to break-even." (needs trading:reduce)
  • "Close half of every open EURUSD position on the demo account." (needs trading:reduce)
  • "Buy 0.01 lots of EURUSD on the demo account with a 20-pip stop." (needs trading:execute)
  • "Did anything go wrong with today's orders? Show me any that are still unknown."

Limits of the MCP server today

  • No streaming or notifications. Tools answer once. Follow an account coming online, or a multi-account order settling, by polling, as with the REST API. For your own server, use webhooks.
  • Custom-scheme sign-in returns (cursor://, vscode://) are not accepted yet. Use an API key with those clients.
  • MetaTrader 5 only. MT4 is not supported.

On this page