use std::error::Error;
use std::sync::Arc;
use clap::Parser;
use dravr_tronc::mcp::transport::{http, stdio};
use dravr_tronc::server::cli::McpArgs;
use dravr_tronc::server::tracing_init;
use dravr_tronc::McpServer;
use embacle::types::RunnerError;
use embacle_mcp::runner::{parse_runner_type, valid_provider_names};
use embacle_mcp::ServerState;
use tokio::sync::RwLock;
#[derive(Parser)]
#[command(name = "embacle-mcp", version, about)]
struct Cli {
#[command(flatten)]
server: McpArgs,
#[arg(long, default_value = "copilot")]
provider: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let cli = Cli::parse();
tracing_init::init(&cli.server.transport);
let provider = parse_runner_type(&cli.provider).ok_or_else(|| {
RunnerError::config(format!(
"Unknown provider: {}. Valid: {}",
cli.provider,
valid_provider_names()
))
})?;
let state = Arc::new(RwLock::new(ServerState::new(provider)));
let registry = embacle_mcp::build_tool_registry();
let server = Arc::new(McpServer::new(
"embacle-mcp",
env!("CARGO_PKG_VERSION"),
registry,
state,
));
tracing::info!(
transport = %cli.server.transport,
provider = %provider,
"Starting embacle MCP server"
);
match cli.server.transport.as_str() {
"stdio" => stdio::run(server).await?,
"http" => {
http::serve(server, &cli.server.host, cli.server.port).await?;
}
other => {
return Err(RunnerError::config(format!(
"Unknown transport: {other}. Valid: stdio, http"
))
.into());
}
}
Ok(())
}