Skip to content

Trading Write

MCP tool overview

futu_place_order

  • Scope: trade:real
  • Python SDK equivalent: OpenTradeContext.place_order
  • Route: MCP JSON-RPC tools/call with name = "futu_place_order"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

⚠️ REAL MONEY when env=real. Place an order on a live brokerage account. REQUIRES futu-mcp started with --enable-trading; real env additionally requires --allow-real-trading; gateway must have been unlocked via futu_unlock_trade first. Market-session fields: US pre/post-market orders must pass the same FTAPI fields as C++ OpenD (fill_outside_rth=true and/or session: 1=RTH, 2=ETH, 3=ALL, 4=OVERNIGHT; optional time_in_force: 0=DAY, 1=GTC, 2=IOC, 3=GTD). The daemon validates market, environment, security type, and broker-specific order-type support locally before any backend write. FTAPI protocol order types 16-19 remain unsupported by ordinary PlaceOrder. Guarded MOC: order type MOC=20 is a versioned v1.8 local extension for real US common stock only and requires an exact current US-equity static-data record; it accepts no price/stop_price, requires a non-empty idempotency_key, and the futu-opend daemon must start with --enable-moc-order (default OFF). An ACK is recorded as pending until an authoritative backend order query correlates the order; cache-only reads never count, and ambiguous outcomes are never resent automatically. This path is source-aligned and fixture-tested but remains UNVERIFIED on an authorized real-money account. Backend still validates symbol, session, and account eligibility. Risk-confirmation errors: when the broker requires the account owner to confirm a risk disclosure first, the error text carries a fixed four-line block (订单尚未提交,需要先完成风险确认。/ 风险确认链接:/ the complete HTTPS URL alone on its own line / 请由账户本人打开并完成确认。完成后重新提交订单。). Relay that block and the link to the user VERBATIM (not in a code fence, never summarised as just "risk confirmation needed"), pause the order flow, never accept the agreement or retry on the user's behalf, and re-check authorization, quotes and buying power before placing the order again after the user confirms.

Request arguments:

