Config schema — ~/.agentproto/config.json
The CLI's global config file. Location: $AGENTPROTO_HOME/config.json
(defaults to ~/.agentproto/config.json). Created lazily — absent
until first agentproto config set or agentproto adapters install.
Read/write via agentproto config:
agentproto config show
agentproto config get adapters
agentproto config set daemon.port 18791Full shape
{
// Runtime adapters loaded by `agentproto run-swarm`. Each entry is an
// npm package id resolvable from the cli's install location OR the
// user's cwd. Loaded in array order; last write wins on duplicate
// adapter kinds.
"adapters": [
"@guilde/agentproto-bridge",
"@acme/agentproto-slack"
],
// Slug → package-name aliases for `agentproto install
// runtime-profile/<slug>`. Without an alias, the verb defaults to
// `@agentproto/runtime-profile-<slug>`.
"profileAliases": {
"guilde": "@guilde/runtime-profile-guilde"
},
// npm packages the `corpus` CLI scans for AIP-10 starter presets.
// Each must declare `package.json#agentproto-corpus-preset` matching
// the agentproto/corpus-preset/v1 schema. Defaults to just
// ["@agentproto/corpus-presets"] when omitted.
"corpusPresetPackages": [
"@agentproto/corpus-presets",
"@vendor/corpus-presets"
],
// Daemon-mode options. Read by `agentproto daemon` and
// `agentproto serve` when launched without explicit flags.
"daemon": {
"port": 18791,
"bind": "127.0.0.1",
"allowedOrigins": [
"https://guilde.work"
],
"turnStallAfterMs": 300000
},
// End-to-end pairing over an untrusted rendezvous broker. Read by
// `agentproto serve` / `pair offer`. See concepts/pairing.md.
"pairing": {
// Rendezvous broker WS URL used by `pair offer` and by autoconnect on
// boot. Mirrors tunnel.host. Three states:
// - absent → offers fall back to the hosted default,
// wss://rdv.agentproto.sh/v1 (the broker relays only
// ciphertext — see concepts/pairing.md).
// - a URL → route through that broker (self-hosted or otherwise).
// - "" → explicit opt-out: no default, `pair offer` requires
// an explicit --rendezvous.
"rendezvous": "wss://rendezvous.example/v1",
// Whether the daemon opens standing rendezvous connections for every
// persisted pairing on boot (so a paired client can reconnect anytime).
// Mirrors tunnel.autoconnect. Default true when a rendezvous is set.
"autoconnect": true,
// Web pair page for `pair offer --qr` (the offer rides in its URL
// fragment). A template with {fp} in the HOSTNAME (the daemon
// fingerprint) for one browser origin per daemon, or a plain http(s) URL
// (one shared origin). Absent → https://{fp}.agentproto.cloud/pair.
// `--pair-page` overrides it.
// See concepts/pairing.md ("The phone pair page").
"pairPage": "https://{fp}.pair.example.com/pair"
},
// Global and per-adapter defaults auto-applied to every `agent_start`
// spawn (CLI, MCP, or HTTP). See "defaults" below.
"defaults": {
"skills": ["review-checklist"],
"options": { "verbose": true },
"adapters": {
"hermes": {
"skills": ["hermes-only-skill"],
"options": { "model": "z-ai/glm-5.2" },
"auth": { "mode": "api-key" }
}
},
"defaultRoleDepthCutoff": 1,
"maxGrantableDelegation": 2,
"langfuseTracing": false,
"traceRedactor": "secrets"
},
// Generic ACP agents — any CLI that speaks the Agent Client Protocol,
// connectable with zero adapter code. Keyed by adapter slug; shadows a
// curated ACP_CATALOG entry of the same slug. Managed via
// `agentproto acp add|ls|rm`. See "acpAgents" below.
"acpAgents": {
"my-agent": {
"bin": "my-agent",
"bin_args": ["acp"],
"resumable": true,
"install_hint": "npm i -g my-agent"
}
},
// Where `agentproto worktree new` creates worktrees + whether the daemon
// isolates spawned agents into one. See "worktrees" below.
"worktrees": {
"root": "~/.agentproto/worktrees",
"isolation": "on-request",
"provisionConcurrency": 2,
"provisionConcurrencyByRepo": { "~/code/big-monorepo": 1 },
"provisionLoadFactor": 0
},
// Spawn-time policy for `agent_start` (dedupe, attach). See "spawn" below.
"spawn": {
"dedupe": "always",
"attach": "always"
},
// Provenance policy — the opt-in `gh` PATH shim. See "provenance" below.
"provenance": {
"wrapGh": false
},
// Named terminal/TUI launch presets for `agentproto sessions terminal
// --preset <name>`. See "terminalPresets" below.
"terminalPresets": {
"terra": { "argv": ["bash", "-l"], "env": { "TERM": "xterm-256color" } }
},
// Session-presence + transcript-storage policy. See "sessions" below.
"sessions": {
"attentionDelaySec": 60,
"eventsDir": "~/.agentproto/sessions"
},
// Feature toggles. See "features" below.
"features": {
"pty": true,
"llmEndpoint": false
},
// Model-role overrides — which model each built-in job uses.
// Each key is a dotted role name; the value is a model id string or
// { model, route?, profile? }. See "models" below.
"models": {
"review.small": "claude-sonnet-5-5",
"review.large": "claude-opus-5-5",
"review.pr": "openrouter/z-ai/glm-5.3-flash",
"judge.session": "claude-sonnet-5-5"
},
// Jev (TypeSafe System One) judge configuration for the session steward.
// See "jev" below.
"jev": {
"apiKey": "...",
"model": "jev-latest",
"baseUrl": "https://api.typesafe.ai/v1/systemone"
}
}Keys
adapters: string[]
npm packages with an agentproto/adapter/v1 manifest. The CLI walks
this list at every run-swarm invocation, reads each adapter's
manifest, dynamic-imports declared adapter factories, and registers
them.
Managed via agentproto adapters — the verb
renamed from plugins in 0.20.0. Direct edit is fine — the verb is
convenience.
profileAliases: Record<string, string>
Maps a runtime-profile slug to an npm package name. Lets you install third-party profiles without typing the full package name:
# Without alias:
agentproto install runtime-profile/guilde \
--package @guilde/runtime-profile-guilde
# With alias above:
agentproto install runtime-profile/guildeThe default resolver (@agentproto/runtime-profile-<slug>) still
applies when no alias matches.
corpusPresetPackages: string[]
Only consumed by the corpus binary (@agentproto/corpus-cli). Each
listed package must declare package.json#agentproto-corpus-preset
listing its starter presets. corpus init <slug> resolves against the
merged set. corpus init --list enumerates everything visible.
daemon: object
Defaults for agentproto daemon and agentproto serve:
| Field | Type | Meaning |
|---|---|---|
port | number | Listen port (default 18790). |
bind | string | Bind address (default 127.0.0.1 — loopback-only). |
allowedOrigins | string[] | CORS allow-list for browser callers of the daemon API. |
authToken | string | Stable bearer token for /mcp, /events, /conversations*, and the heartbeat tick route — survives restarts, unlike the per-boot runtime.json token. Overridden inline by agentproto serve --auth-token <token>. Loopback callers with no X-Forwarded-For header are still exempt. Unset ⇒ those routes stay open. |
turnStallAfterMs | number | Turn-liveness watchdog threshold in ms. When a busy agent-cli session has had no adapter activity for longer than this, the daemon stamps stalledSinceMs on the descriptor and emits session:stalled. If the turn has produced no output or usage at all since its prompt (a provider silently retrying, e.g. a swallowed 429), the descriptor also gets lastTurnErrorMessage: "no output since prompt — provider retrying?". Detection-only — never auto-kills. Default on at 5 minutes (300000). Set to 0 or a negative value to disable. Env override: AGENTPROTO_TURN_STALL_AFTER_MS. |
Verb flags override config; config overrides hard-coded defaults.
defaults: object
Global and per-adapter defaults auto-applied to every agent_start spawn
(CLI sessions start/run, MCP start_agent_session, or the HTTP API) —
introduced in 0.5.0.
| Field | Type | Meaning |
|---|---|---|
skills | string[] | Global skills folded into every spawn's options.skills. |
options | Record<string, boolean|number|string> | Global options merged into every spawn. |
adapters | Record<string, { skills?, options?, auth? }> | Per-adapter overrides, keyed by adapter slug (e.g. "hermes"). |
auth (per-adapter) | { mode?: "subscription" | "api-key", token?: string, apiKey?: string, provider?: string } | Per-adapter billing-auth defaults merged at spawn time. |
defaultRoleDepthCutoff | number | Spawn depth at/above which a session defaults to executor instead of supervisor (default 1). |
maxGrantableDelegation | number | Trust-boundary cap on how much delegation a supervisor can grant a child. |
langfuseTracing | boolean | Opt in to per-session Langfuse tracing by default. |
traceRedactor | string | Redactor slug (e.g. "secrets") applied to traced session content. |
agentPromptInterrupt | boolean | Default interrupt behaviour for agent_prompt / message_parent calls that omit the interrupt field. false (the default) queues the prompt behind any in-flight turn. true cancels the in-flight turn and redirects the session onto the new prompt immediately. An explicit interrupt: true|false on a single call always overrides this default. For message_parent this only requests an interrupt — whether it may cut the parent's turn is messaging.agentInterrupt. |
contextContinuity | { mode?, warnAtPct?, compactAtPct?, continueFreshAtPct?, hardStopAtPct?, handoffAtQuotaRemaining? } | Context-window policy (handoff guide). handoffAtQuotaRemaining (number ≥ 0, unset = off) emits a session:handoff-suggested event, once per quota window, when the session's Anthropic auth profile reports that many requests or fewer remaining. A raw remaining count (no limit is available to make a percentage); only sessions with an access profile are watched. It only suggests — it never switches harness. |
messaging | { allowSiblings?: boolean, agentInterrupt?: "allow" | "deny", pendingPromptStaleMinutes?: number } | Inter-session messaging policy (sessions → Messages between sessions). allowSiblings (default false) lets message_send / message_reply reach a sibling session. agentInterrupt (default "deny") decides whether a session sender's urgency: "interrupt" may cancel the recipient's turn; when denied it's delivered as steer and the result reports it. Human (HTTP/CLI) senders always keep interrupt. pendingPromptStaleMinutes (default 5) is how long a prompt may sit queued behind a mid-turn session before it is flagged stale in session_list / session_recap (pendingPrompts) and its sender is told via a notice message. |
Merge precedence (low → high): defaults.options < defaults.adapters.<slug>.options
< the explicit options passed at spawn time. For skills, an explicit
skills array at spawn time replaces the union of defaults.skills and
defaults.adapters.<slug>.skills rather than merging with it. Adapters with
no declared skills option treat the resolved skills list as a no-op.
acpAgents: Record<string, object>
Generic ACP agents — any CLI that already speaks the Agent Client Protocol,
connectable with zero adapter code. Keyed by adapter slug; each value is a
spawn recipe. A config entry shadows a curated ACP_CATALOG entry of the
same slug, and both lose to a real @agentproto/adapter-<slug> npm package
(resolution order: npm → config → catalog). Managed via
agentproto acp; direct edit is fine.
| Field | Type | Meaning |
|---|---|---|
bin | string (required) | Executable to spawn (e.g. "gemini"). |
bin_args | string[] | Extra argv, e.g. ["--experimental-acp"]. |
name | string | Display name. Default: the slug. |
description | string | One-line summary shown in acp ls. |
env | Record<string, string> | Always-on environment variables for the spawn. |
resumable | boolean | Advertise resumable + native-resume continuation. |
models | { default?, allowed? } | Known model ids (informational hint). |
install_hint | string | Shown by acp ls when the bin is missing from PATH. |
A malformed entry (no string bin) is dropped on load with a warning rather
than failing the whole config. See
concepts/adapters.md.
worktrees: object
Where agentproto worktree new provisions new git worktrees, and the daemon's
policy for isolating spawned agent sessions into one.
| Field | Type | Meaning |
|---|---|---|
root | string | Absolute path new worktrees are created under (layout <root>/<repoName>/<slug>). Resolution order: --root flag > AGENTPROTO_WORKTREES_ROOT env > this field > the hardcoded default ~/.agentproto/worktrees. |
isolation | "always" | "on-request" | "never" | Policy for agent_start's worktree field. on-request (default) isolates only when a spawn passes worktree; always isolates every root spawn whose cwd is inside a git repo (a spawn made through an orchestrator inherits its parent's tree; a cwd outside any repo spawns plain); never turns it off and rejects an explicit worktree rather than silently ignoring it. Resolution order: AGENTPROTO_WORKTREES_ISOLATION env > this field > the default on-request. The worktree is not auto-removed on session exit — reclaim it with agentproto worktree rm|archive|gc. |
provisionConcurrency | integer >= 0 | Daemon-wide cap on concurrently running heavy provisioning phases (depsCmd, cloneGlobs/copyGlobs, worktree.setup hooks). Excess agent_start({worktree}) spawns wait in a FIFO queue (fair across callers) and show provisioning: { state: "queued", position }. 0 disables the cap. Default 2. Resolution order: AGENTPROTO_WORKTREES_PROVISION_CONCURRENCY env > this field > the default. Hot-applied: a change takes effect on the next provisioning without a daemon restart. git worktree add and the other cheap steps are never queued. |
provisionConcurrencyByRepo | object | Extra per-repo cap, { "<repo path or directory name>": cap } (~/ expands; a bare name matches the repo's directory name). Applies in addition to provisionConcurrency, never looser than it. Invalid entries are ignored. |
provisionLoadFactor | number | Optional load guard. When > 0, a queued provisioning is not admitted while the 1-minute load average exceeds cores x provisionLoadFactor, unless nothing is running (an idle scheduler always admits one, so a permanently loaded host cannot deadlock). Default 0 (off). |
spawn: object
Daemon-side policy for agent_start spawns.
| Field | Type | Meaning |
|---|---|---|
attach | "always" | "on-request" | Whether a spawn auto-attaches to its caller as parent lineage. "always" (default) nests a child under the spawning session whenever the identity is derivable; "on-request" disables auto-attribution unless the caller opts in. Resolution order: AGENTPROTO_SPAWN_ATTACH env > this field > "always". A per-call attach: false opts out. |
dedupe | "always" | "on-request" | Implicit idempotency-key policy. "always" (default) derives a key from the spawn's label + a hash of the initial prompt when no explicit idempotencyKey is given; "on-request" disables implicit derivation. Resolution order: AGENTPROTO_SPAWN_DEDUPE env > this field > "always". A per-call dedupe: false opts out. |
provenance: object
Daemon-side provenance policy — the opt-in gh PATH shim.
| Field | Type | Meaning |
|---|---|---|
wrapGh | boolean | When true, every agent session the daemon spawns gets a shim directory prepended to its PATH so any gh pr create it — or an adapter subprocess shelling out (claude-code, codex, …) — runs has a deterministic 🤖 @agentproto-bot provenance footer (session id, adapter, model, workspace) appended to the created PR's body, matching the footer the cloud runner stamps. The tool stamps, never the model; commit messages are never touched. Stamping is cosmetic — a failure never fails the underlying gh. Resolution order: AGENTPROTO_PROVENANCE_WRAP_GH env > this field > default false (off). |
terminalPresets: Record<string, object>
User-defined named terminal/TUI launch recipes for agentproto sessions terminal --preset <name> — local-only, never packaged in shared adapter
manifests or defaults.
| Field | Type | Meaning |
|---|---|---|
argv | string[] | Command + args to spawn. When provided, sessions terminal can be used without -- <argv...>. |
env | Record<string, string> | Extra environment variables layered on top of the daemon's inherited process.env. |
cwd | string | Working directory for the PTY session. Relative paths resolve against the CLI's cwd. |
workspace | string | Workspace slug used for cwd fallback when cwd is omitted. |
name | string | Stable session name passed to the registry. |
label | string | Human-readable label surfaced in session listings. |
sessions: object
Session-presence and transcript-storage policy.
| Field | Type | Meaning |
|---|---|---|
attentionDelaySec | number | How long (seconds) a session stays shown as running after its last turn ends before the dashboard settles it into attention/quiet. Absent ⇒ 60. Env override: AGENTPROTO_SESSIONS_ATTENTION_DELAY_SEC. |
eventsDir | string | Root directory the daemon stores per-session transcripts under: each session's events.jsonl (and a terminal session's terminal.jsonl) lives at <eventsDir>/<sessionId>/events.jsonl. Every writer and reader (the transcript writer, GET /sessions/:id/events, sessions export, tool-call/usage logs) resolves through this single key. Relative paths resolve against the home directory. Absent ⇒ the hardcoded default ~/.agentproto/sessions — zero behaviour change out of the box. Takes effect on daemon restart; existing transcripts are not moved. Spawn responses (agent_start descriptor) carry the resolved absolute path of the current session's events.jsonl as descriptor.eventsPath. |
features: object
Daemon feature toggles. All fields are optional; defaults are conservative (off / informational) so upgrades don't change behaviour.
| Field | Type | Meaning |
|---|---|---|
pty | boolean | Informational hint that PTY support is desired. The daemon still detects node-pty's presence at runtime. |
llmEndpoint | boolean | Enable the local @agentproto/llm-endpoint proxy sidecar. When true, the daemon registers the llm-endpoint route and exposes the llm_endpoint_* MCP tools. Default false — opt-in because the sidecar spawns a child process and binds an extra port. |
models: Record<string, string | object>
Model-role overrides — which model each built-in automated job uses. Each
key is a dotted role name; the value is either a bare model id string or
{ model: string, route?: string, profile?: string }.
Precedence (highest to lowest): explicit run input → the repo's
agentproto.json models → this daemon config → built-in default. Read the
resolved table and its sources with config_get models or the read-only
model_roles MCP tool.
Built-in roles and their defaults:
| Role | Default | Description |
|---|---|---|
review.small | claude-sonnet-5-5 | Reviewer for a small residual (repo-maintenance review step). |
review.large | claude-opus-5-5 | Reviewer for a large residual and the retry reviewer. |
review.pr | openrouter/z-ai/glm-5.3-flash | CI pull-request reviewer. |
judge.session | claude-sonnet-5-5 | Session-steward agent judge. |
Override a role:
agentproto config set models.review.small claude-haiku-5
agentproto config set models.judge.session claude-opus-5-5An id unknown to the model catalog is warned about at set time but accepted.
A AGENT.md step may reference a role with model: role:<name>, resolved
before adapter selection.
jev: object
Configuration for the Jev (TypeSafe System One) judge backend used by the session steward. All fields are optional.
| Field | Type | Meaning |
|---|---|---|
apiKey | string | Jev judge API key. Read before the JEV_API_KEY env var, so the key can live in agentproto's own config rather than a workspace env file. Not writable via config_set; hand-edit ~/.agentproto/config.json (mode 0600 recommended for this field). |
model | string | Jev model id. Default "jev-latest". Writable via config_set jev.model <id>. |
baseUrl | string | Jev endpoint override. Default https://api.typesafe.ai/v1/systemone. Writable via config_set jev.baseUrl <url>. |
tunnel: object
Outbound tunnel defaults read by agentproto serve (and the managed
agentproto daemon) when --connect is not passed explicitly.
| Field | Type | Meaning |
|---|---|---|
host | string | WebSocket URL of the tunnel host. When set with autoconnect: true, the daemon connects on boot. |
token | string | Bearer token used before falling back to credentials.json. Required for e2e: true. |
autoconnect | boolean | Connect the tunnel automatically on daemon start. |
e2e | boolean | Opt into end-to-end encryption of the tunnel. Requires token. |
profiles: Record<string, object> and activeProfile: string
Named connection bundles. profiles.<name> shallow-overrides the top-level
daemon/tunnel/features blocks when selected; activeProfile selects a
profile by default when --profile is not passed. Missing fields fall through
to the top-level config, so a profile typically only declares tunnel.host +
tunnel.token.
{
"activeProfile": "prod",
"profiles": {
"prod": {
"tunnel": { "host": "wss://tunnel.example/connect", "token": "apt_…" },
"daemon": { "port": 18791 }
}
}
}Explicit --profile <name> is fatal if the profile does not exist;
activeProfile pointing at a missing profile only warns and falls back to the
top-level config.
Permissions
Mode 0600 is NOT enforced for config.json — unlike credentials.json,
this file doesn't carry secrets. Plugin names, ports, and alias maps
are not sensitive.
Versioning
The config file is unversioned today. New keys may appear in any
minor release of the CLI; unknown keys are tolerated and preserved
across reads/writes. Removed keys are still readable but are no-ops.
See ../../../VERSIONING.md for the broader
policy.