Skip to main content
Glama
MT5 MCP Server

MT5 MCP Server

by Erfangit23
README.md
# MT5 MCP Server

[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-blue.svg)](pyproject.toml)
[![Windows](https://img.shields.io/badge/Platform-Windows-lightgrey.svg)](#requirements)
[![Tests](https://img.shields.io/badge/tests-30%2B%20passing-brightgreen.svg)](.github/workflows/test.yml)

**Let your AI assistant trade MetaTrader 5 — safely.**

An [MCP](https://modelcontextprotocol.io) server that gives AI assistants (Claude Desktop, Claude Code, ZCode, Cursor, ...) full access to a MetaTrader 5 terminal: market data, indicators, order placement, position management and trade history — with a **dry-run safety mode that is ON by default**.

```
You:  "What's my account status?"
AI:   Balance $10,000 · Equity $10,050 · 1 open XAUUSD position (+$12.40)

You:  "Buy 0.1 lots XAUUSD with stop loss at 2390"
AI:   ✓ Validated: volume 0.1 ✓ Filling mode FOK ✓ Within MT5_MAX_VOLUME
      ⚠ Dry-run mode is ON — no real order sent. Set MT5_DRY_RUN=false to trade.
```

## Highlights

- 🔒 **Dry-run by default** — every order tool validates and previews without sending. Real trading is one env var away, never an accident.
- 🛡 **Guard rails** — volume rounded to the symbol's lot step, capped by `MT5_MAX_VOLUME`, human-readable error messages for every MT5 return code (no more mystery retcode 10016).
- 📊 **Built-in indicators** — SMA, EMA, RSI, ATR computed from candles, no extra dependencies.
- ⚖️ **Risk-based lot sizing** — `calculate_lot_size` tells you exactly how many lots to risk 1% of your account.
- 🔌 **Two connection modes** — attach to your already-running terminal, or log in via environment variables.
- ✅ **Tested** — 30+ tests run against a simulated MT5 terminal, so the whole suite passes even without MT5 installed.

## Requirements

- **Windows** (the MetaTrader5 Python package is Windows-only) + a MetaTrader 5 terminal installed and logged in
- **"Algo Trading" enabled** in the MT5 terminal (button in the toolbar)
- Python 3.10+

## Quick start

### 1. Install

```bash
pip install mt5-mcp-server
```

Or with [uv](https://docs.astral.sh/uv/):

```bash
uvx mt5-mcp-server
```

### 2. Add to your MCP client

**Claude Desktop** — `%APPDATA%\Claude\claude_desktop_config.json` (full example in [examples/](examples/)):

```json
{
  "mcpServers": {
    "mt5": {
      "command": "mt5-mcp-server",
      "env": {
        "MT5_DRY_RUN": "true",
        "MT5_LOGIN": "12345678",
        "MT5_PASSWORD": "your-password",
        "MT5_SERVER": "YourBroker-Server"
      }
    }
  }
}
```

**Claude Code / ZCode:**

```bash
claude mcp add mt5 --env MT5_DRY_RUN=true -- mt5-mcp-server
```

> Leave `MT5_LOGIN` out to attach to whichever account is already logged in
> inside the running terminal.

### 3. Try it (safe — dry-run is on)

Ask your assistant: *"What's my account balance?"* then *"Buy 0.1 lots XAUUSD"*. You will get a validated **preview**, not a real order.

### 4. Enable real trading

Set `"MT5_DRY_RUN": "false"` in the config. **Test on a demo account first.**

## Configuration

| Variable | Default | Meaning |
|---|---|---|
| `MT5_DRY_RUN` | `true` | **Order tools only preview, never send.** Set to `false` for real trading. |
| `MT5_MAX_VOLUME` | `10` | Hard cap on order volume in lots (safety net). |
| `MT5_LOGIN` | — | Account number. Without it, the server uses the terminal's logged-in account. |
| `MT5_PASSWORD` | — | Account password (only with `MT5_LOGIN`). |
| `MT5_SERVER` | — | Broker server name, e.g. `MetaQuotes-Demo`. |
| `MT5_PATH` | — | Path to `terminal64.exe` if the terminal is not running or not in the default location. |
| `MT5_DEVIATION` | `20` | Max slippage in points for market orders. |
| `MT5_MAGIC` | `0` | Magic number attached to orders placed by the AI. |

## Tools

**Account** — `get_account_info` · `get_terminal_info`

**Market data** — `search_symbols` · `get_symbol_info` · `get_tick` · `get_candles` (M1→MN1) · `get_indicator` (SMA / EMA / RSI / ATR)

**Portfolio** — `get_positions` (live P/L) · `get_pending_orders` · `get_history` (net profit, wins/losses per symbol)

**Orders** — `place_market_order` · `place_pending_order` (limit/stop) · `close_position` (full or partial) · `modify_position` (SL/TP) · `modify_pending_order` · `cancel_pending_order`

**Risk** — `calculate_lot_size` (position size from risk % + stop loss)

## Safety model

1. **Dry-run first**: `MT5_DRY_RUN=true` (default) validates the order against symbol rules and returns exactly what *would* be sent.
2. **Volume guard**: lots are rounded down to the symbol's step and capped by `MT5_MAX_VOLUME`; volumes below the symbol minimum are rejected.
3. **Clear errors**: every broker rejection is translated into plain language (retcode 10016 → *"SL/TP is too close to the price or on the wrong side"*).
4. **No keys in code**: credentials go in MCP client env config, never in the repository.

⚠️ **Trading involves risk.** This software is provided as-is, with no warranty. Always test on a **demo account** first. The authors are not responsible for trading losses.

## Example session

> **User:** What's my exposure right now?
>
> **AI:** *(calls `get_positions`)* You have 2 open positions: 0.10 XAUUSD buy (+$12.40) and 0.05 EURUSD sell (−$3.10). Floating P/L: **+$9.30**.
>
> **User:** Close half of the gold position.
>
> **AI:** *(calls `close_position` ticket=X, volume=0.05)* ✓ Closed 0.05 lots at 2401.10. Remaining: 0.05 lots.

## Development

```bash
git clone https://github.com/Erfangit23/mt5-mcp-server
cd mt5-mcp-server
pip install -e ".[dev]"
pytest -v
```

Tests run against a simulated MT5 terminal ([tests/fake_mt5.py](tests/fake_mt5.py)) — no MT5 installation needed. To verify the MCP handshake with a real terminal, run `python scripts/smoke_test.py`.

## راهنمای سریع (فارسی)

۱. نصب: `pip install mt5-mcp-server`
۲. در کلود دسکتاپ، فایل `claude_desktop_config.json` را مثل بالا تنظیم کنید.
۳. حالت **Dry-Run** به‌صورت پیش‌فرض روشن است؛ هیچ معامله واقعی انجام نمی‌شود.
۴. برای معامله واقعی: `MT5_DRY_RUN` را `false` کنید — اول روی حساب **دمو** تست کنید.
۵. دکمه **Algo Trading** در ترمینال MT5 باید فعال باشد.

## Roadmap

- [ ] Streaming tick prices (MCP subscriptions)
- [ ] Chart screenshots via terminal
- [ ] MACD / Bollinger Bands indicators
- [ ] Linux support via Wine bridge

## License

[MIT](LICENSE) — use it, fork it, ship it.

TDQS

B3.3/5.0

Scored across 17 tools

Disambiguation4/5

Most tools have clearly distinct roles (market data, order management, account info), but get_tick duplicates the bid/ask already present in get_symbol_info, creating a minor overlap. Other pairs like get_positions/get_pending_orders and modify_position/modify_pending_order are well separated by their descriptions.

Naming Consistency5/5

All tools use consistent snake_case with a clear verb_noun pattern (get_, search_, place_, close_, modify_, cancel_, calculate_). No mixing of conventions or vague verbs.

Tool Count4/5

With 17 tools, the set is slightly above the ideal 3–15 range, but each tool covers a distinct MT5 operation (terminal/account info, symbol data, candles, indicators, positions, pending orders, trade execution, risk sizing). The count is borderline but justified for a trading server.

Completeness4/5

The surface covers account/terminal info, symbol lookup, market data, indicators, full position/order lifecycle (place, modify, close, cancel), history, and lot sizing. Minor gaps like trailing stops or margin requirement checks exist, but the core trading workflow is complete.