Skip to content

`cotal` CLI reference

Reference: describes the TypeScript reference implementation (the cotal CLI), not the wire contract. · For: operators · Wire contract: SPEC

cotal is the operator command line for the reference implementation: bring a mesh up, mint identities, launch agents, watch what they do, and tear it all down. It is a thin client over the wire contract: the normative subjects and schemas live in the SPEC; this page is lookup material for the commands, not a walkthrough; if you are new, start with Getting started.

Terminal window
npm install -g cotal-ai # puts `cotal` on your PATH (needs Node 20+)
cotal --help # every command, grouped
cotal <command> --help # one command's flags and usage

npx cotal-ai <command> runs it without a global install; in a dev clone, pnpm cotal <command> runs it through tsx with no build step. Bare cotal prints help. Every command generates its own --help, usage, and shell completion from its declared flags.

Commands come from the surfaces the binary composes: the base mesh CLI, the manager (supervise), and the delivery daemon (deliver), plus any operator-installed extensions. cotal ext add <npm-package> adds a package’s commands to this same surface (the web dashboard ships this way; see web).

Area Command Purpose
Set up & lifecycle setup Guided, configure-only setup (installs, seeds personas; launches nothing)
Set up & lifecycle up Start a local mesh (nats-server + JetStream), or boot a whole manifest with -f
Set up & lifecycle down Stop a background mesh, or tear down a manifest / spawn -f deploy
Set up & lifecycle meshes List the running meshes on this machine
Set up & lifecycle use Set the default mesh a bare cotal spawn joins
Set up & lifecycle status Read-only diagnostics for setup, processes, and the selected mesh
Agents & personas spawn Launch an agent from a persona (foreground, or --detach via the manager)
Agents & personas models List connector model catalogs and variants from the manager
Agents & personas ps List managed agents and their mesh status
Agents & personas stop Ask the manager to stop a managed agent
Agents & personas attach Stream and drive a managed agent’s terminal (pty runtime)
Agents & personas personas List, show, edit, create, or remove local personas
Agents & personas supervise Run a manager daemon (the agent supervisor / control plane)
Messaging & watching send Send one message, then exit: DM a peer, post a channel, or ask a role
Messaging & watching channels Inspect or set the channel registry (replay, description, instructions)
Messaging & watching history Clear retained message history
Messaging & watching console Live protocol view for a space (TUI, or --plain line stream)
Messaging & watching web Browser dashboard (installed as the cotal-web extension)
Auth & meshes mint Mint a creds file for a space (auth mode)
Auth & meshes join Join a space as your own presence (interactive)
Manifest topology Validate and view a mesh manifest’s access graph (read-only)
Extensions & misc ext Install / remove operator CLI extensions
Extensions & misc completion Print or install shell completion
Extensions & misc feedback Send feedback to the Cotal developers
Extensions & misc deliver Run the server-side Plane-3 delivery daemon
Extensions & misc feedback-intake Run a self-hosted feedback intake server

The manifest modes of up, spawn, and down (-f <cotal.yaml>) plus topology are covered together under Manifest deploys.

Terminal window
cotal setup [--full] [--demo] [--yes]
Flag Default Meaning
--full off Redo the full guided flow (implies --demo)
--demo off Also seed the guided expert team (david, sven, me)
--yes, -y off Non-interactive accept-all (for agents / CI)

Guided setup is configure-only: it checks prerequisites, installs the Claude Code plugin, and seeds persona files, and it launches nothing (no mesh, no web, no manager). First run gets the narrated flow; later runs print a status card. By default it seeds one default persona; the david/sven/me team is opt-in via --demo. See Getting started and, for maintainers, setup internals.

Terminal window
cotal up [--detach] [--open] [--space <s>] [--server <url>] [--channels <path>]
cotal up -f <cotal.yaml> [--dry-run] [--runtime <pty|tmux|cmux>]
Flag Default Meaning
--server <url> auto (free local port) Listen URL override
--host <host> Bind host override
--space <s> the folder’s name Space name
--store-dir <dir> JetStream store directory
--channels <path> .cotal/channels.json if present Channel-registry seed file (JSON). An explicit path that is missing is an error
--open off (auth) Unauthenticated dev mesh: no JWT, no ACLs
--detach off Run in the background (stop with cotal down)
--file <cotal.yaml>, -f Launch a whole mesh from a manifest
--dry-run off With -f: print the plan, mutate nothing
--runtime <pty|tmux|cmux> manifest’s With -f: override the manifest’s runtime

