use clap::Parser; use config::{Config, Environment, File}; use mcp_rs::error::McpError; use std::path::PathBuf; use mcp_rs::server::McpServer; use mcp_rs::server::config::{ServerConfig, TransportType}; // CLI Arguments #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] pub struct Cli { /// Config file path #[arg(short, long, value_name = "FILE")] config: Option, /// Transport type (stdio, sse, websocket) #[arg(short, long, default_value = "sse")] transport: String, /// Server port for network transports #[arg(short, long, default_value = "3000")] port: u16, /// Log level (error, warn, info, debug, trace) #[arg(short, long, default_value = "info")] log_level: String, /// Resource root directory #[arg(short, long)] resource_root: Option, } #[tokio::main] async fn main() -> Result<(), McpError> { tracing_subscriber::fmt::init(); let cli = Cli::parse(); // Load configuration let mut config = Config::builder(); // Add default config config = config.add_source(Config::try_from(&ServerConfig::default()).unwrap()); // Add config file if specified if let Some(config_path) = cli.config { config = config.add_source(File::from(config_path)); } // Add environment variables config = config.add_source(Environment::with_prefix("MCP")); // Build config let mut server_config: ServerConfig = config.build().unwrap().try_deserialize().unwrap(); // Override with CLI arguments if let Some(resource_root) = cli.resource_root { server_config.resources.root_path = resource_root; } server_config.logging.level = cli.log_level; server_config.server.port = cli.port; server_config.server.transport = match cli.transport.as_str() { "stdio" => TransportType::Stdio, "sse" => TransportType::Sse, "websocket" => TransportType::WebSocket, _ => return Err(McpError::Custom { code: -32000, message: "Invalid transport type".to_string(), }), }; // Create and run server let mut server = McpServer::new(server_config); server.run().await }