//! MCP-server binary for the built-in hyperhive surface. Runs a long-lived //! streamable-http listener (the `hive-mcp-http` systemd unit) on `--http //! `; tools dispatch through `/run/hive/mcp.sock` back into the //! hyperhive broker. claude reconnects to the stable URL each turn via //! `--mcp-config`, avoiding the per-turn re-registration race. HTTP is the //! sole transport — there is no stdio mode. Sibling of `hive-agent` (the //! serve loop that renders the `--mcp-config` blob pointing here). //! //! Standalone bin crate: the MCP surface (`mcp/`) plus its small support //! modules (socket client, send allow-list, loose-end scanner, path //! resolver) live here rather than in the `hive-agent` harness lib, so the //! server binary doesn't link the whole turn loop. use std::path::PathBuf; use anyhow::Result; use clap::Parser; mod mcp; mod paths; mod send_allow; /// Per-agent MCP socket, bind-mounted from the host into every container. const DEFAULT_SOCKET: &str = "/run/hive/mcp.sock"; #[derive(Parser)] #[command(name = "hive-agent-mcp", about = "hyperhive MCP server")] struct Cli { /// Path to the per-agent MCP socket (bind-mounted from the host). #[arg(long, default_value = DEFAULT_SOCKET)] socket: PathBuf, /// Serve streamable-http on this address (e.g. `127.0.0.1:8790`). /// Bind loopback only. #[arg(long)] http: std::net::SocketAddr, } #[tokio::main] async fn main() -> Result<()> { tracing_subscriber::fmt() .with_env_filter( tracing_subscriber::EnvFilter::try_from_default_env() .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")), ) .init(); let cli = Cli::parse(); mcp::serve_http(cli.socket, cli.http).await }