cotal up boots a local nats-server with JetStream and, in auth mode (the default), JWT auth and per-agent ACLs; --detach records the mesh so cotal spawn from any directory can find it. With no --server, it auto-selects a free port if the default address is taken; an explicit --server stays fail-loud on collision. --detach also brings up the control plane (delivery daemon in auth mode, then the manager). The -f form is a manifest deploy; see Run a mesh.

Terminal window
cotal down
cotal down -f <cotal.yaml> | --run <id> [--dry-run]
Flag Default Meaning
--file <cotal.yaml>, -f Tear down this manifest’s deploy
--run <id> Tear down one spawn -f run by id
--dry-run off Print the plan, mutate nothing

Bare cotal down stops a background mesh started with cotal up --detach. The -f / --run forms tear down a manifest deploy without stopping the whole mesh.

Terminal window
cotal meshes
cotal use <space>
cotal status [--space <s>] [--server <url>]

meshes lists the running meshes on this machine; a * marks the current default a bare cotal spawn joins. use <space> sets that default when several are running. status is a read-only report across four sections: machine prerequisites, this folder’s .cotal/, the recorded meshes, and a live snapshot of the selected mesh (roster, channels, membership feed). status takes only --space / --server to pick the mesh to inspect; it starts nothing.

Terminal window
cotal spawn [<persona>] [--detach] [--name <n>] [--agent <a>] [--model <m>] [--variant <v>] [--prompt <text>] [--cwd <dir>]
cotal spawn -f <cotal.yaml> [--dry-run]
Flag Default Meaning
--space <s> resolved mesh Target space
--server <url> registry entry Broker URL override
--creds <path> Control-caller creds for an off-registry manager (--detach only)
--name <n> persona’s name: Presence-name override (does not choose the persona)
--config <persona-or-path> Persona catalog name or file path; wins over the positional
--agent <a> COTAL_DEFAULT_AGENT, else claude Connector type (claude, opencode, hermes, …)
--role <r> persona’s role: Role override
--model <m> persona’s model: Model override
--variant <v> persona’s variant: Model variant override (connector-defined; e.g. OpenCode reasoning tiers)
--cwd <dir> this cwd Working directory to root the agent at
--prompt <text> Initial prompt auto-submitted at start
--resume <id> Fork an existing session id into the mesh (claude only)
--transcript / --no-transcript off Mirror the session transcript to tr-<name>
--share-tools <sel> none Share named operator MCP servers with the agent
--subscribe <a,b> persona’s Channel read-set override
--allow-subscribe <a,b> = subscribe Read-ACL override
--allow-publish <a,b> deny Post-ACL override
--detach, -d off Launch via the manager into a detached PTY (reattach with cotal attach)
--file <cotal.yaml>, -f Deploy a manifest onto the running mesh
--dry-run off With -f: print the plan, mutate nothing
--allow-stale <a,b> With -f: waive named stale agents (apply-only)
--runtime <pty|tmux|cmux> manifest’s With -f: override the manifest’s runtime

The persona (--config > positional > COTAL_DEFAULT_PERSONA > default) is loaded from the target mesh’s .cotal/agents/; the launch flags override the file. Foreground runs the agent attached to your terminal; --detach hands the launch to the running manager. --detach is the only mode that registers a durable delivery membership; a foreground spawn reads live only. See Connect Claude Code and Agent files; -f is a manifest deploy. (cotal start was merged into cotal spawn --detach.)

Terminal window
cotal models [--agent <connector>] [--refresh]
Flag Default Meaning
--space <s> / --server <url> / --creds <path> resolved mesh Which manager to reach
--agent <connector> all registered connectors Connector whose catalog to list
--refresh off Ask the connector to refresh its provider cache

Asks the running manager for each connector’s model catalog (model ids plus their variants) for connectors that expose one (OpenCode today; a connector without a catalog says so). Pick a result with cotal spawn --model <provider/model> --variant <v>.

Terminal window
cotal ps [--space <s>]
cotal stop --name <n> [--space <s>]
cotal attach --name <n> [--space <s>]
Flag Default Meaning
--space <s> / --server <url> / --creds <path> resolved mesh Which manager to reach
--name <n> Managed agent to stop / attach (required)

