refactor(#2112): remove the dead stdio transport from hive-agent-mcp

This commit is contained in:
damocles 2026-07-11 00:55:41 +02:00
commit 4745274fca
3 changed files with 19 additions and 39 deletions

View file

@ -65,8 +65,7 @@ refused by the standard agent socket regardless of who sends them.)
`hive-mcp-http` systemd unit, on `hyperhive.mcp.httpPort`, default
8790); claude connects to its URL via `--mcp-config`. HTTP is the sole
transport — no per-turn stdio child (eliminates the re-registration
race). (A stdio mode still exists in the binary but isn't wired for
the built-in surface.)
race).
- `hive-agent-wake --from <name> --body <body>` — push a message into
our own inbox so the next turn fires with the given body. Used by
co-process helpers (scrapers, webhook listeners) to nudge claude on

View file

@ -1,9 +1,9 @@
//! MCP-server binary. Default is stdio — spawned by `claude` via
//! `--mcp-config`; tools dispatch through `/run/hive/mcp.sock` back into
//! the hyperhive broker. Pass `--http <addr>` to instead run a long-lived
//! streamable-http listener (persistent daemon, the `hive-mcp-http`
//! systemd unit) that claude reconnects to each turn, avoiding the
//! per-turn stdio re-registration race. Sibling of `hive-agent` (the
//! MCP-server binary for the built-in hyperhive surface. Runs a long-lived
//! streamable-http listener (the `hive-mcp-http` systemd unit) on `--http
//! <addr>`; 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) and
//! `hive-agent-wake`.
@ -20,10 +20,10 @@ struct Cli {
#[arg(long, default_value = DEFAULT_SOCKET)]
socket: PathBuf,
/// Serve over streamable-http on this address (e.g.
/// `127.0.0.1:8790`) instead of stdio. Bind loopback only.
/// Serve streamable-http on this address (e.g. `127.0.0.1:8790`).
/// Bind loopback only.
#[arg(long)]
http: Option<std::net::SocketAddr>,
http: std::net::SocketAddr,
}
#[tokio::main]
@ -36,8 +36,5 @@ async fn main() -> Result<()> {
.init();
let cli = Cli::parse();
match cli.http {
Some(addr) => mcp::serve_http(cli.socket, addr).await,
None => mcp::serve_agent_stdio(cli.socket).await,
}
mcp::serve_http(cli.socket, cli.http).await
}

View file

@ -1,12 +1,13 @@
//! Embedded MCP server. Claude Code (running inside the agent container)
//! launches this as a stdio child via `--mcp-config`; tool calls land here
//! and are translated to `AgentRequest::*` / `ManagerRequest::*` against
//! hyperhive's own per-container unix socket at `/run/hive/mcp.sock`.
//! connects to this over streamable-HTTP via `--mcp-config` (the long-lived
//! `hive-mcp-http` daemon); tool calls land here and are translated to
//! `AgentRequest::*` / `ManagerRequest::*` against hyperhive's own
//! per-container unix socket at `/run/hive/mcp.sock`.
//!
//! Two protocols, two surfaces:
//! - **hyperhive socket** at `/run/hive/mcp.sock` — JSON-line, our
//! broker-routed protocol. Unaffected by this module.
//! - **MCP stdio** owned by this module — what claude actually speaks.
//! - **MCP over HTTP** owned by this module — what claude actually speaks.
//!
//! One `AgentServer { socket }` struct for all roles.
//! Tool access is gated upstream by `--allowedTools` (derived from the
@ -17,10 +18,7 @@ use std::future::Future;
use std::path::PathBuf;
use anyhow::Result;
use rmcp::{
ServerHandler, ServiceExt, handler::server::wrapper::Parameters, tool, tool_handler,
tool_router, transport::stdio,
};
use rmcp::{ServerHandler, handler::server::wrapper::Parameters, tool, tool_handler, tool_router};
use crate::client;
@ -1011,24 +1009,10 @@ impl AgentServer {
)]
impl ServerHandler for AgentServer {}
/// Run the MCP server over stdio. Used by all roles. Returns when the client
/// disconnects.
///
/// # Errors
///
/// Returns an error if the MCP server fails to initialize or the transport
/// encounters a fatal error.
pub async fn serve_agent_stdio(socket: PathBuf) -> Result<()> {
let server = AgentServer::new(socket);
let service = server.serve(stdio()).await?;
service.waiting().await?;
Ok(())
}
/// Run the MCP server over HTTP (rmcp streamable-http transport) on `addr`.
///
/// Unlike [`serve_agent_stdio`] — a fresh stdio child claude respawns every turn —
/// this is meant to run as a long-lived in-container daemon. claude reconnects
/// This is the sole transport for the built-in hyperhive surface. It runs as a
/// long-lived in-container daemon. claude reconnects
/// to the stable URL each turn instead of respawning and re-registering a stdio
/// subprocess, which removes the per-turn MCP registration race that can strand
/// an agent when the async `initialize`/`tools/list` loses to claude's first