1use crate::handlers;
4use crate::tool_args::{
5 KLineReq, OrderBookReq, PlateListReq, PlateStocksReq, SymbolListReq, SymbolReq, TickerReq,
6};
7use rmcp::{RoleServer, handler::server::wrapper::Parameters, service::RequestContext};
8
9use super::FutuServer;
10
11impl FutuServer {
12 async fn futu_get_quote_impl(
13 &self,
14 Parameters(req): Parameters<SymbolReq>,
15 req_ctx: RequestContext<RoleServer>,
16 ) -> std::result::Result<String, String> {
17 tracing::info!(tool = "futu_get_quote", symbol = %req.symbol);
18 let client = self
19 .read_client_or_err("futu_get_quote", &req_ctx, None, None)
20 .await?;
21 Self::wrap_result(handlers::core::get_quote(&client, &req.symbol).await)
22 }
23
24 async fn futu_get_snapshot_impl(
25 &self,
26 Parameters(req): Parameters<SymbolReq>,
27 req_ctx: RequestContext<RoleServer>,
28 ) -> std::result::Result<String, String> {
29 tracing::info!(tool = "futu_get_snapshot", symbol = %req.symbol);
30 let client = self
31 .read_client_or_err("futu_get_snapshot", &req_ctx, None, None)
32 .await?;
33 Self::wrap_result(handlers::core::get_snapshot(&client, &req.symbol).await)
34 }
35
36 async fn futu_get_kline_impl(
37 &self,
38 Parameters(req): Parameters<KLineReq>,
39 req_ctx: RequestContext<RoleServer>,
40 ) -> std::result::Result<String, String> {
41 req.validate()?;
42 tracing::info!(
43 tool = "futu_get_kline",
44 symbol = %req.symbol,
45 kl_type = %req.kl_type,
46 count = crate::state::audit_fmt::opt_i32(req.count)
48 );
49 let client = self
50 .read_client_or_err("futu_get_kline", &req_ctx, None, None)
51 .await?;
52 Self::wrap_result(
53 handlers::market::get_kline(
54 &client,
55 &req.symbol,
56 &req.kl_type,
57 req.count,
58 req.begin.as_deref(),
59 req.end.as_deref(),
60 )
61 .await,
62 )
63 }
64
65 async fn futu_get_orderbook_impl(
66 &self,
67 Parameters(req): Parameters<OrderBookReq>,
68 req_ctx: RequestContext<RoleServer>,
69 ) -> std::result::Result<String, String> {
70 req.validate()?;
71 tracing::info!(
72 tool = "futu_get_orderbook",
73 symbol = %req.symbol,
74 depth = req.depth,
75 odd_lot = req.odd_lot
76 );
77 let client = self
78 .read_client_or_err("futu_get_orderbook", &req_ctx, None, None)
79 .await?;
80 Self::wrap_result(
81 handlers::market::get_orderbook(&client, &req.symbol, req.depth, req.odd_lot).await,
82 )
83 }
84
85 async fn futu_get_ticker_impl(
86 &self,
87 Parameters(req): Parameters<TickerReq>,
88 req_ctx: RequestContext<RoleServer>,
89 ) -> std::result::Result<String, String> {
90 req.validate()?;
91 tracing::info!(tool = "futu_get_ticker", symbol = %req.symbol, count = req.count);
92 let client = self
93 .read_client_or_err("futu_get_ticker", &req_ctx, None, None)
94 .await?;
95 Self::wrap_result(handlers::market::get_ticker(&client, &req.symbol, req.count).await)
96 }
97
98 async fn futu_get_rt_impl(
99 &self,
100 Parameters(req): Parameters<SymbolReq>,
101 req_ctx: RequestContext<RoleServer>,
102 ) -> std::result::Result<String, String> {
103 tracing::info!(tool = "futu_get_rt", symbol = %req.symbol);
104 let client = self
105 .read_client_or_err("futu_get_rt", &req_ctx, None, None)
106 .await?;
107 Self::wrap_result(handlers::market::get_rt(&client, &req.symbol).await)
108 }
109
110 async fn futu_get_static_impl(
111 &self,
112 Parameters(req): Parameters<SymbolListReq>,
113 req_ctx: RequestContext<RoleServer>,
114 ) -> std::result::Result<String, String> {
115 tracing::info!(tool = "futu_get_static", symbols = ?req.symbols);
116 let client = self
117 .read_client_or_err("futu_get_static", &req_ctx, None, None)
118 .await?;
119 Self::wrap_result(handlers::market::get_static(&client, &req.symbols).await)
120 }
121
122 async fn futu_get_broker_impl(
123 &self,
124 Parameters(req): Parameters<SymbolReq>,
125 req_ctx: RequestContext<RoleServer>,
126 ) -> std::result::Result<String, String> {
127 tracing::info!(tool = "futu_get_broker", symbol = %req.symbol);
128 let client = self
129 .read_client_or_err("futu_get_broker", &req_ctx, None, None)
130 .await?;
131 Self::wrap_result(handlers::market::get_broker(&client, &req.symbol).await)
132 }
133
134 async fn futu_list_plates_impl(
135 &self,
136 Parameters(req): Parameters<PlateListReq>,
137 req_ctx: RequestContext<RoleServer>,
138 ) -> std::result::Result<String, String> {
139 tracing::info!(tool = "futu_list_plates", market = %req.market, set = %req.plate_set);
140 let client = self
141 .read_client_or_err("futu_list_plates", &req_ctx, None, None)
142 .await?;
143 Self::wrap_result(handlers::plate::list_plates(&client, &req.market, &req.plate_set).await)
144 }
145
146 async fn futu_plate_stocks_impl(
147 &self,
148 Parameters(req): Parameters<PlateStocksReq>,
149 req_ctx: RequestContext<RoleServer>,
150 ) -> std::result::Result<String, String> {
151 tracing::info!(tool = "futu_plate_stocks", plate = %req.plate);
152 let client = self
153 .read_client_or_err("futu_plate_stocks", &req_ctx, None, None)
154 .await?;
155 Self::wrap_result(handlers::plate::plate_stocks(&client, &req.plate).await)
156 }
157}
158
159include!(concat!(env!("OUT_DIR"), "/generated_mcp_routes_market.rs"));