These are operator clients over the running manager’s control plane. ps lists managed agents with their mesh status (starting… / working / waiting / offline). attach streams and drives an agent’s terminal on the pty runtime; detach with the escape key (Ctrl-] by default; see COTAL_DETACH_KEY). stop and attach are cross-agent admin operations, so they need a manager to talk to; launch detached agents with spawn --detach.

Terminal window
cotal personas list [-v] [--running]
cotal personas show <name>
cotal personas edit <name>
cotal personas new <name> (--prompt <t> | --from <f>) [--role <r>] [--model <m>]
cotal personas rm <name> --force
Flag Default Meaning
--space <s> / --server <url> / --creds <path> resolved mesh Which mesh’s persona catalog
--role <r> new: the persona’s role
--model <m> new: the persona’s model
--prompt <t> new: the persona’s prompt text
--from <f> new: seed the prompt from a file
--verbose, -v off list: include role / model / description
--running off list: mark personas live on the mesh
--force rm: required, delete without prompting

Personas are the local agent files under .cotal/agents/ that cotal spawn launches. See Agent files for the file format.

Terminal window
cotal supervise [--runtime <pty|tmux|cmux>] [--space <s>] [--server <url>] [--spawn <names>]
Flag Default Meaning
--space <s> this folder’s auth space Space to supervise
--server <url> the local mesh Broker URL
--runtime <pty|tmux|cmux> pty Agent runtime (tmux/cmux are explicit-only)
--console-port <n> Protocol-console port
--roster <file> Declarative roster to boot at startup
--launch <spec> Resolved manifest launch spec (from up -f / spawn -f)
--spawn <names> Comma-separated personas to pre-spawn at startup

The manager is the agent supervisor and control plane: it answers spawn --detach, stop, ps, attach, and the cotal_* manager tools. cotal up --detach starts one for you; run supervise directly to recover a dead manager or drive a custom runtime. Default runtime is pty; tmux/cmux require their extensions and are never selected implicitly. See Deploy.

Terminal window
cotal send dm <agent> "<text>" [--space <s>] [--server <url>] [--creds <path>]
cotal send msg <channel> "<text>"
cotal send ask <role> "<text>"
Flag Default Meaning
--space <s> / --server <url> / --creds <path> resolved mesh Which mesh, and (off-registry) which credential

One-shot messaging: connect, send a single direct message (dm), channel post (msg), or role ask/anycast (ask), then exit. For a running conversation, agents use the mesh tools instead (MCP tools).

Terminal window
cotal channels list
cotal channels set <name> [--replay | --no-replay] [--window <n>] [--desc <s>] [--instructions <s>]
cotal channels default --replay | --no-replay
Flag Default Meaning
--space <s> / --server <url> / --creds <path> resolved mesh Target mesh
--replay / --no-replay set/default: replay history to new joiners, or not
--window <n> set: replay window size
--desc <s> set: one-line channel description
--instructions <s> set: instructions shown to joiners

Inspects and edits the channel registry: replay policy, description, and joiner instructions. ACL semantics (who may read or post) are set at mint / provision time, not here; see Channels and permissions.

Terminal window
cotal history clear --force [--dms] [--space <s>]
Flag Default Meaning
--space <s> / --server <url> / --creds <path> resolved mesh Target mesh
--dms off Also clear DM history
--force Required: clear without prompting

Purges retained channel history; --dms extends it to direct-message history.

Terminal window
cotal console [--plain] [--space <s>]
Flag Default Meaning
--space <s> / --server <url> / --creds <path> resolved mesh Space to watch
--plain off Line stream instead of the TUI

A live protocol view for a space: a lazygit-style TUI, or a plain line stream on --plain. See Watch a mesh.

Terminal window
cotal ext add cotal-web # install once
cotal web [--port <n>] [--no-open] [--space <s>]
Flag Default Meaning
--space <s> / --server <url> / --creds <path> resolved mesh Space to serve
--port <n> 7799 HTTP port
--no-open off Don’t open the browser

The browser observability dashboard: presence, channels, and a live feed. It is not part of cotal up: it ships as the cotal-web extension (cotal setup installs it automatically; otherwise cotal ext add cotal-web). It self-registers cotal web into this surface and serves http://cotal.localhost:7799 (loopback; *.localhost resolves in Chrome/Firefox/Edge; Safari may need http://127.0.0.1:7799). See Watch a mesh.

