feat(#2112): make http-mcp the sole transport for the built-in surface

This commit is contained in:
damocles 2026-07-11 00:32:51 +02:00
commit 1ba44b77ac
6 changed files with 110 additions and 103 deletions

View file

@ -60,12 +60,13 @@ refused by the standard agent socket regardless of who sends them.)
- `hive-agent` — long-running harness loop (the inbox poll +
claude-pump + ack/requeue cycle described above).
- `hive-agent-mcp` — MCP server. Default: stdio child claude spawns
via `--mcp-config` per turn (the serve loop renders the config to
point at this sibling of its own `/proc/self/exe`). With
`--http <addr>`, runs as a persistent streamable-HTTP daemon
instead (used by the `hive-mcp-http` systemd unit when
`hyperhive.mcp.httpPort` is set).
- `hive-agent-mcp` — MCP server for the built-in `hyperhive` surface.
Run with `--http <addr>` as a persistent streamable-HTTP daemon (the
`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.)
- `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

@ -186,13 +186,13 @@ next turn picks it up like any other inbox message.
`hive_ag3nt::turn::write_*` writes two files next to the per-agent
socket at `/run/hive/` once at startup:
- `claude-mcp-config.json`by default re-invokes the running binary
as `mcp` stdio child (so the same binary serves as harness + MCP
server per turn). When `hyperhive.mcp.httpPort` is set in the
agent's NixOS config, the config instead points claude at the
persistent `hive-mcp-http` daemon (`http://127.0.0.1:{port}/mcp`)
— no stdio child per turn; trades the per-turn re-registration race
for a hard dependency on the daemon's uptime (`Restart=always`).
- `claude-mcp-config.json`points claude at the persistent
`hive-mcp-http` daemon (`http://127.0.0.1:{port}/mcp`, port from
`hyperhive.mcp.httpPort`, default 8790) for the built-in `hyperhive`
surface. HTTP is the sole transport for it — no per-turn stdio child,
so the URL survives the per-turn claude re-spawn (no re-registration
race), trading that for a hard dependency on the daemon's uptime
(`Restart=always`, no stdio fallback). Extra servers stay stdio.
- `claude-system-prompt.md` — rendered from
`hive-ag3nt/prompts/system.md` by `hive_ag3nt::prompt::render`:
HTML-comment markers (`<!-- role:agent -->...<!-- /role:agent -->`,

View file

@ -1,8 +1,16 @@
# MCP surface
The harness ships an embedded MCP server (rmcp 1.7). Claude launches
it as a stdio child via `--mcp-config`. The hyperhive socket name is
`hyperhive`, so the tools land in claude as `mcp__hyperhive__<tool>`.
The harness ships an embedded MCP server (rmcp 1.7). The built-in
`hyperhive` surface is served over streamable HTTP by a persistent
`hive-mcp-http` daemon (loopback, `127.0.0.1:<hyperhive.mcp.httpPort>`,
per-container private netns). Claude connects to its stable URL via
`--mcp-config` rather than respawning a stdio child each turn, so the
URL survives the per-turn claude re-spawn (and a host-side hive-c0re
restart) — there is no per-turn MCP re-registration race for the
built-in surface. HTTP is the sole transport for it (no stdio fallback);
extra servers (`hyperhive.extraMcpServers`, e.g. matrix/bash) stay stdio
bridges. The server name is `hyperhive`, so the tools land in claude as
`mcp__hyperhive__<tool>`.
Tool access is gated by tool groups (`HIVE_TOOL_GROUPS`). The default
preset (`AGENT_DEFAULT`) includes `messaging`, `meta`, `inbox`, and