1use std::sync::Arc;
2
3use crate::types::{
4 prompt::Prompt,
5 resource::{Resource, ResourceTemplate},
6 tool::Tool,
7 ServerInfo,
8};
9
10use crate::server::{
11 cancellation::CancellationManager,
12 core::McpServer,
13 handler::{
14 CompletionHandler, PromptHandler, PromptHandlerFn, ResourceHandler, ResourceHandlerFn,
15 ToolHandler, ToolHandlerFn,
16 },
17 router::Router,
18};
19
20#[cfg(feature = "auth")]
21use crate::auth::DynAuthProvider;
22
23#[cfg(feature = "plugin")]
24use crate::plugin::PluginManager;
25
26pub struct McpServerBuilder {
28 name: String,
29 version: String,
30 instructions: Option<String>,
31 router: Router,
32 #[cfg(feature = "auth")]
33 auth_provider: Option<DynAuthProvider>,
34 #[cfg(feature = "auth")]
35 require_auth: bool,
36 #[cfg(feature = "plugin")]
37 plugin_manager: Option<PluginManager>,
38}
39
40impl McpServerBuilder {
41 pub fn new() -> Self {
42 Self {
43 name: "mcp-server".to_owned(),
44 version: "0.1.0".to_owned(),
45 instructions: None,
46 router: Router::new(),
47 #[cfg(feature = "auth")]
48 auth_provider: None,
49 #[cfg(feature = "auth")]
50 require_auth: true,
51 #[cfg(feature = "plugin")]
52 plugin_manager: None,
53 }
54 }
55
56 pub fn name(mut self, name: impl Into<String>) -> Self {
58 self.name = name.into();
59 self
60 }
61
62 pub fn version(mut self, version: impl Into<String>) -> Self {
64 self.version = version.into();
65 self
66 }
67
68 pub fn instructions(mut self, instructions: impl Into<String>) -> Self {
70 self.instructions = Some(instructions.into());
71 self
72 }
73
74 #[cfg(feature = "auth")]
95 pub fn auth(mut self, provider: DynAuthProvider) -> Self {
96 self.auth_provider = Some(provider);
97 self.require_auth = true;
98 self
99 }
100
101 #[cfg(feature = "auth")]
106 pub fn optional_auth(mut self, provider: DynAuthProvider) -> Self {
107 self.auth_provider = Some(provider);
108 self.require_auth = false;
109 self
110 }
111
112 pub fn tool<M>(mut self, tool: Tool, handler: impl ToolHandler<M>) -> Self {
116 self.router.add_tool(tool, handler.into_handler_fn());
117 self
118 }
119
120 pub fn tool_def(mut self, def: ToolDef) -> Self {
122 self.router.add_tool(def.tool, def.handler);
123 self
124 }
125
126 pub fn tool_fn<M>(
128 mut self,
129 name: impl Into<String>,
130 description: impl Into<String>,
131 handler: impl ToolHandler<M>,
132 ) -> Self {
133 self.router.add_tool(
134 Tool::no_params(name, description),
135 handler.into_handler_fn(),
136 );
137 self
138 }
139
140 pub fn resource<M>(mut self, resource: Resource, handler: impl ResourceHandler<M>) -> Self {
144 self.router
145 .add_resource(resource, handler.into_handler_fn());
146 self
147 }
148
149 pub fn resource_template<M>(
151 mut self,
152 template: ResourceTemplate,
153 handler: impl ResourceHandler<M>,
154 ) -> Self {
155 self.router
156 .add_resource_template(template, handler.into_handler_fn());
157 self
158 }
159
160 pub fn resource_def(mut self, def: ResourceDef) -> Self {
162 match def {
163 ResourceDef::Static { resource, handler } => {
164 self.router.add_resource(resource, handler);
165 }
166 ResourceDef::Template { template, handler } => {
167 self.router.add_resource_template(template, handler);
168 }
169 }
170 self
171 }
172
173 pub fn prompt<M>(mut self, prompt: Prompt, handler: impl PromptHandler<M>) -> Self {
177 self.router.add_prompt(prompt, handler.into_handler_fn());
178 self
179 }
180
181 pub fn prompt_def(mut self, def: PromptDef) -> Self {
183 self.router.add_prompt(def.prompt, def.handler);
184 self
185 }
186
187 pub fn completion<M>(mut self, handler: impl CompletionHandler<M>) -> Self {
212 self.router
213 .set_completion_handler(handler.into_handler_fn());
214 self
215 }
216
217 pub fn resource_completion<M>(
221 mut self,
222 uri_pattern: impl Into<String>,
223 handler: impl CompletionHandler<M>,
224 ) -> Self {
225 self.router
226 .add_resource_completion(uri_pattern.into(), handler.into_handler_fn());
227 self
228 }
229
230 pub fn prompt_with_completion<M1, M2>(
234 mut self,
235 prompt: Prompt,
236 handler: impl PromptHandler<M1>,
237 completion: impl CompletionHandler<M2>,
238 ) -> Self {
239 self.router.add_prompt_with_completion(
240 prompt,
241 handler.into_handler_fn(),
242 completion.into_handler_fn(),
243 );
244 self
245 }
246
247 #[cfg(feature = "plugin")]
269 pub fn with_plugin_manager(mut self, plugin_manager: PluginManager) -> Self {
270 self.plugin_manager = Some(plugin_manager);
271 self
272 }
273
274 #[cfg(all(feature = "plugin", feature = "plugin-native"))]
291 pub fn load_plugin(mut self, path: &str) -> crate::McpResult<Self> {
292 let manager = self.plugin_manager.get_or_insert_with(PluginManager::new);
293 manager.load_from_path(path)?;
294 Ok(self)
295 }
296
297 #[cfg(all(feature = "plugin", feature = "plugin-native"))]
299 pub fn load_plugin_with_config(
300 mut self,
301 path: &str,
302 config: crate::plugin::PluginConfig,
303 ) -> crate::McpResult<Self> {
304 let manager = self.plugin_manager.get_or_insert_with(PluginManager::new);
305 manager.load_from_path_with_config(path, config)?;
306 Ok(self)
307 }
308
309 pub fn build(mut self) -> McpServer {
312 #[cfg(feature = "plugin")]
314 if let Some(plugin_manager) = &self.plugin_manager {
315 tracing::debug!("Registering plugin tools, resources, and prompts");
316
317 for tool_def in plugin_manager.collect_tools() {
319 self.router.add_tool(tool_def.tool, tool_def.handler);
320 }
321
322 for resource_def in plugin_manager.collect_resources() {
324 self.router
325 .add_resource(resource_def.resource, resource_def.handler);
326 }
327
328 for prompt_def in plugin_manager.collect_prompts() {
330 self.router
331 .add_prompt(prompt_def.prompt, prompt_def.handler);
332 }
333 }
334
335 McpServer {
336 info: ServerInfo::new(self.name, self.version),
337 instructions: self.instructions,
338 router: Arc::new(self.router),
339 cancellation: CancellationManager::new(),
340 #[cfg(feature = "auth")]
341 auth_provider: self.auth_provider,
342 #[cfg(feature = "auth")]
343 require_auth: self.require_auth,
344 }
345 }
346}
347
348impl Default for McpServerBuilder {
349 fn default() -> Self {
350 Self::new()
351 }
352}
353
354pub struct ToolDef {
358 pub tool: Tool,
359 pub handler: ToolHandlerFn,
360}
361
362impl ToolDef {
363 pub fn new(tool: Tool, handler: ToolHandlerFn) -> Self {
364 Self { tool, handler }
365 }
366}
367
368pub enum ResourceDef {
372 Static {
373 resource: Resource,
374 handler: ResourceHandlerFn,
375 },
376 Template {
377 template: ResourceTemplate,
378 handler: ResourceHandlerFn,
379 },
380}
381
382impl ResourceDef {
383 pub fn new_static(resource: Resource, handler: ResourceHandlerFn) -> Self {
384 Self::Static { resource, handler }
385 }
386
387 pub fn new_template(template: ResourceTemplate, handler: ResourceHandlerFn) -> Self {
388 Self::Template { template, handler }
389 }
390}
391
392pub struct PromptDef {
396 pub prompt: Prompt,
397 pub handler: PromptHandlerFn,
398}
399
400impl PromptDef {
401 pub fn new(prompt: Prompt, handler: PromptHandlerFn) -> Self {
402 Self { prompt, handler }
403 }
404}