The architecture, in one diagram

The full stack has five layers. Skipping any of them produces a brittle system.

LayerComponentResponsibility
1TradingView alertFire JSON webhook on a Pine condition
2MCP server (HTTP)Receive webhook, expose tools to Claude
3Claude (or another MCP client)Read alert + context, decide
4Exchange / wallet adapterExecute the decision via scoped credentials
5Audit logRecord decision, reasoning, outcome

Step 1: The TradingView webhook

In TradingView, every alert can fire a webhook with a JSON body. The Pine Script alert message field becomes the body verbatim, so the cleanest pattern is to emit structured JSON from Pine.

Pine alert template (Pro+ tier needed for webhook):

{"symbol":"{{ticker}}","price":{{close}},"side":"{{strategy.order.action}}","ts":"{{time}}","reason":"breakout_confirmed"}

Set the webhook URL to your MCP server's /alert endpoint. TradingView fires synchronously; expect 1–5 second latency between condition trigger and webhook receipt.

Step 2: The MCP server

The MCP server has two surfaces. An HTTP endpoint to receive TradingView webhooks, and an MCP tool surface for Claude to call when deciding.

Minimal Python skeleton (FastAPI + mcp-server):

from fastapi import FastAPI; from mcp.server.fastmcp import FastMCP; app = FastAPI(); mcp = FastMCP("trading"); alerts = []

Register three tools on the MCP server: get_recent_alerts(symbol, n) returns the last N TradingView alerts for a symbol; get_market_context(symbol) fetches current price, funding, and recent on-chain flows; place_order(symbol, side, size_usd, max_slippage_bps) executes via the exchange adapter with hardcoded caps. Claude calls these tools after the webhook wakes it.

Step 3: Scoped exchange API keys

The structural rule: the agent must never have withdrawal permission. On Binance, Bybit, Kraken, and Hyperliquid, create an API key with trade-only scope. Withdrawals disabled at the exchange level; IP-allowlist the MCP server's static IP.

Store the key in a secrets manager: never in a config file checked into git, never in the prompt. The MCP server reads the key at startup; Claude never sees credentials.

Step 4: The policy layer

Between Claude's decision and the exchange call, insert a policy layer that enforces hard limits regardless of what the model says. Three rules minimum:

  • Per-trade size cap. Reject orders above a hardcoded USD amount.
  • Per-symbol position cap. Reject if the resulting position would exceed a hardcoded notional.
  • Per-minute throughput cap. Reject if more than N orders have been placed in the trailing 60 seconds (catches a runaway agent).

The policy layer lives in the MCP server, not in the Claude prompt. Models obey prompt rules 99% of the time. The 1% is what bankrupts you.

Step 5: The audit log

Log every webhook, every Claude tool call, every exchange response, and every policy rejection. Structured JSON in append-only storage. The audit log is what lets you debug a bad trade, prove a regulatory inquiry, and improve the agent's prompts over time.

At minimum: alert payload, the reasoning Claude returned, the tool call sequence, the policy decision, the exchange response, and the realised PnL when the position closes. Without this, you cannot tell whether the agent is good or lucky.

A worked example

End-to-end flow for a single signal:

  1. Pine condition fires: 20-period breakout confirmed on BTC/USDT 1h.
  2. TradingView posts {"symbol":"BTCUSDT","price":67250,"side":"buy","ts":"...","reason":"breakout_confirmed"} to the MCP server's /alert endpoint.
  3. The MCP server appends the alert and triggers Claude via the MCP client (or Claude polls a queue).
  4. Claude calls get_market_context("BTCUSDT") and reads funding rate, current spread, recent news. Claude calls get_recent_alerts("BTCUSDT", 5) for context on the recent signal density.
  5. Claude decides: act, with a reasoning trace. It calls place_order("BTCUSDT", "buy", 1000, 10).
  6. The policy layer checks: size $1000 is under cap, position would be $1000 (under cap), throughput is 1/min (under cap). Passes.
  7. The exchange adapter places the order, returns the fill price and order ID.
  8. The audit log records the full chain.

Production checklist

  • API keys with withdrawals disabled and IP-allowlisted: verified at deploy and monthly.
  • Policy caps hardcoded in the MCP server, not just in the prompt.
  • Audit log writes to append-only storage (S3 with object lock, or equivalent).
  • Healthcheck endpoint on the MCP server, with TradingView's alert system pointed at a backup URL on failover.
  • Manual kill switch: a single endpoint that disables place_order instantly.
  • Per-strategy isolation: separate MCP server processes per strategy, with separate API keys, so one runaway agent cannot affect others.

Where this architecture breaks

Three known failure modes worth designing for:

  1. TradingView outage. Webhooks do not fire. The agent has no signal. Either accept the dependency or run a parallel signal source.
  2. Claude rate-limit or downtime. Tool calls fail mid-decision. Build idempotent retries and a fallback to a cheaper model.
  3. Exchange API change. Order placement returns a new error code. The policy layer should fail closed (reject the trade) rather than fail open.

None of these break the architecture conceptually: they just require ops discipline. The TradingView → Claude → exchange pipeline is robust once each layer assumes the others can fail.