mcp_ectors/
server_builder.rs1use 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 println!("Stopping MCP Server...");
42 match &self.transport {
43 Some(TransportActorEnum::Sse(transport_addr)) => {
44 transport_addr.do_send(StopTransport); },
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 transport_addr.do_send(StartTransport);
130 },
131 Some(TransportActorEnum::Wasi(transport_addr)) => {
132 transport_addr.do_send(StartTransport);
134 },
135 Some(TransportActorEnum::Stdio(transport_addr)) => {
136 transport_addr.do_send(StartTransport);
138 },
139 None => {
140 println!("No transport configured");
141 }
142 }
143
144 Ok(self)
145
146 }
147}