t212-mcp
I built this so I could ask an AI assistant about my Trading 212 Stocks ISA: what I hold, what it's worth, what orders I have open, what I've traded before, and the dividends and deposits that have come in. It also lets the assistant set up an order for me, but nothing is ever placed until I say yes to it myself.
It's an MCP server. MCP (Model Context Protocol) is the standard way to give an AI app new tools, so this works with Claude Code, Claude Desktop, GitHub Copilot in VS Code, Cursor and other apps that support MCP.
Please read this first
- This is a personal project. It isn't made by, affiliated with or endorsed by Trading 212.
- It can place real trades with real money. It comes with no warranty (see LICENSE), and you're responsible for every order it places.
- Start with a read-only API key. Only add trading permission once you're comfortable with how it works.
- The only official copies are this repository, github.com/watsonam/t212-mcp, and the
t212-mcppackage on PyPI, which is built and published from this repository by GitHub Actions. Anything else with a similar name isn't mine, and could be built to steal your key. - Found a security problem? Please report it privately, as described in SECURITY.md.
Where things stand
- I've connected it to my own live account and fetched my account summary. The other read tools are tested against fake responses, not my real account.
- The order tools are tested against fake responses only. They haven't placed a real order yet.
- When I asked Claude to place a trade, it declined. Claude may simply refuse to trade on your behalf, so with Claude you might only get as far as a preview. Other apps and models may go further, but every order still needs your yes.
- It runs on macOS, Linux and Windows, with Python 3.11 or newer. The tests run on all three every time something is pushed to
mainor a pull request is opened.
How ordering works
Placing an order always takes two steps.
- The assistant asks for a preview. You get back what the order is: the share, buy or sell, how many, and roughly what it'll cost in pounds.
- The assistant asks to confirm. The server then asks you directly, in a pop-up from your AI app, whether to place it. The question spells out the order exactly as it will be sent. If you say no, or close the question, nothing is sent.
The question comes from the server itself, so the assistant can't answer it for you. That only holds if your app shows you the question. An app set to accept these questions automatically, or one that lets the model answer them, removes that protection. If your app can't show the question at all, the order is refused. Cancelling an order asks you the same way, and tells you which order it is, for example "Cancel order 42: SELL 3 x Vanguard S&P 500 (VUSAl_EQ), stop order, stop 8500?".
A preview lasts 5 minutes and can only be used once.
The server checks these rules on every order, whatever the assistant asks for:
- Live trading is off unless you turn it on with
T212_LIVE_TRADING=1. On the demo account (pretend money) it's always on. - It only trades on accounts held in pounds (GBP).
- Each order is capped at £1,000 and each day at £2,000. Both caps count sells as well as buys. You can change them (see below).
- Trading 212 doesn't offer a live price feed, so the server only allows orders whose cost it can work out:
- A market order is only allowed for something you already own. It's priced from your holding, plus 5% in case the price moves.
- A limit or stop-limit order is priced at the limit you set.
- A stop buy is refused, because there's no way to know what it'll cost. Use a stop-limit order instead.
- For shares priced in another currency, such as US dollars, it works out the exchange rate from your largest holding in that currency. If you hold nothing in that currency, the order is refused.
- Holdings worth under £1 aren't used for pricing, because their rounded values aren't accurate enough.
- London shares are often priced in pence, so a limit price for them is in pence too.
- You can't sell more shares than you have available.
- An order is never sent twice. If Trading 212 doesn't give a clear answer, the server says the outcome is unknown, counts it towards your daily cap, and tells the assistant to check your open orders and history before trying again. Cancellations work the same way.
- Every preview, order and cancellation is written to a log on your computer, at
~/.local/state/t212-mcp/orders-<env>.jsonl. Only your user account can read it. Here~means your home folder (on Windows,C:\Users\you). The daily cap is worked out from this log, per calendar day, and the log is locked while it's checked, so two chats can't both slip under the cap at the same time.
Setting it up
You'll need uv, a tool for running Python projects. There are two ways to get the server.
The quickest is from PyPI. uv downloads it the first time your AI app starts it, so there's nothing to install now. In the app snippets below, use uvx as the command and ["t212-mcp@0.1.1"] as the arguments. Naming the version means you only move to a new one when you choose to.
The other way is to clone this repository and, from inside it, run:
uv sync
A clone uses exactly the dependency versions the tests ran with, and you can read every change before you git pull it.
Next, create an API key in the Trading 212 app, under Settings, then API. You'll get a key and a secret.
- To only read your account, tick account, portfolio, metadata, orders:read, history:orders, history:dividends and history:transactions.
- To place orders too, also tick orders:execute.
- If the app lets you, restrict the key to your home IP address.
- The demo account and your real account need separate keys.
The safest place for the key and secret is your computer's keychain (the macOS Keychain, Windows Credential Manager, or the Secret Service on Linux). Run these and paste each value when asked. Nothing shows on screen while you paste, which is normal.
uv run keyring set t212-mcp live_api_key
uv run keyring set t212-mcp live_api_secret
For a demo key, use demo_api_key and demo_api_secret instead. You can also set them as environment variables (see the settings table below), but never put them in a file you commit.
Connecting it to your AI app
The examples below use a clone. In each one, replace /path/to/t212-mcp with wherever you cloned this repository. The --locked flag makes uv use exactly the versions this repository was tested with, and --no-dev leaves out the test tools. On Windows, write the path with forward slashes, like C:/Users/you/t212-mcp, or double each backslash.
T212_ENV=live points it at your real account. Leave it out to use the demo account.
Claude Code
claude mcp add trading212 -s user --env T212_ENV=live -- uv --directory /path/to/t212-mcp run --locked --no-dev t212-mcp
Or, from PyPI:
claude mcp add trading212 -s user --env T212_ENV=live -- uvx t212-mcp@0.1.1
To allow live orders, add --env T212_LIVE_TRADING=1.
Claude Desktop
Add this to claude_desktop_config.json. On a Mac it's in ~/Library/Application Support/Claude/, and on Windows it's in %APPDATA%\Claude\.
{
"mcpServers": {
"trading212": {
"command": "uv",
"args": ["--directory", "/path/to/t212-mcp", "run", "--locked", "--no-dev", "t212-mcp"],
"env": {"T212_ENV": "live"}
}
}
}
Claude Desktop doesn't see your terminal's environment variables, so keep your key in the keychain, or put the variables in env.
GitHub Copilot in VS Code
Add this to .vscode/mcp.json in your workspace:
{
"servers": {
"trading212": {
"type": "stdio",
"command": "uv",
"args": ["--directory", "/path/to/t212-mcp", "run", "--locked", "--no-dev", "t212-mcp"],
"env": {"T212_ENV": "live"}
}
}
}
Cursor and Gemini CLI
Cursor (~/.cursor/mcp.json) and Gemini CLI (~/.gemini/settings.json) use the same mcpServers block as Claude Desktop.
OpenAI Codex CLI
Add this to ~/.codex/config.toml:
[mcp_servers.trading212]
command = "uv"
args = ["--directory", "/path/to/t212-mcp", "run", "--locked", "--no-dev", "t212-mcp"]
env = { T212_ENV = "live" }
Other apps
Any app that can run a local MCP server should work. For orders, the app also has to support "elicitation", which is how the server asks you to approve. If it doesn't, orders are refused but reading your account still works. These apps change where they keep their settings from time to time, so if a snippet doesn't work, check the app's own documentation.
Changing the limits
Create ~/.config/t212-mcp/config.toml with your own caps, in pounds:
max_order_gbp = 1000
max_daily_gbp = 2000
The server won't start if the file has a typo, a setting it doesn't recognise, or a cap that isn't a positive number. That way a mistake can't quietly switch a cap off.
Settings
| Variable | What it does |
|---|---|
T212_ENV |
demo (the default) or live |
T212_LIVE_TRADING |
Set to 1 to allow orders on your live account |
T212_DEMO_API_KEY, T212_DEMO_API_SECRET |
Demo key, if you're not using the keychain |
T212_LIVE_API_KEY, T212_LIVE_API_SECRET |
Live key, if you're not using the keychain |
T212_CONFIG |
Where the caps file is (default ~/.config/t212-mcp/config.toml) |
T212_CACHE_DIR |
Where the instrument list is cached |
T212_ORDER_LOG |
Where the order log is written |
Tools
These are the tools your AI app can use, with the Trading 212 permission each one needs. Each tool also tells your app whether it only reads or makes changes, so the app can be more careful with the ones that place or cancel orders.
| Tool | What it does | Permission |
|---|---|---|
get_account_summary |
Cash, investments and total value | account |
get_positions |
What you hold and what it's worth | portfolio |
get_pending_orders |
Orders that haven't filled yet | orders:read |
get_order |
One open order | orders:read |
get_order_history |
Past orders, newest first | history:orders |
get_dividends |
Dividends paid in, newest first | history:dividends |
get_transactions |
Deposits, withdrawals, fees and interest, newest first | history:transactions |
search_instruments |
Find a share's ticker by name, ticker or ISIN | metadata |
preview_market_order |
Preview a market order | portfolio, metadata |
preview_limit_order |
Preview a limit order | portfolio, metadata |
preview_stop_order |
Preview a stop order (sells only) | portfolio, metadata |
preview_stop_limit_order |
Preview a stop-limit order | portfolio, metadata |
confirm_order |
Ask you to approve a preview, then place it | orders:execute |
cancel_order |
Ask you to approve, then cancel an open order | orders:execute |
A few details:
get_positionsaddspriceInAccountCurrency, the price of one share in pounds. Trading 212's owncurrentPriceis in the share's currency, which is often pence for London shares.- The full list of shares is saved for 24 hours in
~/.cache/t212-mcp/, because Trading 212 only allows it to be fetched about once a minute. - The server spaces out its requests to stay inside Trading 212's rate limits.
Running the tests
uv run pytest
The tests use fake responses, so they never touch a real account. The code follows Trading 212's API specification, which isn't included here. To download it for reference on a Mac or Linux:
mkdir -p spec && curl -sfL https://docs.trading212.com/_spec/api.json -o spec/api.json
On Windows, in PowerShell:
New-Item -ItemType Directory -Force spec; Invoke-WebRequest https://docs.trading212.com/_spec/api.json -OutFile spec/api.json
Metadata
Release files for t212-mcp 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| t212_mcp-0.1.1.tar.gz | 80.1 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| t212_mcp-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 98.5 kB
Release files / t212_mcp-0.1.1.tar.gz
| Download URL | t212_mcp-0.1.1.tar.gz |
|---|---|
| Size | 80.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c8451d656672e038f8108fbd1f66038ef74d0f8780cb3c2d8363aa66c1bf68ae
|
|
BLAKE2b-256 checksum How to use checksums |
da9d7b13cc947f25b3ad70cf21a99d78466c217f672f83a87510b1333a164053
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logRelease files / t212_mcp-0.1.1-py3-none-any.whl
| Download URL | t212_mcp-0.1.1-py3-none-any.whl |
|---|---|
| Size | 18.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
964f18bf8cf1af892cbdbdbdd91c891f1938e49e327c44cd1c5b923334518a00
|
|
BLAKE2b-256 checksum How to use checksums |
5f48a8bfea54a0b3066067cd9bd7f36e119e12aa7d806bb91d8310e811c711c0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logSecurity for t212-mcp 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for t212_mcp-0.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.