use rmcp::model::{Implementation, ServerCapabilities, ServerInfo};
use crate::providers::{
CompletionProvider, LoggingProvider, PromptsProvider, ResourcesProvider, ServerInfoProvider,
ToolsProvider,
};
use crate::server::{Server, Unset};
pub struct ServerBuilder<T, P, R, C, L, I> {
tools: Option<T>,
prompts: Option<P>,
resources: Option<R>,
completion: Option<C>,
logging: Option<L>,
info: Option<I>,
instructions: Option<String>,
}
impl Default for ServerBuilder<Unset, Unset, Unset, Unset, Unset, Unset> {
fn default() -> Self {
Self::new()
}
}
impl ServerBuilder<Unset, Unset, Unset, Unset, Unset, Unset> {
pub fn new() -> Self {
Self {
tools: None,
prompts: None,
resources: None,
completion: None,
logging: None,
info: None,
instructions: None,
}
}
}
impl<T, P, R, C, L, I> ServerBuilder<T, P, R, C, L, I> {
pub fn tools<NewT: ToolsProvider>(self, provider: NewT) -> ServerBuilder<NewT, P, R, C, L, I> {
ServerBuilder {
tools: Some(provider),
prompts: self.prompts,
resources: self.resources,
completion: self.completion,
logging: self.logging,
info: self.info,
instructions: self.instructions,
}
}
pub fn prompts<NewP: PromptsProvider>(
self,
provider: NewP,
) -> ServerBuilder<T, NewP, R, C, L, I> {
ServerBuilder {
tools: self.tools,
prompts: Some(provider),
resources: self.resources,
completion: self.completion,
logging: self.logging,
info: self.info,
instructions: self.instructions,
}
}
pub fn resources<NewR: ResourcesProvider>(
self,
provider: NewR,
) -> ServerBuilder<T, P, NewR, C, L, I> {
ServerBuilder {
tools: self.tools,
prompts: self.prompts,
resources: Some(provider),
completion: self.completion,
logging: self.logging,
info: self.info,
instructions: self.instructions,
}
}
pub fn completion<NewC: CompletionProvider>(
self,
provider: NewC,
) -> ServerBuilder<T, P, R, NewC, L, I> {
ServerBuilder {
tools: self.tools,
prompts: self.prompts,
resources: self.resources,
completion: Some(provider),
logging: self.logging,
info: self.info,
instructions: self.instructions,
}
}
pub fn logging<NewL: LoggingProvider>(
self,
provider: NewL,
) -> ServerBuilder<T, P, R, C, NewL, I> {
ServerBuilder {
tools: self.tools,
prompts: self.prompts,
resources: self.resources,
completion: self.completion,
logging: Some(provider),
info: self.info,
instructions: self.instructions,
}
}
pub fn info<NewI: ServerInfoProvider>(
self,
provider: NewI,
) -> ServerBuilder<T, P, R, C, L, NewI> {
ServerBuilder {
tools: self.tools,
prompts: self.prompts,
resources: self.resources,
completion: self.completion,
logging: self.logging,
info: Some(provider),
instructions: self.instructions,
}
}
pub fn instructions(mut self, instructions: impl Into<String>) -> Self {
self.instructions = Some(instructions.into());
self
}
}
impl<T, P, R, C, L, I> ServerBuilder<T, P, R, C, L, I>
where
I: ServerInfoProvider,
{
pub fn build(self) -> Server<T, P, R, C, L, I> {
Server {
tools: self.tools,
prompts: self.prompts,
resources: self.resources,
completion: self.completion,
logging: self.logging,
info: self.info.expect("info provider is required"),
instructions: self.instructions,
}
}
}
impl ServerInfoProvider for Implementation {
fn get_info(&self) -> ServerInfo {
ServerInfo::new(ServerCapabilities::default()).with_server_info(self.clone())
}
}
#[derive(Clone, Debug)]
pub struct SimpleInfo {
pub server_info: Implementation,
pub capabilities: ServerCapabilities,
}
impl SimpleInfo {
pub fn new(server_info: Implementation) -> Self {
Self {
server_info,
capabilities: ServerCapabilities::default(),
}
}
pub fn with_capabilities(mut self, capabilities: ServerCapabilities) -> Self {
self.capabilities = capabilities;
self
}
}
impl ServerInfoProvider for SimpleInfo {
fn get_info(&self) -> ServerInfo {
ServerInfo::new(self.capabilities.clone()).with_server_info(self.server_info.clone())
}
fn capabilities(&self) -> ServerCapabilities {
self.capabilities.clone()
}
}