Field Type Required Alias Description
market string ✅ — Trade market — accepts STRING (HK|US|CN|HKCC|FUTURES|SG|AU|JP|MY|CA) OR INT (1=HK, 2=US, 3=CN, 4=HKCC, 5=Futures, 6=SG, 8=AU, 15=JP, 111=MY, 112=CA per Trd_Common.TrdMarket).
acc_id u64? — — Trading account ID (u64). Either acc_id OR card_num is required. Call futu_list_accounts first to discover acc_id — gateway does NOT infer a default. Alternatively pass card_num (last 4 digits or full 16 digits shown in the app) and daemon resolves it via GetAccList.
card_num string? — — Card number shown by the app. Accepts 4-digit suffix (e.g. <card-suffix>, shown in the app as "Margin Composite Account (<card-suffix>)") OR 16-digit full (e.g. <full-card-num>). These are synthetic placeholders, not real account details. Daemon resolves via GetAccList → matched acc_id. Either acc_id OR card_num required; if both passed, daemon validates resolution matches acc_id (mismatch = 400 reject).
env string ✓ default default_env_simulate trd_env Trade environment: real|simulate. Defaults to simulate for safety. Alias: trd_env
side string ✅ trd_side Order side: BUY|SELL|SELL_SHORT|BUY_BACK. Alias: trd_side
order_type string ✓ default default_order_type — Order type — accepts STRING enum OR INT (Trd_Common.OrderType): NORMAL=1 (limit) | MARKET=2 | ABSOLUTE_LIMIT=5 | AUCTION=6 | AUCTION_LIMIT=7 | SPECIAL_LIMIT=8 | SPECIAL_LIMIT_ALL=9 | STOP=10 (stop market) | STOP_LIMIT=11 (stop limit) | MIT=12 (market if touched) | LIT=13 (limit if touched) | TRAILING_STOP=14 (trailing stop market) | TRAILING_STOP_LIMIT=15 (trailing stop limit) | TWAP_MARKET=16 | TWAP_LIMIT=17 | VWAP_MARKET=18 | VWAP_LIMIT=19 | MOC=20 (market on close). Algorithm values are rejected by ordinary PlaceOrder; use the typed futu_place_algo_order/futu_modify_algo_order tools (daemon --enable-algo-orders, default OFF). MOC is limited to real US common stock, accepts no price/stop_price, requires idempotency_key, and the daemon must start with --enable-moc-order. Conditional orders require the appropriate stop_price / trail_type / trail_value / trail_spread fields.alias: LIMIT → NORMAL.
code string ✅ — Security code WITHOUT market prefix, e.g. 00700 / AAPL / 600519
qty float ✅ — Order quantity (shares / contracts)
price float? — — Limit price (required for NORMAL; optional for MARKET; forbidden for MOC)
amount float? — — Event Contract cash amount. Only valid for market=PREDICTION; the gateway derives effective quantity and rejects this field on non-Prediction markets.
pred_side i32? — predSide Event Contract prediction side: 1=Yes, 2=No. Only valid for market=PREDICTION. Alias: predSide.
time_in_force i32? — timeInForce Optional order time-in-force: 0=DAY, 1=GTC, 2=IOC, 3=GTD. Alias: timeInForce.
fill_outside_rth boolean? — fillOutsideRTH US limit orders: allow pre-market / after-hours fills. Alias: fillOutsideRTH.
session i32? — — US order session: 0=NONE, 1=RTH, 2=ETH, 3=ALL, 4=OVERNIGHT.
expire_time string? — expireTime GTD expire date in YYYY-MM-DD, only used when time_in_force=3. Alias: expireTime.
jp_acc_type i32? — jpAccType JP sub-account type (Trd_Common.TrdSubAccType / TrdHeader.jpAccType). Required by JP account backend paths when no position_id/order_id path supplies the sub-account context. Alias: jpAccType.
api_key string? — — Optional per-call API key override (plaintext). When set, this key is used for authorization and usage limits instead of the process-wide FUTU_MCP_API_KEY. Useful for multi-tenant scenarios where different calls should be billed or scoped to different keys.
idempotency_key string? — — Optional for legacy order types, REQUIRED for MOC. Retries with the same key return the cached or durably reconciled result WITHOUT placing a duplicate order. Example: generate one UUID per logical order intent and reuse it for retries.
stop_price float? — — Stop / take-profit trigger price (aka aux_price). Required for STOP / STOP_LIMIT / MIT (market-if-touched) / LIT (limit-if-touched). For MIT/LIT it's the take-profit trigger.
trail_type i32? — — Trailing stop type: 1=Ratio (percentage) / 2=Amount (absolute value). Only for TRAILING_STOP / TRAILING_STOP_LIMIT order types.
trail_value float? — — Trailing stop value: trail percentage (if trail_type=1) or amount (if trail_type=2).
trail_spread float? — — Trailing stop limit price spread for TRAILING_STOP_LIMIT (limit offset from trigger).

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

