use std::fmt;
use std::sync::Arc;
use rmcp::RoleServer;
use rmcp::Service;
use rmcp::model::{Implementation, ServerCapabilities, ServerInfo};
use rmcp::service::{DynService, NotificationContext, RequestContext, ServiceExt};
const NAME: &str = "database-mcp";
const VERSION: &str = env!("CARGO_PKG_VERSION");
const TITLE: &str = "Database MCP Server";
const HOMEPAGE: &str = env!("CARGO_PKG_HOMEPAGE");
#[derive(Clone)]
pub struct Server(Arc<dyn DynService<RoleServer>>);
impl fmt::Debug for Server {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Server").finish_non_exhaustive()
}
}
impl Server {
pub fn new(server: impl ServiceExt<RoleServer>) -> Self {
Self(Arc::from(server.into_dyn()))
}
}
impl Service<RoleServer> for Server {
fn handle_request(
&self,
request: <RoleServer as rmcp::service::ServiceRole>::PeerReq,
context: RequestContext<RoleServer>,
) -> impl Future<Output = Result<<RoleServer as rmcp::service::ServiceRole>::Resp, rmcp::ErrorData>> + Send + '_
{
DynService::handle_request(self.0.as_ref(), request, context)
}
fn handle_notification(
&self,
notification: <RoleServer as rmcp::service::ServiceRole>::PeerNot,
context: NotificationContext<RoleServer>,
) -> impl Future<Output = Result<(), rmcp::ErrorData>> + Send + '_ {
DynService::handle_notification(self.0.as_ref(), notification, context)
}
fn get_info(&self) -> <RoleServer as rmcp::service::ServiceRole>::Info {
DynService::get_info(self.0.as_ref())
}
}
#[must_use]
pub fn server_info() -> ServerInfo {
let capabilities = ServerCapabilities::builder().enable_tools().build();
let server_info = Implementation::new(NAME, VERSION)
.with_title(TITLE)
.with_website_url(HOMEPAGE);
ServerInfo::new(capabilities).with_server_info(server_info)
}