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