Duvo CLI
is the official command-line interface for the
Duvo
public API. It is published to npm as
:
a single binary with resource-grouped subcommands (
,
,
, …) and a low-level
escape hatch for endpoints that don't yet have a dedicated command.
Use the CLI when the user wants to
automate or
script Duvo. The
web UI at
https://app.duvo.ai is the right answer when they want to
click around interactively;
is the right answer the moment they
ask for a shell snippet, a cron job, a CI step, or "how do I do X
without opening the browser?". Both surfaces talk to the same public
API — there is no functional gap to bridge by reaching for
.
Install
bash
npm install -g @duvoai/cli
duvo --version
Requires Node.js ≥ 22.22.0.
also works without
a global install.
Authentication
keeps credentials as
named profiles on disk. One profile per
(team, environment). The first profile added becomes the default; from
then on, every command uses the default unless overridden.
bash
duvo login # OAuth flow — opens your browser
duvo login --name acme # name the profile up front
duvo login --api-key <key> # skip OAuth and store an API key directly
duvo whoami # confirm who's signed in
defaults to
browser-based OAuth against the Duvo
production tenant. Pass
to store a long-lived API key
instead (grab one from
https://app.duvo.ai/settings/api-keys).
Switching between profiles:
bash
duvo profiles list # show all profiles; `▶` marks the default
duvo profiles use # interactively pick the default profile
duvo profiles use acme # set a named profile as the default
duvo --profile acme whoami # one-off override for a single command
Resolution precedence (the first match wins):
- Profile: flag → env → in config.
- Credential: env (bypasses the profile's stored credential lookup) → the profile's stored credential.
- Base URL: env → the profile's → .
Reading the help
Every command supports
. Reach for it first instead of guessing:
bash
duvo --help # global help, lists every top-level group
duvo agents --help # subcommand group
duvo agents create --help # exact flags for one command
The CLI's help text is the source of truth — if a flag doesn't appear
there, it doesn't exist in your installed version. Always show the
user
rather than copy-pasting flags from
memory if you're unsure.
Output modes
Each command picks a default output shape based on what it returns:
- Single resource (, ) →
human-readable key/value text.
- Collection (, ) → table with a
fixed column set per resource.
- on either of the above → raw JSON to stdout. This is the
stable contract for scripts — table and text formats can change
between versions, JSON is safe to pipe into or .
bash
duvo agents list --json | jq '.agents[].id'
For scripting, always pass
and parse the response. Don't
parse the table output — column widths and truncation thresholds are
not part of the public contract. Envelope keys differ across
endpoints —
returns
,
returns
,
returns
,
returns
. Inspect the shape with a one-off
call before
hard-coding a jq path.
The escape hatch
Any endpoint in the public API is reachable via
, modelled directly on
. Reach for it when:
- A new public endpoint shipped but doesn't have a dedicated
command yet.
- You need a very narrow query-string or body shape that the
high-level command doesn't expose.
- You're debugging — shows exactly what the API returned,
with no formatting in the way.
bash
duvo api GET /v1/agents -F limit=20 -F offset=0
duvo api POST /v1/agents -f name="Ops bot" -F build[name]="v1"
duvo api POST /v1/agents --input body.json
cat body.json | duvo api POST /v1/agents --input -
sends the value as a
string;
parses it as a typed value
(boolean, number, JSON
, or
to load JSON from disk). See
references/api-escape-hatch.md
for the full flag table.
High-level commands like
are sugar over
— they share the same HTTP client, output pipeline, and exit
codes, so a script can mix the two freely.
Resource groups
See
for the full command tree with flags.
The top-level groups are:
- Auth & profiles — , , ,
- Agents — , ,
- Agent folders — (organize agents in a tree)
- Revisions — , (versioned configs)
- Runs — (start, get, message, stop, respond to HITL)
- Queues & cases — , ,
- Files & sandboxes — ,
- Connections & integrations — , ,
- Clarity — (read-only process search, versions, captures, gaps, evidence, facets, export, doctor)
- Skills & plugins — ,
- Team — ,
- Low-level —
For end-to-end recipes (create an agent → start a run → respond to
HITL; manage a queue and its cases; upload files for a sandboxed run;
authorize a custom MCP server) see
.
Conventions you can rely on across commands
These hold for every command group, so call them out when explaining
the CLI rather than restating per-command:
- is a global flag that overrides the default
profile for that single invocation.
- is available on every command that hits the API and is the
shape to use in scripts.
- Destructive operations (, ,
,
duvo agent-folders delete
, ,
, , ,
, …) prompt for confirmation in a TTY and refuse
on a non-TTY stdin. Pass / to skip the prompt — never
pipe into the CLI to bypass the prompt; it explicitly refuses
inferred consent from piped input.
- Exit codes: success, generic error, auth error (missing
or invalid key, unknown profile), not found. Useful for CI
scripts that want to branch on the failure mode.
- IDs are printed bare (no quotes) so they copy cleanly into shell
pipelines and substitutions:
bash
agent=$(duvo agents create --name "Ops bot" --input "What to do" --json | jq -r .agent.id)
duvo runs start --agent "$agent"
- Deprecation warnings print to stderr (so they don't corrupt
stdout) and can't be silenced. If a user reports an
unexpected warning, check whether their version is
behind.
Pitfalls and gotchas
- Profile vs credential. changes which profile is
read; overrides the credential but still uses
the selected profile's . To target a totally different
environment, set both and .
- with no argument opens an interactive picker that
only works in a TTY. In CI, always pass a name explicitly.
- is interactive by default. When and
are omitted and stdin is a TTY, the CLI prompts. In CI,
pass both flags (and if you don't want an initial
build) so it never blocks waiting for input.
cases create --from-file -
reads JSON from stdin. The file (or
stdin) is a single case object or an array of up to 100 cases. Each
case is { "title": "…", "data": "…", "labels": [{ "key": "…", "value": "…" }] }
. Labels with no are tag-only labels.
- Sandbox files vs team files. manages persistent
team files (visible in the Files surface in the UI); stages files for a single run (
duvo runs start --sandbox-id <id>
). Don't mix them.
- Connections vs integrations. shows the
team's catalog of integration types; shows
the user's actual connected accounts (one per OAuth/credential
flow). OAuth-based connections (Gmail, Slack, …) are started by
duvo oauth native start <provider>
or duvo oauth composio start …
, not by — the latter is only for
user-provided MCP servers.
- Clarity is read-only in this CLI surface. Start with
duvo clarity overview <process-id>
, then use , ,
, , , , , or as
needed. Those v2-only commands require a Clarity v2 process; legacy v1
processes support only , , , , and
. Default output is compact; transcripts and media URLs are
included only when a JSON command explicitly passes
.
When the CLI is the wrong tool
Steer users to a different surface in these cases:
- They want to read a stream of run events as they happen. The
CLI's / are point-in-time reads. Use
on to receive events asynchronously,
or open the run in the web UI.
- They want to edit an SOP or agent configuration interactively.
and accept a config file, but
composing the config by hand is painful. Direct them to the
Assignment editor in the web UI for anything beyond a small targeted
patch.
- They want to run an agent in their own process rather than on
Duvo. That's not what the public API exposes; the CLI is a client
to the hosted Duvo platform.
In-skill references
- — full command tree with flags, grouped by
resource. Use this when you need the exact flag a command expects.
- — end-to-end recipes (create an agent and
start a run; queue + cases lifecycle; sandboxed runs with uploaded
files; authorize a custom MCP server).
references/api-escape-hatch.md
— flag reference, with
worked examples of vs , typed fields, and
for raw JSON bodies.
When in doubt, run
— the installed binary is
the final source of truth.
See also
- — author or rewrite the SOP that ships in a Build ( / ).
- — diagnose a failed Job; pairs with , , and for API-mode reads.
- — audit an Assignment or workflow across many Jobs; pairs with , , and .
Resources
- Duvo — product website
- Duvo documentation — concepts, building Assignments, Connections
- Duvo API reference — every endpoint the CLI wraps
- on npm — versions, install instructions, changelog
- Web app — interactive surface for everything the CLI scripts
- API keys — issue and revoke API keys for
- Public skill repository — the MIT-licensed community release of this skill, packaged for installation in third-party Claude Code setups