pub mod cli;
pub mod discovery;
pub mod errors;
pub mod federation;
pub mod health;
pub mod subsystem;
pub mod tool;
pub mod transport;
pub mod usb;
pub mod wire;
pub use cli::{CommonCli, LogLevel, McpTransport};
pub use discovery::{KeywordSearchEngine, ListMode, Scope, SearchEngine, ToolHit};
pub use errors::{DiscoveryError, McpError};
pub use federation::FederationAggregator;
pub use health::{HealthLevel, HealthStatus, SubsystemDescriptor};
pub use subsystem::{ConnectArgs, RingId, RingIdError, Subsystem};
pub use tool::{ToolDescriptor, ToolDescriptorError};
pub use transport::serve_mcp;
pub use usb::{
discover_by_name_pattern, discover_by_vid_pid, discover_composite_port_by_index, VidPid,
};
pub use wire::{WireFormat, WireNameTranslator};
pub fn init_tracing(log_level: cli::LogLevel) {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new(log_level.as_filter())),
)
.init();
}
pub async fn run<S: Subsystem>(subsystem: S, cli: CommonCli) -> Result<(), McpError> {
init_tracing(cli.log_level);
let mut s = subsystem;
let connect_args = ConnectArgs::from_cli(&cli)?;
s.connect(&connect_args).await?;
let transport = cli.transport.clone();
serve_mcp(s, transport).await
}
pub async fn run_federation(
subsystems: Vec<Box<dyn Subsystem>>,
cli: CommonCli,
) -> Result<(), McpError> {
init_tracing(cli.log_level);
let mut aggregator = FederationAggregator::new(subsystems, WireFormat::default());
let connect_args = ConnectArgs::from_cli(&cli)?;
aggregator.connect_all(&connect_args).await?;
let transport = cli.transport.clone();
serve_mcp(aggregator, transport).await
}