---
title: heretic-cli agents
description: "Manage global agent profiles — list, add, edit, show, validate, delete, and import MCP servers, with every prompt, flag, masking rule and error message"
canonical: https://giglabo.com/heretic/docs/heretic-cli/commands/agents
locale: en
---

# heretic-cli agents

> Markdown twin of https://giglabo.com/heretic/docs/heretic-cli/commands/agents
> Fetch this instead of the HTML page: same content, a fraction of the bytes.
> Site structure and the full page list for agents: https://giglabo.com/llms.txt

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" }]`.

> **Note: 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:

1. **Docker image** — required
2. **Runner type** — Docker / Docker Compose / Custom
3. **Volumes** — repeating loop: source (required), target (required), read-only (default no)
4. **Environment variables** — repeating loop: name (`[A-Z_][A-Z0-9_]*`), value
5. **Working directory** — optional
6. **Command** — optional, split on whitespace into an array
7. **Interactive mode (stdin)?** and **TTY?** — both default yes
8. **Network mode** — optional, e.g. `host` → `extra.network`
9. **Ports** — repeating loop, must match `<host>:<container>` → `extra.ports`

Then a summary and `Save this profile?`. Declining prints `Profile not saved.` and exits 0.

> **Warning: 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`](https://giglabo.com/heretic/docs/heretic-cli/commands/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?`.

```bash
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`:

```bash
$ 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
```

> **Note: 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](https://giglabo.com/heretic/docs/heretic-cli/reference/validation).

## `agents delete <name>`

1. Finds containers labelled `heretic.managed=true` **and** `heretic.agent=<name>` in any state (skipped when Docker is unavailable)
2. 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`
3. Confirms — default **No** — unless `-f/--force`
4. 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`.

```bash
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
```

> **Note: 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:

```json
{ "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](https://giglabo.com/heretic/docs/heretic-cli/configuration/agent-profiles) — every profile field and default
- [MCP Servers](https://giglabo.com/heretic/docs/heretic-cli/configuration/mcp-servers) — transports and mount paths
- [Validation](https://giglabo.com/heretic/docs/heretic-cli/reference/validation) — the complete rule set

## Related

- HTML version of this page: https://giglabo.com/heretic/docs/heretic-cli/commands/agents
- Site map for agents: https://giglabo.com/llms.txt
