use super::daemon_utils::{daemon_base_url, http_addr_path};
use anyhow::Result;
use colored::Colorize;
pub async fn handle_serve(no_http: bool, port: u16, http: Option<String>) -> Result<()> {
let daemon_url = daemon_base_url();
let bind_addr: Option<String> = if no_http {
None
} else if let Some(addr) = http {
Some(addr)
} else {
Some(format!("127.0.0.1:{port}"))
};
let server = crate::mcp::McpServer::new(daemon_url.clone());
match bind_addr {
Some(addr) => serve_http(server, addr, &daemon_url).await,
None => {
eprintln!(
"{} MCP stdio (no HTTP) → daemon {}",
"◉".green(),
daemon_url.dimmed()
);
crate::mcp::stdio::run(server).await?;
Ok(())
}
}
}
async fn serve_http(server: crate::mcp::McpServer, addr: String, daemon_url: &str) -> Result<()> {
let listener = tokio::net::TcpListener::bind(&addr).await?;
let local = listener.local_addr()?;
let addr_file = http_addr_path();
if let Some(ref path) = addr_file {
if let Some(parent) = path.parent() {
let _ = std::fs::create_dir_all(parent);
}
if let Err(e) = std::fs::write(path, format!("{local}\n")) {
eprintln!("{} could not write {}: {e}", "⚠".yellow(), path.display());
}
}
eprintln!(
"trusty-search v{} — HTTP admin panel: http://{}",
env!("CARGO_PKG_VERSION"),
local,
);
eprintln!(
"{} MCP HTTP/SSE on {} → daemon {}",
"◉".green(),
local.to_string().cyan(),
daemon_url.dimmed()
);
let app = crate::mcp::sse::router(server);
let serve_result = axum::serve(listener, app).await;
if let Some(path) = addr_file {
let _ = std::fs::remove_file(&path);
}
serve_result?;
Ok(())
}