Metadata-Version: 2.4
Name: meta-trader-mcp
Version: 1.2.0
Summary: A production-grade, cross-platform MCP Server for MetaTrader 5
Project-URL: Homepage, https://github.com/shubhvisputek/meta-trader-mcp
Project-URL: Repository, https://github.com/shubhvisputek/meta-trader-mcp
Project-URL: Issues, https://github.com/shubhvisputek/meta-trader-mcp/issues
Author: Meta Trader MCP Contributors
License: MIT
License-File: LICENSE
License-File: NOTICE
Keywords: ai-agents,llm,mcp,metatrader,model-context-protocol,mt5,trading
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.10
Requires-Dist: mcp>=1.0.0
Requires-Dist: numpy>=1.26.0
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: requests>=2.31.0
Requires-Dist: websockets>=12.0
Provides-Extra: autostart
Requires-Dist: psutil>=5.9.0; extra == 'autostart'
Provides-Extra: dev
Requires-Dist: fastapi>=0.110.0; extra == 'dev'
Requires-Dist: httpx>=0.27.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Provides-Extra: fastmcp
Requires-Dist: fastmcp>=2.0.0; extra == 'fastmcp'
Provides-Extra: pandas
Requires-Dist: pandas>=2.0.0; extra == 'pandas'
Requires-Dist: pytz>=2023.3; extra == 'pandas'
Provides-Extra: remote
Requires-Dist: fastapi>=0.110.0; extra == 'remote'
Requires-Dist: uvicorn>=0.29.0; extra == 'remote'
Provides-Extra: ta
Requires-Dist: pandas>=2.0.0; extra == 'ta'
Requires-Dist: ta>=0.11.0; extra == 'ta'
Provides-Extra: windows
Requires-Dist: metatrader5>=5.0.45; extra == 'windows'
Description-Content-Type: text/markdown

# Meta-Trader-MCP

<!--
  Keywords: MetaTrader 5 MCP server, MT5 MCP, MetaTrader Python, MT5 macOS,
  MT5 Linux, MT5 on Mac, MetaTrader 5 Wine, MCP server trading, Claude MetaTrader,
  AI trading bot, algorithmic trading MCP, Model Context Protocol MetaTrader,
  MT5 Python API macOS/Linux, MetaTrader5 pip macOS, MT5 bridge Wine.
-->

