trading212-mcp-guardrails
An MCP server that exposes the Trading 212 API with a hard-enforced safety layer—including idempotency ledger, circuit breaker, and position limits—to enable safe live and paper trading through natural language.
README
trading212-mcp-guardrails
An MCP server that exposes the Trading 212 API to Claude (or any MCP client) — with a hard-enforced safety layer that Trading 212's own API doesn't give you, and that no other Trading 212 MCP server currently implements.
This connects to a real brokerage account. place_market_order and
friends can spend real money if DRY_RUN=false. Read the whole "Safety
model" section before pointing this at a live account.
Why this one
There are several Trading 212 MCP servers already. They're solid for read-only use and for pointing an agent at
T212's own demo (paper-trading) environment. What none of them do is add
any protection on top of the raw API for live trading — as of this
writing, none implement request-level dedup, a loss-based circuit breaker,
or position-size enforcement independent of what the model asks for:
| This project | Other T212 MCP servers | |
|---|---|---|
| Duplicate-order protection | Same-day ledger keyed by full order payload — a retried tool call submits a byte-identical order and is refused, while distinct orders on the same ticker (e.g. a buy then a protective stop) still go through | Not implemented; T212's order API is documented as non-idempotent, so a retry can silently duplicate a trade |
| Circuit breaker | Halts all trading (persisted to disk, survives restarts) if daily equity drop exceeds a configurable threshold, until a human manually clears it | Not implemented |
| Position limits | Hard-rejects (not silently shrinks) any buy that would exceed configured max position count or max % of equity per position | Not implemented |
| Paper trading | T212_ENV=demo (T212's own demo environment) |
Several also support this |
| DRY_RUN simulation | Local simulate-only mode that still validates against your real account balance/positions before "placing" — lets you sanity-check exact tool behavior without touching T212's demo environment | Not implemented |
| Credential redaction in logs | Regex filter strips Basic-auth tokens from every log line as defense in depth | Not checked/not applicable (most don't log to disk) |
None of this is about having more tools — it's about the tools you already have not being able to hurt you by accident: a retried MCP call, an agent that free-associates a position size, or a bad day in the market.
Tools
Read-only: get_account_summary, get_positions, get_pending_orders,
get_order, get_order_history, get_dividend_history,
search_instruments, get_halt_status.
Trading (all gated by the safety layer below): place_market_order,
place_limit_order, place_stop_order, place_stop_limit_order,
cancel_order.
Safety model
- Idempotency ledger. Every order actually submitted is recorded in
state/orders_<date>.json, keyed by a hash of the full order payload (type, ticker, signed quantity, and any prices/flags). Re-submitting a byte-identical order the same day is refused outright — this is the only thing standing between a retried tool call and a duplicate order, since T212's API is documented as non-idempotent. Genuinely different orders on the same ticker (a buy followed by a protective stop-loss sell, or averaging into a position) hash differently, so they aren't false-flagged as duplicates. - Circuit breaker. Before any trading tool executes, it re-fetches
account equity and compares it to the first equity reading of the day.
If the drop exceeds
MAX_DAILY_LOSS_PCT, it writesstate/HALTand every subsequent call — this run, this process, any other process that imports this code — refuses to trade until a human deletes that file by hand. Nothing in this codebase clears it automatically. - Position limits. Buys are hard-rejected (not silently resized) if
they'd open a position beyond
MAX_POSITIONSdistinct tickers, or push any single position aboveMAX_POSITION_PCTof total account equity. DRY_RUN. Controlled solely by.env— no tool accepts adry_runargument, so an agent can't be talked into flipping it mid-conversation. When true, every trading tool runs its full validation (funds check, position limits, circuit breaker) against your real account data and logs/ledgers exactly what it would have submitted, but never calls the order endpoint.- Credential redaction. A logging filter strips any
Basic <token>auth header from every log line before it's written, as defense in depth on top of application code never logging the raw key/secret.
None of this is advisory — every check above runs inside the tool call itself, every time, regardless of what a connected model asks for.
Setup
git clone https://github.com/sandeepanmukherjee/trading212-mcp-guardrails
cd trading212-mcp-guardrails
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS/Linux
pip install -r requirements.txt
cp .env.example .env # then fill in T212_API_KEY / T212_API_SECRET
Get API credentials from Trading 212 under Settings → API (Beta). Leave
DRY_RUN=true until you've reviewed exactly what a tool call would have
submitted.
Claude Code
claude mcp add trading212 -- /path/to/.venv/bin/python /path/to/mcp_server.py
Claude Desktop
Add to claude_desktop_config.json (Developer settings → Local MCP
servers → Edit Config):
{
"mcpServers": {
"trading212": {
"command": "/path/to/.venv/bin/python",
"args": ["/path/to/mcp_server.py"]
}
}
}
Any other MCP client
This is a stock stdio MCP server built on the standard Python mcp SDK —
nothing Claude-specific about it. Any client that speaks MCP over stdio can
launch it the same way: run /path/to/.venv/bin/python /path/to/mcp_server.py
as the command, no arguments needed. In practice that means pointing the
client at that command + interpreter path in whatever config format it uses:
OpenAI Codex CLI — either run:
codex mcp add trading212 -- /path/to/.venv/bin/python /path/to/mcp_server.py
or add directly to ~/.codex/config.toml:
[mcp_servers.trading212]
command = "/path/to/.venv/bin/python"
args = ["/path/to/mcp_server.py"]
Cursor — .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):
{
"mcpServers": {
"trading212": {
"command": "/path/to/.venv/bin/python",
"args": ["/path/to/mcp_server.py"]
}
}
}
Windsurf — ~/.codeium/windsurf/mcp_config.json
(%USERPROFILE%\.codeium\windsurf\mcp_config.json on Windows), same
mcpServers shape as Cursor above.
Cline (VS Code extension) — via the Cline panel's MCP settings, or
directly in cline_mcp_settings.json (path varies by OS — see
Cline's docs), same mcpServers
shape as Cursor above.
VS Code (native MCP support) — .vscode/mcp.json in the workspace:
{
"servers": {
"trading212": {
"type": "stdio",
"command": "/path/to/.venv/bin/python",
"args": ["/path/to/mcp_server.py"]
}
}
}
Gemini CLI — mcpServers in settings.json, same shape as Cursor above.
For every client above: if T212_API_KEY/T212_API_SECRET are set as OS
environment variables rather than in .env, add them explicitly under that
server's "env" block instead of relying on inheritance. GUI-launched apps
in particular often don't pick up environment variables added after the app
(or its launcher process) last started — if the server can authenticate from
a terminal but a GUI client reports it disconnected or missing credentials,
that mismatch is almost always why. env: {} (or an explicit env block
with the two keys) sidesteps it entirely.
Testing
pytest tests/
Every guarantee in the safety model above has tests behind it, with mocked HTTP calls — no live API access or credentials required:
- Idempotency ledger — an identical retry is refused on every order type; a different type, or the same type at a different size, on the same ticker is not false-flagged; and a rejected order (4xx) leaves nothing in the ledger, so a failed submit doesn't block a legitimate retry for the rest of the day.
- Circuit breaker — halts on a breach, stays halted on the next call even
if equity recovers, is never cleared automatically, and gates every trading
tool via
_check_trading_allowed. - Position limits — both directions of the contract: breaches of
MAX_POSITIONS/MAX_POSITION_PCTare refused rather than resized, and legitimate orders aren't over-refused (topping up a held position at the count cap, quantity-0 closed positions ignored in the count). The%cap is judged on projected total, and an order value that can't be verified warns without becoming a way around the count cap. DRY_RUN— the order endpoint is never called, for any order type.- Pagination —
cursorreaches the API from both history tools.
CI runs the suite on Python 3.10–3.12. There's no integration test against
the real T212 API; run with DRY_RUN=true against your real account for that.
Disclaimer
This is not financial advice and not an official Trading 212 product. You
are responsible for anything it does to your account. Start with
DRY_RUN=true, review the simulated output, and only flip to live trading
once you're satisfied it's behaving the way you expect.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。