mod elicit;
mod server;
mod watch;
use std::process::ExitCode;
use std::sync::Arc;
use anyhow::{Context, Result};
use rmcp::ServiceExt;
use tokio::sync::Mutex;
use tracing::info;
use uuid::Uuid;
use crate::socket_client::SocketClient;
use server::AstridMcpServer;
pub(crate) async fn serve(principal: Option<&str>) -> Result<ExitCode> {
let caller = crate::context::resolve_agent(principal)
.context("Failed to resolve principal for `astrid mcp serve`")?;
let socket_path = crate::socket_client::proxy_socket_path();
if !socket_path.exists() {
anyhow::bail!(
"No Astrid daemon is running (socket not found at {}). \
Start it with `astrid start` before launching `astrid mcp serve`.",
socket_path.display()
);
}
let session = astrid_core::SessionId::from_uuid(Uuid::new_v4());
let client = SocketClient::connect(session)
.await
.context("Failed to connect to the Astrid daemon socket")?;
info!(
principal = %caller,
"astrid mcp serve: uplink established, starting MCP stdio transport"
);
let server = AstridMcpServer::new(Arc::new(Mutex::new(client)), caller.to_string());
let running = server
.serve(rmcp::transport::stdio())
.await
.context("Failed to start MCP stdio transport")?;
let peer = running.peer().clone();
tokio::spawn(watch::run(peer, caller.to_string()));
let quit_reason = running
.waiting()
.await
.context("MCP stdio transport terminated abnormally")?;
info!(?quit_reason, "astrid mcp serve: MCP transport closed");
Ok(ExitCode::SUCCESS)
}