Skip to main content

rmcp_server_builder/
builder.rs

1//! Builder for composing MCP servers from individual capability providers.
2
3use rmcp::model::{Implementation, ServerCapabilities, ServerInfo};
4
5use crate::providers::{
6    CompletionProvider, LoggingProvider, PromptsProvider, ResourcesProvider, ServerInfoProvider,
7    ToolsProvider,
8};
9use crate::server::{Server, Unset};
10
11/// Builder for constructing a composed MCP server.
12///
13/// # Example
14///
15/// ```ignore
16/// use rmcp_server_builder::ServerBuilder;
17/// use rmcp::model::Implementation;
18///
19/// let server = ServerBuilder::new()
20///     .info(Implementation::from_build_env())
21///     .tools(my_tools_provider)
22///     .prompts(my_prompts_provider)
23///     .build();
24/// ```
25pub struct ServerBuilder<T, P, R, C, L, I> {
26    tools: Option<T>,
27    prompts: Option<P>,
28    resources: Option<R>,
29    completion: Option<C>,
30    logging: Option<L>,
31    info: Option<I>,
32    instructions: Option<String>,
33}
34
35impl Default for ServerBuilder<Unset, Unset, Unset, Unset, Unset, Unset> {
36    fn default() -> Self {
37        Self::new()
38    }
39}
40
41impl ServerBuilder<Unset, Unset, Unset, Unset, Unset, Unset> {
42    /// Create a new server builder with no providers set.
43    pub fn new() -> Self {
44        Self {
45            tools: None,
46            prompts: None,
47            resources: None,
48            completion: None,
49            logging: None,
50            info: None,
51            instructions: None,
52        }
53    }
54}
55
56impl<T, P, R, C, L, I> ServerBuilder<T, P, R, C, L, I> {
57    /// Set the tools provider.
58    pub fn tools<NewT: ToolsProvider>(self, provider: NewT) -> ServerBuilder<NewT, P, R, C, L, I> {
59        ServerBuilder {
60            tools: Some(provider),
61            prompts: self.prompts,
62            resources: self.resources,
63            completion: self.completion,
64            logging: self.logging,
65            info: self.info,
66            instructions: self.instructions,
67        }
68    }
69
70    /// Set the prompts provider.
71    pub fn prompts<NewP: PromptsProvider>(
72        self,
73        provider: NewP,
74    ) -> ServerBuilder<T, NewP, R, C, L, I> {
75        ServerBuilder {
76            tools: self.tools,
77            prompts: Some(provider),
78            resources: self.resources,
79            completion: self.completion,
80            logging: self.logging,
81            info: self.info,
82            instructions: self.instructions,
83        }
84    }
85
86    /// Set the resources provider.
87    pub fn resources<NewR: ResourcesProvider>(
88        self,
89        provider: NewR,
90    ) -> ServerBuilder<T, P, NewR, C, L, I> {
91        ServerBuilder {
92            tools: self.tools,
93            prompts: self.prompts,
94            resources: Some(provider),
95            completion: self.completion,
96            logging: self.logging,
97            info: self.info,
98            instructions: self.instructions,
99        }
100    }
101
102    /// Set the completion provider.
103    pub fn completion<NewC: CompletionProvider>(
104        self,
105        provider: NewC,
106    ) -> ServerBuilder<T, P, R, NewC, L, I> {
107        ServerBuilder {
108            tools: self.tools,
109            prompts: self.prompts,
110            resources: self.resources,
111            completion: Some(provider),
112            logging: self.logging,
113            info: self.info,
114            instructions: self.instructions,
115        }
116    }
117
118    /// Set the logging provider.
119    pub fn logging<NewL: LoggingProvider>(
120        self,
121        provider: NewL,
122    ) -> ServerBuilder<T, P, R, C, NewL, I> {
123        ServerBuilder {
124            tools: self.tools,
125            prompts: self.prompts,
126            resources: self.resources,
127            completion: self.completion,
128            logging: Some(provider),
129            info: self.info,
130            instructions: self.instructions,
131        }
132    }
133
134    /// Set the server info provider.
135    pub fn info<NewI: ServerInfoProvider>(
136        self,
137        provider: NewI,
138    ) -> ServerBuilder<T, P, R, C, L, NewI> {
139        ServerBuilder {
140            tools: self.tools,
141            prompts: self.prompts,
142            resources: self.resources,
143            completion: self.completion,
144            logging: self.logging,
145            info: Some(provider),
146            instructions: self.instructions,
147        }
148    }
149
150    /// Set human-readable instructions for using this server.
151    pub fn instructions(mut self, instructions: impl Into<String>) -> Self {
152        self.instructions = Some(instructions.into());
153        self
154    }
155}
156
157// Build method - requires I to be set
158impl<T, P, R, C, L, I> ServerBuilder<T, P, R, C, L, I>
159where
160    I: ServerInfoProvider,
161{
162    /// Build the server.
163    ///
164    /// This will use `Unset` for any providers that weren't explicitly set,
165    /// which will return "method not found" errors for those capabilities.
166    pub fn build(self) -> Server<T, P, R, C, L, I> {
167        Server {
168            tools: self.tools,
169            prompts: self.prompts,
170            resources: self.resources,
171            completion: self.completion,
172            logging: self.logging,
173            info: self.info.expect("info provider is required"),
174            instructions: self.instructions,
175        }
176    }
177}
178
179// =============================================================================
180// ServerInfoProvider implementation for Implementation
181// =============================================================================
182
183impl ServerInfoProvider for Implementation {
184    fn get_info(&self) -> ServerInfo {
185        ServerInfo::new(ServerCapabilities::default()).with_server_info(self.clone())
186    }
187}
188
189/// A simple server info provider that wraps an Implementation.
190#[derive(Clone, Debug)]
191pub struct SimpleInfo {
192    pub server_info: Implementation,
193    pub capabilities: ServerCapabilities,
194}
195
196impl SimpleInfo {
197    /// Create a new SimpleInfo from an Implementation.
198    pub fn new(server_info: Implementation) -> Self {
199        Self {
200            server_info,
201            capabilities: ServerCapabilities::default(),
202        }
203    }
204
205    /// Set capabilities.
206    pub fn with_capabilities(mut self, capabilities: ServerCapabilities) -> Self {
207        self.capabilities = capabilities;
208        self
209    }
210}
211
212impl ServerInfoProvider for SimpleInfo {
213    fn get_info(&self) -> ServerInfo {
214        ServerInfo::new(self.capabilities.clone()).with_server_info(self.server_info.clone())
215    }
216
217    fn capabilities(&self) -> ServerCapabilities {
218        self.capabilities.clone()
219    }
220}