Skip to main content
Glama
dearvn

tradebox-mcp

by dearvn

tradebox-mcp

A flight recorder + circuit breakers for AI trading agents.

Exchanges are starting to let AI agents trade — and they admit they cannot see what the agents are thinking. tradebox is a local proxy that sits between your LLM (Claude, Cursor, or any MCP host) and any broker MCP server. It records every tool call and the agent's reasoning, and it blocks any order that breaks your limits — before the order reaches the exchange.

  • Zero agent changes — point your MCP host at tradebox instead of the broker server; the agent sees the exact same tools.

  • Local-first — your API keys go straight into the broker child process. tradebox never parses, logs, or transmits them, and makes zero network calls of its own.

  • Deny ≠ crash — a blocked order comes back as a plain-language tool result the agent can read and adapt to, not a protocol error that sends it into a retry loop.


How it works

tradebox speaks MCP on both sides: it is a server to your host and a client to each broker server it spawns.

flowchart LR
    subgraph HOST["Your machine"]
        A["MCP host<br/>(Claude Desktop / Cursor)"]
        subgraph TB["tradebox-mcp"]
            G["Guardrail engine<br/>(allow / deny)"]
            R["Recorder<br/>(JSONL blackbox)"]
        end
        C["CCXT MCP server<br/>(child process)"]
        L[("~/.tradebox/logs/<br/>YYYY-MM-DD.jsonl")]
    end
    X["Exchange<br/>(Binance, …)"]

    A -- "stdio (JSON-RPC / MCP)" --> G
    G -- "allowed calls only" --> C
    G -.-> R
    R -.-> L
    C -- "HTTPS (your API keys<br/>never leave this hop)" --> X

Every tools/call goes through the same pipeline:

sequenceDiagram
    participant Agent as Agent (LLM)
    participant TB as tradebox
    participant Broker as CCXT MCP
    participant Ex as Exchange

    Note over Agent,Ex: ✅ order within limits
    Agent->>TB: createOrder BTC/USDT, $150
    TB->>TB: classify → trade.place<br/>guardrails → ALLOW
    TB->>Broker: forward
    Broker->>Ex: place order
    Ex-->>Broker: filled
    Broker-->>TB: result
    TB->>TB: log call + result (JSONL)
    TB-->>Agent: result

    Note over Agent,Ex: ⛔ order over the limit
    Agent->>TB: createOrder DOGE/USDT, $520
    TB->>TB: classify → trade.place<br/>guardrails → DENY (allowed_symbols)
    TB->>TB: log the denial
    TB-->>Agent: "Order denied: DOGE/USDT is not<br/>in allowed_symbols (BTC/USDT, ETH/USDT)."
    Note over Agent: agent reads the reason<br/>and adjusts — no crash loop

The order never reaches the broker process when a rule denies it — the deny happens one process before your API keys are even involved.


Related MCP server: SentinelGate

Quick start

1 — Create your config (keys stay on your machine; chmod 600 it):

mkdir -p ~/.tradebox
cp config.example.yaml ~/.tradebox/config.yaml
chmod 600 ~/.tradebox/config.yaml
# ~/.tradebox/config.yaml (minimal)
downstreams:
  ccxt:
    command: npx
    args: ["-y", "@lazydino/ccxt-mcp", "--config", "~/.tradebox/ccxt-accounts.json"]
    # ccxt-accounts.json holds your exchange keys (see config.example.yaml).
    # Use a read + trade key. NEVER enable withdrawals on it.

guardrails:
  allowed_symbols: ["BTC/USDT", "ETH/USDT"]
  max_order_notional: 200        # $ per single order
  max_orders_per_hour: 6
  max_daily_loss: 100            # trips the circuit breaker (UTC day)
  dry_run: true                  # ON by default — flip to false to go live

2 — Point your MCP host at tradebox instead of the broker server (claude_desktop_config.json or .cursor/mcp.json):

{
  "mcpServers": {
    "trading": {
      "command": "npx",
      "args": ["-y", "tradebox-mcp", "run", "--config", "~/.tradebox/config.yaml"]
    }
  }
}

3 — (Optional but recommended) add one line to your agent's system prompt so the blackbox records reasoning, not just actions:

Before every trading decision, call the log_reasoning tool with a short explanation of what you are about to do and why.

That's it. The agent sees ccxt__createOrder, ccxt__fetchTicker, … as usual. Nothing on the agent side changes.


Guardrails

Rule

Config key

What it does

Symbol whitelist

allowed_symbols

Deny any order outside your list

Order size cap

max_order_notional

Deny a single order over the cap (market orders are valued with a ticker price ≤ 60 s old — otherwise denied with "fetch the ticker first")

Rate limit

max_orders_per_hour

Runaway-loop breaker — the most common real failure mode of buggy agents (sliding 1-hour window)

Daily loss breaker

max_daily_loss

The main circuit breaker — see the diagram below

Trading hours

trading_hours

Only allow orders inside a UTC time window

Transfers

(built-in)

Denied by default. A trading agent has no business withdrawing funds. Opening it requires an explicit allow_transfers: true

Unknown tools

unknown_tools

A tool that no map recognizes and that looks mutating is denied, not assumed to be read-only

Panic button

tradebox stop

Instantly deny all trade tools, even while the agent is mid-run

The circuit breaker's life cycle

