1use crate::{
2 error::ErrorData as McpError,
3 model::*,
4 service::{NotificationContext, RequestContext, RoleServer, Service, ServiceRole},
5};
6
7pub mod common;
8pub mod prompt;
9mod resource;
10pub mod router;
11pub mod tool;
12pub mod wrapper;
13impl<H: ServerHandler> Service<RoleServer> for H {
14 async fn handle_request(
15 &self,
16 request: <RoleServer as ServiceRole>::PeerReq,
17 context: RequestContext<RoleServer>,
18 ) -> Result<<RoleServer as ServiceRole>::Resp, McpError> {
19 match request {
20 ClientRequest::InitializeRequest(request) => self
21 .initialize(request.params, context)
22 .await
23 .map(ServerResult::InitializeResult),
24 ClientRequest::PingRequest(_request) => {
25 self.ping(context).await.map(ServerResult::empty)
26 }
27 ClientRequest::CompleteRequest(request) => self
28 .complete(request.params, context)
29 .await
30 .map(ServerResult::CompleteResult),
31 ClientRequest::SetLevelRequest(request) => self
32 .set_level(request.params, context)
33 .await
34 .map(ServerResult::empty),
35 ClientRequest::GetPromptRequest(request) => self
36 .get_prompt(request.params, context)
37 .await
38 .map(ServerResult::GetPromptResult),
39 ClientRequest::ListPromptsRequest(request) => self
40 .list_prompts(request.params, context)
41 .await
42 .map(ServerResult::ListPromptsResult),
43 ClientRequest::ListResourcesRequest(request) => self
44 .list_resources(request.params, context)
45 .await
46 .map(ServerResult::ListResourcesResult),
47 ClientRequest::ListResourceTemplatesRequest(request) => self
48 .list_resource_templates(request.params, context)
49 .await
50 .map(ServerResult::ListResourceTemplatesResult),
51 ClientRequest::ReadResourceRequest(request) => self
52 .read_resource(request.params, context)
53 .await
54 .map(ServerResult::ReadResourceResult),
55 ClientRequest::SubscribeRequest(request) => self
56 .subscribe(request.params, context)
57 .await
58 .map(ServerResult::empty),
59 ClientRequest::UnsubscribeRequest(request) => self
60 .unsubscribe(request.params, context)
61 .await
62 .map(ServerResult::empty),
63 ClientRequest::CallToolRequest(request) => self
64 .call_tool(request.params, context)
65 .await
66 .map(ServerResult::CallToolResult),
67 ClientRequest::ListToolsRequest(request) => self
68 .list_tools(request.params, context)
69 .await
70 .map(ServerResult::ListToolsResult),
71 }
72 }
73
74 async fn handle_notification(
75 &self,
76 notification: <RoleServer as ServiceRole>::PeerNot,
77 context: NotificationContext<RoleServer>,
78 ) -> Result<(), McpError> {
79 match notification {
80 ClientNotification::CancelledNotification(notification) => {
81 self.on_cancelled(notification.params, context).await
82 }
83 ClientNotification::ProgressNotification(notification) => {
84 self.on_progress(notification.params, context).await
85 }
86 ClientNotification::InitializedNotification(_notification) => {
87 self.on_initialized(context).await
88 }
89 ClientNotification::RootsListChangedNotification(_notification) => {
90 self.on_roots_list_changed(context).await
91 }
92 };
93 Ok(())
94 }
95
96 fn get_info(&self) -> <RoleServer as ServiceRole>::Info {
97 self.get_info()
98 }
99}
100
101#[allow(unused_variables)]
102pub trait ServerHandler: Sized + Send + Sync + 'static {
103 fn ping(
104 &self,
105 context: RequestContext<RoleServer>,
106 ) -> impl Future<Output = Result<(), McpError>> + Send + '_ {
107 std::future::ready(Ok(()))
108 }
109 fn initialize(
111 &self,
112 request: InitializeRequestParam,
113 context: RequestContext<RoleServer>,
114 ) -> impl Future<Output = Result<InitializeResult, McpError>> + Send + '_ {
115 if context.peer.peer_info().is_none() {
116 context.peer.set_peer_info(request);
117 }
118 std::future::ready(Ok(self.get_info()))
119 }
120 fn complete(
121 &self,
122 request: CompleteRequestParam,
123 context: RequestContext<RoleServer>,
124 ) -> impl Future<Output = Result<CompleteResult, McpError>> + Send + '_ {
125 std::future::ready(Ok(CompleteResult::default()))
126 }
127 fn set_level(
128 &self,
129 request: SetLevelRequestParam,
130 context: RequestContext<RoleServer>,
131 ) -> impl Future<Output = Result<(), McpError>> + Send + '_ {
132 std::future::ready(Err(McpError::method_not_found::<SetLevelRequestMethod>()))
133 }
134 fn get_prompt(
135 &self,
136 request: GetPromptRequestParam,
137 context: RequestContext<RoleServer>,
138 ) -> impl Future<Output = Result<GetPromptResult, McpError>> + Send + '_ {
139 std::future::ready(Err(McpError::method_not_found::<GetPromptRequestMethod>()))
140 }
141 fn list_prompts(
142 &self,
143 request: Option<PaginatedRequestParam>,
144 context: RequestContext<RoleServer>,
145 ) -> impl Future<Output = Result<ListPromptsResult, McpError>> + Send + '_ {
146 std::future::ready(Ok(ListPromptsResult::default()))
147 }
148 fn list_resources(
149 &self,
150 request: Option<PaginatedRequestParam>,
151 context: RequestContext<RoleServer>,
152 ) -> impl Future<Output = Result<ListResourcesResult, McpError>> + Send + '_ {
153 std::future::ready(Ok(ListResourcesResult::default()))
154 }
155 fn list_resource_templates(
156 &self,
157 request: Option<PaginatedRequestParam>,
158 context: RequestContext<RoleServer>,
159 ) -> impl Future<Output = Result<ListResourceTemplatesResult, McpError>> + Send + '_ {
160 std::future::ready(Ok(ListResourceTemplatesResult::default()))
161 }
162 fn read_resource(
163 &self,
164 request: ReadResourceRequestParam,
165 context: RequestContext<RoleServer>,
166 ) -> impl Future<Output = Result<ReadResourceResult, McpError>> + Send + '_ {
167 std::future::ready(Err(
168 McpError::method_not_found::<ReadResourceRequestMethod>(),
169 ))
170 }
171 fn subscribe(
172 &self,
173 request: SubscribeRequestParam,
174 context: RequestContext<RoleServer>,
175 ) -> impl Future<Output = Result<(), McpError>> + Send + '_ {
176 std::future::ready(Err(McpError::method_not_found::<SubscribeRequestMethod>()))
177 }
178 fn unsubscribe(
179 &self,
180 request: UnsubscribeRequestParam,
181 context: RequestContext<RoleServer>,
182 ) -> impl Future<Output = Result<(), McpError>> + Send + '_ {
183 std::future::ready(Err(McpError::method_not_found::<UnsubscribeRequestMethod>()))
184 }
185 fn call_tool(
186 &self,
187 request: CallToolRequestParam,
188 context: RequestContext<RoleServer>,
189 ) -> impl Future<Output = Result<CallToolResult, McpError>> + Send + '_ {
190 std::future::ready(Err(McpError::method_not_found::<CallToolRequestMethod>()))
191 }
192 fn list_tools(
193 &self,
194 request: Option<PaginatedRequestParam>,
195 context: RequestContext<RoleServer>,
196 ) -> impl Future<Output = Result<ListToolsResult, McpError>> + Send + '_ {
197 std::future::ready(Ok(ListToolsResult::default()))
198 }
199
200 fn on_cancelled(
201 &self,
202 notification: CancelledNotificationParam,
203 context: NotificationContext<RoleServer>,
204 ) -> impl Future<Output = ()> + Send + '_ {
205 std::future::ready(())
206 }
207 fn on_progress(
208 &self,
209 notification: ProgressNotificationParam,
210 context: NotificationContext<RoleServer>,
211 ) -> impl Future<Output = ()> + Send + '_ {
212 std::future::ready(())
213 }
214 fn on_initialized(
215 &self,
216 context: NotificationContext<RoleServer>,
217 ) -> impl Future<Output = ()> + Send + '_ {
218 tracing::info!("client initialized");
219 std::future::ready(())
220 }
221 fn on_roots_list_changed(
222 &self,
223 context: NotificationContext<RoleServer>,
224 ) -> impl Future<Output = ()> + Send + '_ {
225 std::future::ready(())
226 }
227
228 fn get_info(&self) -> ServerInfo {
229 ServerInfo::default()
230 }
231}