heretic-cli agents
Manage global agent profiles — list, add, edit, show, validate, delete, and import MCP servers, with every prompt, flag, masking rule and error message
Profiles live one per file in ~/.heretic/agents/<name>.yaml. The profile name is the filename stem — it is injected automatically if the file omits name:.
Synopsis
heretic-cli agents list [--json]
heretic-cli agents add <name> [--force]
heretic-cli agents edit <name> [--editor]
heretic-cli agents show <name> [--resolved] [--reveal]
heretic-cli agents validate [name]
heretic-cli agents delete <name> [-f|--force]
heretic-cli agents mcp <name> [--local] [--file <path>]
agents list
$ heretic-cli agents list
NAME IMAGE RUNNER LOCAL
claude giglabo/claude-heretic:latest docker ✓
claude-zai giglabo/claude-heretic:latest docker -
| Column | Meaning |
|---|---|
RUNNER | from the profile; docker when omitted |
LOCAL | ✓ when the current directory has an override for that profile — .heretic/cli/<name>.yaml, or a legacy .heretic/cli/agent.yaml whose extends: matches |
--json prints [{ "name", "image", "runner", "local" }].
A missing profile usually means invalid YAML
Invalid profiles are skipped with a warning instead of failing the listing. If a profile does not appear, run heretic-cli agents validate.
Empty state: No agent profiles found. Run 'heretic-cli agents add <name>' to create one. (or []).
agents add <name>
An interactive, container-focused wizard. It exits 1 if the profile exists without --force: Profile '<name>' already exists. Use --force to overwrite.
Prompt order:
- Docker image — required
- Runner type — Docker / Docker Compose / Custom
- Volumes — repeating loop: source (required), target (required), read-only (default no)
- Environment variables — repeating loop: name (
[A-Z_][A-Z0-9_]*), value - Working directory — optional
- Command — optional, split on whitespace into an array
- Interactive mode (stdin)? and TTY? — both default yes
- Network mode — optional, e.g.
host→extra.network - Ports — repeating loop, must match
<host>:<container>→extra.ports
Then a summary and Save this profile?. Declining prints Profile not saved. and exits 0.
The wizard covers a subset of the schema
agents add cannot set secrets, mcp, mcp_file, git, ssh, tool_backends, dind, claude_settings, agent_type, provider, memory, cpus, shm_size, capabilities, privileged, user, run_as_root, hostname or labels. Use agents edit --editor, the init wizard, or write the YAML directly. A profile created here has no provider, so it is inferred (copilot-cli → copilot, otherwise anthropic).
agents edit <name>
Interactive (default) — the same prompts as add, pre-filled. Volumes, environment variables and ports offer Keep existing vs Edit; choosing Edit discards the old list and starts a fresh add-loop (there is no per-item editing). name, description and enabled are preserved; fields that have no prompt are dropped.
--editor — dumps the profile to a temp file, opens $EDITOR (then $VISUAL, else vi), reads it back, parses and validates it. On invalid YAML or a validation error you get Re-edit / Discard changes, with your text preserved. Terminal editors are detected by name (vi vim nvim nano pico emacs micro hx helix ed joe jed ne); GUI editors that fork are tolerated and you are asked to press Enter when done. The temp file is always removed.
Both modes print a change summary (image, runner, workdir, command, interactive, tty, volume/env counts, whether extra changed) and ask Save changes?.
heretic-cli agents edit claude # guided prompts
heretic-cli agents edit claude --editor # full YAML, validated on save
--editor is the only supported way to hand-edit with validation. Editing ~/.heretic/agents/<name>.yaml directly is allowed but stays unvalidated until you run agents validate.
agents show <name>
Prints YAML.
| Form | Output |
|---|---|
agents show x | the raw profile file (plus the injected name:) |
agents show x --resolved | the resolved config after the three-layer merge, ${VAR} interpolation and secret resolution: image, runner, volumes, env, workdir, command, interactive, tty, extra |
+ --reveal | do not mask sensitive environment values |
Masking applies to any environment key whose lowercase name contains key, token, secret or password; the value becomes first 8 characters + **** + last 4 (or **** under 12 characters).
--resolved executes secret scripts and reads the local override from the current directory, which makes it the best pre-flight check before run:
$ heretic-cli agents show claude --resolved
image: giglabo/claude-heretic:latest
runner: docker
volumes:
- source: /abs/path/to/cwd # ${CWD} expanded
target: /workspace
env: {}
interactive: true
tty: true
For the complete resolved object use local-validate
--resolved omits mcp, ssh, tool_backends, git, dind, secrets, claudeSettings, sessionName and projectDir. heretic-cli local-validate <profile> prints all of them — including resolved secret values in plaintext, so keep that output out of tickets and CI logs.
agents validate [name]
Validating profile "claude"...
[pass] YAML syntax
[pass] Required fields
[pass] All validation checks passed
With no argument every *.yaml in ~/.heretic/agents/ is checked. Any [fail] exits 1; [warn] alone does not. The only implemented warning is compose section present but runner is "docker". Compose config will be ignored. A YAML parse error prints [fail] YAML syntax: … and, for a single named profile, exits immediately; in all-profiles mode it continues. A missing profile prints Profile '<name>' not found and exits 1.
This checks shape only — it never contacts Docker, never interpolates ${VAR} and never runs secret scripts. Absolute-path and sidecar-wiring rules are enforced later; see Validation.
agents delete <name>
- Finds containers labelled
heretic.managed=trueandheretic.agent=<name>in any state (skipped when Docker is unavailable) - Lists what will go: containers (name, session, state), the profile path, and the associated files
get-<name>-key.sh,get-<name>-key.cmd,<name>-settings.json - Confirms — default No — unless
-f/--force - Stops (10 s timeout) and removes each container, warning and continuing on failure, then deletes the files
$ heretic-cli agents delete claude-zai -f
Stopped heretic-claude-zai-default-1a2b3c4d
Removed heretic-claude-zai-default-1a2b3c4d
Deleted profile: /home/you/.heretic/agents/claude-zai.yaml
Deleted secret script: /home/you/.heretic/get-claude-zai-key.sh
Deleted Claude settings: /home/you/.heretic/claude-zai-settings.json
Agent 'claude-zai' deleted.
It does not delete project-local .heretic/cli/<name>.yaml, .heretic/temp/* session state, images, or named cache volumes. The per-run sidecar network is not removed either — run heretic-cli stop --all first if that matters.
agents mcp <name>
Merges MCP server definitions into the global profile, or into the project-local override with --local.
heretic-cli agents mcp claude --file ./mcp.json # read from a file
heretic-cli agents mcp claude # opens $EDITOR to paste JSON
heretic-cli agents mcp claude --local --file ./mcp.json # write .heretic/cli/claude.yaml
Paste mode uses your editor
Without --file the command opens $EDITOR (inquirer's editor prompt) for the paste, rather than reading raw stdin. Save and close the editor to submit.
Supported JSON shapes
All three are auto-detected:
{ "mcpServers": { "fs": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"] } } }
{ "servers": { "fs": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"] } } }
{ "fs": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"] } }
Per entry the transport is http when type: "http" is set, or when there is no type and a string url is present (then url is required and headers is optional). Otherwise it is stdio and command is required (args optional). env is carried through. An invalid entry aborts with MCP server '<name>' in <source> is missing required field 'command'.
Merge strategy
Servers merge by name: same name replaces, new names are appended, unrelated servers are kept. The command prints a preview, asks for confirmation, then reports Added / Updated / total. With --local the file .heretic/cli/<name>.yaml is created with extends: <name> if it does not exist yet.
The profile must exist in ~/.heretic/agents/ even for --local. There is no way to delete a server with this command — edit the YAML.
Common errors
| Message | Cause |
|---|---|
Profile not found: <name> | no ~/.heretic/agents/<name>.yaml |
Invalid profile '<name>': <errors> | the file failed validation — every command that loads a profile fails here, including run |
Failed to load profile '<name>': … | YAML parse or I/O failure |
Profile '<name>' not found. Use 'heretic-cli agents list' … | friendly wrapper printed by edit / show / mcp / delete |
Next Steps
- Agent Profiles — every profile field and default
- MCP Servers — transports and mount paths
- Validation — the complete rule set