Skip to main content

futu_mcp/tools/
reference_corporate_short_brokers.rs

1//! MCP v10.6 corporate-actions, short-interest, and broker-flow reference tools.
2
3use crate::handlers;
4use crate::tool_args::*;
5use rmcp::{
6    RoleServer, handler::server::wrapper::Parameters, service::RequestContext, tool, tool_router,
7};
8
9use super::FutuServer;
10
11#[tool_router(router = reference_corporate_short_brokers_tool_router, vis = "pub(crate)")]
12impl FutuServer {
13    #[tool(
14        description = "Daily short volume for HK/US securities. Futu API v10.6: OpenQuoteContext.get_daily_short_volume."
15    )]
16    async fn futu_get_daily_short_volume(
17        &self,
18        Parameters(req): Parameters<ShortInfoReq>,
19        req_ctx: RequestContext<RoleServer>,
20    ) -> std::result::Result<String, String> {
21        req.validate("futu_get_daily_short_volume")?;
22        tracing::info!(
23            tool = "futu_get_daily_short_volume",
24            symbol = %req.symbol,
25            next_key = ?req.next_key,
26            num = ?req.num
27        );
28        let client = self
29            .read_client_or_err("futu_get_daily_short_volume", &req_ctx, None, None)
30            .await?;
31        Self::wrap_result(
32            handlers::reference::get_daily_short_volume(
33                &client,
34                &req.symbol,
35                req.next_key.as_deref(),
36                req.num,
37            )
38            .await,
39        )
40    }
41
42    #[tool(
43        description = "Corporate action buyback records for HK/A-share securities. Futu API v10.6: OpenQuoteContext.get_corporate_actions_buybacks."
44    )]
45    async fn futu_get_corporate_actions_buybacks(
46        &self,
47        Parameters(req): Parameters<ShortInfoReq>,
48        req_ctx: RequestContext<RoleServer>,
49    ) -> std::result::Result<String, String> {
50        req.validate("futu_get_corporate_actions_buybacks")?;
51        tracing::info!(
52            tool = "futu_get_corporate_actions_buybacks",
53            symbol = %req.symbol,
54            next_key = ?req.next_key,
55            num = ?req.num
56        );
57        let client = self
58            .read_client_or_err("futu_get_corporate_actions_buybacks", &req_ctx, None, None)
59            .await?;
60        Self::wrap_result(
61            handlers::reference::get_corporate_actions_buybacks(
62                &client,
63                &req.symbol,
64                req.next_key.as_deref(),
65                req.num,
66            )
67            .await,
68        )
69    }
70
71    #[tool(
72        description = "Corporate action dividend records for securities. Futu API v10.6: OpenQuoteContext.get_corporate_actions_dividends."
73    )]
74    async fn futu_get_corporate_actions_dividends(
75        &self,
76        Parameters(req): Parameters<SymbolReq>,
77        req_ctx: RequestContext<RoleServer>,
78    ) -> std::result::Result<String, String> {
79        tracing::info!(
80            tool = "futu_get_corporate_actions_dividends",
81            symbol = %req.symbol
82        );
83        let client = self
84            .read_client_or_err("futu_get_corporate_actions_dividends", &req_ctx, None, None)
85            .await?;
86        Self::wrap_result(
87            handlers::reference::get_corporate_actions_dividends(&client, &req.symbol).await,
88        )
89    }
90
91    #[tool(
92        description = "Corporate action stock split records for HK/US securities. Futu API v10.6: OpenQuoteContext.get_corporate_actions_stock_splits."
93    )]
94    async fn futu_get_corporate_actions_stock_splits(
95        &self,
96        Parameters(req): Parameters<ShortInfoReq>,
97        req_ctx: RequestContext<RoleServer>,
98    ) -> std::result::Result<String, String> {
99        req.validate("futu_get_corporate_actions_stock_splits")?;
100        tracing::info!(
101            tool = "futu_get_corporate_actions_stock_splits",
102            symbol = %req.symbol,
103            next_key = ?req.next_key,
104            num = ?req.num
105        );
106        let client = self
107            .read_client_or_err(
108                "futu_get_corporate_actions_stock_splits",
109                &req_ctx,
110                None,
111                None,
112            )
113            .await?;
114        Self::wrap_result(
115            handlers::reference::get_corporate_actions_stock_splits(
116                &client,
117                &req.symbol,
118                req.next_key.as_deref(),
119                req.num,
120            )
121            .await,
122        )
123    }
124
125    #[tool(
126        description = "Short interest for HK/US securities. Futu API v10.6: OpenQuoteContext.get_short_interest."
127    )]
128    async fn futu_get_short_interest(
129        &self,
130        Parameters(req): Parameters<ShortInfoReq>,
131        req_ctx: RequestContext<RoleServer>,
132    ) -> std::result::Result<String, String> {
133        req.validate("futu_get_short_interest")?;
134        tracing::info!(
135            tool = "futu_get_short_interest",
136            symbol = %req.symbol,
137            next_key = ?req.next_key,
138            num = ?req.num
139        );
140        let client = self
141            .read_client_or_err("futu_get_short_interest", &req_ctx, None, None)
142            .await?;
143        Self::wrap_result(
144            handlers::reference::get_short_interest(
145                &client,
146                &req.symbol,
147                req.next_key.as_deref(),
148                req.num,
149            )
150            .await,
151        )
152    }
153
154    #[tool(
155        description = "Top ten net buy/sell brokers for HK securities. Futu API v10.6: OpenQuoteContext.get_top_ten_buy_sell_brokers."
156    )]
157    async fn futu_get_top_ten_buy_sell_brokers(
158        &self,
159        Parameters(req): Parameters<TopTenBuySellBrokersReq>,
160        req_ctx: RequestContext<RoleServer>,
161    ) -> std::result::Result<String, String> {
162        req.validate()?;
163        tracing::info!(
164            tool = "futu_get_top_ten_buy_sell_brokers",
165            symbol = %req.symbol,
166            days_before = ?req.days_before
167        );
168        let client = self
169            .read_client_or_err("futu_get_top_ten_buy_sell_brokers", &req_ctx, None, None)
170            .await?;
171        Self::wrap_result(
172            handlers::reference::get_top_ten_buy_sell_brokers(
173                &client,
174                &req.symbol,
175                req.days_before,
176            )
177            .await,
178        )
179    }
180}