Skip to main content

futu_mcp/tool_args/
push.rs

1//! v1.4.110 P1-1: 拆自 `tool_args.rs` 按 handler 域分组.
2
3use rmcp::schemars;
4use serde::Deserialize;
5
6use crate::tool_enums;
7
8use super::*;
9
10#[derive(Debug, Deserialize, schemars::JsonSchema)]
11#[serde(deny_unknown_fields)]
12pub struct QuerySubscriptionReq {
13    #[schemars(description = "true=query all connections; false=only this connection (default)")]
14    #[serde(default)]
15    pub is_req_all_conn: bool,
16}
17
18#[derive(Debug, Deserialize, schemars::JsonSchema)]
19#[serde(deny_unknown_fields)]
20pub struct UnsubscribeReq {
21    #[schemars(
22        description = "Security symbols to unsubscribe (ignored if unsub_all=true); alias: stocks / code_list / symbol_list / security_list"
23    )]
24    // v1.4.84 §5 B1
25    #[serde(
26        default,
27        alias = "stocks",
28        alias = "code_list",
29        alias = "symbol_list",
30        alias = "security_list"
31    )]
32    pub symbols: Vec<String>,
33    #[schemars(
34        description = "Sub-type ids to unsubscribe. Accept int (1=Basic, 2=OrderBook, 4=Ticker, \
35                       5=RT, 6=KL_Day, 7=KL_5Min, 8=KL_15Min, 9=KL_30Min, 10=KL_60Min, 11=KL_1Min, \
36                       12=KL_Week, 13=KL_Month, 14=Broker, 15=KL_Quarter, 16=KL_Year, 17=KL_3Min) \
37                       OR string (\"Basic\" / \"OrderBook\" / \"KL_Day\" / \"day\" / ...). Alias: \
38                       sub_type_list. Uses the daemon proto mapping: 3 is reserved/None, 4=Ticker, \
39                       10=KL_60Min, 13=KL_Month."
40    )]
41    // v1.4.84 §5 B2 field migration: Vec<SubTypeEnum> 双接
42    #[serde(
43        default,
44        alias = "sub_type_list",
45        deserialize_with = "tool_enums::deser_subtype_list_as_vec_i32"
46    )]
47    pub sub_types: Vec<i32>,
48    #[schemars(
49        description = "true=clear all subscriptions on this connection (ignores symbols/sub_types); alias: unsubscribe_all"
50    )]
51    #[serde(default, alias = "unsubscribe_all")]
52    pub unsub_all: bool,
53}
54
55/// v1.4.74 A1 BUG-011 fix: MCP `futu_subscribe` request body(对称于
56/// `UnsubscribeReq`)。
57#[derive(Debug, Deserialize, schemars::JsonSchema)]
58#[serde(deny_unknown_fields)]
59pub struct SubscribeReq {
60    #[schemars(
61        description = "Security symbols to subscribe, e.g. [\"HK.00700\", \"US.AAPL\"]. Alias: stocks / code_list / symbol_list / security_list"
62    )]
63    // v1.4.84 §5 B1
64    #[serde(
65        alias = "stocks",
66        alias = "code_list",
67        alias = "symbol_list",
68        alias = "security_list"
69    )]
70    pub symbols: Vec<String>,
71    #[schemars(
72        description = "Sub-type ids to subscribe. Accept int (1=Basic, 2=OrderBook, 4=Ticker, \
73                       5=RT, 6=KL_Day, 7=KL_5Min, 8=KL_15Min, 9=KL_30Min, 10=KL_60Min, 11=KL_1Min, \
74                       12=KL_Week, 13=KL_Month, 14=Broker, 15=KL_Quarter, 16=KL_Year, 17=KL_3Min) \
75                       OR string (\"Basic\" / \"OrderBook\" / \"KL_Day\" / \"day\" / ...). Alias: \
76                       sub_type_list. Uses the daemon proto mapping: 3 is reserved/None, 4=Ticker, \
77                       10=KL_60Min, 13=KL_Month."
78    )]
79    // v1.4.84 §5 B2 field migration
80    #[serde(
81        alias = "sub_type_list",
82        deserialize_with = "tool_enums::deser_subtype_list_as_vec_i32"
83    )]
84    pub sub_types: Vec<i32>,
85    #[schemars(
86        description = "If true, backend pushes current snapshot immediately after subscribe (useful for agents needing warm state). Default true."
87    )]
88    #[serde(default = "default_is_first_push")]
89    pub is_first_push: bool,
90    #[schemars(
91        description = "If true, register push on this connection (agent will receive push via SSE notification in HTTP mode). Default true."
92    )]
93    #[serde(default = "default_is_reg_push")]
94    pub is_reg_push: bool,
95}
96
97#[derive(Debug, Deserialize, schemars::JsonSchema)]
98#[serde(deny_unknown_fields)]
99pub struct SubAccPushReq {
100    #[schemars(description = "Array of account IDs (u64) to receive order/deal push \
101                       for. ⚠️ Call `futu_list_accounts` first to discover real \
102                       `acc_id` values; do NOT hallucinate 18-digit numbers — \
103                       invalid ids will silently fail to receive push. Alias: account_ids / accounts")]
104    // v1.4.84 §5 B1
105    #[serde(alias = "account_ids", alias = "accounts")]
106    pub acc_ids: Vec<u64>,
107    #[schemars(
108        description = "Optional per-call API key plaintext. Priority: tool args > HTTP Bearer > startup key. Use to scope this push subscription to a specific narrow key."
109    )]
110    #[serde(default)]
111    pub api_key: Option<String>,
112}
113
114/// v1.4.58 Phase A: `futu_unsub_acc_push` request body.
115#[derive(Debug, Deserialize, schemars::JsonSchema)]
116#[serde(deny_unknown_fields)]
117pub struct UnsubAccPushReq {
118    /// session_id from previous `futu_sub_acc_push` response — **required**.
119    /// rmcp 的 Peer<RoleServer> 不实装 PartialEq,无法按 peer 身份批量撤销。
120    #[schemars(description = "Required: session_id returned by `futu_sub_acc_push` \
121                       response (session_id field or unsub_hint). If omitted, \
122                       handler returns an error. If session_id not found (e.g. \
123                       4h auto-purged), removed_count=0 is returned.")]
124    #[serde(default)]
125    pub session_id: Option<String>,
126    #[schemars(
127        description = "Optional per-call API key plaintext. Priority: tool args > HTTP Bearer > startup key. Use the same key that created the push subscription when running in stdio mode with multiple keys."
128    )]
129    #[serde(default)]
130    pub api_key: Option<String>,
131}