mcp_ectors/
server_builder.rs

1use actix::{Actor, Addr};
2use tracing_appender::rolling::{RollingFileAppender, Rotation};
3use tracing_subscriber::EnvFilter;
4use crate::client::ClientRegistryActor;
5use crate::mcp::InitializationActor;
6use crate::messages::{StartTransport, StopTransport};
7use crate::router::RouterServiceManager;
8use crate::transport::transport_config::Config;
9use crate::transport::{SseTransportActor, StdioTransportActor, WasiTransportActor};
10use crate::utils::LogConfig;
11
12pub const SERVER: &str = "Multi MCP Router Server";
13pub const VERSION: &str = "0.1.0";
14pub enum TransportActorEnum
15{
16    Sse(Addr<SseTransportActor>),
17    Wasi(Addr<WasiTransportActor>),
18    Stdio(Addr<StdioTransportActor>),
19}
20pub struct McpServer{
21    router_service_manager: Option<RouterServiceManager>,
22    transport_config: Option<Config>,
23    log_config: Option<LogConfig>,
24    transport: Option<TransportActorEnum>,
25}
26
27impl McpServer
28{
29    pub fn new() -> Self {
30        Self {
31            router_service_manager: None,
32            transport_config: None,
33            log_config: None,
34            transport: None,
35        }
36    }
37
38
39    pub fn stop(&self) {
40        // Stop the server with the configured router and transport
41        println!("Stopping MCP Server...");
42        match &self.transport {
43            Some(TransportActorEnum::Sse(transport_addr)) => {
44                transport_addr.do_send(StopTransport); // Assuming TransportRequest has Stop variant
45            },
46            Some(TransportActorEnum::Wasi(transport_addr)) => {
47                transport_addr.do_send(StopTransport); 
48            },
49            Some(TransportActorEnum::Stdio(transport_addr)) => {
50                transport_addr.do_send(StopTransport);
51            },
52            None => {
53                println!("No transport configured");
54            }
55        }
56    }
57
58    pub fn router_manager(mut self,  router_service_manager: RouterServiceManager) -> Self {
59        self.router_service_manager = Some(router_service_manager);
60        self
61    }
62
63    pub fn transport(mut self, transport_config: Config) -> Self {
64        self.transport_config = Some(transport_config);
65        self
66    }
67
68    pub fn with_logging(mut self, log_config: LogConfig) -> Self {
69        let file_appender = RollingFileAppender::new(Rotation::DAILY, log_config.clone().log_dir, log_config.clone().log_file);
70        
71        tracing_subscriber::fmt()
72            .with_env_filter(EnvFilter::from_default_env().add_directive(log_config.level.into()))
73            .with_writer(file_appender)
74            .with_target(false)
75            .with_thread_ids(true)
76            .with_file(true)
77            .with_line_number(true)
78            .init();
79        self.log_config = Some(log_config.clone());
80        self
81    }
82
83    pub fn start(mut self) -> std::result::Result<Self, std::string::String> {
84        
85        if self.router_service_manager.is_none() || self.transport_config.is_none() {
86            return Err("Missing required configuration".to_string());
87        }
88        let router_registry = self.router_service_manager.as_ref().unwrap().get_registry();
89        let list_prompts_actor = self.router_service_manager.as_ref().unwrap().get_list_prompts();
90        let list_tools_actor = self.router_service_manager.as_ref().unwrap().get_list_tools();
91        let list_resources_actor = self.router_service_manager.as_ref().unwrap().get_list_resources();
92        let client_registry = ClientRegistryActor::new().start();
93        let transport_config = self.transport_config.as_ref().unwrap().clone();
94
95        let transport = match transport_config {
96            Config::Sse(sse_transport) => {
97                let addr = SseTransportActor::new(
98                    sse_transport, 
99                    client_registry, 
100                    router_registry, 
101                    InitializationActor::new(),
102                    list_prompts_actor,
103                    list_tools_actor,
104                    list_resources_actor,
105                ).start();
106                TransportActorEnum::Sse(addr)
107            },
108            Config::Wasi(wasi_transport_config) => {
109                let addr = WasiTransportActor::new(
110                    wasi_transport_config, 
111                    client_registry, 
112                        router_registry,
113                    list_prompts_actor,
114                list_tools_actor,
115            list_resources_actor).unwrap().start();
116                TransportActorEnum::Wasi(addr)
117            },
118            Config::Stdio(_stdio_transport_config) => {
119                let addr = StdioTransportActor::new(router_registry).start();
120                TransportActorEnum::Stdio(addr)
121            },
122        };
123
124        self.transport = Some(transport);
125
126        match &self.transport {
127            Some(TransportActorEnum::Sse(transport_addr)) => {
128                // Start the SseTransportActor
129                transport_addr.do_send(StartTransport);
130            },
131            Some(TransportActorEnum::Wasi(transport_addr)) => {
132                // Start the WasiTransportActor
133                transport_addr.do_send(StartTransport); 
134            },
135            Some(TransportActorEnum::Stdio(transport_addr)) => {
136                // Start the StdioTransportActor
137                transport_addr.do_send(StartTransport);
138            },
139            None => {
140                println!("No transport configured");
141            }
142        }
143
144        Ok(self)
145
146    }
147}