stateDiagram-v2
    [*] --> Trading
    Trading --> Locked : realized daily PnL ≤ −max_daily_loss
    Trading --> Locked : operator runs "tradebox stop"
    Locked --> Trading : operator runs "tradebox resume"
    Locked --> Locked : every trade.* call → denied<br/>(reads still pass through)

    note right of Locked
        The lock survives restarts —
        state is a projection of the log,
        so a crash never resets the breaker.
    end note

Dry-run: audit your agent before you give it money

dry_run: true (the default) blocks every trade at the proxy, logs it as if it were real, and returns a simulated fill. tradebox keeps a fake order book so the simulation stays coherent: cancelling or fetching a simulated order id gets a consistent answer, and every simulated result is tagged "simulated": true. Run your agent for a week in dry-run, read the report, then flip the switch.


The blackbox

Every call — allowed or denied — is appended to ~/.tradebox/logs/YYYY-MM-DD.jsonl, one JSON event per line:

{"ts":"2026-08-25T12:00:00.123Z","event":"tool_call","server":"ccxt","tool":"createOrder","category":"trade.place","args":{"symbol":"BTC/USDT","side":"buy","type":"limit","amount":0.02,"price":58900},"decision":"allow","latency_ms":840,"result":{"order_id":"123","filled":0.02,"avg_price":58895}}
{"ts":"2026-08-25T12:05:01.000Z","event":"tool_call","server":"ccxt","tool":"createOrder","category":"trade.place","args":{"symbol":"DOGE/USDT","side":"buy","amount":50000},"decision":"deny","rule":"allowed_symbols","latency_ms":2}
{"ts":"2026-08-25T12:05:04.500Z","event":"reasoning","text":"DOGE blocked. Holding BTC, waiting for the 58K retest."}
{"ts":"2026-08-25T13:00:00.000Z","event":"guardrail_trip","rule":"max_daily_loss","value":-102.5,"limit":-100,"action":"trading_locked"}

Secrets never enter the log: downstream env blocks are never seen by the recorder, and any field named like key|secret|token|password is redacted.

Drift report — is your agent still the agent you tested?

$ tradebox report --window 7d

AGENT BEHAVIOR REPORT              2026-08-18 → 2026-08-25
──────────────────────────────────────────────────────────
                      baseline (7d)    last 24h        Δ
orders/day                  4.2            11        ×2.6  ⚠
avg order notional        $145           $410        ×2.8  ⚠
symbols traded        BTC 82% · ETH 18%  +SOL 37%          ⚠ new symbol
avg hold time             3.1 h          22 min      ÷8.5  ⚠
denied calls                 0             7    max_order_notional ×5
realized PnL              +$83           −$61
──────────────────────────────────────────────────────────
⚠ BEHAVIORAL DRIFT: the agent is behaving differently than
  it did 7 days ago. Model update? Prompt change? Check
  before it costs you.

Offline, reads local JSONL only, no network.


CLI

tradebox run --config <path>    start the proxy (spawned by your MCP host)
tradebox report [--window 7d]   behavior + drift report from local logs
tradebox stop                   PANIC — deny all trading immediately
tradebox resume                 clear the panic / daily-loss lock

Honest limitations (v0.1)

We would rather list these than have you find them with real money:

  1. stdio downstreams only (CCXT MCP and equivalents). HTTP transport for Binance Agent OS / Robinhood MCP is the top roadmap item.

  2. The daily-loss breaker sees fills through the proxy. Fills are parsed from order results and from the agent's own fetch_my_trades / fetch_closed_orders calls. An agent that never fetches its fills leaves the breaker blind.

  3. Position tracking is an estimate built from orders passing through the proxy — no exchange balance reconciliation yet.

  4. Dry-run fills are simulated instantly. Real balance/position reads pass through unchanged and will not reflect simulated trades (every simulated result carries "simulated": true).

  5. All day boundaries are UTC. One proxy instance at a time.


Contributing a rule

One file, one interface — PRs welcome:

export interface GuardrailRule {
  name: string;
  // return null to pass; return a string to deny (the reason is sent to the LLM)
  check(call: ClassifiedToolCall, state: SessionState, cfg: Config): string | null;
}

Drop it in src/guardrails/rules/, register it in engine.ts, add a test. See docs/DESIGN.md for the architecture decisions and their reasons.

Roadmap

  1. HTTP transport proxy → Binance Agent OS, Robinhood MCP

  2. Position limits reconciled against exchange balances

  3. Hosted dashboard + real-time alerts — the local proxy and report stay free and MIT-licensed forever

License

MIT

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    A transparent proxy and execution firewall that intercepts and audits AI agent tool calls against configurable security policies before forwarding them to downstream MCP servers. It provides safe execution environments with features like data redaction, anti-loop protection, and unified alert dispatching.
  • A
    license
    Not graded
    quality
    A
    maintenance
    Open-source MCP proxy that enforces security policies, content scanning, and audit logging between AI agents and tool servers
    25
    AGPL 3.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Security gateway for MCP tool calls. Sits between your LLM client and MCP servers, enforcing per-tool policies (allow/block/approve/read-only), logging every call, and pausing dangerous operations for human approval in terminal or Slack.
    2
    1
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to operate a local financial terminal, including market data, backtesting, paper portfolio management, and news digest, through safe, gated tools over MCP.
    6
    MIT

View all related MCP servers

Related MCP Connectors

  • Security firewall for AI agents — scans MCP calls for injection, secrets, and risks.

  • MCP server for OpenMM — exposes market data, account, trading, and strategy tools to AI agents

  • MCP server exposing the Backtest360 engine API as tools for AI agents.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dearvn/tradebox-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server