Environment variables reference
This page lists all FUTU_* environment variables supported by the daemon
(futu-opend), CLI (futucli), and MCP (futu-mcp), with purpose, default
values, and matching CLI flags.
Credentials
| Env var |
Purpose |
Default |
Matching CLI flag |
FUTU_ACCOUNT |
Login-account hint. futucli unlock-trade / futu-mcp can use it to select account-scoped trade-password keychain entries when --trade-pwd-account is not set; helper scripts also use it to start the daemon |
(as needed) |
Prefer daemon --login-account <ACCOUNT> |
FUTU_PWD |
Login password (plaintext or 32-hex MD5, auto-detected) |
(required or use CLI flag) |
--login-pwd <PWD> |
FUTU_TRADE_PWD |
Trade unlock password (futucli unlock / MCP unlock) |
(as needed) |
--trade-pwd <PWD> |
FUTU_TRADE_PWD_ACCOUNT |
Account hint for account-scoped trade-password keychain lookup |
(as needed) |
--trade-pwd-account <ACCOUNT> |
FUTU_API_KEY |
Bearer token used when futucli stock-note-labels, stock-notes, or set-stock-note forwards to OpenD REST; this is only the environment-variable input for those commands' --api-key option |
(as needed in secure KeyStore mode) |
futucli ... --api-key <KEY> |
FUTU_MCP_API_KEY |
Process-wide default API key for futu-mcp --keys-file stdio scope mode; HTTP scope mode never uses it as a fallback and requires a valid Authorization: Bearer on every /mcp request |
(required for stdio scope mode; not used by HTTP) |
futu-mcp --api-key <KEY> |
FUTU_MCP_OPEND_REST_URL |
OpenD REST base URL that futu-mcp guarded real-money write tools (group orders / algorithm orders / position actions) forward to when the daemon disables raw TCP in secure KeyStore mode; unset means those write tools refuse |
(as needed; secure deployments only) |
futu-mcp --opend-rest-url <URL> |
Security tip: Prefer systemd EnvironmentFile=/etc/futu-opend.env
(mode 0600) to avoid leaking plaintext to shell history / ps aux.
Connection addresses
| Env var |
Purpose |
Default |
FUTU_GATEWAY |
MCP / futucli daemon gRPC address |
127.0.0.1:11111 |
FUTU_REST_URL |
futucli daemon REST URL |
http://127.0.0.1:11112 |
FUTU_ADDR |
Used by examples/live_test for daemon address |
127.0.0.1:11111 |
Browser entrypoints / Metrics security
| Env var |
Purpose |
Default |
FUTU_REST_ALLOWED_ORIGINS |
REST CORS Origin allowlist, comma-separated; * / any / all means development wildcard |
With REST keys configured: loopback only. Legacy unauth mode keeps wildcard compatibility |
FUTU_WS_ALLOWED_ORIGINS |
WebSocket handshake Origin allowlist, comma-separated |
Loopback Origin only when unset; non-browser clients without Origin skip this check |
FUTU_METRICS_PUBLIC=1 |
Revert /metrics to public access and plaintext key_id labels |
By default /metrics follows auth posture and redacts key_id labels |
Production guidance:
- Browser UI deployments should set exact origins such as
https://app.example.com.
- Use
FUTU_METRICS_PUBLIC=1 only when the metrics port is protected by firewall / sidecar controls.
Long-running daemon hardening (v1.4.103+)
Compatibility env opt-in, default OFF. You can also enable the same behavior
with futu-opend --client-sig-proactive-refresh /
--client-sig-reactive-refresh, or TOML
client_sig_proactive_refresh = true /
client_sig_reactive_refresh = true. See
long-running daemon deployment guide
for details.
| Env var |
Purpose |
Default |
Risk |
FUTU_CLIENT_SIG_PROACTIVE_REFRESH=1 |
Proactively refresh client_sig 1h before expiry |
OFF |
Low — single refresh action; validate server acceptance on a non-critical account first |
FUTU_CLIENT_SIG_REACTIVE_REFRESH=1 |
Reactive refresh after tcp_login persistent failures (≥3) |
OFF |
Medium — ret_type=15 semantics not exclusively "client_sig invalid" (includes rate limiting / risk control); in multi-account daemon, misfire may affect other accounts; safe for single-account |
FUTU_QOT_RELOGIN_BACKOFF_MS |
QOT login-health self-heal ladder, four millisecond values: fail0,fail1,fail2,fail3+ |
60000,120000,240000,600000 |
Medium — useful for real-machine verification / long-run diagnostics; avoid overly frequent production relogin |
FUTU_WEBSIG_REFRESH |
Master switch for proactive WebSig refresh. Set only to 0 / false / no / off for emergency rollback, then restart the daemon |
ON |
High — when disabled, an expired WebSig can recover only through failure-driven reconnect / ticket replacement |
FUTU_SESSION_KEY_REFRESH |
Control the C++-aligned periodic TCP session-key refresh actor; a refresh failure invalidates the connection and enters the unified reconnect path |
ON; disabled only by 0 / false / no / off |
Low — emergency opt-out; normal operation does not need this variable |
FUTU_WEBTCP_SITE_CONFIG_REFRESH |
Enable the periodic WebTCP site-config refresh timer; the initial fetch and commconfig-target-change refresh still run when disabled |
OFF; enabled only by 1 / true / yes / on |
Low — last-good remains active |
When to flip the two client-sig switches to default ON: after enough real
deployments show that FUTU_CLIENT_SIG_PROACTIVE_REFRESH and
FUTU_CLIENT_SIG_REACTIVE_REFRESH do not trigger extra rate limiting or
risk-control behavior. These two switches remain experimental opt-in; this note
does not apply to the WebSig and session-key refresh rows that are already
default-on.
Client (CLI / SDK / MCP)
| Env var |
Purpose |
Default |
FUTU_CLI_AUTO_IDEM=1 |
futucli auto-derives idempotency_key (param hash) for place-order/modify/cancel |
OFF |
FUTU_UPDATE_CHECK_URL |
Override URL for futucli version --check / futucli doctor version.json update checks |
unset uses https://futuapi.com/version.json; unavailable, non-2xx, or schema-incompatible manifests fail closed |
Startup and local caches
| Env var |
Purpose |
Default |
FUTU_STOCK_LIST_STARTUP_WAIT_SECS |
Seconds to wait for the first stock-list sync before ready when the local list is empty; background sync continues after timeout |
3; 0 disables the wait |
FUTU_LANGUAGE_PACK_CACHE_DIR |
Root directory for the language-pack manifest and last-good cache |
futu-opend-rs/language-packs under the OS cache directory |
Quote quota diagnostics
| Env var |
Purpose |
Default |
FUTU_HISTORY_KLINE_CLOUD_SYNC |
Whether to synchronize used historical K-line quota with official OpenD/App; accepts only true / false |
true; use --history-kline-cloud-sync false or history_kline_cloud_sync = false to enter local-only compatibility mode |
FUTU_HISTORY_KL_QUOTA_MAX |
Override for the max unique stocks allowed in one local historical K-line quota period; unset follows the account's dynamic quota |
unset (cold-start fallback 100) |
FUTU_HISTORY_KL_QUOTA_PERIOD_SECS |
Historical K-line quota period length, in seconds |
604800 (7 days) |
Note: the historical K-line total quota prefers the account quota returned after login by CMD6024, matching the value shown in official OpenD UI. FUTU_HISTORY_KL_QUOTA_MAX is only an explicit override for debugging or stress tests; before the dynamic quota arrives, Rust uses the C++ cold-start default 100 as a fail-closed fallback.
Trade diagnostics
| Env var |
Purpose |
Default |
FUTU_HISTORY_ORDER_AUDIT=1 |
Enable history-orders backend-row filtering / projection audit logs for investigating Rust vs official C++ history-order count or field differences |
OFF |
Testing / Chaos engineering
| Env var |
Purpose |
Default |
FUTU_E2E_SIM_ACC |
E2E test sim account |
(test-only) |
FUTU_E2E_SIM_PWD |
E2E test sim password |
(test-only) |
FUTU_E2E_SIM_PLATFORM |
E2E test platform (futunn / moomoo) |
futunn |
FUTU_CHAOS_ENABLE=1 |
chaos test fault-injection toggle |
OFF |
FUTU_MULTI_VERSION_GUARD_STRICT=1 |
multi_version_smoke.sh strict mode (binary fingerprint diff → exit 1) |
(set by ship.sh A9) |
| Env var |
Purpose |
FUTU_MULTI_VERSION_GUARD_STRICT=1 |
Forced by ship.sh A9; fingerprint diff blocks release |
FUTU_MV_CACHE_DIR |
Cache directory for historical binaries downloaded by scripts/multi_version_smoke.sh |
| Env var |
Purpose |
Default |
FUTU_OPEND_RS_GIT_SHA |
Override the git SHA compiled into device_alias / version diagnostics |
build script reads git rev-parse --short HEAD |
Naming convention
FUTU_<SUBSYSTEM>_<FEATURE>_<ACTION>=<VALUE>:
FUTU_ prefix — shared namespace for daemon / CLI / SDK
- subsystem:
CLIENT_SIG / TRADE / CLI / E2E / CHAOS etc
- feature/action: describes the functionality itself, no internal ticket
numbers exposed (for example, use
PROACTIVE_REFRESH instead of
INTERNAL_123)
- value:
1 = enable; otherwise / unset = disable
Precedence vs CLI flags
The general order is CLI flag > env var > config file > built-in default;
feature-specific compatibility rules are documented in their table rows.
FUTU_HISTORY_KLINE_CLOUD_SYNC uses CLI > config file > env > default true.
Example: FUTU_PWD=foo futu-opend --login-pwd bar uses bar (CLI flag).