1use crate::builder_utils::{AuthConfig, IpFilter};
4use crate::events::McpEventHandler;
5use crate::http::{HttpServerAdapter, HttpServerConfig, HttpServerInstance};
6use crate::protocol::ToolProtocol;
7use crate::server::UnifiedMcpServer;
8use std::error::Error;
9use std::net::SocketAddr;
10use std::sync::Arc;
11
12pub struct MCPServerBuilder {
14 server: UnifiedMcpServer,
15 ip_filter: IpFilter,
16 auth: AuthConfig,
17 adapter: Arc<dyn HttpServerAdapter>,
18 event_handler: Option<Arc<dyn McpEventHandler>>,
19}
20
21impl MCPServerBuilder {
22 pub fn new() -> Self {
24 Self {
25 server: UnifiedMcpServer::new(),
26 ip_filter: IpFilter::new(),
27 auth: AuthConfig::None,
28 adapter: Self::default_adapter(),
29 event_handler: None,
30 }
31 }
32
33 #[cfg(feature = "server")]
34 fn default_adapter() -> Arc<dyn HttpServerAdapter> {
35 Arc::new(crate::http::AxumHttpAdapter)
36 }
37
38 #[cfg(not(feature = "server"))]
39 fn default_adapter() -> Arc<dyn HttpServerAdapter> {
40 panic!(
41 "{}",
42 "MCPServerBuilder requires the 'server' feature to be enabled."
43 )
44 }
45
46 pub async fn with_custom_tool(
48 mut self,
49 tool_name: &str,
50 protocol: Arc<dyn ToolProtocol>,
51 ) -> Self {
52 self.server.register_tool(tool_name, protocol).await;
53 self
54 }
55
56 pub fn with_bearer_token(mut self, token: impl Into<String>) -> Self {
58 self.auth = AuthConfig::bearer(token);
59 self
60 }
61
62 pub fn with_basic_auth(
64 mut self,
65 username: impl Into<String>,
66 password: impl Into<String>,
67 ) -> Self {
68 self.auth = AuthConfig::basic(username, password);
69 self
70 }
71
72 pub fn allow_ip(mut self, ip: &str) -> Result<Self, String> {
74 self.ip_filter.allow(ip)?;
75 Ok(self)
76 }
77
78 pub fn allow_cidr(mut self, cidr: &str) -> Result<Self, String> {
80 self.ip_filter.allow(cidr)?;
81 Ok(self)
82 }
83
84 pub fn allow_localhost_only(mut self) -> Self {
86 let _ = self.ip_filter.allow("127.0.0.1");
87 let _ = self.ip_filter.allow("::1");
88 self
89 }
90
91 pub fn with_adapter(mut self, adapter: Arc<dyn HttpServerAdapter>) -> Self {
93 self.adapter = adapter;
94 self
95 }
96
97 pub fn with_event_handler(mut self, handler: Arc<dyn McpEventHandler>) -> Self {
99 self.event_handler = Some(handler);
100 self
101 }
102
103 pub async fn start_on(
105 self,
106 port: u16,
107 ) -> Result<HttpServerInstance, Box<dyn Error + Send + Sync>> {
108 self.start_at(SocketAddr::from(([127, 0, 0, 1], port)))
109 .await
110 }
111
112 pub async fn start_at(
114 self,
115 addr: SocketAddr,
116 ) -> Result<HttpServerInstance, Box<dyn Error + Send + Sync>> {
117 let bearer_token = match self.auth {
118 AuthConfig::None => None,
119 AuthConfig::Bearer(token) => Some(token),
120 AuthConfig::Basic { .. } => {
121 return Err("Basic auth is not supported by the generic MCP HTTP adapter".into())
122 }
123 };
124
125 self.adapter
126 .start(
127 HttpServerConfig {
128 addr,
129 bearer_token,
130 ip_filter: self.ip_filter,
131 event_handler: self.event_handler,
132 },
133 Arc::new(self.server),
134 )
135 .await
136 }
137}
138
139impl Default for MCPServerBuilder {
140 fn default() -> Self {
141 Self::new()
142 }
143}