agent-hq-mcp
v0.15.0
Published
Local stdio MCP server that runs coding tasks through OpenCode or trusted CLI worker profiles.
Maintainers
Readme
Agent HQ MCP
A coding agent should not grade its own homework. Agent HQ turns one MCP registration into a local control plane for other vendors' coding agents: a Claude Code session can hand work to Codex, Cursor, or free OpenCode-routed models — and get genuinely independent reviews and second opinions back.
agent_workflowruns standard review, schema-constrained adversarial review, or rescue as one durable logical operation through one exact qualified route or ordered panel. Foreground work returns the final operation result from one caller-visible invocation; background work returns oneoperation_id, never one orchestration obligation per worker.agent_reviewandagent_delegateremain low-level compatibility fan-out. They never silently replace a requested model, but callers must poll their individual job ids. The legacyagent_reviewadversarial strategy is rejected because native Codex review cannot satisfy the pinned structured contract.agent_consiliumruns the same prompt through an exact panel of detached, no-workspace advisors; each report stays independent and the host owns synthesis.- One per-user daemon owns worker processes and durable SQLite state. Jobs survive MCP host restarts and adapter disconnects; any host using the same trusted config can pick results back up.
agent_modelsis a routing catalog with auth readiness and empirical per-model reliability from your own run history — model choice backed by evidence, not vibes.- A localhost console (FLEET / LEDGER / SHEETS / RIG) shows the live worker topology and durable history; its deliberately narrow write surface is confirmed by hand in the launching terminal, operation by operation.
Published on npm as agent-hq-mcp
(the bare name agent-hq is blocked by npm's similar-name rule); the binaries
and the MCP registration name are agent-hq.
Why not native subagents?
Native subagents are the default for same-family work they can satisfy because they retain the host's richest context and coordination. Explicit user choice of Agent HQ still wins within capabilities Agent HQ can enforce. Agent HQ exists for what native delegation cannot do:
- Cross-vendor judgment. A host's native subagents run the host vendor's models. Agent HQ routes exact model ids to Codex, Cursor Agent, Claude Code, or OpenCode workers, so a review panel can disagree with the model that wrote the code.
- Durability. Workers are owned by a daemon, not the host process. Closing or restarting the host does not kill running jobs; results and bounded, durable event timelines are retrievable afterward from any adapter.
- Global admission.
maxConcurrentJobsis enforced across all connected hosts, and a running write job takes an overlapping-path workspace lease so two agents cannot mutate the same tree concurrently. - Observed vs. asserted results.
files_changedandcommands_runcome only from completed worker tool events, never from prose; summaries record their provenance, and structuralfailure_tagsdistinguish timeouts and auth failures from bad answers.
Which backends work where?
Agent HQ exposes a model only where its runner has a verified execution boundary. Installation or login alone is not enough, and a missing model in a panel picker is therefore a capability decision rather than a UI fallback.
| Backend | Prompt-only advice | Repository read/review | Workspace write | | --- | --- | --- | --- | | OpenCode | verified | verified | verified | | Claude Code | verified | verified | verified | | Codex CLI | not verified: no detached boundary | verified | verified | | Cursor Agent | not verified: no detached boundary | verified | verified | | Antigravity | verified | not verified: no repository boundary | not verified: no repository boundary |
Here, verified means the built-in runner has an enforceable contract for that execution mode. It does not mean a model is ready merely because its CLI is installed: authentication, configuration, and the current executable still have to pass their live checks. A detached boundary gives the worker no repository; a repository boundary constrains what it can read or change.
- Prompt-only advice runs through
agent_consiliumwithworkspace_mode:"none". Every member needs thedetachedcapability, so Codex CLI and Cursor Agent are intentionally absent from that picker. - Repository read/review uses a read-only workspace boundary. Antigravity is absent because its non-interactive runner has not demonstrated that boundary; its detached contract must not be treated as repository read-only.
- Workspace write requires an explicit write-capable runner and still uses overlapping-path leases to prevent concurrent writers.
- Qualified workflows are narrower.
agent_workflowadditionally requires current exact evidence for the requested model, runner, workflow, mode, template, output contract, harness, and executable identity. A model being available for ordinary review does not automatically qualify it for Standard Review, Adversarial Review, Risk Queue, or Rescue.
The saved workspace panel (defaultPanel) and prompt-only panel
(defaultConsiliumPanel) are intentionally separate. Each accepts from one to
twenty ordered model slots, including deliberate replicas, and may not exceed
maxConcurrentJobs. RIG filters each picker by the capability that panel
actually requires and shows the verified uses for every installed backend.
Architecture at a glance
flowchart LR
Task["Host task"] --> Choice{"Native agent satisfies it?"}
Choice -->|"Same-family automatic path"| Native["Host-native agents"]
Choice -->|"Cross-family, managed, or explicit Agent HQ"| MCP["Agent HQ MCP adapter"]
MCP --> Daemon["Authenticated per-user daemon"]
Daemon --> Workflow["Durable qualified workflow<br/>one logical operation"]
Workflow --> Workspace["Workspace-aware<br/>review / rescue"]
Daemon --> Legacy["Compatibility fan-out<br/>review / delegate / spawn"]
Legacy --> Workspace
Daemon --> Consilium["Prompt-only consilium<br/>workspace_mode: none"]
Workspace --> Workers["Verified OpenCode / CLI workers"]
Consilium --> Isolated["Private empty cwd + deny boundary"]
Isolated --> Workers
Workers --> State["SQLite jobs/events + redacted transcripts"]
State --> Synthesis["Host retrieves one logical result<br/>or low-level job results"]
Native --> SynthesisThe detailed process, trust, detached-runner, and config-activation flows are in ARCHITECTURE.md.
Quick start: zero to a working panel
Requires Node >= 24.15 on the machine running Agent HQ. Workers additionally need whichever agent CLI they invoke. Developed and tested on macOS — see Platform support.
1. Register the server with your MCP host (pick your host, once):
# Claude Code
claude mcp add agent-hq --scope user -- npx -y agent-hq-mcp# Codex ~/.codex/config.toml
[mcp_servers.agent_hq]
command = "npx"
args = ["-y", "agent-hq-mcp"]After a global install (npm install -g agent-hq-mcp) use agent-hq as the
command instead of npx -y agent-hq-mcp. agent-hq register detects and
repairs Claude Code, Codex, and Cursor registrations interactively. Restart
the host after registering; the first MCP connection starts the local job
daemon automatically.
Command notation. Except for a command generated by Agent HQ itself,
agent-hq … in this guide is shorthand. Run the current installation's server
entry with the same --config <path> used by that installation (when one was
specified); this matters for npx, direct package-manager, and local/source
runs. A CLI or RIG safe-stop command is the authoritative paste-safe form for
its current server entry and config—copy it unchanged.
2. Run a first job with zero config — a free OpenCode model, no API key:
curl -fsSL https://opencode.ai/install | bash # skip if opencode is installedIn the restarted host, call runner_doctor, then use agent_models to choose a
ready read-only model explicitly:
agent_review { "cwd": "/absolute/project/path", "models": ["opencode/deepseek-v4-flash-free"] }
agent_delegate { "cwd": "/absolute/project/path", "mode": "read_only", "models": ["opencode/deepseek-v4-flash-free"], "prompt": "Explain this repository." }Zero-config mode restricts workers to the directory the server was launched
from and creates no defaultPanel. Free models can queue: poll agent_status
(its last_activity_at is only the time of the most recent emitted output;
buffered workers can remain quiet), inspect agent_events when useful, then
read agent_result after terminal status. The shared database keeps capacity, overlapping write leases,
and recursion defense machine-wide, so zero-config intentionally supports one
launch-directory policy at a time. A host launched from another directory is
refused rather than silently widening access; runner_doctor names the active
conflict and safe stop/restart sequence. For concurrent roots, register every
host with one explicit trusted config whose allowedRoots lists them.
3. Configure default panels. Run agent-hq init for stable allowed
roots and guided setup. Interactive init also offers host registration and then
the separate broad MCP auto-approval setting, both independently consented and
with approval defaulting to No. Fresh setup uses the same capability-aware model catalog
as RIG: it independently seeds defaultPanel from verified read-only models and
defaultConsiliumPanel from verified detached models. A single compatible model
is seeded honestly as a one-slot panel; family diversity remains visible advice,
not a reason to leave a runnable panel unconfigured. Unsupported capabilities
leave their corresponding panel absent and init prints the exact missing capability instead of claiming
they are ready. Direct CLI candidates also pass a read-only login-status probe;
a signed-out Codex, Claude, Cursor, or Antigravity CLI is shown with its login
command and excluded from panel seeding (a configured Cursor API key is an
accepted substitute for Cursor login). Activate a saved configuration
explicitly: after active jobs finish, run the generated safe-stop command for
the matching old installation and config, then restart the MCP host. Stopping
the daemon terminates active workers. A host restart alone can reconnect to an
existing daemon; it does not reload the daemon's boot-time trusted
configuration, and a mixed configuration is deliberately refused.
RIG treats a missing config as SETUP REQUIRED, with agent-hq init as the
primary action. It never labels zero-config mode as a live saved configuration.
If init creates the file or an invalid config is repaired while RIG is open,
the sheet detects the load-state transition through a narrow authenticated
probe and refreshes its full setup snapshot.
4. Use a qualified workflow. agent_workflow accepts an exact route or an
ordered one-to-twenty-route panel, additionally bounded by maxConcurrentJobs. Omit models to use defaultPanel exactly;
duplicate ids intentionally request independent replicas. Dynamic selectors do
not inherit qualification and are rejected. The checked-in
workflow-by-route matrix
is authoritative: a pending, unavailable, expired, or executable-mismatched row
fails before credentials, evidence capture, admission, or spawn.
The current matrix qualifies all eight combinations of
codex/gpt-5.6-sol or claude/sonnet with standard review, adversarial review,
read-only rescue, and write rescue. The source-backed gate combines candidate
v2 run e2a72420-ea84-4d04-99ac-4321e7dee2b6 (24 managed exact-worker jobs)
with public v2 run fc92e3d5-6469-46d5-83b0-2e1f58408a35 (36 MCP workflow
jobs), including separate worker and logical lifecycle controls plus committed
branch targets for every review cell. The candidate adversarial artifacts also
contain one direct raw-output bootstrap probe per exact runner, outside the
24-job count, because ordinary low-level jobs use canonical report wrapping;
the public run proves integrated raw_v1. The registry references 102
digest-verified observations under workflow-parity-harness-v2, valid through
2026-10-14T10:42:45.212Z while every bound identity still matches.
This does not qualify aliases or future rows: any unrecorded, changed, pending,
or stale cell still fails closed.
Published qualification evidence uses privacy v2: shared recursive redaction,
semantic placeholders instead of machine-specific paths, and no
transcript_ref, log_tail, or prompt_preview. Package verification rejects
non-portable or sensitive bytes across the whole evidence tree before checking
the 102 source-referenced path/digest pairs.
agent_workflow { "workflow": "standard_review", "cwd": "/absolute/project/path", "models": ["codex/gpt-5.6-sol"], "execution": "wait" }
agent_workflow { "workflow": "adversarial_review", "cwd": "/absolute/project/path", "models": ["codex/gpt-5.6-sol", "claude/sonnet"], "focus": "Find security regressions", "execution": "background" }
agent_workflow { "workflow": "rescue", "cwd": "/absolute/project/path", "models": ["claude/sonnet"], "prompt": "Diagnose the failing build.", "mode": "read_only" }The caller-visible invocation budget is exact. execution:"wait" is one
agent_workflow call returning the terminal logical result. Background is one
start call followed only by optional agent_workflow_status reads, one
agent_workflow_result, or agent_workflow_cancel, all keyed by the same
operation_id; panel size adds no per-member calls. Internally the adapter
waits by polling short authenticated daemon reads with one deadline. A timeout
or disconnect leaves the durable operation running, and an ambiguous start is
never replayed. agent_workflow_list pages retained parents and recovers a lost
operation_id, including operations whose member admission failed completely.
Qualified Claude Code 2.1.211 workers emit one strict JSON result envelope. The
adapter requires the exact qualified 20-key shape, explicit success and
terminal_reason:"completed", a maximum 1 MiB line, and at most 32 permission
denials. It retains only final text, the denial count, and tool-name/action
digests; session ids, UUIDs, cost, usage, timings, raw tool inputs, attempted
content, paths, and commands are discarded. Shape drift is a surfaced parse
failure. Normal job summaries stay within 4,000 characters; a differing
redacted full report is retained up to 64 KiB and paged through
agent_result detail:"report", while workflow results keep their separate
120,000-byte aggregate bound. Raw standard reviews are usable without cosmetic
headings or vendor-specific markers. Strict adversarial JSON is validated only
at the workflow boundary against the retained final response.
For the currently qualified typed routes, that response is Claude's verified
JSON-envelope result text or native codex exec review stdout. OpenCode
multi-part text remains raw-only until an exact final-message contract is
qualified.
There is no separate workflow setup path. Use runner_doctor (or
agent-hq doctor) for installation/auth/config diagnosis and agent_models to
select exact routable ids, then let the workflow qualification registry enforce
the narrower route/workflow contract. Resume, native session transfer, and the
host Stop gate are present as explicit fail-closed capability cells until a
real backend adapter or host integration is qualified; Agent HQ does not replace
them with transcript prompting or a fail-open heuristic.
The existing agent_review, agent_delegate, and agent_consilium tools remain
for one compatibility release when a caller explicitly needs raw jobs. Their
result is still jobs[], so the caller owns every job lifecycle and synthesis.
agent_review strategy:"adversarial" is obsolete and fails with a remediation
to use agent_workflow workflow:"adversarial_review".
Prompt-only advisory panels use the separate defaultConsiliumPanel, or an
explicit ordered list of detached-capable models:
agent_consilium { "models": ["antigravity/gemini-3.1-pro", "opencode/deepseek-v4-flash-free"], "prompt": "Stress-test this architecture." }Every setup step also has an unattended form for CI or a coding agent:
agent-hq init --yes --root <dir> [--profiles ...] [--dry-run],
agent-hq doctor --json, and agent-hq register (prints snippets without a
TTY). --root is never guessed: allowedRoots is the security boundary workers
run inside. agent-hq init --yes never touches provider keys, host hints, or
host approval policy.
Optional host hint
Package installation, MCP startup, registration, and unattended init never inject persistent instructions into Claude Code or Codex. Interactive init offers the optional hint separately for each host, with No as the default. The same explicit flow is available later:
agent-hq hint # per-host y/N install or update
agent-hq hint --claude --yes # explicit unattended Claude-only opt-in
agent-hq hint --codex --yes # explicit unattended Codex-only opt-in
agent-hq hint --remove --claude # per-host removal confirmation
agent-hq hint --remove --codex --yes # explicit unattended Codex-only removalClaude Code and Codex receive SessionStart hooks in ~/.claude/settings.json
and ~/.codex/hooks.json, respectively. Both emit the same short, static,
config-independent availability reminder as additional developer context:
Native-first by default; Agent HQ adds managed workflows and cross-family
perspectives alongside the host’s native model. The Codex file includes the
top-level string description required by the native hook-file schema. The hint
does not probe configuration, SQLite, models, authentication, or daemon
readiness, and it makes no model-availability promise. Always-on MCP
instructions remain capability-neutral.
Install/update/removal is idempotent, preserves unrelated host content, and
fails closed on malformed or ambiguous owned markers or hook structures.
Best-effort migration cleanup of a superseded Claude CLAUDE.md or Codex
AGENTS.md block is separate: a malformed or concurrently edited sibling is
left unchanged with a warning after the selected SessionStart hook succeeds.
Codex requires the newly installed command hook to be reviewed and trusted with
/hooks before it runs; the installer prints that activation step. When Codex
lifecycle hooks are disabled, interactive installation asks separately before
enabling them and writes no Codex hint if consent is declined. --codex --yes
is explicit unattended consent to both enable the native hook feature and
install the selected hint; a failed enablement aborts before the hook is written.
Claude hooks installed by Agent HQ 0.11.1 or earlier become active again as
soon as they invoke a version whose session-brief emits this restored static
payload; remove one explicitly with agent-hq hint --remove --claude if that
is not wanted. The compatibility-only --config accepted by old hook commands
does not affect the payload.
Optional broad MCP auto-approval
Registration does not imply tool approval. After registration, interactive
agent-hq init offers a separate default-No choice for Claude Code and Codex,
or the same operation can be run directly:
agent-hq approvals # per-host y/N opt-in
agent-hq approvals --claude --yes # explicit Claude-only consent
agent-hq approvals --codex --yes # explicit Codex-only consent
agent-hq approvals --remove --claude # remove the exact Claude wildcard
agent-hq approvals --remove --codex --yes # remove the owned Codex blockThis is intentionally broad. Enabling it requests auto-approval for every
current Agent HQ MCP tool and every Agent HQ tool added by future updates.
Those tools can send private repository or prompt content to configured
external providers and can start, write, cancel, or inspect worker
activity. The CLI prints this warning even with --yes; package installation,
update, MCP startup, registration, and unattended init never enable the setting.
Claude receives the documented mcp__agent-hq__* user allow rule in
~/.claude/settings.json. Codex receives an Agent-HQ-owned
default_tools_approval_mode = "approve" block inside its existing
[mcp_servers.agent_hq] section. Both writers require an existing Agent HQ
registration, lock and re-read the host file, create a 0600 backup, replace it
atomically, verify the result, and restore the previous file after a failed
post-write check. Removal touches only the exact Claude rule or exact owned
Codex marker block; a manually authored Codex approve value is left alone.
Symlinked, malformed, duplicated, raced, or conflicting host configurations
fail closed. Restart the changed host afterward. Managed organization policy
or hooks may override user settings, and Codex can still require approval for
tools marked destructive. Agent HQ does not falsify tool annotations or enable
Codex's global --dangerously-bypass-approvals-and-sandbox mode. The command
therefore reports configured user intent and does not claim effective approval.
No Agent HQ trusted-config, SQLite, daemon-protocol, or stored-job migration is required. This feature adds only an explicitly consented host-config mutation.
Cold-start convergence contract
For each fresh configuration, Agent HQ either writes and doctor-verifies a
panel whose installed runner can enforce the required capability, or labels
that capability unavailable before the first tool call with a concrete
remediation. It never seeds an unverified CLI template, substitutes a
workspace-aware worker for detached consilium, or reports LIVE for a missing
or invalid trusted config. A successful version probe is not treated as proof
of CLI authentication. Existing-config repair and package update remain
narrow: they preserve valid optional operator policy and never invent an absent
panel merely because a newer release can recommend one.
Platform support
Agent HQ is developed and tested on macOS. The keychain secret backend is
macOS-only (hardcoded /usr/bin/security; on other platforms the store
reports unavailable and environment variables still work). The daemon uses a
0600 Unix socket under /tmp on POSIX and has a Windows named-pipe code
path, but Linux and Windows have not been verified end to end — treat them as
unsupported until they have been.
Security model
Agent HQ assumes the parent MCP host is trusted but the repositories workers run in are not. It is built around these invariants:
- Config is loaded only from trusted locations (
--config,AGENT_HQ_CONFIG,~/.config/agent-hq/config.jsonc) — never from the process working directory, which may be an untrusted repo. - Workers get a minimal environment: a fixed allowlist (
PATH,HOME, locale, …) plus exactly one provider credential for the selected model — never the server's full environment. - Default worker profiles deny web access: a worker reading an untrusted repo with outbound fetch is an exfiltration channel, so web tools are a per-profile operator opt-in.
- One redaction policy owns every egress — results, log tails, transcripts, and errors are scrubbed for provider key formats, env/argv secrets, and URL-embedded credentials before anything leaves the server.
- Secrets flow one way: provider keys live in the OS keychain, are read per spawn, and no tool, log, doctor report, or console response ever returns a stored value — presence and source only.
- No nested spawning: every worker env carries a recursion flag, and the daemon independently rejects a new server whose process ancestry contains a running or process-quarantined Agent HQ worker recorded in the job database.
- The console binds to localhost only, requires a random per-process
browser token, and
every operation on its narrow write surface is confirmed with
y/Nin the launching terminal.
The source repository is not public today. What you install is still
inspectable: the server code in the tarball is unbundled per-module JavaScript
compiled directly from the TypeScript sources (the browser console UI is the
one Vite-bundled asset under dist/console/) — run npm pack agent-hq-mcp
(or read the installed copy) and audit dist/ plus the shipped config schema
to check these commitments against the code that actually runs.
Data retention
The state directory (default ~/.local/state/agent-hq) holds the daemon's
SQLite job history — prompts, redacted results, and event timelines for the
newest 1000 jobs — plus redacted per-job transcripts and the daemon log.
Retention prunes beyond 1000 jobs but keeps running, quarantined, and
lease-holding rows. To remove everything: agent-hq daemon stop, delete the
state directory, and remove stored keys with agent-hq secrets rm <provider>
(keychain entries are separate from the state directory).
Install and update (optional)
npx -y agent-hq-mcp needs no install. For the agent-hq and
agent-hq-console binaries on your PATH:
npm install -g agent-hq-mcp
agent-hq update # update the global install in place (alias: upgrade)update only mutates a genuine npm-global install (from npx caches or source
checkouts it prints the right steps and exits nonzero). It takes a
cross-process lease, refuses while jobs run, stops an idle daemon, verifies
the configured registry's online latest metadata, installs that exact target,
requires the installed entry to report the same version, runs deterministic
config repair through the newly installed entry, then the doctor and managed-
console activation. An exit-zero update therefore means the trusted config
selected for that invocation (--config, AGENT_HQ_CONFIG, or the standard
home path) is correct on disk and the idle pre-update daemon was stopped. Every
successful update explicitly tells the operator to restart the MCP host; do not
restart after a nonzero update result. A bare update cannot discover a host
registration's nonstandard --config path, so pass that same path to update.
Other install routes do not use npm postinstall to mutate trusted user state.
Normal MCP, daemon, and console activation only loads and validates the trusted
config; it never repairs or writes it. Run agent-hq init explicitly for a
compatibility repair. To apply any saved trusted-config change from any install
route, finish active work, run the generated safe-stop command for the matching
old installation and config, then restart the MCP host. A host restart remains
mandatory because Agent HQ cannot replace code already loaded by another
application, and it alone does not reload an existing daemon's trusted
configuration.
For a direct package-manager update or source rebuild, stop the old daemon before replacing the code: finish active work, run the generated stop command from the old matching installation and config, then install or rebuild and restart the MCP host. A newer wire protocol cannot safely administer an older daemon.
The explicit configuration contract is:
| New-version path | When reconciliation runs | What success guarantees |
| --- | --- | --- |
| agent-hq update [--config <path>] | Inside the update, through the newly installed binary, for the config selected by that invocation | Before exit 0: the exact registry target is installed and verified, deterministic repairs are persisted, the full selected config parses, required doctor checks pass, the idle pre-update daemon is stopped, and any recorded managed console is activated. The command then explicitly tells the operator to restart the MCP host. |
| Completed, non-dry-run agent-hq init | During mutating init, for both creation and repair | Before exit 0: the created/repaired config is persisted, reloads successfully, required doctor checks pass, and any recorded managed console is activated. Finish work, stop the daemon, then restart the MCP host before relying on any trusted-config change. |
| npx, direct package-manager install, or source checkout | Never implicitly; normal activation only loads and validates config | Invalid or obsolete config fails loudly. Run agent-hq init to repair it, then use the same explicit daemon-stop and host-restart sequence. |
Generation boundary. An intentional daemon stop—including an update's idle-daemon stop—retires that daemon generation. The paste-safe stop command is safe even when no daemon is running: it still records the boundary, so a stale already-running adapter cannot relaunch old policy. An unexpected daemon crash is different: an already-connected adapter may recover it only within that same package, deployment, and boot-time trusted-config generation. A saved disk edit or an in-place package replacement therefore cannot become live through crash reconnect; it requires the explicit stop-and-restart sequence.
No ordinary activation can change user configuration, so Agent HQ deliberately
has no state-mutating postinstall. Explicit repair is compatibility-only: it
never guesses roots, profiles, credentials, or optional panels. Ambiguous or
unsafe configuration fails with an explicit error instead of being silently
rewritten.
One v0.8 compatibility migration is intentionally subtractive: if the old
defaultPanel contains models that cannot satisfy its now-explicit read_only
contract (notably Antigravity), repair removes only those slots, preserves the
remaining order and replicas, and deletes an empty panel. Removed slots are not
copied into defaultConsiliumPanel, because consilium membership is
new operator policy rather than a safe inference.
A second subtractive repair covers two Antigravity workspace profiles that old
Agent HQ releases generated before live testing revoked every non-detached
Antigravity contract. Doctor fails explicitly while either historical
invocation shape remains. agent-hq init removes it only when its name,
command/arguments, description, null model, and absent profile env still match
the package-generated shape exactly. Customized or defaultProfile-referenced
profiles are preserved for an operator decision. This is an explicit trusted-
config migration; it does not change SQLite or persisted jobs.
agent-hq init --dry-run is intentionally a no-write preview, and declining
the interactive repair prompt is an exit-zero no-op; neither is a successful
mutating init and neither carries the persistence/doctor guarantee above.
The guarantee is deliberately keyed to the command outcome, not merely to npm
having replaced package files. If npm succeeds but new-binary repair or doctor
fails, agent-hq update exits nonzero and says the installed package is not
confirmed ready; it does not claim success or attempt a risky package/config
rollback. Likewise, a nonzero init may leave an atomically written, schema-valid
config whose runtime/auth checks still need attention. Only the exit-zero
mutating paths in the table are confirmed ready.
Configured default panels are required doctor checks: if a saved panel is
known to be over capacity, unavailable, unauthenticated, or bound to an
unavailable CLI mode/template, doctor—and therefore update/init readiness—fails
until the panel is runnable or removed. A routine CLI update does not by itself
invalidate an unchanged invocation contract: doctor reports the current release
as accepted version_drift, preserves the live-tested versions as diagnostic
evidence, and leaves the saved model unchanged. Agent HQ admits the current
executable by content identity and repeats that identity/version probe at the
spawn boundary. Explicit init/update and first managed use additionally preserve
content-addressed recovery runtimes for every managed CLI under trusted
stateDir/qualified-runtimes/; they are used only when the current command
cannot be admitted. Missing, contradictory, or digest-drifted snapshots fail
closed.
Init config writes serialize against
the same transition lease as update. The newly installed setup child inherits
that lease only when the lock owner is its direct parent, which keeps upgrades
from earlier Agent HQ versions compatible without granting unrelated processes
a bypass.
Management console
agent-hq open-console # or: agent-hq-console
agent-hq activate # reconcile a previously managed console with this installation- FLEET plots the live orchestrator/worker topology, activity, and attention states, and hosts the job-cancel control; LEDGER searches the durable history and opens full redacted reports; SHEETS shows the sanitized active config and diagnostics; RIG owns the config and key writes.
- The write surface is exactly five operations: store/delete a provider key
(OS keychain), set a model-effective profile's model, set the ordered
workspace-review or prompt-only-consilium panel, set
maxConcurrentJobs(comment-preserving JSONC edits), and cancel a running job from FLEET — each confirmed withy/Nin the terminal that launched the console. No interactive terminal means writes are disabled. - The console binds to
127.0.0.1with a random tokenized URL; write endpoints additionally require theAuthorization: Bearerheader. Reports are bounded and redacted, exposetotal/truncated, and carry an explicitcontrolPlaneflag so persisted state is never presented as live. - The console process, PATH CLI, daemon, and MCP host adapters are separate deployment identities. RIG/SHEETS expose the console's captured startup version, real package root, and executable-artifact digest; a different PATH installation is a blocking banner, never silently described as current.
- Each current console writes one atomic 0600 control record under its trusted
stateDir. A later init/update can authenticate to it, verify instance identity, start a fresh random origin/token, send that URL through the old console's authenticated handoff endpoint, and navigate open tabs before the old server retires. Record commit and handoff share one transition lock, and a refused handoff restores the prior record. Activation authenticates back to the replacement before reporting success. Only connection refusal discards crash residue; timeouts and ambiguous transport failures retain trusted state and fail closed. Stored pids are diagnostic only and are never signaled. Consoles from releases before this record cannot be discovered safely: after the first upgrade, runagent-hq consoleonce from the intended installation and close the legacy console terminal; later upgrades hand off automatically. - RIG keeps the routine path short: default panels first, named worker profiles second, capacity and provider access next, and CLI/template detail under Advanced. Recommendations and pickers are filtered by the capability required by the selected panel. Prompt-only consilium recommendations are quality-first: explicit HIGH/THINKING effort tiers outrank MEDIUM/LOW after unavailable, degraded, and recent-failure candidates are removed.
- Model selection is UI-first for every supported first-party runtime. RIG
exposes account-aware Codex models, Cursor Agent, stable Claude Code aliases,
live Antigravity models (including Google), OpenCode Go, the complete
OpenCode runtime, and OpenRouter as separate source chips. OpenCode Go uses
the exact
opencode-go/*ids returned by the authenticated runtime. A source above the 128-row response window remains searchable across its complete captured catalog from the same picker. - RIG shows MCP host registration separately from daemon lifecycle management. Its model selectors use only current catalog evidence. Manual config editing is needed only for operator-owned opaque custom commands/ids whose invocation contract Agent HQ cannot safely infer; ordinary Codex, Cursor, Claude, Antigravity, OpenCode Go, OpenCode, and OpenRouter selection stays in RIG.
- After any config or panel edit, finish active work, run the shown safe daemon stop command, then restart the MCP host. Restarting the host alone does not reload an existing daemon's policy; key changes apply to the next spawned worker immediately.
Secrets
agent-hq secrets set openrouter # hidden TTY prompt; value never touches argv
agent-hq secrets list # sources only — never values
agent-hq secrets rm openrouterResolution is keychain-first with env fallback, read live at every spawn.
Key slots exist for openrouter and cursor (a logged-in cursor-agent
works without one); claude, codex, and antigravity authenticate through
their own login state.
Doctor
agent-hq doctor (or the runner_doctor MCP tool) reports config checks,
agent CLI discovery with install hints and paste-ready profile snippets,
per-provider secret sources, host connect snippets, and compatibility with an
already-running daemon; --json emits the machine-readable form. The daemon
check never launches, stops, or replaces a daemon. Exit 0 iff all required
checks pass. Missing credentials on optional configured profiles remain named
optional failures; a blocked defaultProfile, revoked generated profile, or
unrunnable saved panel is required. A broken config still prints discovery and
secrets — precisely when you need the doctor.
Tools
agent_workflow— one durable, exact-qualified standard review, adversarial review, or rescue operation.waitreturns the bounded final result in the start call;backgroundreturns oneoperation_id. Results preserve ordered independent member reports and partial failures under a 120,000-byte hard bound. Write rescue is explicit and single-model. Dynamic selectors, resume, transfer, Stop-gate emulation, and unqualified route/workflow cells fail closed. Adversarial output must be one raw strict-schema object or one whole- output bare/jsonMarkdown fence; surrounding prose is unusable.agent_workflow_status/agent_workflow_result/agent_workflow_cancel— logical-operation lifecycle. Internal job ids are retained only as provenance/debug references.agent_workflow_list— strict filtered workflow-parent roster for reconnect recovery (workflow/status/limit/offset, default 25, maximum 100,next_offset, 24 KiB text ceiling).agent_consilium— compatibility prompt-only fan-out with no caller workspace; workers do not see peer output, and the host polls every result and owns synthesis.agent_review— compatibility read-only review fan-out;strategypicks a built-in lens (standard,red-team-attacker,ux-critic, and more) or one fromreviewStrategies. The obsoleteadversarialstrategy is rejected in favor ofagent_workflow. One private content-addressed evidence bundle is streamed to disk before launch; every panel member receives only its path, SHA-256 digest, and a small per-file manifest instead of another copy of the diff in its prompt. Branch scope pins the committedbase_ref..head_refrange and excludes live working-tree residue. Working-tree capture detects concurrent mutation. Bundles are validated and leased before spawn, exposed only to the read-only worker, deduplicated, and pruned under bounded storage quotas without deleting evidence owned by running or quarantined workers.agent_delegate— compatibility task fan-out; read-only by default. Pass explicit model ids or caller-directed selectors, or omitmodelsto run the saveddefaultPanelexactly.workspace_writeis explicit and single-model; built-in CLI templates additionally requireallowWriteCliWorkers, while OpenCode-routed write workers run the sandboxed built-in permission block instead.agent_models— the canonical catalog: routing, backend/family/tier, auth readiness, probe freshness, empirical reliability, operator notes, and a diversity-aware recommendation. Userecommended_panels.reviewor the quality-firstrecommended_panels.consilium; the genericrecommended_panelremains as a backward-compatible alias of the review recommendation. The first request accepts optionalbackend,query,projection(idsorcatalog), andpage_size; continue by sending exactly{ "cursor": next_cursor }. Each cursor is HMAC-bound to one immutable five-minute adapter-local snapshot, so pages have stable order and exact totals even if live provider output changes between calls. Every page is bounded (≤32 rows and ≤32,000 encoded bytes), recursively redacted, and reportssource_total, filteredtotal,returned, snapshot metadata, andtruncated === (next_cursor !== null). Discovery, probe, and recommendation context appears only on the first page (context_included: true); continuation pages keep the stable routing/pagination envelope without repeating it. Adapter restart, expiry, or bounded cache eviction invalidates the cursor with restart guidance. Stable Claude aliases such assonnet(the current Sonnet line) andopusstay ahead of bulk probe rows; arbitrary direct-CLI full ids without explicit current evidence remain diagnostic and are not reported as available.agent_spawn— start a worker through an operator-authored profile; always scheduled as conservativeworkspace_write. Known mandatory provider credentials and option-like/whitespace model overrides fail before job admission.agent_status/agent_events/agent_result/agent_cancel/agent_list— lifecycle: sanitized status and log tail, durable ordered event pages, compact final result, termination, and a strict paged roster (status/limit/offset, default 25,next_offset, 24 KiB text ceiling).agent_statusdefaults to lifecycle-only detail so polling does not repeat result bodies;detail:"result"preserves the legacy snapshot during migration, while new callers read terminal content fromagent_result. Public lifecycle, event, and history response fields use snake_case, including nestedprompt_preview.max_chars.agent_list.truncatedis true exactly whennext_offsetis non-null. Terminalstatusis the process outcome; onlyresult_quality: "clean"is usable validation.degradedandunknowncarry machine-readablequality_reasonsand must not be counted as a substantive opinion. New terminal rows also expose additiveresult_assembly: primary-output truncation degrades quality, whilestructured_projection_truncatedreports clipping of bounded convenience fields without invalidating a complete raw report. Its absence identifies a legacy row with unknown assembly state.agent_history— search persisted prompts/results with paging; compact summaries by default.detail: "full"returns one complete row only when its redacted projection fits the 128,000-byte response budget.agent_profiles— read-only configured profiles plus compact OpenCode probe health/count diagnostics; it accepts no arguments, and model ids live only inagent_models.runner_doctor— the doctor report over MCP, with compact model-probe diagnostics rather than a duplicate model catalog.
Model ids route by prefix (codex/, cursor/, claude/, antigravity/
always win; openrouter/*, ollama/*, lmstudio/*, opencode/*,
opencode-go/* run through
the OpenCode runner), documented bare-id families cover the rest, and dynamic
selectors (family:, backend:, tier:free|paid) resolve against the
catalog. Generic CLI fan-out is verified before it runs: the resolved command,
the capability-specific invocation-contract hash, and its qualified purposes
must match a published template. CLI release strings are diagnostic evidence,
not an allowlist: routine version drift is accepted under an unchanged
contract. Runtime selection may use only the current catalog command or a
manager-owned content-addressed snapshot; the selected executable is
digest-bound and its identity plus version
probe output are revalidated across daemon IPC and immediately before spawn. A
contract, probe, or identity mismatch is refused before credentials or a job
are created. Explicit ids and caller-directed selectors
resolve before spawn, while saved panels run their slots unchanged. A blocked
slot, capacity race, or workspace-lease race remains visible rather than
triggering a fallback. Use an operator-owned agent_spawn profile for deliberately custom
invocations.
The backend capability matrix is the public selection contract. Installation and authentication are additional live gates; the RIG tooling table shows the verified uses on this machine and each panel picker offers only models ready for its required boundary.
Antigravity's published template is available only for agent_consilium: Agent HQ gives each
job an isolated process-local Gemini data directory, selects its unique
Antigravity project, and uses shared-engine grants to deny every file, command,
URL, and MCP action. The real HOME remains available only for OS-keyring
sign-in; inherited Antigravity config and customizations stay out. This is
prompt-only execution, not repository read-only. Antigravity remains unavailable
to agent_review and workspace-aware agent_delegate
because its non-interactive mode still read outside a project whose file-access
setting said deny. Editing antigravity-cli/settings.json is not an equivalent
boundary; live --print execution auto-approved that CLI-only policy layer.
Config
Config is loaded from the first of --config <path>, AGENT_HQ_CONFIG, or
~/.config/agent-hq/config.jsonc — set-but-missing explicit paths are errors.
Start from agent-hq.config.example.jsonc (shipped in the package, next to
the JSON schema agent-hq.schema.json). The load-bearing points:
- With no config file,
allowedRootsdefaults to the server process cwd and the built-in free OpenCode profiles (review,explore,implement) are exposed. When a config declaresprofiles, that list is authoritative. - A source-backed config must declare
allowedRootsexplicitly. To repair a legacy config that lacks it, choose a workspace boundary and runagent-hq init --yes --root <workspace> --profiles none --config <path>. The command never guesses$HOME, the filesystem root, or a worker boundary. allowedRootsmay not be/or your home directory. Worker commands must be absolute paths or bare names onPATH; relative paths are rejected.stateDir(default~/.local/state/agent-hq) scopes the daemon endpoint, database, transcripts, and log, and must stay outsideallowedRootsunlessallowStateDirInsideAllowedRootsis set. One daemon deployment owns a state directory; normal clients require matching protocol, package, and deployment identity plus a token-keyed configuration-compatibility proof. The proof only refuses a mixed adapter/daemon configuration: it does not expose a reusable fingerprint or replace a daemon. A daemon retains its boot-time trusted configuration until explicitly stopped. If changingstateDir, stop the old daemon with the previous config before editing it; the new config points at a different endpoint and cannot stop the old daemon.maxConcurrentJobs(default 8, bounded 1..256) is a global cap across all hosts. Jobs default todefaultTimeoutSec(7200 s), overridable per spawn up tomaxJobTimeoutSec.- Every job carries
workspace_mode:noneis detached from the caller's workspace, whileread_onlyandworkspace_writeare workspace-aware.agent_reviewis always read-only;agent_delegatedefaults read-only;agent_spawnprofiles are opaque, so those jobs are always scheduledworkspace_writeand take the lease. defaultPanel(optional) is the exact ordered one-to-twenty-slot read-only fan-out used whenmodelsis omitted — a per-request panel, not a weighted scheduler. A panel that cannot fit current capacity fails admission rather than silently shrinking; every slot must structurally support read-only workspace execution.defaultConsiliumPanelis the separate exact panel for omitted-modelagent_consilium; capability verification can make it differ from the workspace-aware panel, and every slot must support detached execution.reviewStrategiesmerges custom review lenses over the built-ins by name. The removed exact nameadversarialis reserved: a trusted config containingreviewStrategies.adversarialfails load until that lens is removed or renamed. It is not auto-mapped to the structuredagent_workflowadversarial_reviewcontract.modelNotesattaches short operator notes to catalog entries, served redacted throughagent_models.- OpenCode workers get per-run config in memory (
OPENCODE_CONFIG_CONTENT); Agent HQ never writes runner config into target repos. CLI profiles are trusted local commands: validated, env-minimized, transcribed, and process-group-terminated, but not sandboxed.
Job daemon and durable state
The stdio MCP process is an adapter; one local daemon per stateDir owns
workers and state, reachable over a private 0600 endpoint with a
length-prefixed JSON protocol. Workflow methods advanced that protocol from v5
to v6; the bounded workflow roster advances it to v7. Clients must match protocol, package version,
and deployment identity. Authenticated normal clients also send a one-way,
daemon-token-keyed proof of their loaded trusted configuration. The daemon
returns only whether the proof matches and refuses a mixed configuration before
credentials or a worker request cross IPC; it neither exposes a configuration
fingerprint nor replaces the daemon. After any saved trusted-config change,
finish active work, run agent-hq daemon stop [--config <path>], then restart
the MCP host. Workflow parents/members, jobs, ordered event streams, and model
statistics
live in ${stateDir}/database/agent-hq.sqlite (WAL, indexed history,
1000-job retention). Daemon startup transactionally migrates schema v5 to v6
by adding workflow_operations and workflow_members, then v6 to v7 by
preserving those rows while expanding the workflow-member bound to twenty;
existing jobs are not rewritten or backfilled into invented workflows. Other trusted-config fields
retain their meanings; the exact obsolete reviewStrategies.adversarial key is
a required remove-or-rename migration and is never converted automatically.
Admission is transactional; a running workspace_write
job blocks another writer at the same, ancestor, or descendant path. After an
unclean daemon exit, recovery probes detached process groups instead of
signaling possibly-recycled pids, and quarantines live orphans until proven
dead.
STDIO ownership is per host session. The tested Codex CLI creates an MCP connection manager for every retained task/subagent, so a large native-agent fan-out can create one Agent HQ adapter process per thread even though all of them share the single daemon. Ending the adapter on an idle timer is unsafe because a stdio client does not promise to restart it. The planned zero-process- per-agent option is a daemon-owned Streamable HTTP MCP endpoint, but Codex does not currently provide the dynamic token-file authentication needed for Agent HQ's rotating state-directory proof. The safer default migration is therefore a small native stdio proxy that starts and reconnects the exact daemon generation; managed HTTP can follow when service startup and stable local authentication are solved together. Until either ships, closing retained Codex tasks or restarting the app is the host-level cleanup boundary.
agent-hq daemon status # protocol, package, stateDir, running/quarantined counts
agent-hq daemon stop # stop the daemon and its running workersAdministrative status/stop still work across package, deployment, and
configuration mismatches when the wire protocol matches, so an old daemon stays
recoverable; normal job clients remain strict.
Gotchas
agent-hqwith no arguments starts the stdio MCP server (it waits on stdin); the browser UI isagent-hq open-console.- The tokenized console URL is an access token for that process — keep it out of shared logs and tickets.
- Console writes are confirmed in the launching terminal; an unanswered prompt auto-denies after 120 s. Everything beyond the five write operations is edited by hand in the trusted config file.
- Opening the console does not register the MCP server with a host — that is step 1 of the quick start.
- A source rebuild cleans
dist/. If active work exists, let it finish before replacing the built package. While the old build and config are still available, run itsagent-hq daemon stop [--config <old-path>]; then rebuild and restart the MCP host. Do not rely on the new build to stop an old-protocol daemon. - In Codex, every retained native task/subagent can own a separate copy of each configured local stdio MCP server. Agent HQ still has only one durable daemon, but the Node adapters themselves consume memory until Codex closes those agent threads or the app restarts.
