apus agents

Manage isolated agents (workspaces + auth + routing). Running apus agents with no subcommand is equivalent to apus agents list.

Examples

apus agents list
apus agents list --bindings
apus agents add work --workspace ~/.apus/workspace-work
apus agents add work --workspace ~/.apus/workspace-work --bind telegram:*
apus agents add ops --workspace ~/.apus/workspace-ops --bind telegram:ops --non-interactive
apus agents add research --role researcher --non-interactive
apus agents team create --non-interactive
apus agents bindings
apus agents bind --agent work --bind telegram:ops
apus agents unbind --agent work --bind telegram:ops
apus agents set-identity --workspace ~/.apus/workspace --from-identity
apus agents set-identity --agent main --avatar avatars/apus.png
apus agents delete work

Command surface

agents list

Options: --json, --bindings (include full routing rules, not only per-agent counts/summaries).

For an explicit multi-agent roster, the default badge and JSON isDefault field use agents.defaults.systemAgent.agentId. Doctor preserves the migrated default there across restarts. Without a designation, every entry reports isDefault: false; set one with apus config set agents.defaults.systemAgent.agentId <id>. The Control UI's Set Default action writes the same designation.

Provider-status labels include optional account display names beside account IDs. Routing rules continue to identify accounts by channel and account ID.

An agent whose database belongs to another agent appears as degraded, with the refusal reason and repair guidance. The Gateway can continue serving healthy agents when a secondary agent is refused. Follow Doctor's database recovery guidance, then restart the Gateway after repairing the files.

Provider rows summarize local account status for the displayed binding scopes. A wildcard includes each locally known account once; message routing still applies peer and account precedence. Stored bindings with an omitted or blank account id refer to the literal default account key, independently of a channel's preferred account for commands. Use --json --bindings to include provider rows in JSON.

Identity fields saved in config take precedence. Fields that are not configured fall back to IDENTITY.md in the agent's workspace. Unsupported avatar values and unreadable local images also fall back to the workspace avatar.

agents add [name]

Options: --role <role>, --workspace <dir>, --model <id>, --agent-dir <dir>, --bind <channel[:accountId]> (repeatable), --non-interactive, --json.

Role templates

--role works in interactive and non-interactive creation, including --json. Bundled roles are Claw sources: each role directory contains a CLAW.md manifest with identity and SOUL.md content, plus its operating program in workspace/AGENTS.md. Available roles:

Role Title Purpose
coordinator Chief of staff Coordinate specialists as your single point of contact.
researcher Researcher Gather evidence and return a cited research brief.
writer Writer Turn a brief and source material into a usable draft.
reviewer Reviewer Check artifacts against requirements and return actionable findings.

A role seeds AGENTS.md, SOUL.md, and a complete IDENTITY.md; USER.md still uses the standard template. Existing workspace files are preserved. The role's name, emoji, and theme are saved in agent config, and new role workspaces skip the identity ceremony: no BOOTSTRAP.md is created. The bundled roles leave skills unchanged. Role delegation settings are also applied. A standalone chief of staff targets the standard specialist ids; use the team command to create and wire all four agents. When creating an agent through Ask Apus, you can give a display name separately from its id, such as “QA Writer” with id qa-writer. The approval includes both. An explicit display name replaces the role's default name while keeping its emoji, theme, and operating instructions. Unknown roles are rejected with the available role names. A workspace with an unfinished bootstrap cannot adopt a role. Apus checks completion before adding role files; rejected adoption leaves workspace files and agent config unchanged. Complete its bootstrap or choose a new workspace.

With the experimental Claws surface enabled, the equivalent source path is apus claws add docs/reference/templates/roles/<role> from a source checkout. Follow the Claw preview and consent flow to add it. Use agents team create to wire the agents into a team.

agents team create

Options: --preset <name> (default and only bundled preset: team), --coordinator <id> (default: coordinator), --prefix <p>, --workspace-root <dir>, --non-interactive, --json.

Creates a chief of staff (coordinator) plus researcher, writer, and reviewer from the role templates. Each workspace lives at <workspace-root>/<agentId>; the default root is the installation's default workspace directory. --prefix editorial namespaces every id, producing editorial-coordinator, editorial-researcher, editorial-writer, and editorial-reviewer. It also prefixes a custom --coordinator id. If any resulting id exists, the command reports the conflicts and adds no agents.

