`require_descendant` (`socket_server/mod.rs:666`) authorises
kill/start/restart/update/get_logs with `topology::is_descendant_of` — the
caller's whole subtree, itself included. That has been true since `53b4e752`
(#1865), whose message says "a parent owns its whole subtree; the root covers
every agent as a consequence, no positional privilege", and two tests pin it
(`is_descendant_of_in_grandchild`, `is_descendant_of_in_self_is_true`).
The prose never followed. The four lifecycle tool descriptions, their
`// IMPORTANT:` comments, `docs/tools/lifecycle.md`, the tools README,
hive-agent-mcp's README and the system prompt every agent is rendered from all
still said "direct children only" — while `list_containers`, four tools away in
the same file, said "direct children + their subtrees".
`lifecycle.md` also taught the model #1865 deleted: "Privileged agents (for
example ruth) may operate on any sub-agent — the topology scope applies to all
others." There is no privileged class to belong to; ruth reaches every agent
because the check is transitive and everything sits under it.
Same drift on the state-query side: `resolve_agent_state_target` is
subtree-scoped by the same commit, so `get_loose_ends`' argument doc, the
`QueryAgentState` capability doc and `docs/turn-loop/mcp.md` were all telling a
parent it needs a capability to read a grandchild's threads.
Two smaller corrections found on the way:
* `list_containers` returns the caller itself. `is_descendant_of` is true for
`candidate == ancestor` and `handle_list_descendants` filters the topology
with it; called from a leaf agent it answers one row, that agent.
* `request_init_config` accepts any unused name — the requester becomes its
parent — or an existing agent already in the caller's subtree, not "a direct
child". The editing surface is narrower than the guard, though: only direct
children's config repos are bind-mounted, so re-seeding deeper in the subtree
leaves no local copy to edit. `lifecycle.md` now says so.
The prompt's other stale claim, the dead `request_apply_commit`, is #4226 and
was fixed independently by damocles in #4227 while this was being gated. This
branch keeps only the scope wording on that line.
Closes #4225.
34 lines
1.6 KiB
Markdown
34 lines
1.6 KiB
Markdown
# hive-agent-mcp
|
|
|
|
The built-in hyperhive MCP server every agent gets by default. Runs a
|
|
long-lived streamable-http listener (the `hive-mcp-http` systemd unit)
|
|
that claude reconnects to each turn via `--mcp-config` — this avoids
|
|
the per-turn stdio re-registration race that a spawned-per-turn server
|
|
would hit. HTTP is the sole transport; there is no stdio mode here.
|
|
|
|
## When to use it
|
|
|
|
This is where the core hyperhive tool surface lives: `send`, `recv`,
|
|
`remind`, `get_loose_ends`, `set_status`,
|
|
`get_agent_meta`, lifecycle (`kill`/`start`/`restart`/`update` on the
|
|
agent's own subtree), scheduling, and the approval-request tools. Reach
|
|
for this crate when you're adding or changing a built-in tool rather
|
|
than an `extraMcpServers` add-on — those are separate stdio bridges
|
|
(see `hive-bash-mcp`, `hive-matrix-mcp`) that dial the harness socket
|
|
or their own daemon instead of living here.
|
|
|
|
## Shape
|
|
|
|
- **`mcp/`** — the tool surface itself: one handler per tool, dispatch
|
|
through `client.rs` back into the hyperhive broker
|
|
(`/run/hive/mcp.sock`) or, for loose-ends v2 (todos/reminders), the
|
|
in-agent socket the `hive-agent` harness serves.
|
|
- **`client.rs`** — socket client to the hyperhive broker.
|
|
- **`send_allow.rs`** — enforces the per-agent
|
|
`hyperhive.allowedRecipients` allow-list on `send`.
|
|
- **`paths.rs`** — socket + state path resolution shared with the
|
|
harness's own `paths.rs` conventions.
|
|
|
|
Sibling of `hive-agent` (the serve loop that renders the
|
|
`--mcp-config` blob pointing here). Standalone bin crate so the
|
|
always-on MCP server doesn't need to link the whole turn-loop lib.
|