Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/docs/tools/bash.md
iris 2d1b6a4e1a docs/tools: the bash and matrix pages say what the tools do around the edges, not how to call them
Each page opens with its audience (the operator). The per-parameter tool
listings, which repeat the tools' own MCP descriptions, become short summaries
of the behaviour an operator needs: the completion todo, what status clears,
the process-group kill, the unread guard, how invites resolve. The wiring and
architecture sections are unchanged.
2026-10-26 17:56:39 +01:00

5.1 KiB

Bash execution tools

For the operator: this page covers the daemon as deployed and what the tools do around the edges. How an agent calls them is in the tools' own MCP descriptions.

Background shell execution via hive-bash-daemon. Tools land as mcp__bash__<tool> (the MCP server name is bash, not hyperhive). nix/agent-modules/mcp.nix registers bash into services.hyperhive.agent.extraMcpServers by default (lib.mkDefault, with allowedTools = ["*"]) — an agent.nix can override or drop the entry, so this is a default, not an unconditional grant. Even where the entry is present, the server is only actually rendered into an agent's claude config when the agent also holds the execution permission: extra_server_required_permission in hive-agent/src/mcp_config.rs suppresses it entirely without that permission, so an agent lacking execution gets no mcp__bash__* tools at all, not just an unused grant. The harness rewrites the config each turn, so a change applies at the next one. See "Relationship to the execution permission" below.

Tools

Each tool's parameters and return values are in its own MCP description, which is what an agent reads at call time. This section says what the tools do around the edges.

  • run submits a shell command (through bash) as a background task. Its stdout and stderr stream to harness/bash-tasks/<id>.{out,err}. When the task finishes, times out or its process errors, it surfaces as a todo in the agent's loose-ends, with the exit code and a pointer to the captured output. run waits up to 3 seconds (30 at most) for a result before it returns; a result delivered that way makes no todo. A caller-chosen name replaces the generated id. The daemon accepts the name again once its task has finished, and rejects it while the task is still pending or running.
  • status polls a task: its state (pending, running, done, timed_out, interrupted or killed), the exit code, the run time and the last 4 KiB of each stream. A call that sees a finished task clears its completion todo, since the agent already has the result; in a narrow race both can still appear. A task marked interrupted had its process killed by a harness restart, and a best-effort todo is still made so the agent isn't blocked silently.
  • kill stops a running or pending task and returns without waiting. The completion surfaces as a todo like any other. It signals the task's whole process group, so children the shell started stop too: SIGINT by default, SIGKILL with force. The daemon cancels a task still pending before it starts, and the task ends as killed.

Namespace note

run and status live in the bash MCP server, not hyperhive. The tool names in claude are mcp__bash__run and mcp__bash__status. hyperhive blocks the Bash built-in tool — all shell execution goes through this structured path so tasks get task-id tracking and structured output.

Architecture

hive-bash-daemon is a single long-running process (one per agent container, systemd service in nix/agent-modules/mcp.nix) — no stdio bridge. It owns subprocess management, output file writing, todo delivery on the harness's in-agent socket, and serves the run/status/kill MCP tools directly over streamable-http on services.hyperhive.agent.mcp.bashHttpPort (declared in services.hyperhive.agent.extraMcpServers.bash as { type = "http"; url = ...; }). Same shape as the built-in hyperhive surface (hive-mcp-http) — claude reconnects to the stable URL every turn instead of respawning a stdio child, so there's no per-turn MCP re-registration race and no round-trip socket hop for tool calls.

Completion as a todo (loose-ends v2)

When a bash task changes state, hive-bash-daemon upserts a single keyed todo (key = task id) on the harness's in-agent socket (HIVE_AGENT_SOCKET) — "running" at start, then the completion summary when it finishes. The summary change signals the harness turn loop directly (in-process, no broker round-trip), so the harness drives a turn for the agent to handle it via get_loose_ends, then clears the todo with cancel_loose_end(kind: "todo", id: N) (dials the in-container socket directly — no bash task involved, so clearing doesn't spawn another todo). Same mechanism the matrix daemon uses for unread rooms. An inline wait_seconds / status observation that already delivered the result instead clears the keyed todo, so no redundant loose-end follows.

Relationship to the execution permission

Permission::Execution (in Permission::DEFAULT) is the real gate on bash: extra_server_required_permission (in hive-agent/src/mcp_config.rs) controls whether the bash MCP server reaches the agent's claude config at all, suppressing every mcp__bash__* tool when absent — not just leaving them unused. Its own tools() returns &[]: mcp__bash__run/status/kill live on the separate bash MCP server that extra_server_required_permission gates, not on the mcp__hyperhive__* allowlist tools() builds. Removing execution from an agent's permissions does remove bash availability.