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-mcpas a child process. - stdin/stdout carry the protocol frames.
- One LLM client = one
futu-mcpprocess (exclusive). - Simplest; most LLM clients default to this.
futu-mcpruns 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):
{
"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:simulatefor a week before moving totrade:real. - Enable audit + tight limits:
--max-order-value 10000 --max-daily-value 50000 --max-orders-per-minute 3. - Do not give
unlock_tradeto the LLM: unlock trading viafutucli unlock-trademanually — 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 |