Terminal window
cotal mint <name> [--profile <agent|observer|admin>] [--out <path>] [--signer]
Flag Default Meaning
--profile <agent|observer|admin> agent Credential profile
--out <path> .cotal/auth/creds/<name>.creds Output path
--signer off Emit a stripped account-signing file instead
--force off With --signer: overwrite an existing file
--allow-subscribe <a,b> profile default Read-ACL override
--allow-publish <a,b> profile default Post-ACL override

Mints a NATS creds file for a space in auth mode, scoped to a profile and (optionally) explicit read/post ACLs. --signer emits an account-signing file for delegating minting to another host. See Identity and auth.

Terminal window
cotal join --space <s> --name <n> [--role <r>] [--channel <c>]
cotal join --link <url> | --token <t>
Flag Default Meaning
--space <s> / --server <url> / --creds <path> resolved mesh Which mesh, and which credential
--name <n> Your presence name
--role <r> Your role
--channel <c> Channel to join
--kind <k> agent Endpoint kind
--link <url> Join link (cotal://…)
--token <t> Join token
--tls off Connect over TLS

An interactive presence: join a space under your own name and role, without launching an agent harness. A --link or --token supplies the where and the auth in one value. See Spaces and Identity and auth.

A cotal.yaml manifest declares a whole mesh (channels, personas, roles, and ACLs) in one file. Three commands consume it, plus a read-only validator:

Terminal window
cotal up -f cotal.yaml # boot a fresh mesh from the manifest
cotal spawn -f cotal.yaml # deploy the manifest additively onto a running mesh
cotal down -f cotal.yaml # tear that deploy down (or --run <id> for one run)
cotal topology view -f cotal.yaml # validate + view the access graph, change nothing

up -f and spawn -f differ in target: up -f brings up a new broker and applies the manifest; spawn -f requires an already-reachable mesh and applies additively (ownership-scoped). Both take --dry-run to print the plan without mutating anything. topology validates the manifest and renders its channel / role / ACL graph. See Define a team and the manifest reference.

Terminal window
cotal ext add <npm-package>
cotal ext remove <name>
cotal ext list

Operator-installed CLI extensions: add installs an npm package into a cotal-owned prefix and makes its commands appear in help, completion, and dispatch; remove and list manage them. The cotal-web dashboard is the canonical example. Installed packages and their location are described in config.

Terminal window
cotal completion <bash|zsh|fish|powershell> # print a stub to eval / source
cotal completion install [shell] # install it persistently

Prints or installs shell completion. Completion candidates come from each command’s declared flags and, where useful, live mesh state (spaces, personas, managed agents) resolved offline.

Terminal window
cotal feedback "<summary>" [--type <t>] [--email <e>] [--details <text>]
Flag Default Meaning
--type <t> bug | idea | friction | praise | other
--details <text> Longer free-form details
--severity <s> low | medium | high
--area <a> The part of Cotal this concerns
--email <e> git email Contact email (required on the keyless public path)
--name <n> Your name (optional)
--url <url> keyed / public intake Intake URL override
--key <k> COTAL_FEEDBACK_KEY Feedback key

Sends feedback to the Cotal developers. With a key (--key / COTAL_FEEDBACK_KEY) it routes to the keyed beta intake; without one it goes to the public cotal.ai intake and requires a contact email (--email / COTAL_FEEDBACK_EMAIL, else your git email). Run a self-hosted intake with feedback-intake.

Two long-lived infra roles ship with the CLI. They are not part of everyday operation; the delivery daemon comes up automatically with cotal up --detach in auth mode.

Terminal window
cotal deliver --space <s> [--server <url>] [--creds <file>]
cotal feedback-intake --keys <keys.json> [--port <n>] [--creds <file>]

deliver runs the server-side Plane-3 delivery daemon: the durable backstop and membership/ACL authority. It is auth-mode-only and single-instance (--shard/--shards accept only N=1); --dev-mint mints a scoped cred from the local signer for standalone dev. See the delivery daemon. feedback-intake runs a self-hosted feedback server (requires --keys and a scoped --creds), announcing submissions into a space channel; flags include --host/--port, --store, --space/--channel, --max-bytes, and --rate-limit.

cotal __complete <words…> is the internal entry the shell-completion stubs call to emit candidates for the current command line; you never run it directly. (cotal start is a removed tombstone: it errors and points you to cotal spawn --detach.)