Skip to main content
Glama
aquaherd
by aquaherd

goose-herdr

A goose integration for Herdr — the terminal workspace manager for AI coding agents.

The repo ships two complementary pieces:

Piece

Direction

What it does

goose_herdr MCP extension

goose → Herdr

Exposes the herdr CLI as first-class goose tools: inspect workspaces/tabs/panes/agents, create layout, run commands, read output, wait for state.

agent-state/ hook plugin

goose → Herdr

Reports goose's lifecycle state (working / idle) to the Herdr pane hosting the goose session, so Herdr's sidebar shows goose correctly.

Both directions are "goose → Herdr". Herdr itself needs no code change: it detects agents by foreground process and exposes a local socket + CLI.


Prerequisites

  • goose installed.

  • Herdr installed and on your PATH (or HERDR_BIN_PATH set), with a Herdr server running.

The MCP extension works from any shell that can reach the Herdr server. The state-reporting hook only activates when goose itself is running inside a Herdr-managed pane (HERDR_ENV=1).


Install the MCP extension

goose extensions are MCP servers. The package exposes a herdr-mcp console script.

Option A — config file (persistent)

Add an entry under extensions in ~/.config/goose/config.yaml:

extensions:
  herdr:
    name: Herdr
    cmd: uvx
    args: ["--from", "git+https://github.com/aquaherd/goose-herdr", "herdr-mcp"]
    enabled: true
    envs: {}
    type: stdio
    timeout: 300

Once the package is published to PyPI, you can use the shorter form:

    args: ["--from", "goose-herdr", "herdr-mcp"]

Option B — interactive CLI

goose configure

Choose Add Extension → Command-line Extension, then enter:

uvx --from git+https://github.com/aquaherd/goose-herdr herdr-mcp

Option C — one-off session (not installed)

goose session --with-extension "uvx --from git+https://github.com/aquaherd/goose-herdr herdr-mcp"

Option D — local development install

git clone https://github.com/aquaherd/goose-herdr
cd goose-herdr
uv pip install -e .          # or: pip install -e .

Then register the extension with cmd: herdr-mcp (and empty args):

extensions:
  herdr:
    name: Herdr
    cmd: herdr-mcp
    args: []
    enabled: true
    envs: {}
    type: stdio
    timeout: 300

Install the state-reporting hook

Copy the agent-state/ directory into a goose plugin location, for example:

mkdir -p ~/.agents/plugins/goose-herdr-agent-state
cp -r agent-state/plugin.json agent-state/hooks agent-state/scripts \
  ~/.agents/plugins/goose-herdr-agent-state/
chmod +x ~/.agents/plugins/goose-herdr-agent-state/scripts/report-state.sh

This reports idle on SessionStart/Stop, working on UserPromptSubmit/PreToolUse, and releases the agent on SessionEnd. It is a no-op unless HERDR_ENV=1 and HERDR_PANE_ID are set (i.e. goose is running in a Herdr pane).

On SessionStart it also forwards the session identity (session_id from the hook payload) via herdr pane report-agent-session, so Herdr persists an agent_session reference for the pane.

SessionStart reports idle (not working) so a freshly started or restarted goose session is not shown as active in Herdr's sidebar until it actually begins working.

Resume caveat: this hook reports the session id only (goose stores sessions in sessions.db and resumes by id via goose session --resume --session-id <id>). Herdr persists the id but will not relaunch the pane on a Herdr restore by itself — that would require a Herdr-native goose integration. See Restore goose after a Herdr restart for the goose-herdr-restore command that works around this.


Restore goose after a Herdr restart

Herdr's resume_agents_on_restore only relaunches agents it has an official integration for, and goose is not one of them. The hook records each goose session's identity (pane id + session id) on SessionStart, and the goose-herdr-restore command relaunches goose in those panes after a Herdr restart.

goose-herdr-restore            # relaunch any goose sessions that are not running
goose-herdr-restore --dry-run  # preview without sending commands

Records live under ${XDG_STATE_HOME:-~/.local/state}/goose-herdr/restore/. The command skips panes where goose is already running, so it is safe to run repeatedly. Relaunch uses goose session --resume --session-id <id>, which restores the conversation; extensions come from your normal goose config.

For fully automatic restore, run it from a user timer (the herdr and goose binaries must be on PATH):

# ~/.config/systemd/user/goose-herdr-restore.service
[Unit]
Description=Restore goose sessions into Herdr panes

[Service]
Type=oneshot
ExecStart=%h/.local/bin/goose-herdr-restore
# ~/.config/systemd/user/goose-herdr-restore.timer
[Unit]
Description=Restore goose sessions into Herdr panes periodically

[Timer]
OnBootSec=10s
OnUnitActiveSec=30s

[Install]
WantedBy=timers.target
systemctl --user daemon-reload
systemctl --user enable --now goose-herdr-restore.timer

Tools

The extension registers herdr_* tools. The read-only ones are safe to call anytime; the rest perform one Herdr action each.

Group

Tools

Status / sessions

herdr_status, herdr_session_list, herdr_help

Workspaces

herdr_workspace_list, _get, _create, _focus, _rename, _close

Tabs

herdr_tab_list, _get, _create, _focus, _rename, _close

Panes

herdr_pane_list, _current, _get, _split, _read, _run, _send_text, _send_keys, _wait_output, _rename, _focus, _close

Agents

herdr_agent_list, _get, _read, _prompt, _send_keys, _rename, _focus, _wait, _start, _goose_restore

Agent states used by Herdr: idle, working, blocked, done, unknown.


Development

uv venv .venv
uv pip install --python .venv/bin/python -e .
.venv/bin/herdr-mcp            # starts the MCP server over stdio
.venv/bin/goose-herdr-restore  # restores goose sessions after a Herdr restart

The package uses the official mcp Python SDK (>= 2.0) and wraps the herdr CLI rather than speaking the raw socket protocol.