Skip to content

MCP integration with LLMs

Give Claude / GPT / Cursor / Continue and other MCP-capable LLM clients access to 19 Futu tools (quote + account + trade).

Two transport modes

  • LLM client launches futu-mcp as a child process.
  • stdin/stdout carry the protocol frames.
  • One LLM client = one futu-mcp process (exclusive).
  • Simplest; most LLM clients default to this.
  • futu-mcp runs as a standalone service listening on a port.
  • Multiple LLM clients connect to the same server.
  • Each request can carry its own Authorization: Bearer <token> (v1.1+); audit / limits tracked independently per token.
  • Suitable for team-shared + multi-tenant scenarios.

1. Prerequisite: a trade:simulate key

First, follow API Key setup to generate one:

./futucli gen-key \
  --id claude-bot \
  --scopes qot:read,acc:read,trade:simulate \
  --allowed-markets HK,US \
  --max-order-value 50000 \
  --max-orders-per-minute 3

Save the plaintext (fc_xxxx...).

2. stdio mode — Claude Desktop

Edit Claude Desktop config (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):

claude_desktop_config.json
{
  "mcpServers": {
    "futu": {
      "command": "/usr/local/bin/futu-mcp",
      "args": [
        "--gateway", "127.0.0.1:11111",
        "--keys-file", "/home/you/.config/futu/keys.json"
      ],
      "env": {
        "FUTU_MCP_API_KEY": "fc_8a3f2b9c1e5d7a4b8c2f9e1d3a5b7c9f"
      }
    }
  }
}

Restart Claude Desktop; open a new chat — the bottom-left will show a "futu" tool icon. Try asking:

"Show me the latest quotes for Tencent and Apple."

Claude will call futu_get_quote / futu_get_snapshot and synthesize the answer.

3. stdio mode — Cursor / VS Code Continue

Cursor: edit ~/.cursor/mcp.json:

{
  "mcpServers": {
    "futu": {
      "command": "futu-mcp",
      "args": ["--gateway", "127.0.0.1:11111", "--keys-file", "/path/to/keys.json"],
      "env": { "FUTU_MCP_API_KEY": "fc_xxxx..." }
    }
  }
}

Continue: add the same entry to experimental.modelContextProtocolServers in ~/.continue/config.json.

4. HTTP mode (multi-LLM shared)

# start an HTTP MCP server on the host
./futu-mcp --gateway 127.0.0.1:11111 \
           --keys-file /etc/futu/keys.json \
           --http-listen 0.0.0.0:38765 \
           --audit-log /var/log/futu-mcp-audit.jsonl

Client config points at the HTTP endpoint (format depends on the client):

{
  "mcpServers": {
    "futu": {
      "type": "http",
      "url": "http://<server>:38765/mcp",
      "headers": {
        "Authorization": "Bearer fc_bot_a_xxxx..."
      }
    }
  }
}

Multi-tenant: each LLM client carries its own Bearer token → audit / limits tracked by that key.

  • Bot A: Authorization: Bearer fc_bot_a_xxx → uses bot_a's scope / limits
  • Bot B: Authorization: Bearer fc_bot_b_xxx → uses bot_b's
  • /metrics: curl http://<server>:38765/metrics (no token needed)

5. Tool inventory

See the full 19 tools in the MCP guide →

Summary:

Category Tools Scope
Quote futu_get_quote / futu_get_kline / futu_get_orderbook / futu_get_ticker / futu_get_rt / futu_get_snapshot / futu_get_static / futu_get_broker / futu_ping qot:read
Plate futu_list_plates / futu_plate_stocks qot:read
Account futu_list_accounts / futu_get_funds / futu_get_positions / futu_get_orders / futu_get_deals acc:read
Trade futu_place_order / futu_modify_order / futu_cancel_order trade:real or trade:simulate

6. Security notes

  • Start with trade:simulate for a week before moving to trade:real.
  • Enable audit + tight limits: --max-order-value 10000 --max-daily-value 50000 --max-orders-per-minute 3.
  • Do not give unlock_trade to the LLM: unlock trading via futucli unlock-trade manually — password never flows through the LLM.
  • Always configure --audit-log: every trading action from the LLM is recorded in JSONL for forensic review.

Troubleshooting

Symptom Likely cause
Claude doesn't see the tools Config JSON syntax error / binary path wrong / keys.json not readable
"missing scope" on tool call The key doesn't carry that scope; futucli list-keys to verify
"limit check failed: rate limit" Rate cap exceeded; wait 60 s or bump --max-orders-per-minute
HTTP mode 401 Bearer header missing or token wrong
"gateway not connected" futu-opend not running, or --gateway address wrong

Next