Runtime validation: this request type has a validate() method that adds runtime required-field / enum-value validation on top of the JSON schema.

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_place_order",
    "arguments": {
      "market": "HK",
      "acc_id": 123456,
      "env": "simulate",
      "side": "BUY",
      "order_type": "NORMAL",
      "code": "00700",
      "qty": 100,
      "api_key": "optional-per-call-api-key",
      "idempotency_key": "uuid-v4-here"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_modify_order

  • Scope: trade:real
  • Python SDK equivalent: OpenTradeContext.modify_order
  • Route: MCP JSON-RPC tools/call with name = "futu_modify_order"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

⚠️ REAL MONEY when env=real. Modify an existing live order (change qty/price, cancel, disable/enable/delete). REQUIRES --enable-trading; real env needs --allow-real-trading. For simple cancel, prefer futu_cancel_order. Market hours requirement: same as futu_place_order — off-hours hit server-side refusal regardless of op.

Request arguments:

Field Type Required Alias Description
market string ✅ — Trade market — accepts STRING (HK|US|CN|HKCC|FUTURES|SG|AU|JP|MY|CA) OR INT (1=HK, 2=US, 3=CN, 4=HKCC, 5=Futures, 6=SG, 8=AU, 15=JP, 111=MY, 112=CA per Trd_Common.TrdMarket).
acc_id u64? — — Trading account ID (u64). Either acc_id OR card_num is required; alternatively pass card_num.
card_num string? — — Card number (4-digit suffix or 16-digit full). See PlaceOrderReq.card_num for semantics.
env string ✓ default default_env_simulate trd_env Trade environment: real|simulate (default simulate); alias: trd_env
order_id string ✅ — Order ID to modify. Accepts numeric orderID (integer or integer string) OR backend orderIDEx string such as FU.../FH...; string recommended for JS clients since u64 > 2^53 loses precision as JSON number.
op string ✓ default default_modify_op — Modify op: NORMAL (change qty/price) | CANCEL | DISABLE | ENABLE | DELETE
qty float? — — New quantity (for NORMAL op)
price float? — — New price (for NORMAL op)
jp_acc_type i32? — jpAccType JP sub-account type (Trd_Common.TrdSubAccType / TrdHeader.jpAccType). Alias: jpAccType.
api_key string? — — Optional per-call API key override. See PlaceOrderReq.api_key.
idempotency_key string? — — Optional idempotency key (90s TTL). See PlaceOrderReq.idempotency_key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

Runtime validation: this request type has a validate() method that adds runtime required-field / enum-value validation on top of the JSON schema.

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_modify_order",
    "arguments": {
      "market": "HK",
      "acc_id": 123456,
      "env": "simulate",
      "order_id": "123456789",
      "op": "NORMAL",
      "api_key": "optional-per-call-api-key",
      "idempotency_key": "uuid-v4-here"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_unlock_trade

  • Scope: trade:unlock
  • Python SDK equivalent: OpenTradeContext.unlock_trade
  • Route: MCP JSON-RPC tools/call with name = "futu_unlock_trade"

Description:

⚠️ Opens a trade window for subsequent futu_place_order / futu_modify_order / futu_cancel_order / futu_reconfirm_order calls. NEVER pass the password via tool args: configure FUTU_TRADE_PWD (trimmed) or, on Linux / Windows, an account-scoped OS credential-store entry selected by futu-mcp --trade-pwd-account <login-account>; packaged macOS builds do not support cross-binary Keychain writers. Compatibility credential-store reads have a 3-second safety boundary. Requires trade:unlock scope. Lifetime: once unlocked, all subsequent trade calls succeed without re-authenticating until gateway restart or an explicit unlock=false lock-back. Do NOT call this on every trade (server-side anti-abuse may throttle).

Request arguments:

Field Type Required Alias Description
unlock boolean ✓ default default_true — true to unlock trading (default); false to lock trading cipher back (defensive). Lock does not require a password.
otp string? — token, one_time_password OTP / 2FA token (plaintext). Only required when a previous unlock call returned need_otp=true or err_code=-8 (TRADE_AUTH_NEED_AUTH_TOKEN). Leave empty for accounts without 2FA. Alias: token / one_time_password
security_firm i32? — broker, security_firm_id Optional. Restrict unlock to a single security firm (broker). SecurityFirm enum (i32): 1=FutuHK, 2=FutuUS/MooMoo, 3=FutuSG, 4=FutuAU, 5=FutuCA, 6=FutuMY, 7=FutuJP. If omitted, unlocks all brokers in parallel (backward-compatible default). Alias: broker / security_firm_id
acc_ids array of u64? — account_ids, accounts Optional. Array of positive non-zero u64 acc_ids to unlock (empty / omitted = no per-account filter, use security_firm rule or unlock all). Intersects with security_firm: account must satisfy BOTH. Use when you need to exclude a shadow sub-account that shares a broker with the main account — pass only the main acc_id here. Alias: account_ids / accounts

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_unlock_trade",
    "arguments": {
      "unlock": true,
      "acc_ids": [
        123456
      ]
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_reconfirm_order

  • Scope: trade:real
  • Python SDK equivalent: OpenTradeContext.reconfirm_order
  • Route: MCP JSON-RPC tools/call with name = "futu_reconfirm_order"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

⚠️ REAL MONEY when env=real. Reconfirm a pending high-risk or price-warning order by numeric order_id. REQUIRES --enable-trading; real env needs --allow-real-trading; gateway must have been unlocked via futu_unlock_trade first. Use only for orders that the backend explicitly asked to reconfirm.

Request arguments:

Field Type Required Alias Description
market string ✅ — Trade market — accepts STRING (HK|US|CN|HKCC|FUTURES|SG|AU|JP|MY|CA) OR INT (1=HK, 2=US, 3=CN, 4=HKCC, 5=Futures, 6=SG, 8=AU, 15=JP, 111=MY, 112=CA per Trd_Common.TrdMarket).
acc_id u64? — — Trading account ID (u64). Either acc_id OR card_num is required.
card_num string? — — Card number (4-digit suffix or 16-digit full). Either acc_id OR card_num is required.
env string ✓ default default_env_simulate trd_env Trade environment: real|simulate (default simulate); alias: trd_env
order_id string ✅ — FTAPI numeric order_id to reconfirm. Accepts JSON number or integer string; orderIDEx strings are not supported by Trd_ReconfirmOrder.
reason i32 ✅ — Reconfirm reason int per Trd_Common.ReconfirmOrderReason.
jp_acc_type i32? — jpAccType JP sub-account type (Trd_Common.TrdSubAccType / TrdHeader.jpAccType). Alias: jpAccType.
api_key string? — — Optional per-call API key override. See PlaceOrderReq.api_key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_reconfirm_order",
    "arguments": {
      "market": "HK",
      "acc_id": 123456,
      "env": "simulate",
      "order_id": "123456789",
      "reason": 0,
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_sub_acc_push

  • Scope: acc:read
  • Python SDK equivalent: OpenTradeContext.subscribe_acc_push (internal to Futu daemon)
  • Route: MCP JSON-RPC tools/call with name = "futu_sub_acc_push"

Description:

Subscribe account order / deal push for given trading accounts. Legacy MCP clients receive LoggingMessage notifications with {kind, proto_id, body_base64}. MCP 2026-07-28 returns resource_uri: using a reusable HTTP Bearer or stdio startup key with acc:read, keep the same identity and call subscriptions/listen, receive notifications/resources/updated, then atomically drain events with resources/read; finish with futu_unsub_acc_push. Payload body is raw Futu protobuf; decode client-side. Python SDK: OpenTradeContext.sub_acc_push.

Request arguments:

Field Type Required Alias Description
acc_ids array of u64 ✅ account_ids, accounts Array of account IDs (u64) to receive order/deal push for. ⚠️ Call futu_list_accounts first to discover real acc_id values; do NOT hallucinate 18-digit numbers — invalid ids will silently fail to receive push. Alias: account_ids / accounts
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_sub_acc_push",
    "arguments": {
      "acc_ids": [
        123456
      ],
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_unsub_acc_push

  • Scope: acc:read
  • Python SDK equivalent: — (daemon-only session control)
  • Route: MCP JSON-RPC tools/call with name = "futu_unsub_acc_push"

Description:

Unsubscribe from account push notifications. Pass session_id from previous futu_sub_acc_push response (session_id field or unsub_hint). Returns {removed_count}. If session_id is not found, removed_count=0 (likely auto-purged or never registered).

Request arguments:

Field Type Required Alias Description
session_id string? — — Required: session_id returned by futu_sub_acc_push response (session_id field or unsub_hint). If omitted, handler returns an error. If session_id not found (e.g. 4h auto-purged), removed_count=0 is returned.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode use the same tool/startup key that created the subscription.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_unsub_acc_push",
    "arguments": {
      "session_id": "abc-session-xyz",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_cancel_all_order

  • Scope: trade:real
  • Python SDK equivalent: OpenTradeContext.cancel_all_order
  • Route: MCP JSON-RPC tools/call with name = "futu_cancel_all_order"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Cancel all pending orders for an account in a specific market. market is REQUIRED (HK / US / HKCC / A_SH / A_SZ / SG / JP / AU / CA). Python SDK: OpenTradeContext.cancel_all_order. REQUIRES --enable-trading. Real env requires --allow-real-trading. DANGER: unrecoverable — cancels every pending order in the specified market immediately.

Request arguments:

Field Type Required Alias Description
env string ✓ default default_env_simulate trd_env Trading env: simulate (default) / real; alias: trd_env
acc_id u64 ✅ — Trading account ID (u64). ⚠️ Call futu_list_accounts first to discover — gateway does NOT infer a default.
market string ✓ default default — Market (REQUIRED, NOT optional) — accepts STRING (HK|US|CN|HKCC|FUTURES|SG|AU|JP|MY|CA) OR INT (1=HK, 2=US, 3=CN, 4=HKCC, 5=Futures, 6=SG, 8=AU, 15=JP, 111=MY, 112=CA). Leaving empty returns a validation error — the backend needs a specific market to cancel orders in.
api_key string? — — Per-call API key override (optional)

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

Runtime validation: this request type has a validate() method that adds runtime required-field / enum-value validation on top of the JSON schema.

Runtime validation: market must be non-empty. The schema description marks this field as required, but serde accepts an omitted string as the empty default; this check returns a clear validation error before the request reaches the backend.

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_cancel_all_order",
    "arguments": {
      "env": "simulate",
      "acc_id": 123456,
      "market": "HK",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_cancel_order

  • Scope: trade:real
  • Python SDK equivalent: OpenTradeContext.modify_order(op=ModifyOrderOp.CANCEL)
  • Route: MCP JSON-RPC tools/call with name = "futu_cancel_order"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

⚠️ REAL MONEY when env=real. Cancel a live order by order_id. REQUIRES --enable-trading; real env needs --allow-real-trading. Convenience wrapper over futu_modify_order with op=CANCEL. Same market-hours requirement as futu_place_order.

Request arguments:

Field Type Required Alias Description
market string ✅ — Trade market — accepts STRING (HK|US|CN|HKCC|FUTURES|SG|AU|JP|MY|CA) OR INT (1=HK, 2=US, 3=CN, 4=HKCC, 5=Futures, 6=SG, 8=AU, 15=JP, 111=MY, 112=CA per Trd_Common.TrdMarket).
acc_id u64? — — Trading account ID (u64). Either acc_id OR card_num is required; alternatively pass card_num.
card_num string? — — Card number (4-digit suffix or 16-digit full). See PlaceOrderReq.card_num for semantics.
env string ✓ default default_env_simulate trd_env Trade environment: real|simulate (default simulate); alias: trd_env
order_id string ✅ — Order ID to cancel. Accepts numeric orderID (integer or integer string) OR backend orderIDEx string such as FU.../FH...; string recommended for JS clients since u64 > 2^53 loses precision as JSON number.
jp_acc_type i32? — jpAccType JP sub-account type (Trd_Common.TrdSubAccType / TrdHeader.jpAccType). Alias: jpAccType.
api_key string? — — Optional per-call API key override. See PlaceOrderReq.api_key.
idempotency_key string? — — Optional idempotency key (90s TTL). See PlaceOrderReq.idempotency_key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_cancel_order",
    "arguments": {
      "market": "HK",
      "acc_id": 123456,
      "env": "simulate",
      "order_id": "123456789",
      "api_key": "optional-per-call-api-key",
      "idempotency_key": "uuid-v4-here"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_place_combo_order

  • Scope: trade:real
  • Python SDK equivalent: OpenSecTradeContext.place_combo_order
  • Route: MCP JSON-RPC tools/call with name = "futu_place_combo_order"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

⚠️ REAL MONEY when header.trd_env=1. Place a combo-option order. REQUIRES --enable-trading; real env additionally requires --allow-real-trading. c2s_json must include header.acc_id, header.trd_env, header.trd_market, combo_legs, qty, and order_type.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official Trd_PlaceComboOrder.C2S JSON. Field names use generated proto serde snake_case. packet_id may be omitted; daemon fills it before forwarding.
api_key string? — — Optional per-call API key override. See PlaceOrderReq.api_key.
idempotency_key string? — — Optional idempotency key. When set, retries with the same key derive the same PacketId and hit daemon replay guard instead of placing a duplicate combo order.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_place_combo_order",
    "arguments": {
      "c2s_json": "…",
      "api_key": "optional-per-call-api-key",
      "idempotency_key": "uuid-v4-here"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_place_order_group

  • Scope: trade:real
  • Python SDK equivalent: —
  • Route: MCP JSON-RPC tools/call with name = "futu_place_order_group"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Place one guarded server-atomic Bracket, OCO, or Basket group. Requires --enable-group-orders; default OFF; live backend unverified.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official generated C2S JSON. Field names use generated proto serde snake_case, e.g. multi_legs / combo_legs / order_type.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_place_order_group",
    "arguments": {
      "c2s_json": "{\"header\":{\"trd_env\":1,\"acc_id\":900000001,\"trd_market\":2},\"initial\":{\"idempotency_key\":\"group-example-1\",\"group_type\":3,\"order_list\":[{\"acc_id\":900000001,\"client_order_id\":\"leg-1\",\"code\":\"AAPL\",\"sec_market\":2,\"trd_side\":1,\"order_type\":1,\"qty\":\"1\",\"price\":\"100\",\"lot_type\":2,\"children_relation\":0,\"brother_relation\":0}]},\"extension_version\":1}",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_modify_order_group

  • Scope: trade:real
  • Python SDK equivalent: —
  • Route: MCP JSON-RPC tools/call with name = "futu_modify_order_group"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Modify one authoritative current server order group. Requires --enable-group-orders; default OFF; live backend unverified.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official generated C2S JSON. Field names use generated proto serde snake_case, e.g. multi_legs / combo_legs / order_type.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_modify_order_group",
    "arguments": {
      "c2s_json": "{\"header\":{\"trd_env\":1,\"acc_id\":900000001,\"trd_market\":2},\"initial\":{\"idempotency_key\":\"group-modify-1\",\"group_type\":3,\"order_list\":[{\"order_id\":\"server-order-id\",\"order_version\":1,\"new_price\":\"101\"}]},\"extension_version\":1}",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_cancel_order_group

  • Scope: trade:real
  • Python SDK equivalent: —
  • Route: MCP JSON-RPC tools/call with name = "futu_cancel_order_group"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Cancel one authoritative current server order group. Requires --enable-group-orders; default OFF; live backend unverified.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official generated C2S JSON. Field names use generated proto serde snake_case, e.g. multi_legs / combo_legs / order_type.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_cancel_order_group",
    "arguments": {
      "c2s_json": "{\"header\":{\"trd_env\":1,\"acc_id\":900000001,\"trd_market\":2},\"initial\":{\"idempotency_key\":\"group-cancel-1\",\"group_type\":3,\"order_id_list\":[\"server-order-id\"]},\"extension_version\":1}",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_delete_order_group

  • Scope: trade:real
  • Python SDK equivalent: —
  • Route: MCP JSON-RPC tools/call with name = "futu_delete_order_group"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Delete one authoritative current server order group. Requires --enable-group-orders; default OFF; live backend unverified.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official generated C2S JSON. Field names use generated proto serde snake_case, e.g. multi_legs / combo_legs / order_type.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_delete_order_group",
    "arguments": {
      "c2s_json": "{\"header\":{\"trd_env\":1,\"acc_id\":900000001,\"trd_market\":2},\"initial\":{\"idempotency_key\":\"group-delete-1\",\"group_type\":3,\"order_id_list\":[\"server-order-id\"]},\"extension_version\":1}",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_place_algo_order

  • Scope: trade:real
  • Python SDK equivalent: —
  • Route: MCP JSON-RPC tools/call with name = "futu_place_algo_order"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Place a guarded typed TWAP/VWAP/POV/Slicer/Peg/Iceberg order only when the pinned product/price-mode/side/round-lot table, live capability cell, customer-company fact, and required BCAN facts all agree. Requires --enable-algo-orders; default OFF; live backend unverified.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official generated C2S JSON. Field names use generated proto serde snake_case, e.g. multi_legs / combo_legs / order_type.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_place_algo_order",
    "arguments": {
      "c2s_json": "{\"header\":{\"trd_env\":1,\"acc_id\":900000001,\"trd_market\":2},\"initial\":{\"idempotency_key\":\"algo-example-1\",\"client_order_id\":\"algo-client-1\",\"code\":\"AAPL\",\"sec_market\":2,\"trd_side\":1,\"qty\":\"100\",\"price_mode\":2,\"limit_price\":\"100\",\"lot_type\":2,\"order_trade_time_type\":1,\"position_open_type\":1,\"pdt_protection\":true,\"algo\":{\"algo_type\":2,\"start_time\":1788138000000000,\"end_time\":1788141600000000,\"vwap\":{\"participation_rate\":\"0.25\"}}},\"extension_version\":1}",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_modify_algo_order

  • Scope: trade:real
  • Python SDK equivalent: —
  • Route: MCP JSON-RPC tools/call with name = "futu_modify_algo_order"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Modify one nonterminal authoritative current algorithm order without changing its product, market, algorithm/price-mode, or server vendor. Requires fresh live/static/customer facts and --enable-algo-orders.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official generated C2S JSON. Field names use generated proto serde snake_case, e.g. multi_legs / combo_legs / order_type.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_modify_algo_order",
    "arguments": {
      "c2s_json": "{\"header\":{\"trd_env\":1,\"acc_id\":900000001,\"trd_market\":2},\"initial\":{\"idempotency_key\":\"algo-modify-1\",\"order_id\":\"server-algo-order-id\",\"order_version\":1,\"new_qty\":\"200\",\"algo\":{\"algo_type\":2,\"start_time\":1788138000000000,\"end_time\":1788141600000000,\"vwap\":{\"participation_rate\":\"0.25\"}}},\"extension_version\":1}",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_reverse_position

  • Scope: trade:real
  • Python SDK equivalent: —
  • Route: MCP JSON-RPC tools/call with name = "futu_reverse_position"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Reverse one exact ordinary monthly futures position through server-atomic CMD4732. Both close/open legs are authorized atomically; success requires one fresh two-member legacy group plus exact 21056 side/qty/static proof. Requires --enable-position-actions; default OFF; live backend unverified.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official generated C2S JSON. Field names use generated proto serde snake_case, e.g. multi_legs / combo_legs / order_type.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_reverse_position",
    "arguments": {
      "c2s_json": "{\"header\":{\"trd_env\":1,\"acc_id\":900000001,\"trd_market\":5},\"initial\":{\"idempotency_key\":\"reverse-example-1\",\"position_id\":9001,\"price_type\":1},\"extension_version\":1}",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_roll_position

  • Scope: trade:real
  • Python SDK equivalent: —
  • Route: MCP JSON-RPC tools/call with name = "futu_roll_position"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Roll one exact ordinary monthly futures position to a different contract with the same linkage identity through CMD4733. Source-close and target-open symbols/sides are authorized atomically; because CMD4733 has no target price, value-limited API keys fail closed. Success requires a fresh exact two-member group. Requires --enable-position-actions.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official generated C2S JSON. Field names use generated proto serde snake_case, e.g. multi_legs / combo_legs / order_type.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_roll_position",
    "arguments": {
      "c2s_json": "{\"header\":{\"trd_env\":1,\"acc_id\":900000001,\"trd_market\":5},\"initial\":{\"idempotency_key\":\"roll-example-1\",\"position_id\":9001,\"target_code\":\"HSI2610\",\"target_sec_market\":1},\"extension_version\":1}",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_clear_futures_positions

  • Scope: trade:real
  • Python SDK equivalent: —
  • Route: MCP JSON-RPC tools/call with name = "futu_clear_futures_positions"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Clear explicit non-calendar-spread futures contracts, including supported futures options, through one CMD4734 and exact req_id operation-result reconciliation. Account-wide clear additionally requires all_positions=true and --allow-all-position-clear.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official generated C2S JSON. Field names use generated proto serde snake_case, e.g. multi_legs / combo_legs / order_type.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_clear_futures_positions",
    "arguments": {
      "c2s_json": "{\"header\":{\"trd_env\":1,\"acc_id\":900000001,\"trd_market\":5},\"idempotency_key\":\"clear-example-1\",\"position_id_list\":[9001],\"price_type\":1,\"all_positions\":false,\"extension_version\":1}",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.

futu_batch_close_positions

  • Scope: trade:real
  • Python SDK equivalent: —
  • Route: MCP JSON-RPC tools/call with name = "futu_batch_close_positions"
  • ⚠️ Trade write: launch futu-mcp with --enable-trading (real env also needs --allow-real-trading)

Description:

Close an explicit deduplicated non-portfolio security-position list through one CMD4737 with Desktop-derived side/order/session fields and exact req_id result reconciliation. FUTU_JP and unsupported markets fail closed; KRX uses guarded local market contracts 18/121/111. Requires --enable-position-actions.

Request arguments:

Field Type Required Alias Description
c2s_json string ✅ — Official generated C2S JSON. Field names use generated proto serde snake_case, e.g. multi_legs / combo_legs / order_type.
api_key string? — — Optional per-call API key plaintext. HTTP scope mode still requires a valid Bearer on every /mcp request; this field overrides that identity for the tool handler. In stdio mode: tool argument > startup key.

⚠️ Unknown fields: deny_unknown_fields is enabled — any field not listed above returns an unknown field error (previously silently dropped).

JSON-RPC call example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "futu_batch_close_positions",
    "arguments": {
      "c2s_json": "{\"header\":{\"trd_env\":1,\"acc_id\":900000001,\"trd_market\":2},\"idempotency_key\":\"batch-close-example-1\",\"mode\":1,\"target_list\":[{\"position_id\":9002,\"qty\":\"10\"}],\"extension_version\":1}",
      "api_key": "optional-per-call-api-key"
    }
  }
}

Response: JSON text matching the corresponding REST endpoint / Python SDK. On failure MCP CallToolResult.is_error=true + content carries {"error": "...", "status": "error"}.