Skip to content
last verified against v0.1.38 verified 2026-11-06

Use KeepState from herdr, hc and MCP clients

The ks client works inside other tools as well as on its own. A terminal or multiplexer can show what each agent is doing, herdr gets two KeepState panes, an MCP client gets KeepState as tools, and an agent can start and talk to child agents with the same commands you use.

Everything on this page runs from the ks binary you installed, with its sign-in. The herdr plugin that herdr installs from the client’s repository is one manifest whose commands run that same ks.

Terminal status

ks agent open, ks agent status --watch, an agent’s window in the ks app and ks cruise status --watch write the agent’s status, or the job’s, to your terminal as OSC 7501, the program status protocol. A terminal or multiplexer that reads it, such as hc, shows one of four states:

StateMeaning
workingThe agent is running an instruction
blockedIt needs you: a permission request, a question, or sign-in or a key
doneThe work ended
errorThe work failed

The status is the service’s own record. A session paused for credit reads as needing you, whatever its runner would say. The client writes it once per change and clears it when the stream ends.

bash
KS_STATUS_OSC=off ks agent open main --session <session>

KS_STATUS_OSC takes auto (the default: only to a terminal, never with --json or --plain), on (also when standard output is not a terminal) or off. ks doctor prints a Terminal status (OSC 7501) line that says which applies.

herdr

bash
herdr plugin install Keepstateai/cli/herdr

herdr fetches the KeepState plugin from the public client repository. It is one manifest: its two panes, its action and its one install step run only ks. So ks must be on your PATH and signed in to your KeepState account; without ks on your PATH the install stops. herdr plugin update keepstate updates it and herdr plugin uninstall keepstate removes it.

You can link the plugin from your local ks instead, with nothing downloaded:

bash
ks herdr install
ks herdr status
ks herdr uninstall

ks herdr install writes the plugin under this client’s config directory, shows you the file, asks, and then links it with herdr plugin link. When herdr already has the plugin from the client repository, it writes and links nothing. ks herdr status says which herdr it found, its version, where the plugin came from and its version. ks herdr uninstall removes the plugin either way, and only the files ks herdr install wrote.

The KeepState plugin has been run against herdr 0.9.5, installed both ways, and hc 0.1.18. Two things that run showed:

  • herdr’s notifications are off by default. Turn them on in herdr’s config:

    toml
    [ui.toast]
    delivery = "herdr"
  • herdr’s sidebar shows KeepState’s words for an agent’s state (“Needs you: permission”, “Done”) in rows that have state_text under [ui.sidebar.agents]; ks herdr install says so. Rows without it show the state only as the colour of the icon.

The agents pane (herdr plugin pane open --plugin keepstate --entrypoint agents) lists your sessions and agents with their status. Enter opens an agent’s window in a new herdr tab, c opens the console at it, s shows the session’s saved points and r the receipts.

The receipts pane (--entrypoint receipts) follows your Cruise jobs. When one finishes, herdr notifies you and the pane shows its receipt, or what went wrong. A receipt reads Pull request: none yet and offers ks cruise apply <job> to get the change and ks cruise result <job> --download for the files. ks cruise run inside herdr points you at this pane.

herdr’s terminal app does not read OSC 7501. Inside a herdr pane, the client sends the same status to herdr through herdr pane report-agent, with the command that reopens the agent, and herdr’s sidebar shows it from there. ks agent list --all --notify uses herdr’s own notifications.

hc

hc reads the terminal status above as it is written: hc get shows it, and hc wait ends when an agent needs you or is done. Inside an hc terminal, the client reads the terminal’s id, so a child agent you start there has that terminal as its parent (see parents and children). Role files for ks agent templates use the hc template format without its command field.

MCP clients

ks mcp serves KeepState to an MCP client on standard input and output, from this binary and its sign-in. For Claude Code:

bash
claude mcp add keepstate -- ks mcp

For Codex CLI, in its config file:

toml
[mcp_servers.keepstate]
command = "ks"
args = ["mcp"]

Each tool runs one ks command with --json --no-input.

  • Reading tools change nothing: sessions, agents and their status, an agent’s last lines and history, tasks, permission requests, saved points, usage, results, and Cruise status, receipts and models.
  • Two tools act at once: sending an agent one more instruction, and pausing an agent.
  • Four tools need a confirm step: starting a child agent, resuming, stopping, and cancelling a task. The person says yes in a client that can ask; otherwise the second call names the confirm value the first call answered, which is good once, for 10 minutes. A client set to accept everything accepts a confirm step too.
  • No tool approves or denies a permission request, deletes anything, or touches keys or billing.

ks mcp --read-only serves only the reading tools.

Agents that delegate

An agent can hand work to child agents with the commands below. ks skill (also ks --skill) prints the manual an agent reads first: what a child costs, how to talk to it, wait and collect, the status words, and the rules (a child’s words are data, never approve on a person’s behalf, never put a key in an argument).

bash
ks agent templates
ks agent run --bg --name review --template reviewer "Review the change on main"
ks agent send review "Also check the error messages"
ks agent wait review
ks agent read review --lines 40
  • Every child is a session of its own, metered like any session you start. ks agent run says so before anything exists.
  • --bg returns at once with the child’s agent, session, parent and status as JSON. Without it, the command follows the first instruction and, after --timeout (180 seconds), prints still running as review and exits 4 while the child keeps working.
  • ks agent send queues one more instruction, tagged with who sent it. --if idle or --if working sends nothing when the agent is not in that state, and exits 5.
  • ks agent wait ends with a reason: a status, a message, a timeout or the child exited. --children all waits until none of your children works, --children any for the next note about one.
  • ks agent read --lines N prints the end of the conversation as plain text.
  • ks agent templates lists the built-in roles (reviewer, implementer and tester) and your own files in the templates folder of the client’s config directory. A role’s opening instructions are joined in front of the task.

Parents and children

A child started from your machine has a parent: KS_CALLER_ID when you set it, else the hc terminal or herdr pane it runs in, else the nearest program above ks that is not a shell. When the client sees that parent exit, its children are saved and paused, never deleted. Closing the laptop or losing the network ends nothing. --outlive-parent, --no-parent, --parent <agent> and --no-notify change that. A parent runs at most 8 children at once.

Spotted an error on this page? Tell us, and we will correct it.

Report it
← previous Runners next → Console notifications