Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/theonetrade/ai-trading-mcp/llms.txt

Use this file to discover all available pages before exploring further.

The AI Trading MCP rig runs as two separate OS processes that communicate over a local HTTP bridge. The stdio MCP server (npx @backtest-kit/mcp) sits in the agent’s world and holds no trading state whatsoever — every tool call is an HTTP request forwarded to the trading process (@backtest-kit/cli), which owns the engine, the broker, and all live state. This split is intentional: the agent’s attack surface is three verbs; everything consequential lives behind the bridge.

Two Processes, One Contract

stdio MCP server

Spawned by Claude Code via mcp.servers.json as npx @backtest-kit/mcp. Translates JSON-RPC tool calls into HTTP requests toward 127.0.0.1:60051. Holds no positions, no prices, no session.

Trading process

Started by npm start -- --paper or --live. Owns the backtest-kit engine, broker adapter, GramJS Telegram client, and the MCP HTTP bridge. All state lives here.
The contract between the two processes is an HTTP envelope:
{ "error": "" }          // success — empty string
{ "error": "engine message" }  // failure — exact engine message
Transport success (HTTP 200) is not operation success. An HTTP 200 with a non-empty error field means the engine rejected the call — a symbol not in the whitelist, a duplicate open, nothing to close. That error string is relayed to the agent verbatim as an isError: true tool result, so the model can read and react to it without any prompt-engineering shim.

Process Roles

Responsibilitystdio MCP serverTrading process
JSON-RPC ↔ Claude
HTTP forwarding to bridge
Trading state (positions, signals)
Engine (TP/SL, validation, risk)
Broker (paper fills / Binance spot)
GramJS Telegram scraper
Audit trail (dump/)
get_status renderer
The stdio server is stateless by construction — it can crash and restart without losing a single open position or pending signal.

The MCP HTTP Bridge

config/setup.config.ts calls serve() from @backtest-kit/mcp as the last statement after wiring all persistence backends:
import { serve } from '@backtest-kit/mcp';

// ... persistence configuration ...

serve();
The bridge listens on 127.0.0.1:60051 by default. Both the host and port are configurable:
VariableDefaultPurpose
CC_MCP_HOST127.0.0.1Bind address for the HTTP bridge
CC_MCP_PORT60051Port for the HTTP bridge
The stdio server (mcp.servers.json) is wired to Claude Code with no extra configuration needed:
{
  "mcpServers": {
    "backtest-kit-mcp": {
      "command": "npx",
      "args": ["-y", "@backtest-kit/mcp@latest"]
    }
  }
}
The dashboard UI runs on port :60050. The MCP bridge runs on :60051. Both are local-only — neither is exposed to the network in the default configuration.

Persistence and Restart Safety

config/setup.config.ts configures live backends with .usePersist() and backtest counterparts with in-memory or local backends:
BackendLive modeBacktest mode
StorageusePersist() — diskuseMemory()
RecentusePersist() — diskuseMemory()
NotificationusePersist() — diskuseMemory()
MemoryusePersist() — diskuseLocal()
StateusePersist() — diskuseLocal()
SessionusePersist() — diskuseLocal()
DumpuseMarkdown()useMarkdown()
MarkdownuseDummy()useDummy()
LoguseJsonl()useJsonl()
Everything written under dump/data/ (signals, storage, notifications, recent, memory, state, sessions) survives a process restart. Restart the trading process and the open position, its TP/SL brackets, and its full history are exactly where they were. The paper trail — every get_status response ever sent to the model — is in dump/mcp/ and dump/images/.
Engine event streams write into dump/report/*.jsonl for live, performance, max_drawdown, and highest_profit. The web UI on :60050 ships a built-in dump viewer that renders these alongside the markdown audit trail.

Architecture Diagram

The flow from Telegram through both processes to Claude:
┌─────────────────────────────────────────────────────────────────┐
│  Telegram channel — posts + chart screenshots                    │
└───────────────────────────────┬─────────────────────────────────┘
                                │ GramJS (QR-authorized user session)

┌─────────────────────────────────────────────────────────────────┐
│  Trading process  (@backtest-kit/cli)                            │
│                                                                  │
│   ┌──────────────────────────────────┐                          │
│   │  manual_mcp — get_status renderer│                          │
│   │  portfolio + last 15 posts       │                          │
│   │  (text + image blocks)           │◄── GramJS scraper        │
│   └──────────────────────────────────┘                          │
│                                                                  │
│   ┌───────────────────────────────┐                             │
│   │  engine — candles, signals,   │                             │
│   │  TP/SL, risk, validation,     │                             │
│   │  persistence                  │                             │
│   └───────────────────────────────┘                             │
│                                                                  │
│   ┌───────────────────────────────┐                             │
│   │  broker — paper fills or      │────► Binance spot (ccxt)   │
│   │  Binance spot execution       │                             │
│   └───────────────────────────────┘                             │
│                                                                  │
│   ┌───────────────────────────────┐                             │
│   │  HTTP bridge  127.0.0.1:60051 │                             │
│   │  serve() from @backtest-kit/  │                             │
│   │  mcp                          │                             │
│   └───────────────┬───────────────┘                             │
└───────────────────│─────────────────────────────────────────────┘
                    │ HTTP envelope { error: "" | "engine message" }

┌─────────────────────────────────────────────────────────────────┐
│  stdio MCP server  (npx @backtest-kit/mcp)                       │
│  holds no trading state — translates JSON-RPC ↔ HTTP            │
└───────────────────────────────┬─────────────────────────────────┘
                                │ stdio JSON-RPC

┌─────────────────────────────────────────────────────────────────┐
│  Claude Code — mcp.servers.json                                  │
└─────────────────────────────────────────────────────────────────┘
The error field in the HTTP envelope is either an empty string (success) or the exact message the engine produced. The stdio server relays it as an isError tool result — the model sees it as a first-class error it can reason about and act on.

Build docs developers (and LLMs) love