Existing agents remain in place, including an implicit main on an already configured installation.

apus agents team create --prefix editorial --workspace-root ~/agents --non-interactive --json
apus agent --agent editorial-coordinator --message "Research this topic and draft a brief."

The coordinator's subagents.allowAgents names the three specialist ids and delegationMode is "prefer". Specialists receive subagents.allowAgents: [] and instructions to return results without further delegation. This does not change global delegation defaults or tool policy. See Team preset. Delegation remains team wiring in config; the role Claws will carry these settings once the separate Claw profile support lands.

The coordinator is an explicit chat target. If agents.defaults.systemAgent.agentId is unset, team creation sets it to the coordinator for ambient system work and default-compatible operations. An existing owner is preserved and reported. Channel bindings take precedence over this default. With --json, the summary includes coordinatorId, the created agents and their paths, ambientOwnerId, and a note when another ambient owner is retained.

agents bindings

Options: --agent <id>, --json.

agents bind

Options: --agent <id> (defaults to the current default agent), --bind <channel[:accountId]> (repeatable), --json.

agents unbind

Options: --agent <id> (defaults to the current default agent), --bind <channel[:accountId]> (repeatable), --all, --json. Accepts either --all or one or more --bind values, not both.

agents set-identity

Options: --agent <id>, --workspace <dir>, --identity-file <path>, --from-identity, --name <name>, --theme <theme>, --emoji <emoji>, --avatar <value>, --json. See Set identity below.

agents delete <id>

Options: --force, --json.

Automatic local fallback never applies to a remote Gateway or an APUS_GATEWAY_URL override, including loopback SSH tunnels. Connection or credential failures exit with an error and leave local config, workspace, and session state alone. Restore the Gateway connection and credentials, or run the command on the Gateway host.

Routing bindings

Use routing bindings to pin inbound channel traffic to a specific agent.

If you also want different visible skills per agent, configure agents.defaults.skills and agents.entries.*.skills in apus.json. See Skills config and Configuration reference.

List bindings:

apus agents bindings
apus agents bindings --agent work
apus agents bindings --json

Add bindings:

apus agents bind --agent work --bind telegram:ops --bind discord:guild-a

You can also add bindings when creating an agent:

apus agents add work --workspace ~/.apus/workspace-work --bind telegram:* --bind discord:*

If you omit accountId (--bind <channel>), Apus resolves it from plugin setup hooks, forced account binding, or the channel's configured account count.

If you omit --agent for bind or unbind, Apus targets the current default agent.

--bind format

Format Meaning
--bind <channel>:* Match all accounts on the channel.
--bind <channel>:<account> Match one account.
--bind <channel> Match the default account only, unless the CLI can safely resolve a plugin-specific account scope.

Binding scope behavior

Examples:

# match all accounts on the channel
apus agents bind --agent work --bind telegram:*

# match a specific account
apus agents bind --agent work --bind telegram:ops

# initial channel-only binding
apus agents bind --agent work --bind telegram

# later upgrade to account-scoped binding
apus agents bind --agent work --bind telegram:alerts

After the upgrade, routing for that binding is scoped to telegram:alerts. If you also want default-account routing, add it explicitly (for example --bind telegram:default).

Remove bindings:

apus agents unbind --agent work --bind telegram:ops
apus agents unbind --agent work --all

Identity files

Each agent workspace can include an IDENTITY.md at the workspace root:

Avatar paths resolve relative to the workspace root and cannot escape it, even through a symlink.

Set identity

set-identity writes fields into agents.entries.*.identity: name, theme, emoji, avatar (workspace-relative path, http(s) URL, or data URI).

Load from IDENTITY.md:

apus agents set-identity --workspace ~/.apus/workspace --from-identity

Override fields explicitly:

apus agents set-identity --agent main --name "Apus" --emoji "🦞" --avatar avatars/apus.png

Relocate the stored workspace:

apus config set agents.entries.work.workspace ~/.apus/workspace-work
apus agents list

Config sample:

{
  agents: {
    entries: {
      main: {
        identity: {
          name: "Apus",
          theme: "space lobster",
          emoji: "🦞",
          avatar: "avatars/apus.png",
        },
      },
    },
  },
}

Related