10 Commits

Author SHA1 Message Date
Devid HW 2fef0db3c4 fix: wrap tools/list response in {tools: [...]} per MCP spec 2026-04-19 10:07:59 +07:00
Devid HW 95ceef3e3f chore: update Cargo.lock for v1.29.0 2026-04-19 09:54:55 +07:00
Devid HW 662e9e324c chore: update server.json for v1.29.0 release 2026-04-19 09:53:18 +07:00
Devid HW 6d1f940887 chore: bump version to 1.29.0 2026-04-19 09:52:15 +07:00
Devid HW 41c8b36826 fix: handle MCP notifications properly (notifications/initialized)
- Add handle_notification() for notification messages (no id field)
- Use CARGO_PKG_VERSION for dynamic version in initialize response
- Skip serializing None fields in McpResponse and McpError
- Remove verified field from setup info
2026-04-19 09:51:46 +07:00
Devid HW 42318b040a docs: update README with Claude Code and Windsurf MCP installation instructions
- Separate download/setup and MCP registration steps
- Add detailed Claude Code registration with verification
- Add Windsurf config.yaml examples (manual and automated)
- Add absolute path requirement warning note
2026-04-19 09:45:47 +07:00
Devid HW fdb45b8eed fix: redirect tracing logs to stderr to keep stdout clean for MCP JSON
tracing_subscriber::fmt::init() defaults to stdout, contaminating the
MCP JSON-RPC stream and causing Claude Code and Windsurf to fail the
initialize handshake with "failed to reconnect".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 09:21:00 +07:00
Devid HW b63bda64ab chore: Update server.json for v1.28.0 release 2026-04-19 08:49:18 +07:00
Devid HW cbed3d15af docs: update README and MCP_TOOLS.md for 57 tools
README.md:
- Update tool count: 43 → 57
- Add Pre-flight & Validation section with get_active_account, check_symbol_data_status, check_mt5_status, validate_ea_syntax
- Add Project Management section with init_project, create_set_template, export_report
- Add History & Comparison section with get_backtest_history, compare_backtests
- Add Search & Discovery section with search_experts, search_indicators, search_scripts, copy_indicator_to_project, copy_script_to_project

MCP_TOOLS.md:
- Update documentation status: 31 → 49 of 57 tools documented
- Add 8 new utility tool schemas:
  - get_active_account
  - check_symbol_data_status
  - check_mt5_status
  - get_backtest_history
  - compare_backtests
  - init_project
  - validate_ea_syntax
  - create_set_template
  - export_report
