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:
| State | Meaning |
|---|---|
| working | The agent is running an instruction |
| blocked | It needs you: a permission request, a question, or sign-in or a key |
| done | The work ended |
| error | The 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.
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
herdr plugin install Keepstateai/cli/herdrherdr 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:
ks herdr install
ks herdr status
ks herdr uninstallks 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:
[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_textunder[ui.sidebar.agents];ks herdr installsays 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:
claude mcp add keepstate -- ks mcpFor Codex CLI, in its config file:
[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).
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 runsays so before anything exists. --bgreturns 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), printsstill running as reviewand exits 4 while the child keeps working.ks agent sendqueues one more instruction, tagged with who sent it.--if idleor--if workingsends nothing when the agent is not in that state, and exits 5.ks agent waitends with a reason: a status, a message, a timeout or the child exited.--children allwaits until none of your children works,--children anyfor the next note about one.ks agent read --lines Nprints the end of the conversation as plain text.ks agent templateslists the built-in roles (reviewer, implementer and tester) and your own files in thetemplatesfolder 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.