Skip to main content
Glama
martinsgirss

MT5 MCP Server

by martinsgirss
README.md
# MT5 MCP Server

Custom Model Context Protocol (MCP) server that connects Claude Desktop directly
to MetaTrader 5. Lets Claude pull historical/live data, run backtests, inspect
your account, and place orders **with mandatory two-step confirmation**.

## Features

- **Historical data**: OHLCV candles, raw ticks, symbol contract specs
- **Real-time quotes**: bid/ask/spread, market depth, live tick monitoring
- **Account inspection**: balance, equity, open positions, pending orders, deal history
- **Order management**: market & pending orders, position close, SL/TP modify — all with token-based confirmation
- **Backtesting**: vectorized signal-based engine with EMA/SMA/RSI/cross helpers, returns Sharpe, drawdown, profit factor, win rate
- **Safety gateway**: lot-size limits, per-session order cap, demo-only enforcement by default

## Requirements

- Windows (MetaTrader5 Python package is Windows-only)
- Python 3.13 or newer
- MetaTrader 5 desktop terminal, logged into a broker account
- Claude Desktop

## Installation

### 1. Place the project

Copy the entire `mt5_mcp_server` folder to a permanent location, for example:

```
C:\Users\YourName\mt5_mcp_server\
```

### 2. Install Python dependencies

Open PowerShell in the project folder and run:

```powershell
pip install -r requirements.txt
```

### 3. Configure environment

Copy `.env.example` to `.env` and edit if you need custom settings. The defaults
are safe (demo-only, 1.0 lot max, 20 orders per session, confirmation required).

```powershell
copy .env.example .env
```

If your MT5 terminal is already logged in, you can leave login/password blank —
the server will use the active session.

### 4. Configure MT5 to allow algorithmic trading

In MetaTrader 5:

1. Tools → Options → Expert Advisors
2. Check **"Allow algorithmic trading"**
3. Check **"Allow DLL imports"** (for the Python integration)
4. Click OK

### 5. Run the connection test

```powershell
python test_connection.py
```

You should see `[OK]` on every check. If any check fails, fix it before
registering the MCP server with Claude Desktop.

### 6. Register with Claude Desktop

Open Claude Desktop's config file:

- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

Merge in the MCP server entry from `claude_desktop_config.example.json`,
adjusting paths to match your install. A minimal example:

```json
{
  "mcpServers": {
    "mt5": {
      "command": "python",
      "args": ["C:\\Users\\YourName\\mt5_mcp_server\\server.py"],
      "env": {
        "PYTHONPATH": "C:\\Users\\YourName\\mt5_mcp_server",
        "SAFETY_MODE": "demo",
        "MAX_LOT_SIZE": "0.1"
      }
    }
  }
}
```

Restart Claude Desktop. The `mt5` server should now appear in the connectors
list, and Claude can call its tools.

## Available Tools

### Connection
- `mt5_info` — terminal + account info
- `safety_status` — current safety config & session counters

### Historical Data
- `get_ohlcv(symbol, timeframe, count|start, end)` — OHLCV bars
- `get_ticks(symbol, count|start, end)` — raw ticks
- `get_symbol_info(symbol)` — contract specs
- `list_symbols(group?)` — broker symbol list

### Real-time
- `get_current_price(symbol)` — bid/ask/spread snapshot
- `get_market_depth(symbol)` — DOM (broker-dependent)
- `monitor_symbol(symbol, duration_seconds)` — sample live ticks (max 30s)

### Account & Positions (read-only)
- `get_account_info()` — balance, equity, margin, leverage
- `get_positions(symbol?)` — open positions
- `get_orders(symbol?)` — pending orders
- `get_history(days)` — closed deals over last N days

### Order Operations (two-step)
Every write operation requires `prepare_*` then `confirm_*` with the token:
- `prepare_order` / `confirm_order` — open new market or pending order
- `prepare_close_position` / `confirm_close_position` — close (full or partial)
- `prepare_modify_position` / `confirm_modify_position` — change SL/TP

### Backtesting
- `run_backtest(symbol, timeframe, buy_when, sell_when, ...)` — vectorized backtest
- `calculate_metrics(trades, initial_balance)` — performance metrics

Backtest signal expressions support:
- `sma(close, n)`, `ema(close, n)`, `rsi(close, n)`
- `cross_above(a, b)`, `cross_below(a, b)`, `shift(s, n)`
- References: `open`, `high`, `low`, `close`, `volume`

Example:
```
buy_when:  cross_above(ema(close, 12), ema(close, 26)) & (rsi(close, 14) < 70)
sell_when: cross_below(ema(close, 12), ema(close, 26))
```

## Safety Architecture

The server is designed to make accidental order placement very hard:

1. **Demo enforcement.** `SAFETY_MODE=demo` (default) refuses to operate if the
   logged-in account is not demo. This catches the most common foot-gun.

2. **Two-step orders.** Every trade-modifying tool is split into `prepare_*` and
   `confirm_*`. The prepare step returns a one-time token that's bound to exact
   parameters. The confirm step validates the token + that the params match.
   This means a single rogue tool call cannot place an order — Claude must
   first call prepare, show you the summary, wait for your "go ahead", then
   call confirm with the token. Tokens expire after 5 minutes.

3. **Lot-size limit.** `MAX_LOT_SIZE` (default 1.0) caps any single order's
   volume.

4. **Per-session cap.** `MAX_ORDERS_PER_SESSION` (default 20) prevents runaway
   loops from filling your account with trades. Resets on server restart.

5. **Broker-side validation.** All orders go through MT5's own validation
   (volume_min/max, allowed trade modes, margin checks).

### Going to live trading

When you're ready (after substantial demo testing), edit `.env`:

```
SAFETY_MODE=live
MAX_LOT_SIZE=0.05    # start TINY on real money
```

The two-step confirmation flow stays in place — there is intentionally no
way to disable it.

## Troubleshooting

**"MT5 initialize() failed"** — Make sure the MT5 desktop terminal is running
and logged in. The Python package attaches to a running terminal; it doesn't
launch one. Try setting `MT5_TERMINAL_PATH` in `.env` if auto-detect fails.

**"Symbol 'XXXUSD' not found"** — The symbol must exist for your broker. Use
`list_symbols(group="*USD*")` to see what's available. Some brokers add
suffixes like `EURUSD.r` or `EURUSD-pro`.

**Server doesn't appear in Claude Desktop** — Check the path in
`claude_desktop_config.json` is absolute and uses double backslashes on Windows.
Check Claude Desktop's developer logs (Help → View Logs) for spawn errors.

**"SAFETY: account is REAL"** — You connected a live account but
`SAFETY_MODE=demo`. This is intentional protection. Either log into a demo
account in MT5, or set `SAFETY_MODE=live` in `.env` (only after you've
thoroughly tested).

**Ticks/quotes empty during weekend** — Forex market is closed Friday evening
to Sunday evening (UTC). Historical data still works.

## Development workflow

The recommended Claude flow when building a new strategy:

1. *"Pull the last 5000 H1 EURUSD bars"* — `get_ohlcv`
2. *"Try a 12/26 EMA crossover strategy"* — `run_backtest`
3. *"Show me the metrics broken down by year"* — Claude analyses returned trade list
4. *"Tighten the SL to 30 points and retest"* — iterate
5. *"Once happy, draft the equivalent MQL5 EA file"* — Claude writes `.mq5` to your
   `MQL5/Experts/` folder via the FileSystem connector
6. *"Open a 0.01 lot demo BUY at market with 30-point SL"* —
   `prepare_order` → you review → `confirm_order`

## License

MIT