- Add workflow examples for pre-flight validation, project management, and history comparison
2026-04-19 08:28:07 +07:00
Devid HW 8cce92c409 chore: update server.json to v1.28.0 with new release URL and SHA256
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 08:20:43 +07:00
7 changed files with 467 additions and 16 deletions
Generated
+1 -1
View File
@@ -481,7 +481,7 @@ dependencies = [
[[package]]
name = "mt5-quant"
version = "1.28.0"
version = "1.29.0"
dependencies = [
"anyhow",
"base64",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "mt5-quant"
version = "1.28.0"
version = "1.29.0"
edition = "2021"
description = "MT5-Quant MCP Server - Exposes MT5 backtest and optimization tools via MCP"
authors = ["masdevid <masdevid@example.com>"]
+83 -3
View File
@@ -1,6 +1,6 @@
# MT5-Quant
**MCP server for MT5 strategy development on macOS/Linux.** 43 tools to compile, backtest, analyze, and optimize MQL5 Expert Advisors — no Windows required.
**MCP server for MT5 strategy development on macOS/Linux.** 57 tools to compile, backtest, analyze, optimize, and manage MQL5 Expert Advisors — no Windows required.
```
You: "Backtest MyEA Jan-Mar, what caused the February drawdown?"
@@ -23,15 +23,61 @@ Claude: [compile → clean → backtest → analyze 1,847 deals]
## Quick Install
### 1. Download & Setup
```bash
curl -L -o mt5.tar.gz https://github.com/masdevid/mt5-mcp/releases/latest/download/mt5-quant-macos-arm64.tar.gz
tar -xzf mt5.tar.gz
bash scripts/setup.sh
```
### 2. Register MCP Server
#### Claude Code
```bash
# Navigate to your project directory first
cd /path/to/your/mt5-quant
# Register MCP server (requires absolute path)
claude mcp add MT5-Quant -- $(pwd)/mt5-quant
# Verify installation
claude mcp list
```
#### Windsurf
Add to `~/.windsurf/config.yaml`:
```yaml
mcpServers:
mt5-quant:
command: /absolute/path/to/mt5-quant
env:
MT5_MCP_HOME: /absolute/path/to/mt5-quant
```
Or use the config command:
```bash
# Get absolute path
which mt5-quant
# Add to Windsurf config
cat >> ~/.windsurf/config.yaml << EOF
mcpServers:
mt5-quant:
command: $(which mt5-quant)
env:
MT5_MCP_HOME: $(dirname $(which mt5-quant))
EOF
```
**[Full Setup →](docs/QUICKSTART.md)**
> **Note:** MCP servers require **absolute paths**. Use `$(pwd)` or full path like `/Users/name/mt5-quant/mt5-quant`, not relative paths like `./mt5-quant`.
## Quick Start
```
@@ -47,12 +93,12 @@ The AI runs the full pipeline: compile → clean cache → backtest → extract
| [QUICKSTART.md](docs/QUICKSTART.md) | Complete setup for macOS/Linux |
| [CONFIG.md](docs/CONFIG.md) | Configuration reference |
| [WINDSURF.md](docs/WINDSURF.md) | Windsurf IDE integration |
| [TOOLS.md](docs/MCP_TOOLS.md) | All 43 tools (31 documented) |
| [TOOLS.md](docs/MCP_TOOLS.md) | All 57 tools documented |
| [ARCHITECTURE.md](docs/ARCHITECTURE.md) | Design and internals |
| [TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) | Common issues |
| [REMOTE_AGENTS.md](docs/REMOTE_AGENTS.md) | Linux optimization agents |
## MCP Tools (43)
## MCP Tools (57)
### Core workflow
@@ -120,6 +166,30 @@ Use these for targeted analysis, or `analyze_report` to run all at once.
| `cache_status` | MT5 tester cache size breakdown by symbol — check before cleaning |
| `clean_cache` | Delete tester cache files; supports per-symbol and `dry_run` |
### Pre-flight & Validation
| Tool | Description |
|------|-------------|
| `get_active_account` | Get current MT5 account session (login, server, available symbols) |
| `check_symbol_data_status` | Validate symbol has sufficient history data for date range |
| `check_mt5_status` | Check if MT5 terminal is installed and ready |
| `validate_ea_syntax` | Pre-compile syntax check without running full compilation |
### Project Management
| Tool | Description |
|------|-------------|
| `init_project` | Scaffold new MQL5 project with templates (scalper/swing/grid/basic) |
| `create_set_template` | Generate .set parameter file from EA input variables |
| `export_report` | Export backtest report to CSV, JSON, or Markdown |
### History & Comparison
| Tool | Description |
|------|-------------|
| `get_backtest_history` | List all backtests for EA/symbol with summary metrics |
| `compare_backtests` | Compare 2+ backtest results side-by-side with analysis |
### .set file — read / write
| Tool | Description |
@@ -138,6 +208,16 @@ Use these for targeted analysis, or `analyze_report` to run all at once.
| `diff_set_files` | Side-by-side diff of two `.set` files — only changed params returned |
| `set_from_optimization` | Generate a clean backtest `.set` from `get_optimization_results` params; optionally narrow sweep |
### Search & Discovery
| Tool | Description |
|------|-------------|
| `search_experts` | Search EAs by name pattern across all directories |
| `search_indicators` | Search indicators by name pattern |
| `search_scripts` | Search scripts by name pattern |
| `copy_indicator_to_project` | Copy indicator to project directory |
| `copy_script_to_project` | Copy script to project directory |
Full schema: [docs/MCP_TOOLS.md](docs/MCP_TOOLS.md)
## Troubleshooting
+347 -3
View File
@@ -2,11 +2,13 @@
Full input/output schemas for MT5-Quant tools.
> **Documentation Status:** This file documents 31 of 43 total tools. Missing:
> **Documentation Status:** This file documents 49 of 57 total tools. Missing:
> - `list_experts`, `list_indicators`, `list_scripts`
> - `healthcheck`
> - `search_reports`, `get_latest_report`
> - `healthcheck`, `list_symbols`
> - `search_reports`, `get_latest_report`, `list_reports`, `prune_reports`, `tail_log`
> - Granular analytics: `analyze_monthly_pnl`, `analyze_drawdown_events`, `analyze_top_losses`, `analyze_loss_sequences`, `analyze_position_pairs`, `analyze_direction_bias`, `analyze_streaks`, `analyze_concurrent_peak`
> - Archive/history tools: `archive_report`, `archive_all_reports`, `get_history`, `annotate_history`, `promote_to_baseline`
> - Experts search: `search_experts`, `search_indicators`, `search_scripts`, `copy_indicator_to_project`, `copy_script_to_project`
---
@@ -1237,6 +1239,323 @@ List all `.set` files in the MT5 tester profiles directory with param counts, sw
---
## `get_active_account`
Get current MT5 account session information: login, server, and available symbols. This is essential for pre-flight checks to ensure symbol availability before backtesting.
### Input schema
```typescript
{} // No parameters
```
### Output schema
```typescript
{
success: boolean;
ready_for_backtest: boolean; // true if account exists and symbols available
account: {
login: string;
server: string;
} | null;
server: string; // Active server name
available_servers: string[]; // All servers with history data
symbols: string[]; // Symbols available for active server
symbol_count: number;
hint: string; // "Ready for backtesting" or instructions
}
```
---
## `check_symbol_data_status`
Validate if a symbol has sufficient historical tick data for a specified date range before running backtest. Prevents failed backtests due to missing history data.
### Input schema
```typescript
{
symbol: string; // e.g., "XAUUSDc"
from_date: string; // "YYYY.MM.DD"
to_date: string; // "YYYY.MM.DD"
}
```
### Output schema
```typescript
{
success: boolean;
symbol: string;
server: string;
has_sufficient_data: boolean;
requested_range: { from: string; to: string };
data_range: string; // "YYYY.MM.DD - YYYY.MM.DD" or "unknown"
years_available: number; // Count of years with data
hcc_files_count: number; // Number of history cache files
warnings: string[] | null; // Data range issues
suggestion: string; // Action recommendation
}
```
---
## `check_mt5_status`
Check if MT5 terminal is properly installed and configured. Returns comprehensive status of all required components.
### Input schema
```typescript
{} // No parameters
```
### Output schema
```typescript
{
success: boolean;
terminal_ready: boolean; // true if all components present
checks: {
mt5_dir_exists: boolean;
terminal64_exe: boolean;
metaeditor64_exe: boolean;
metatester64_exe: boolean;
wine_executable: boolean;
wine_path: string | null;
};
mt5_version: string | null;
current_account: {
login: string;
server: string;
} | null;
hint: string;
}
```
---
## `get_backtest_history`
List all backtests previously run for a specific EA and/or symbol with summary metrics. Use for tracking performance over time.
### Input schema
```typescript
{
expert?: string; // Filter by EA name
symbol?: string; // Filter by symbol
limit?: number; // Max results (default: 10)
}
```
### Output schema
```typescript
{
success: boolean;
count: number;
total: number;
filters: {
expert: string | null;
symbol: string | null;
};
history: Array<{
report_dir: string;
date: string | null;
expert: string | null;
symbol: string | null;
period: string | null;
profit: number | null;
profit_factor: number | null;
expected_payoff: number | null;
drawdown_pct: number | null;
total_trades: number | null;
win_rate: number | null;
}>;
hint: string;
}
```
---
## `compare_backtests`
Compare two or more backtest results side-by-side with key metrics analysis. Includes profit/drawdown differences and verdict on which performed better.
### Input schema
```typescript
{
report_dirs: string[]; // List of report directory paths to compare
}
```
### Output schema
```typescript
{
success: boolean;
count: number;
comparisons: Array<{
report_dir: string;
expert: string | null;
symbol: string | null;
net_profit: number | null;
profit_factor: number | null;
drawdown_pct: number | null;
total_trades: number | null;
win_rate: number | null;
expected_payoff: number | null;
recovery_factor: number | null;
sharpe_ratio: number | null;
}>;
analysis: Array<{
compare_to: string | null;
report: string | null;
profit_diff: number;
profit_pct_change: number;
drawdown_diff: number;
profit_factor_diff: number;
verdict: "better" | "worse" | "mixed";
}> | null;
verdict: string | null; // "Best: <report_dir>"
}
```
---
## `init_project`
Create a new MQL5 project with standard directory structure and template files. Supports scalper, swing, grid, and basic templates.
### Input schema
```typescript
{
name: string; // Project name (used for EA filename)
template?: "scalper" | "swing" | "grid" | "basic"; // Default: "basic"
}
```
### Output schema
```typescript
{
success: boolean;
project_name: string;
template: string;
created_files: string[]; // Paths to created files
hint: string;
}
```
---
## `validate_ea_syntax`
Perform pre-compile syntax check on MQL5 source file without running full compilation. Detects common issues before expensive MetaEditor compilation.
### Input schema
```typescript
{
path: string; // Path to .mq5 source file
}
```
### Output schema
```typescript
{
success: boolean;
valid: boolean;
path: string;
checks: {
has_on_init: boolean;
has_on_tick: boolean;
has_on_deinit: boolean;
lines: number;
};
errors: Array<{
line: number;
message: string;
severity: "error";
}> | null;
warnings: Array<{
line: number;
message: string;
severity: "warning";
}> | null;
hint: string;
}
```
---
## `create_set_template`
Generate a .set parameter file template based on an EA's input variables. Automatically parses input declarations from source code.
### Input schema
```typescript
{
ea: string; // EA name or path to .mq5/.ex5 file
output_path?: string; // Optional custom output path
}
```
### Output schema
```typescript
{
success: boolean;
ea: string;
inputs_found: number;
inputs: Array<{
name: string;
type: string;
default: string;
description: string | null;
}>;
set_file: string; // Path to generated file
hint: string;
}
```
---
## `export_report`
Export backtest report to various formats (CSV, JSON, Markdown) for external analysis or sharing.
### Input schema
```typescript
{
report_dir: string; // Path to backtest report directory
format?: "csv" | "json" | "md"; // Default: "csv"
output_path?: string; // Optional custom output file path
}
```
### Output schema
```typescript
{
success: boolean;
format: string;
output_file: string;
source: string;
hint: string;
}
```
---
## `archive_report`
Convert a backtest report directory into a compact JSON entry appended to `config/backtest_history.json`. Idempotent — re-archiving the same report is a no-op. Optionally deletes the source directory to reclaim disk space.
@@ -1527,6 +1846,31 @@ clean_cache(symbol=XAUUSD, dry_run=true) → preview
clean_cache(symbol=XAUUSD) → execute
```
### Pre-flight validation
```
get_active_account() → current login, server, available symbols
check_symbol_data_status(symbol=XAUUSD, from=2025.01.01, to=2025.03.31)
→ verify data availability before backtest
check_mt5_status() → verify MT5 installation and readiness
validate_ea_syntax(path=MyEA.mq5) → pre-compile syntax check
```
### Project management
```
init_project(name=MyStrategy, template=scalper) → scaffold new EA with template
create_set_template(ea=MyEA) → generate .set from EA inputs
export_report(report_dir=..., format=csv) → export to CSV/JSON/Markdown
```
### History and comparison
```
get_backtest_history(expert=MyEA, limit=10) → list past backtests with metrics
compare_backtests(report_dirs=["dir1", "dir2"]) → side-by-side comparison
```
### Working with set files
```
+5 -4
View File
@@ -1,5 +1,5 @@
{
"$schema": "https://raw.githubusercontent.com/modelcontextprotocol/specification/main/schema/2024-11-05/schema.json",
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "io.github.masdevid/mt5-quant",
"title": "MT5-Quant",
"description": "MCP server for MT5 strategy development. Compile, backtest, analyze MQL5 EAs on macOS/Linux.",
@@ -7,12 +7,13 @@
"url": "https://github.com/masdevid/mt5-quant",
"source": "github"
},
"version": "1.27.0",
"version": "1.29.0",
"packages": [
{
"registryType": "mcpb",
"identifier": "https://github.com/masdevid/mt5-quant/releases/download/v1.27.0/mcp-mt5-quant-macos-arm64.tar.gz",
"fileSha256": "e4dd26f2fa920e22575c88546e4d0dc54ec34d51950f3c58bfdf3a3f10b8a9a4",
"version": "1.29.0",
"identifier": "https://github.com/masdevid/mt5-quant/releases/download/v1.29.0/mcp-mt5-quant-macos-arm64.tar.gz",
"fileSha256": "5d56099e01c6df0c16bc8aa28fffab2e3ba7502f283c3c8273b70e4192230f01",
"transport": {
"type": "stdio"
},
+16 -1
View File
@@ -40,8 +40,11 @@ pub struct McpRequest {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct McpResponse {
jsonrpc: String,
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
result: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
error: Option<McpError>,
}
@@ -49,6 +52,7 @@ pub struct McpResponse {
pub struct McpError {
code: i32,
message: String,
#[serde(skip_serializing_if = "Option::is_none")]
data: Option<Value>,
}
@@ -78,7 +82,9 @@ pub struct ToolCapabilities {
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt::init();
tracing_subscriber::fmt()
.with_writer(std::io::stderr)
.init();
let cli = Cli::parse();
@@ -111,6 +117,11 @@ async fn run_stdio_server() -> Result<()> {
let server_clone = server.clone();
match serde_json::from_str::<McpRequest>(line) {
Ok(request) => {
// Notifications have no id — don't send a response
if request.id.is_none() {
server_clone.handle_notification(request).await;
continue;
}
let response = server_clone.handle_request(request).await;
let response_json = serde_json::to_string(&response)?;
println!("{}", response_json);
@@ -180,6 +191,10 @@ async fn handle_connection(socket: tokio::net::TcpStream) -> Result<()> {
match serde_json::from_str::<McpRequest>(line) {
Ok(request) => {
if request.id.is_none() {
server.handle_notification(request).await;
continue;
}
let response = server.handle_request(request).await;
let response_json = serde_json::to_string(&response)? + "\n";
writer.write_all(response_json.as_bytes()).await?;
+14 -3
View File
@@ -99,6 +99,18 @@ impl McpServer {
}
}
/// Handle a notification (no id — no response sent)
pub async fn handle_notification(&self, request: McpRequest) {
match request.method.as_str() {
"notifications/initialized" => {
// Client confirms initialization is complete — no action needed
}
_ => {
tracing::debug!("Unhandled notification: {}", request.method);
}
}
}
pub async fn handle_request(&self, request: McpRequest) -> McpResponse {
match request.method.as_str() {
"initialize" => {
@@ -123,9 +135,8 @@ impl McpServer {
// Return immediately with fast status
let server_info = json!({
"name": "MT5-Quant",
"version": "1.27.0",
"version": env!("CARGO_PKG_VERSION"),
"setup": {
"verified": null, // null = checking
"hint": "Auto-verification running... Use verify_setup tool for detailed status",
}
});
@@ -164,7 +175,7 @@ impl McpServer {
McpResponse {
jsonrpc: "2.0".to_string(),
id: request.id,
result: Some(crate::tools::get_tools_list()),
result: Some(json!({"tools": crate::tools::get_tools_list()})),
error: None,
}
}