rust_mcp_sdk/mcp_runtimes/server_runtime/
mcp_server_runtime.rs1use std::sync::Arc;
2
3use async_trait::async_trait;
4use rust_mcp_schema::{
5 schema_utils::{
6 CallToolError, ClientMessage, MessageFromServer, NotificationFromClient, RequestFromClient,
7 ResultFromServer,
8 },
9 CallToolResult, InitializeResult, RpcError,
10};
11use rust_mcp_transport::Transport;
12
13use super::ServerRuntime;
14#[cfg(feature = "hyper-server")]
15use rust_mcp_transport::SessionId;
16
17use crate::{
18 error::SdkResult,
19 mcp_handlers::mcp_server_handler::ServerHandler,
20 mcp_traits::{mcp_handler::McpServerHandler, mcp_server::McpServer},
21};
22
23pub fn create_server(
42 server_details: InitializeResult,
43 transport: impl Transport<ClientMessage, MessageFromServer>,
44 handler: impl ServerHandler,
45) -> ServerRuntime {
46 ServerRuntime::new(
47 server_details,
48 transport,
49 Arc::new(ServerRuntimeInternalHandler::new(Box::new(handler))),
50 )
51}
52
53#[cfg(feature = "hyper-server")]
54pub(crate) fn create_server_instance(
55 server_details: Arc<InitializeResult>,
56 transport: impl Transport<ClientMessage, MessageFromServer>,
57 handler: Arc<dyn McpServerHandler>,
58 session_id: SessionId,
59) -> ServerRuntime {
60 ServerRuntime::new_instance(server_details, transport, handler, session_id)
61}
62
63pub(crate) struct ServerRuntimeInternalHandler<H> {
64 handler: H,
65}
66impl ServerRuntimeInternalHandler<Box<dyn ServerHandler>> {
67 pub fn new(handler: Box<dyn ServerHandler>) -> Self {
68 Self { handler }
69 }
70}
71
72#[async_trait]
73impl McpServerHandler for ServerRuntimeInternalHandler<Box<dyn ServerHandler>> {
74 async fn handle_request(
75 &self,
76 client_jsonrpc_request: RequestFromClient,
77 runtime: &dyn McpServer,
78 ) -> std::result::Result<ResultFromServer, RpcError> {
79 match client_jsonrpc_request {
80 rust_mcp_schema::schema_utils::RequestFromClient::ClientRequest(client_request) => {
81 match client_request {
82 rust_mcp_schema::ClientRequest::InitializeRequest(initialize_request) => self
83 .handler
84 .handle_initialize_request(initialize_request, runtime)
85 .await
86 .map(|value| value.into()),
87 rust_mcp_schema::ClientRequest::PingRequest(ping_request) => self
88 .handler
89 .handle_ping_request(ping_request, runtime)
90 .await
91 .map(|value| value.into()),
92 rust_mcp_schema::ClientRequest::ListResourcesRequest(
93 list_resources_request,
94 ) => self
95 .handler
96 .handle_list_resources_request(list_resources_request, runtime)
97 .await
98 .map(|value| value.into()),
99 rust_mcp_schema::ClientRequest::ListResourceTemplatesRequest(
100 list_resource_templates_request,
101 ) => self
102 .handler
103 .handle_list_resource_templates_request(
104 list_resource_templates_request,
105 runtime,
106 )
107 .await
108 .map(|value| value.into()),
109 rust_mcp_schema::ClientRequest::ReadResourceRequest(read_resource_request) => {
110 self.handler
111 .handle_read_resource_request(read_resource_request, runtime)
112 .await
113 .map(|value| value.into())
114 }
115 rust_mcp_schema::ClientRequest::SubscribeRequest(subscribe_request) => self
116 .handler
117 .handle_subscribe_request(subscribe_request, runtime)
118 .await
119 .map(|value| value.into()),
120 rust_mcp_schema::ClientRequest::UnsubscribeRequest(unsubscribe_request) => self
121 .handler
122 .handle_unsubscribe_request(unsubscribe_request, runtime)
123 .await
124 .map(|value| value.into()),
125 rust_mcp_schema::ClientRequest::ListPromptsRequest(list_prompts_request) => {
126 self.handler
127 .handle_list_prompts_request(list_prompts_request, runtime)
128 .await
129 .map(|value| value.into())
130 }
131
132 rust_mcp_schema::ClientRequest::GetPromptRequest(prompt_request) => self
133 .handler
134 .handle_get_prompt_request(prompt_request, runtime)
135 .await
136 .map(|value| value.into()),
137 rust_mcp_schema::ClientRequest::ListToolsRequest(list_tools_request) => self
138 .handler
139 .handle_list_tools_request(list_tools_request, runtime)
140 .await
141 .map(|value| value.into()),
142 rust_mcp_schema::ClientRequest::CallToolRequest(call_tool_request) => {
143 let result = self
144 .handler
145 .handle_call_tool_request(call_tool_request, runtime)
146 .await;
147
148 Ok(result.map_or_else(
149 |err| CallToolResult::with_error(CallToolError::new(err)).into(),
150 |value| value.into(),
151 ))
152 }
153 rust_mcp_schema::ClientRequest::SetLevelRequest(set_level_request) => self
154 .handler
155 .handle_set_level_request(set_level_request, runtime)
156 .await
157 .map(|value| value.into()),
158 rust_mcp_schema::ClientRequest::CompleteRequest(complete_request) => self
159 .handler
160 .handle_complete_request(complete_request, runtime)
161 .await
162 .map(|value| value.into()),
163 }
164 }
165 rust_mcp_schema::schema_utils::RequestFromClient::CustomRequest(value) => self
166 .handler
167 .handle_custom_request(value, runtime)
168 .await
169 .map(|value| value.into()),
170 }
171 }
172
173 async fn handle_error(
174 &self,
175 jsonrpc_error: RpcError,
176 runtime: &dyn McpServer,
177 ) -> SdkResult<()> {
178 self.handler.handle_error(jsonrpc_error, runtime).await?;
179 Ok(())
180 }
181
182 async fn handle_notification(
183 &self,
184 client_jsonrpc_notification: NotificationFromClient,
185 runtime: &dyn McpServer,
186 ) -> SdkResult<()> {
187 match client_jsonrpc_notification {
188 rust_mcp_schema::schema_utils::NotificationFromClient::ClientNotification(
189 client_notification,
190 ) => match client_notification {
191 rust_mcp_schema::ClientNotification::CancelledNotification(
192 cancelled_notification,
193 ) => {
194 self.handler
195 .handle_cancelled_notification(cancelled_notification, runtime)
196 .await?;
197 }
198 rust_mcp_schema::ClientNotification::InitializedNotification(
199 initialized_notification,
200 ) => {
201 self.handler
202 .handle_initialized_notification(initialized_notification, runtime)
203 .await?;
204 self.handler.on_initialized(runtime).await;
205 }
206 rust_mcp_schema::ClientNotification::ProgressNotification(
207 progress_notification,
208 ) => {
209 self.handler
210 .handle_progress_notification(progress_notification, runtime)
211 .await?;
212 }
213 rust_mcp_schema::ClientNotification::RootsListChangedNotification(
214 roots_list_changed_notification,
215 ) => {
216 self.handler
217 .handle_roots_list_changed_notification(
218 roots_list_changed_notification,
219 runtime,
220 )
221 .await?;
222 }
223 },
224 rust_mcp_schema::schema_utils::NotificationFromClient::CustomNotification(value) => {
225 self.handler.handle_custom_notification(value).await?;
226 }
227 }
228 Ok(())
229 }
230
231 async fn on_server_started(&self, runtime: &dyn McpServer) {
232 self.handler.on_server_started(runtime).await;
233 }
234}