database_mcp_server/
server.rs1use std::fmt;
8use std::sync::Arc;
9
10use rmcp::RoleServer;
11use rmcp::Service;
12use rmcp::model::{Implementation, ServerCapabilities, ServerInfo};
13use rmcp::service::{DynService, NotificationContext, RequestContext, ServiceExt};
14
15const NAME: &str = "database-mcp";
17
18const VERSION: &str = env!("CARGO_PKG_VERSION");
20
21const TITLE: &str = "Database MCP Server";
23
24const HOMEPAGE: &str = env!("CARGO_PKG_HOMEPAGE");
26
27#[derive(Clone)]
33pub struct Server(Arc<dyn DynService<RoleServer>>);
34
35impl fmt::Debug for Server {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 f.debug_struct("Server").finish_non_exhaustive()
38 }
39}
40
41impl Server {
42 pub fn new(server: impl ServiceExt<RoleServer>) -> Self {
44 Self(Arc::from(server.into_dyn()))
45 }
46}
47
48impl Service<RoleServer> for Server {
49 fn handle_request(
50 &self,
51 request: <RoleServer as rmcp::service::ServiceRole>::PeerReq,
52 context: RequestContext<RoleServer>,
53 ) -> impl Future<Output = Result<<RoleServer as rmcp::service::ServiceRole>::Resp, rmcp::ErrorData>> + Send + '_
54 {
55 DynService::handle_request(self.0.as_ref(), request, context)
56 }
57
58 fn handle_notification(
59 &self,
60 notification: <RoleServer as rmcp::service::ServiceRole>::PeerNot,
61 context: NotificationContext<RoleServer>,
62 ) -> impl Future<Output = Result<(), rmcp::ErrorData>> + Send + '_ {
63 DynService::handle_notification(self.0.as_ref(), notification, context)
64 }
65
66 fn get_info(&self) -> <RoleServer as rmcp::service::ServiceRole>::Info {
67 DynService::get_info(self.0.as_ref())
68 }
69}
70
71#[must_use]
77pub fn server_info() -> ServerInfo {
78 let capabilities = ServerCapabilities::builder().enable_tools().build();
79
80 let server_info = Implementation::new(NAME, VERSION)
81 .with_title(TITLE)
82 .with_website_url(HOMEPAGE);
83
84 ServerInfo::new(capabilities).with_server_info(server_info)
85}