rmcp/handler/
server.rs

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    // handle requests
110    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}