**MetaTrader 5 (MT5) MCP server for AI assistants — live market data, order
execution, and backtesting on macOS, Linux, and Windows.**
Connect Claude, Cursor, or any [Model Context Protocol](https://modelcontextprotocol.io)
client to MetaTrader 5: native on Windows, or via Wine on macOS/Linux, or a
remote bridge to any Windows host.

[![PyPI version](https://img.shields.io/pypi/v/meta-trader-mcp.svg?label=PyPI&color=blue)](https://pypi.org/project/meta-trader-mcp/)
[![Downloads](https://img.shields.io/pypi/dm/meta-trader-mcp.svg?color=blue)](https://pypi.org/project/meta-trader-mcp/)
[![Python](https://img.shields.io/pypi/pyversions/meta-trader-mcp.svg)](https://pypi.org/project/meta-trader-mcp/)
[![CI](https://github.com/shubhvisputek/meta-trader-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/shubhvisputek/meta-trader-mcp/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Platforms](https://img.shields.io/badge/platforms-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey)](#supported-platforms)
[![MCP](https://img.shields.io/badge/Model%20Context%20Protocol-compatible-6E56CF)](https://modelcontextprotocol.io)

> The **PyPI** badge above always reflects the **latest published version**.

**Meta-Trader-MCP** is a production-grade, cross-platform MCP server that exposes
a unified AI interface to **MetaTrader 5**: live quotes, historical candles,
technical indicators, order execution, position management, and headless
Strategy Tester backtests — all behind a mandatory risk interceptor. It is the
straightforward way to run **MetaTrader 5 with Python on macOS and Linux** (where
the official `MetaTrader5` binding is Windows-only) by hosting it under Wine and
bridging to it automatically.

**Who is this for?** Algorithmic traders and developers who want an AI assistant
(Claude, Cursor, Claude Code, or any MCP host) to read MT5 market data, run
backtests, and — when explicitly enabled — place trades, safely and locally.

---

## ⚠️ Risk disclaimer (read this first)

**This software can place real orders against a live brokerage account and
can cause real financial loss.** It is provided *as is*, with no warranty and
no financial advice of any kind — see [DISCLAIMER.md](DISCLAIMER.md).

Safety defaults:

* **Trading is OFF by default.** The server starts read-only; every
  state-changing tool is rejected until you explicitly set
  `MTM_ENABLE_TRADING=true` (or pass `--enable-trading`).
* Every order passes a **non-bypassable risk interceptor**: max-lot cap,
  equity-drawdown ceiling, payload guardrails and rate limiting.
* Credentials are read only from the environment / OS keychain and are never
  logged ([SECURITY.md](SECURITY.md)).

---

## 📚 Documentation

Full guides live in **[docs/](docs/README.md)** — start there for the complete index:

- **[Installation & Setup](docs/INSTALLATION.md)** — every install path, per-platform, with copy-paste commands and client config.
- **[Configuration Reference](docs/CONFIGURATION.md)** — every `MTM_*`/`MT5_*` env var, grouped, with recipes.
- **[Usage & Execution](docs/USAGE.md)** — running the server + worked end-to-end examples.
- Platform deep-dives: [LOCAL_WINE](docs/LOCAL_WINE.md) · [WINDOWS](docs/WINDOWS.md) · [IDE_SETUP](docs/IDE_SETUP.md)

---

## Supported platforms

| Platform | Mode | Status | Guide |
|----------|------|--------|-------|
| **macOS** (Apple Silicon & Intel) | `local-wine` (MT5 under the bundled Wine) | ✅ **Tested & validated** (macOS 26, Apple Silicon, Wine 11) | [docs/LOCAL_WINE.md](docs/LOCAL_WINE.md) |
| **Windows** | `windows-native` (direct `MetaTrader5` binding) | ⚠️ **Supported, not yet maintainer-tested** | [Windows install](#windows-installation) |
| **Linux** | `local-wine` (MT5 under system Wine) | ⚠️ **Supported, not yet maintainer-tested** | [docs/LOCAL_WINE.md](docs/LOCAL_WINE.md) |
| **Any** (MT5 on a separate Windows box) | `remote-bridge` | ⚠️ Supported, community-tested | [remote-bridge setup](#remote-bridge-setup) |

### Platform installation

<details open>
<summary><b>macOS</b> (tested) — live MT5 via Wine</summary>

1. Install MetaTrader 5 (the official macOS app bundles Wine) and log in once.
2. Install the server: `pipx install meta-trader-mcp` (or `uv tool install meta-trader-mcp`).
3. Bootstrap the in-prefix Python + bridge: `meta-trader-mcp setup-wine`.
4. Configure your MCP client for `MTM_MODE=local-wine` and call `get_market_status`.

Full guide, including the Claude Desktop config block: **[docs/LOCAL_WINE.md](docs/LOCAL_WINE.md)**.
</details>

<details id="windows-installation">
<summary><b>Windows</b> (not yet maintainer-tested) — native binding</summary>

1. `pip install "meta-trader-mcp[windows]"` (pulls the official `MetaTrader5` binding).
2. Install MetaTrader 5 and log in.
3. Configure your MCP client with `MTM_MODE=windows-native` (or `auto`).

This path uses MetaQuotes' native Python binding directly — lowest latency, no
Wine. It *should* work out of the box, but the maintainers have not yet
validated it end-to-end.

**Full local/dev Windows guide (install from source/wheel, config, and the
native-Windows capability matrix): [docs/WINDOWS.md](docs/WINDOWS.md).**
</details>

<details>
<summary><b>Linux</b> (not yet maintainer-tested) — live MT5 via Wine</summary>

1. Install Wine and MetaTrader 5 into a prefix; log in once.
2. `pipx install meta-trader-mcp`, then `meta-trader-mcp setup-wine` (uses your
   system `wine`/`wine64`; override with `MTM_WINE_BINARY`).
3. Configure your MCP client for `MTM_MODE=local-wine`.

Mechanically identical to the macOS path (same `setup-wine`, systemd `--user`
daemon instead of launchd). See **[docs/LOCAL_WINE.md](docs/LOCAL_WINE.md)**.
</details>

> ⚠️ **A note on Linux & Windows.** These platforms are fully implemented and
> share the same code paths as macOS, but the maintainers have so far only
> validated the macOS (Apple Silicon) flow end-to-end. If you run into any
> problem on Linux or Windows, **please [open an issue](https://github.com/shubhvisputek/meta-trader-mcp/issues)**
> with your OS, architecture, and the error — or, even better, **send a pull
> request with the fix**. Community reports are how these platforms graduate to
> "tested," and every issue helps the next person. Thank you for contributing. 🙏

## Quick start (Claude Desktop)

There are two ways to install in Claude Desktop. Both end with the server
loading automatically when the app starts — pick whichever you prefer.

### Option A — config entry (most reliable)

Point Claude Desktop at the installed CLI. First install it once:

```bash
brew install shubhvisputek/tap/meta-trader-mcp     # macOS (Homebrew)
# or, any OS with uv:
uv tool install meta-trader-mcp                     # gives a `meta-trader-mcp` on PATH
```

Then add this to `claude_desktop_config.json` (Settings → Developer → Edit
Config), using the **absolute path** to the binary — Claude Desktop launches
servers with a minimal `PATH`, so a bare command name often isn't found:

```json
{
  "mcpServers": {
    "meta-trader-mcp": {
      "command": "/opt/homebrew/bin/meta-trader-mcp",
      "args": ["serve", "--transport", "stdio"],
      "env": { "MTM_MODE": "auto", "MTM_ENABLE_TRADING": "false" }
    }
  }
}
```

Find your path with `which meta-trader-mcp`. Restart Claude Desktop (fully
quit, ⌘Q) and the server appears under Settings → Developer.

### Option B — one-click `.mcpb` bundle

1. Download the `.mcpb` for your platform from the
   [latest release](https://github.com/shubhvisputek/meta-trader-mcp/releases)
   (`-macos-arm64`, `-windows-x64`, `-linux-x64`).
2. Double-click it; Claude Desktop installs it and prompts for settings (the
   MT5 password is stored in the OS keychain, never in a file).
3. Done. It needs `python3` (3.10–3.12) on PATH — the bundle carries every
   other dependency.

> **Either way, you don't run anything to start the server.** Claude Desktop
> launches it over stdio when the app opens and stops it when the app closes.
> No terminal, no autostart, no background service.

> **Which to pick?** Option A is the most robust (it reuses a normal install
> and sidesteps Claude Desktop's bundle handling). Option B is the zero-prior-
> install path. If a `.mcpb` double-click ever fails to import (e.g. *"reply
> was never sent"* on an older/very large build), use Option A.

If MetaTrader 5 isn't running yet, that's fine — see the mental model below.

## How it works (mental model)

```text
Claude Desktop / MCP client          (you chat)
        │  spawns on app launch, stdio
        ▼
meta-trader-mcp serve                (this package)
        │  connects lazily, on the FIRST tool call
        ▼
MetaTrader 5 terminal                (your broker connection)
```

* The MCP client owns the server's lifecycle — the server "loads with the
  LLM".
* The server **never requires MT5 at startup**. The first tool call
  connects; if the terminal is down you get a structured, non-fatal answer:

  ```json
  { "status": "ERROR", "code": "MT5_NOT_RUNNING",
    "message": "MetaTrader 5 terminal is not running. Start MT5 and retry." }
  ```

  Start MT5 and ask again — the same call now succeeds, no restart needed.

## Install matrix

| You are… | Recommended install |
|----------|--------------------|
| A Claude Desktop user | Config entry (Option A) or one-click `.mcpb` (Option B) above |
| Using Cursor / Claude Code / another MCP client | `uvx` config snippet (below) — zero install |
| A developer (Windows, trading) | `pip install "meta-trader-mcp[windows]"` |
| A developer (macOS/Linux) | `pip install meta-trader-mcp` + `local-wine` or `remote-bridge` mode |
| Running the Windows bridge companion | `pip install "meta-trader-mcp[remote]"` on the Windows box |
| Wanting start-with-MT5 / always-on serving | add the `[autostart]` extra |

```bash
# Developers / virtualenvs
pip install meta-trader-mcp                 # base (macOS/Linux/Windows) — lean
pip install "meta-trader-mcp[windows]"      # Windows: pulls the MetaTrader5 binding
pip install "meta-trader-mcp[remote]"       # remote-bridge HTTP companion (FastAPI/uvicorn)
pip install "meta-trader-mcp[autostart]"    # psutil-based supervisor
pip install "meta-trader-mcp[pandas]"       # MT5Client dataframe history helpers
pip install "meta-trader-mcp[fastmcp]"      # the standalone FastMCP framework (optional)

# Isolated app install (recommended for end users on a workstation)
pipx install "meta-trader-mcp[windows]"

# Zero-install run (no global state) — great for MCP client configs
uvx --from "meta-trader-mcp[windows]" meta-trader-mcp serve
```

The `MetaTrader5` binding is an **optional** `[windows]` extra, so the base
package installs cleanly on macOS/Linux/CI — importing `meta_trader_mcp`
never raises a Windows-only `ImportError`.

## Per-client configuration

Any MCP client that reads a JSON config gets the same client-managed launch
with one entry:

```json
{
  "mcpServers": {
    "meta-trader-mcp": {
      "command": "uvx",
      "args": ["--from", "meta-trader-mcp[windows]", "meta-trader-mcp", "serve", "--transport", "stdio"],
      "env": { "MTM_MODE": "auto", "MTM_ENABLE_TRADING": "false" }
    }
  }
}
```

| Client | Config file location |
|--------|---------------------|
| Claude Desktop (manual) | `%APPDATA%\Claude\claude_desktop_config.json` (Windows) / `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) |
| Claude Code | `.mcp.json` in your project, or `claude mcp add meta-trader-mcp -- uvx --from "meta-trader-mcp[windows]" meta-trader-mcp serve` |
| Cursor | `~/.cursor/mcp.json` or `.cursor/mcp.json` per project |
| Other MCP hosts | Same `command`/`args`/`env` triple in the host's MCP config |

On macOS/Linux replace `meta-trader-mcp[windows]` with plain
`meta-trader-mcp` and set `MTM_MODE` to `local-wine` or `remote-bridge`.

## Runtime modes

| Mode | When to pick it |
|------|-----------------|
| `windows-native` | You run MT5 on this Windows machine. Auto-selected by `auto`. Direct, in-process binding — lowest latency. |
| `local-wine` | macOS/Linux with MT5 installed under [Wine](https://www.winehq.org). Explicit opt-in: `--mode local-wine`. |
| `remote-bridge` | MT5 runs on a Windows VPS/VM elsewhere. `--mode remote-bridge --host <ip> --port 8080`. |
| `auto` (default) | Windows → `windows-native`. Anywhere else the server *asks you to choose* instead of guessing. |

### local-wine setup (macOS/Linux) — one command

The Windows-only `MetaTrader5` binding can't run in your host Python, so
`local-wine` talks to a small bridge served by a **Windows Python installed
inside the MT5 Wine prefix**. Setting that up by hand is fiddly (the bundled
macOS Wine is 64-bit-only, so the python.org GUI installer fails). The
`setup-wine` subcommand does the whole thing for you:

```bash
meta-trader-mcp setup-wine
```

It will, **inside your MT5 Wine prefix only** (no sudo, no system Python, no
PATH changes):

1. download the embeddable **CPython** from python.org — pinned and
   **SHA-256-verified before it runs**;
2. `pip install meta-trader-mcp[remote,windows]==<this version>` (pulls
   `MetaTrader5`, FastAPI, uvicorn) into that in-prefix Python;
3. prompt for your MT5 `login` / `server` / `password` and store them in a
   `0600` env file (**never** in argv, logs, or your MCP client config);
4. by **default install no background daemon** — the MCP server starts the
   bridge on demand (self-healing) and stops it when the client exits.

**Prerequisites:** MetaTrader 5 already installed under Wine and logged in once
to your account. On macOS the Wine bundled inside `MetaTrader 5.app` is detected
automatically; on Linux any `wine`/`wine64` on `PATH` is used (override with
`MTM_WINE_BINARY`). The prefix is auto-detected (override with
`MTM_WINE_PREFIX`).

Then point your MCP client at `MTM_MODE=local-wine`. The first tool call routes
host → loopback bridge → MT5 under Wine; if the bridge isn't up yet, the server
launches it and you simply retry.

Useful flags:

| Command | Effect |
|---------|--------|
| `meta-trader-mcp setup-wine` | Default: in-prefix Python + bridge + creds, **no** background item. |
| `meta-trader-mcp setup-wine --daemon` | Also register an always-on per-user daemon (LaunchAgent / systemd `--user`). Adds a background login item. |
| `meta-trader-mcp setup-wine --yes` | Non-interactive (reads `MT5_LOGIN`/`MT5_SERVER`/`MT5_PASSWORD` from the env). |
| `meta-trader-mcp setup-wine --uninstall` | Remove the daemon, runner and credential file. |

> **Why a background item appears with `--daemon`:** the daemon is a per-user
> LaunchAgent whose launcher is `/bin/bash`, so macOS lists it under
> *Login Items & Extensions* as "bash". The default (self-healing) install has
> no daemon and therefore no background item.

📖 **Full reference:** architecture, client config, security, an FAQ and a
complete troubleshooting catalog live in
**[docs/LOCAL_WINE.md](docs/LOCAL_WINE.md)**.

### remote-bridge setup

On the **Windows host next to MT5**:

```powershell
pip install "meta-trader-mcp[remote,windows]"
meta-trader-mcp bridge --host 0.0.0.0 --port 8080
```

On your machine: `MTM_MODE=remote-bridge`, `MTM_REMOTE_HOST=<windows-ip>`,
`MTM_REMOTE_PORT=8080`. A Docker recipe for the client side ships in
[docker-compose.yml](docker-compose.yml).

> Plain HTTP is acceptable only on a trusted LAN. For anything else put the
> bridge behind TLS (`MTM_REMOTE_USE_TLS=true` + a reverse proxy).

## Configuration reference

All settings come from environment variables or a local `.env`
(see [.env.example](.env.example)). CLI flags override the environment.

| Variable | Default | Meaning |
|----------|---------|---------|
| `MTM_MODE` | `auto` | `auto` \| `windows-native` \| `local-wine` \| `remote-bridge` |
| `MTM_ENABLE_TRADING` | `false` | **Must** be `true` for any state-changing tool |
| `MTM_ENABLE_EXEC` | `false` | **Must** be `true` for the code-execution tools (arbitrary code — isolated machines only; re-checked by the bridge) |
| `MTM_TRANSPORT` | `stdio` | `stdio` (client-managed) \| `http` (background/shared) |
| `MTM_HTTP_HOST` | `127.0.0.1` | HTTP bind host (loopback by default — keep it that way) |
| `MTM_HTTP_PORT` | `8000` | HTTP bind port |
| `MTM_WATCH_PROCESS` | `terminal64.exe` | Process the `supervise` command watches |
| `MTM_STOP_WITH_MT5` | `true` | Stop the supervised server when MT5 exits |
| `MT5_LOGIN` | — | MT5 account number (optional; terminal session reused if unset) |
| `MT5_PASSWORD` | — | MT5 password. Keychain via `.mcpb`; never logged |
| `MT5_SERVER` | — | Broker server name |
| `MT5_TERMINAL_PATH` | — | Explicit `terminal64.exe` path (native/wine) |
| `MTM_WINE_PREFIX` | `~/.mt5` | Wine prefix containing MT5 |
| `MTM_WINE_BINARY` | `wine64` | Wine launcher binary |
| `MTM_REMOTE_HOST` | — | Companion bridge host (remote-bridge mode) |
| `MTM_REMOTE_PORT` | `8080` | Companion bridge port |
| `MTM_BRIDGE_TOKEN` | — | Shared secret required on every bridge `/rpc` (sent as `X-MTM-Token`). Generated by `setup-wine`; authenticates host↔bridge even on loopback |
| `MTM_REMOTE_USE_TLS` | `false` | Use `https` for the remote bridge (set true off-LAN) |
| `MTM_BRIDGE_ALLOW_INSECURE` | `false` | Override the refusal to bind the bridge to a non-loopback host without a token/TLS (not recommended) |
| `MTM_MAX_LOT` | `10.0` | Risk: max volume of a single order |
| `MTM_MAX_DRAWDOWN_PCT` | `5.0` | Risk: equity-drawdown ceiling blocking new entries |
| `MTM_REPORTS_DB` | `~/.meta-trader-mcp/reports.db` | SQLite backtest-report history |
| `MTM_OPTIMIZATIONS_DB` | `~/.meta-trader-mcp/optimizations.db` | SQLite optimization-job store |
| `MTM_NEWS_PROVIDER` / `MTM_NEWS_API_KEY` | `rss` / — | News source (`rss` is free, no key) + key for marketaux/finnhub |
| `MTM_ECONCAL_API_KEY` / `MTM_FUNDAMENTALS_API_KEY` / `MTM_OPTIONS_API_KEY` | — | Free-tier keys for the creds-gated external-data tools |

**Credential safety:** secrets live in the environment / OS keychain only.
`.env` is gitignored; the settings object masks the password in any debug
output; tests use mocks exclusively.

## Tool reference

**141 MCP tools + 4 `mtm://` resources + 3 prompt templates** (also reachable over
REST/WebSocket, or from the shell via `meta-trader-mcp tool <name> …` — see
[docs/IDE_SETUP.md](docs/IDE_SETUP.md)). All tools return JSON. State-changing
tools (marked ⚡) pass the risk interceptor first and require
`MTM_ENABLE_TRADING=true`; the code-execution tools require `MTM_ENABLE_EXEC=true`
(both OFF by default); everything else is read-only.

### Market data (read-only)

| Tool | Parameters | Example prompt |
|------|-----------|----------------|
| `get_market_status` | — | "Is my MT5 connected? What's the latency?" |
| `get_historical_candles` | `symbol`, `timeframe` (`M1`…`MN1`), `count` | "Show me the last 50 H1 candles for EURUSD" |
| `get_candles_range` | `symbol`, `timeframe`, `from_date`, `to_date` | "EURUSD H1 candles for the first week of January" |
| `get_candles_from` | `symbol`, `timeframe`, `from_date`, `count` | "100 H1 candles starting 2025-01-02" |
| `get_ticks` | `symbol`, `from_date`, `count`, `flags` | "Tick history for GBPUSD since yesterday" |
| `get_live_ticks` | `symbol` | "What's the current spread on XAUUSD?" |
| `get_symbol_info` | `symbol` | "Contract spec for EURUSD (digits, volume limits)" |
| `get_symbols` | `group?` (e.g. `*USD*`) | "List all USD symbols" |
| `check_symbol_data_status` | `symbol`, `timeframe`, `count` | "Does EURUSD have H1 history for a backtest?" |
| `compute_indicator` | `symbol`, `timeframe`, `indicator`, `period` | "Compute the 14-period RSI on GBPUSD H4" |
| `scan_market` | `symbols`/`group`, `timeframe`, `sort_by`, `top` | "Top movers among the majors right now" |

`compute_indicator` supports **15** always-on numpy built-ins: `SMA`, `EMA`,
`RSI`, `MACD`, `BOLLINGER`, `ATR`, `STOCHASTIC`, `ADX`, `CCI`, `WILLIAMS`, `ROC`,
`MOMENTUM`, `OBV`, `VWAP`, `MFI`. Installing the **`[ta]` extra**
(`pip install 'meta-trader-mcp[ta]'`) adds ~30 more (KAMA, AROON, ICHIMOKU, PSAR,
KELTNER, DONCHIAN, VORTEX, TSI, UO, …) through the same tool; `list_ta_indicators`
reports what's available.

Example response (`get_historical_candles`, latest candle mirrored at the
top level for single-candle reads):

```json
{
  "symbol": "EURUSD", "timeframe": "H1", "count": 1,
  "candles": [{ "time": 1774112000, "open": 1.1000, "high": 1.1050,
                "low": 1.0990, "close": 1.1020, "tick_volume": 500 }],
  "time": 1774112000, "open": 1.1, "high": 1.105, "low": 1.099,
  "close": 1.102, "tick_volume": 500
}
```

### Analytics & quant (read-only, pure-numpy/stdlib — no heavy deps)

- **Risk/return:** `analyze_volatility` (realized/EWMA/Parkinson), `value_at_risk`
  (VaR+CVaR), `correlation_matrix`, `seasonality`, `cointegration`, `lead_lag`.
- **Forecasting & signals:** `forecast_prices` (Holt/Theta/drift), `detect_regime`,
  `detect_candlestick_patterns`, `barrier_probability` (Monte-Carlo TP/SL),
  `ml_signal` (logistic regression).
- **Options:** `black_scholes` (price + greeks), `implied_volatility`.
- **Charts:** `render_chart` (line/candlestick SVG, no matplotlib).
- **Denoising/swings:** `kalman_smooth` (1-D random-walk filter), `detect_fractals`
  (Williams swing high/low → support/resistance).
- **Chart patterns:** `detect_chart_patterns` (head-and-shoulders, double/triple
  tops & bottoms, triangles, wedges, channels, flags — geometry + measured target),
  `detect_elliott_wave` (rule-checked heuristic 5-wave+ABC screen, not a definitive
  count).
- **Market depth:** `get_market_depth` (Level-2 DOM where the broker provides it).

### Account & portfolio (read-only)

`get_account_info`, `get_positions` (+ `_by_symbol`, `_by_currency`),
`get_pending_orders` (+ `_by_symbol`, `_by_currency`), `get_deals_history`,
`get_orders_history`. **Deal-level queries:** `list_deals` (P/L summary, symbol +
profit-sign filters), `search_deals_by_comment`, `search_deals_by_magic`.

### Pre-trade calculators & checks (read-only)

`calculate_margin`, `calculate_profit`, `calculate_price_targets`, and
`check_order` — a full `mt5.order_check` preview (broker retcode + projected
margin/equity) **without** placing anything.

### Order management ⚡

| Tool | Parameters |
|------|-----------|
| `place_market_order` | `symbol`, `volume`, `action` (`BUY`/`SELL`), `sl?`, `tp?`, `max_allowed_lot?`, `dry_run?` |
| `place_pending_order` | `symbol`, `volume`, `action`, `price`, `order_type` (`LIMIT`/`STOP`), `sl?`, `tp?`, `dry_run?` |
| `modify_position` | `ticket`, `sl?`, `tp?`, `trailing?` |
| `close_position` | `ticket`, `volume?` (omit = close fully) |
| `close_all_positions` / `_by_symbol` / `_profitable` / `_losing` | (filter args) — returns `{closed, attempted, failed}` |
| `cancel_pending_order` / `cancel_all_pending_orders` | `ticket` / — |
| `modify_pending_order` | `ticket`, `price?`, `sl?`, `tp?` |

Pass `dry_run=true` to `place_market_order` / `place_pending_order` to preview the
order via `order_check` (broker retcode + projected margin) **without** sending it
— this path skips the trading gate, so it works even with trading disabled.

Success payload (canonical):

```json
{ "status": "SUCCESS", "ticket": 99881122, "retcode": 10009, "comment": "Success" }
```

A rejected order is an exception payload, e.g. an oversize lot:

```json
{ "status": "ERROR", "code": "RISK_VIOLATION",
  "message": "Volume target exceeds maximum allowed risk threshold: requested 100.0 lots > allowed 10.0 lots." }
```

### Backtesting (MT5 Strategy Tester — read-only sandbox)

| Tool | Parameters |
|------|-----------|
| `trigger_backtest` | `expert`, `symbol`, `from_date`, `to_date` (`YYYY.MM.DD`), `timeframe?`, `deposit?`, `leverage?` |
| `fetch_backtest_report` | `run_id` |
| `analyze_backtest_report` | `report` (path under `MTM_REPORTS_DIR`) |

`trigger_backtest` writes a Strategy Tester `.ini`, launches the terminal
headlessly (`ShutdownTerminal=1`) and returns a `run_id`; `fetch_backtest_report`
parses the report into `{profit_factor, max_drawdown, win_rate, net_profit,
total_trades}`. `analyze_backtest_report` does deal-level analytics (monthly P/L,
drawdown events, top losses, streaks, direction bias, hold-time/profit
distributions, costs, efficiency).

### Strategy files & report history

- **`.set` engine:** `list_set_files`, `read_set_file`, `write_set_file`,
  `patch_set_file`, `diff_set_files`, `describe_sweep` (UTF-16LE, optimization
  sweeps; path-confined to `MTM_SET_FILES_DIR`).
- **Report history (SQLite, `MTM_REPORTS_DB`):** `store_backtest_report`,
  `list_backtest_reports`, `search_backtest_reports`, `get_backtest_report`,
  `compare_backtest_reports`, `set_backtest_baseline`, `update_backtest_report`,
  `delete_backtest_report`, `get_reports_by_set_file` (every run of one `.set`).

### Optimizer jobs (SQLite, `MTM_OPTIMIZATIONS_DB`)

`run_optimization` records a job you can poll later: `list_jobs`,
`get_optimization_status` (reconciles against the exported results XML — only
`COMPLETED` when the file is on disk), `get_optimization_results` (per-pass
profit/PF/drawdown/trades + swept inputs; `NO_RESULTS_FILE` until present, never
faked), `set_from_optimization` (write the winning pass to a path-confined `.set`).
Results complete on native Windows / full Wine; the macOS bundle stays
`NO_RESULTS_FILE`.

### External data (optional, creds-gated)

- `get_market_news` — **free, no key** by default (Yahoo per-symbol / Nasdaq RSS);
  set `MTM_NEWS_PROVIDER=marketaux|finnhub` + `MTM_NEWS_API_KEY` for sentiment.
- `get_economic_calendar`, `get_fundamentals`, `get_options_chain` — need a free
  API key (`MTM_ECONCAL_API_KEY` / `MTM_FUNDAMENTALS_API_KEY` / `MTM_OPTIONS_API_KEY`;
  Finnhub/FMP/Polygon). Unconfigured, they return a clear error naming the env var
  — they never fabricate data. Use `black_scholes` for option pricing without a key.

### Code execution ⚡ (opt-in, `MTM_ENABLE_EXEC` — OFF by default)

**High-risk, owner-approved, dual-gated** (see [docs/SECURITY_REVIEW.md](docs/SECURITY_REVIEW.md)).
Requires `MTM_ENABLE_EXEC=true` (and, over the bridge, the bridge's own flag):
`write_ea` / `write_script` (path-confined MQL5 authoring → then `compile_ea` /
`run_backtest`), `execute_mql_script` (compile + honest status), `execute_mt5`
(Python with the `mt5` module in scope), `execute_python`, `execute_shell`. Host
and `mt5` code run in a child subprocess with a hard timeout + output cap.

### Wine-driving suite (needs MT5 + Wine, or native Windows)

Drives MetaEditor / the Strategy Tester directly (not via the live bridge):
`compile_ea`, `validate_ea_syntax`, `run_backtest`, `run_backtest_quick`,
`run_optimization`; diagnostics `diagnose_wine`, `list_experts`,
`list_indicators`, `list_scripts`, `list_tester_symbols`, `get_mt5_logs`,
`search_mt5_errors`, `check_mt5_process`, `kill_mt5_process`,
`get_backtest_crash_info`; environment validation `check_system_resources`
(disk/CPU/memory/load), `validate_mt5_config` (binaries + MQL5 + tester dirs);
cache `cache_status`, `clean_cache`; scaffolding `init_project`,
`create_set_template`, `export_report`. See
[docs/WINDOWS.md](docs/WINDOWS.md) for which run natively on Windows.

### Resources & prompts

Read-only `mtm://account`, `mtm://market-status`, `mtm://symbols`,
`mtm://positions`; prompt templates `analyze_account`, `evaluate_trade`,
`review_backtest`.

### Command-line tool access

Any tool is also callable from the shell (handy for scripts/cron), running
through the same risk interceptor as the MCP server:

```bash
meta-trader-mcp tools                 # list every tool (add --json for metadata)
meta-trader-mcp tool get_symbol_info symbol=EURUSD
meta-trader-mcp tool black_scholes spot=100 strike=105 t=0.5 vol=0.2 kind=call
meta-trader-mcp tool list_deals --json '{"days": 7, "profitable": true}'
```

`key=value` arguments are parsed as JSON when possible (`count=5` → int,
`profitable=true` → bool), otherwise treated as strings. State-changing tools
still require `--enable-trading` **and** `MTM_ENABLE_TRADING=true`.

## Trading safety

1. **Opt in deliberately.** `MTM_ENABLE_TRADING=true` (env / `.mcpb` config
   toggle / `--enable-trading`). Until then every mutation returns
   `TRADING_DISABLED`.
2. **Risk limits** (`MTM_MAX_LOT`, `MTM_MAX_DRAWDOWN_PCT`) are enforced on
   every order, in front of the adapter — there is no code path around the
   interceptor. Closing/reducing positions is always allowed; opening new
   exposure past the drawdown ceiling is not.
3. **Start on a demo account.** Point `MT5_LOGIN`/`MT5_SERVER` at your
   broker's demo server until you trust your setup end to end.

## Optional: always-on / autostart (advanced)

> Most users should skip this — the client-managed default already starts
> the server with your LLM app.

Needed only when the server must outlive the client (shared server, HTTP-only
client, headless VPS) or should track the MT5 terminal's lifecycle:

```bash
meta-trader-mcp install-autostart --on-boot     # always-on HTTP on 127.0.0.1:8000
meta-trader-mcp install-autostart --with-mt5    # start/stop together with MT5
meta-trader-mcp uninstall-autostart             # remove the artifact
meta-trader-mcp supervise --stop-with-mt5       # run the watcher in foreground
```

What gets written ([templates](packaging/autostart)):

* **Windows** — a Task Scheduler task at the least-privilege `LIMITED` level
* **macOS** — a user LaunchAgent `~/Library/LaunchAgents/com.metatradermcp.server.plist`
* **Linux** — a systemd *user* unit `~/.config/systemd/user/meta-trader-mcp.service`
  (use `loginctl enable-linger` for always-on VPS boxes)

Autostart always serves **HTTP on loopback** (stdio has no client when the
OS launches it) and never writes credentials anywhere.

## Troubleshooting

| Symptom | Fix |
|---------|-----|
| `MT5_NOT_RUNNING` errors | Start the MT5 terminal, retry the call — no server restart needed. |
| `Cannot auto-select a runtime on 'darwin'` | You're not on Windows: pick `--mode local-wine` or `--mode remote-bridge --host …`. |
| `MetaTrader5 binding is not installed` | `pip install "meta-trader-mcp[windows]"` — on Windows only; the binding does not exist for macOS/Linux. |
| Client doesn't list the server | Check the client's MCP config path (table above), then restart the client; for `uvx`, confirm `uv` is on PATH. |
| `.mcpb` install fails / *"reply was never sent"* | The bundle was too large for Claude Desktop to unpack. Use the current slim bundle from the latest release, or switch to **Option A** (config entry pointing at the installed binary). |
| Port 8000 already in use (HTTP) | `--port 9000` or `MTM_HTTP_PORT=9000`. |
| Wine: `terminal64.exe not found` | Install MT5 into the prefix or set `MT5_TERMINAL_PATH` to the exe inside `drive_c`. |
| Wine: bridge unreachable | Run `meta-trader-mcp setup-wine` once (installs the in-prefix Python/bridge + creds). The server self-launches the bridge afterwards; just retry the call. |
| Wine: `-6 Authorization failed` | The bridge reached the terminal but credentials are wrong/missing. Re-run `setup-wine` and check `MT5_SERVER` is the exact, case-sensitive server name. |
| Orders rejected with `TRADING_DISABLED` | That's the safety default — see *Trading safety*. |

## Architecture & contributing

The codebase is hexagonal: role ports (`protocols.py`), pluggable registries
(`registry.py`), one composition root (`container.py`), three runtime
adapters behind one contract. Adding a tool/adapter/risk rule touches **zero**
core files. Read [docs/architecture.md](docs/architecture.md), then
[CONTRIBUTING.md](CONTRIBUTING.md).

```bash
git clone https://github.com/shubhvisputek/meta-trader-mcp
cd meta-trader-mcp
uv venv && uv pip install -e ".[dev]"
pytest tests/ -v          # fully mocked; no MT5 or network needed
ruff check src tests
```

Releases are cut manually via the [Release workflow](.github/workflows/release.yml)
(`workflow_dispatch` or a `v*` tag) — wheel + sdist to PyPI (OIDC), the
`.mcpb` bundle and checksums to GitHub Releases.

## Credits & license

MIT © Meta Trader MCP Contributors — see [LICENSE](LICENSE).

This project deliberately **reuses proven open source** instead of
reinventing it. It incorporates MIT-licensed code from, and owes its design
to ([NOTICE](NOTICE), [THIRD_PARTY_LICENSES.md](THIRD_PARTY_LICENSES.md)):

* [ariadng/metatrader-mcp-server](https://github.com/ariadng/metatrader-mcp-server) — the modular MT5 client core and the remote bridge shapes
* [Qoyyuum/mcp-metatrader5-server](https://github.com/Qoyyuum/mcp-metatrader5-server) — FastMCP tool/resource schemas and packaging conventions
* [Cloudmeru/MetaTrader-5-MCP-Server](https://github.com/Cloudmeru/MetaTrader-5-MCP-Server) — risk guardrails, rate limiting and the error taxonomy
* [emerzon/mt-data-mcp](https://github.com/emerzon/mt-data-mcp) — fast market-data reads and indicator semantics
* [masdevid/mt5-quant](https://github.com/masdevid/mt5-quant) — conceptual reference for headless MT5 under Wine (no code copied)

*Not affiliated with MetaQuotes. MetaTrader is a trademark of MetaQuotes Ltd.*
