use std::path::Path;
use anyhow::Result;
use colored::Colorize;
use tracing::{debug, info};
use crate::cli::server::resolve_servers;
use crate::cli::OutputFormat;
use crate::ui::{ConnectionSpinner, MultiServerProgress, OutputMode, Printer};
use crate::validator::ProtocolValidator;
pub async fn run(
server: Option<&str>,
config: Option<&Path>,
_features: Option<Vec<String>>,
timeout: u64,
format: OutputFormat,
) -> Result<()> {
let servers = resolve_servers(server, config)?;
let output_mode = if matches!(format, OutputFormat::Text) {
OutputMode::detect()
} else {
OutputMode::Plain };
let printer = Printer::with_mode(output_mode);
let multi_progress = MultiServerProgress::new(output_mode, servers.len());
let mut all_passed = true;
for spec in &servers {
let name = &spec.name;
let command = &spec.command;
let args = &spec.args;
let env = &spec.env;
info!("Validating MCP server: {} ({})", name, command);
debug!(
"Args: {:?}, Env: {:?}, Timeout: {}s",
args,
env.keys().collect::<Vec<_>>(),
timeout
);
if matches!(format, OutputFormat::Text) && !multi_progress.is_enabled() {
printer.separator();
println!("{} {}", "Validating:".cyan(), name.yellow().bold());
println!(" Command: {} {}", command, args.join(" ").dimmed());
if !env.is_empty() {
println!(" Env: {} variables", env.len());
}
printer.newline();
}
let mut spinner = ConnectionSpinner::new(output_mode);
spinner.start(name);
let validator = ProtocolValidator::new(command, args, env.clone(), timeout);
spinner.phase_initializing();
let results = match validator.validate().await {
Ok(r) => {
if r.failed > 0 {
spinner.finish_error(&format!(
"{}: {} passed, {} failed",
name, r.passed, r.failed
));
} else {
spinner.finish_success(&format!("{}: {} passed", name, r.passed));
}
r
}
Err(e) => {
spinner.finish_error(&format!("{}: {}", name, e));
return Err(e);
}
};
multi_progress.server_complete(name);
match format {
OutputFormat::Text => {
results.print_text();
}
OutputFormat::Json => {
results.print_json()?;
}
OutputFormat::Sarif => {
results.print_sarif()?;
}
OutputFormat::Junit | OutputFormat::Gitlab | OutputFormat::Html => {
results.print_json()?;
}
}
if results.failed > 0 {
all_passed = false;
}
printer.newline();
}
multi_progress.finish();
if servers.len() > 1 {
printer.separator();
if all_passed {
printer.success("All servers passed validation");
} else {
printer.error("Some servers failed validation");
}
}
Ok(())
}