Model Context Protocol server for QTSurfer — exposes backtesting and market data as AI-accessible tools over stdio JSON-RPC 2.0.
Run a backtesting workflow from any MCP-capable AI assistant: list exchanges, explore instruments, submit a strategy, and get full execution metrics — all without leaving the chat.
- Stdio transport — compatible with Claude Code, OpenAI Codex, and any MCP client.
- Native binary — ~17 ms startup, ~44 MB, no JVM required. Available for Linux, macOS, and Windows.
- Fat JAR fallback — single file, runs anywhere with JDK 21+.
- Docker —
docker run -ifor containerised deployments (eclipse-temurin:21-jre-alpine, ~230 MB). - Backed by
com.qtsurfer:sdk-java— compile → prepare → execute orchestration with retry and cancellation.
Pre-built binaries are attached to every GitHub Release:
| Platform | Asset |
|---|---|
| Linux x86_64 | qtsurfer-mcp-linux-amd64 |
| macOS arm64 (Apple Silicon) | qtsurfer-mcp-macos-arm64 |
| Windows x86_64 | qtsurfer-mcp-windows-amd64.exe |
Intel Mac users: use the fat JAR with JDK 21+.
# Linux
curl -Lo qtsurfer-mcp https://github.com/QTSurfer/mcp-java/releases/latest/download/qtsurfer-mcp-linux-amd64
chmod +x qtsurfer-mcp
# macOS Apple Silicon
curl -Lo qtsurfer-mcp https://github.com/QTSurfer/mcp-java/releases/latest/download/qtsurfer-mcp-macos-arm64
chmod +x qtsurfer-mcp
# Windows (PowerShell)
Invoke-WebRequest -Uri https://github.com/QTSurfer/mcp-java/releases/latest/download/qtsurfer-mcp-windows-amd64.exe `
-OutFile qtsurfer-mcp.exeRequires JDK 21+. Works on any platform.
curl -LO https://github.com/QTSurfer/mcp-java/releases/latest/download/qtsurfer-mcp-java-0.2.1.jar
java -jar qtsurfer-mcp-java-0.2.1.jar --helpdocker pull ghcr.io/qtsurfer/mcp-java:latest
# Run (MCP over stdio — pipe stdin/stdout)
docker run -i --rm -e QTS_TOKEN=<token> ghcr.io/qtsurfer/mcp-java:latestNative binary:
{
"mcpServers": {
"qtsurfer": {
"type": "stdio",
"command": "/path/to/qtsurfer-mcp",
"args": ["--url", "https://api.qtsurfer.com/v1"],
"env": { "QTS_TOKEN": "<your-api-token>" }
}
}
}Fat JAR:
{
"mcpServers": {
"qtsurfer": {
"type": "stdio",
"command": "java",
"args": ["-jar", "/path/to/qtsurfer-mcp-java-0.2.1.jar", "--url", "https://api.qtsurfer.com/v1"],
"env": { "QTS_TOKEN": "<your-api-token>" }
}
}
}Docker:
{
"mcpServers": {
"qtsurfer": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "QTS_TOKEN", "ghcr.io/qtsurfer/mcp-java:latest"]
}
}
}[mcp_servers.qtsurfer]
command = "/path/to/qtsurfer-mcp"
args = ["--url", "https://api.qtsurfer.com/v1"]
[mcp_servers.qtsurfer.env]
QTS_TOKEN = "<your-api-token>"Usage: qtsurfer-mcp [options] # native binary
java -jar qtsurfer-mcp-java.jar [options] # fat JAR
Options:
--url <base-url> API base URL (default: https://api.qtsurfer.com/v1)
Override with QTS_URL env var
--token <jwt> Bearer token (default: QTS_TOKEN env var)
--stub Use in-memory stub (no backend required)
--help Print this message and exit
MCP transport: stdio (stdin/stdout JSON-RPC 2.0)
| Tool | Description |
|---|---|
list_exchanges |
List available exchanges (e.g. binance, binancefutures) |
list_instruments |
List instruments for an exchange with data-availability windows and market info |
submit_backtest |
Compile a Java strategy and submit a backtesting run; returns a job ID |
get_job_status |
Get status and full execution metrics for a submitted job |
list_jobs |
List jobs from the current session, optionally filtered by status |
> list_exchanges
Available exchanges:
- binance: Binance — Binance spot exchange
- binancefutures: Binance Futures — Binance perpetual futures exchange
> list_instruments exchangeId=binance
Instruments on binance (142 total):
- BTC/USDT (last: 84250.50) data: 2026-03-17 → 2026-05-17
- ETH/USDT (last: 3120.75) data: 2026-03-17 → 2026-05-17
...
> submit_backtest exchangeId=binance instrument=BTC/USDT from=2026-05-10 to=2026-05-16 strategyCode=<...>
Backtest submitted. Job ID: abc123
Use get_job_status with jobId="abc123" to poll results.
> get_job_status jobId=abc123
Job abc123: COMPLETED
Exchange: binance | Instrument: BTC/USDT
=== Results ===
P&L: +42.7500
Trades: 156 (win rate: 58.3%)
Sharpe: 1.245 | Sortino: 1.872
CAGR: 15.34%
Max Drawdown: 8.75%
Signals: 100000
Strategies are written in Java and extend AbstractTickerStrategy. The MCP server compiles them server-side — no local Java compiler required.
import com.wualabs.qtsurfer.engine.strategy.AbstractTickerStrategy;
// ... see SDK docs for the full strategy API
public class MyStrategy extends AbstractTickerStrategy {
@Override
protected void setupIndicators(InstrumentGroupRTIndicator indicators) {
// define indicators and trade logic here
}
}For help writing strategies — indicators, window listeners, state management, examples, and advanced patterns — install the QTSurfer Strategy Skills:
npx skills add QTSurfer/strategy-skillsgit clone https://github.com/QTSurfer/mcp-java.git
cd mcp-java
# Fat JAR
mvn package -DskipTests # → target/mcp-*.jar
# Unit + integration tests
mvn verify
# Native binary (requires GraalVM 21+)
mvn -Pnative -DskipTests package native:compile-no-fork # → target/qtsurfer-mcp
# Native via Docker (Linux x86_64, no local GraalVM needed)
docker build --platform linux/amd64 -f Dockerfile.native -t qtsurfer/mcp-native .
docker cp $(docker create qtsurfer/mcp-native):/app/qtsurfer-mcp ./qtsurfer-mcpRequires JDK 21+ (GraalVM for native) and Maven 3.8+.
Apache-2.0 — see LICENSE.