use clap::Parser;
use winx_code_agent::{start_winx_server, Result, WinxError};
#[derive(Parser)]
#[command(name = "winx")]
#[command(author = "Gabriel Maia")]
#[command(version)]
#[command(about = "High-performance MCP server for shell and file operations", long_about = None)]
struct Cli {
#[arg(short, long)]
verbose: bool,
#[arg(long)]
debug: bool,
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(clap::Subcommand)]
enum Commands {
Serve {
#[arg(long)]
debug_mode: bool,
#[arg(long)]
http: bool,
#[arg(long, default_value = "127.0.0.1:8000")]
bind: String,
#[arg(long)]
token: Option<String>,
#[arg(long = "allowed-host")]
allowed_host: Vec<String>,
},
}
fn setup_logging(verbose: bool, debug: bool) {
let level = if debug {
tracing::Level::DEBUG
} else if verbose {
tracing::Level::INFO
} else {
tracing::Level::WARN
};
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::from_default_env().add_directive(level.into()),
)
.with_writer(std::io::stderr)
.with_ansi(true)
.init();
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
setup_logging(cli.verbose, cli.debug);
match cli.command {
Some(Commands::Serve { http: true, bind, token, allowed_host, .. }) => {
run_http_server(bind, token, allowed_host).await
}
None | Some(Commands::Serve { .. }) => run_server().await,
}
}
async fn run_http_server(
bind: String,
token: Option<String>,
allowed_hosts: Vec<String>,
) -> Result<()> {
let token = token.or_else(|| std::env::var("WINX_HTTP_TOKEN").ok()).unwrap_or_default();
tracing::info!("Starting winx remote MCP (HTTP) v{} on {bind}", env!("CARGO_PKG_VERSION"));
winx_code_agent::http_server::start_http_server(&bind, token, allowed_hosts)
.await
.map_err(|e| WinxError::ShellInitializationError(format!("HTTP server failed: {e}")))
}
async fn run_server() -> Result<()> {
tracing::info!("Starting winx MCP server v{}", env!("CARGO_PKG_VERSION"));
match start_winx_server().await {
Ok(()) => {
tracing::info!("Server shutting down normally");
Ok(())
}
Err(e) => {
tracing::error!("Server error: {}", e);
Err(WinxError::ShellInitializationError(format!("Failed to start server: {e}")))
}
}
}