Skip to content

Command Line Reference

William Koch edited this page Sep 30, 2026 · 14 revisions

uv run keryx --help lists the commands, and keryx <command> --help lists a command's flags. uv run keryx --version prints the installed version.

Read-only commands read the stored data directly, so they work even when the server is stopped. These are tasks, memory, doctor, approvals, restart --status, config list|get, plugins list|hosts, and tools. They hide INFO logs but still show warnings. To see every log line, set LOG_LEVEL=DEBUG.

Exit codes are 0 for success, 1 for a failure or a refusal, and 2 for invalid usage.

Setting up

uv run keryx setup                           # walk only what is still missing
uv run keryx setup --all                     # walk every section, and ask again about what is set
uv run keryx setup --agent-instructions      # the command-line path, for a coding agent

keryx setup needs a terminal. It reads doctor's checks to decide what's left, saves each answer as it goes, and remembers which optional sections you've completed. Before it updates the Twilio webhooks, it shows you both addresses and asks you to confirm. A coding agent can handle the command-line steps, but you still need to do the browser sign-ins, the PIN, and the webhook approval yourself.

Settings

uv run keryx config list [--json] [--group phone]   # every setting, where it comes from
uv run keryx config get PUBLIC_HOST [--shell]       # never prints a secret
uv run keryx config set OWNER_NAME "Sam" SMS_ENABLED false
uv run keryx config set TWILIO_AUTH_TOKEN --stdin   # a secret: from stdin…
uv run keryx config set OPENAI_API_KEY --from-env OPENAI_API_KEY   # …or a variable
uv run keryx config unset KEY…                      # back to the default
uv run keryx config path [--shell]                  # every directory; --shell for eval
uv run keryx config import-env [PATH]               # move one old .env into the store
uv run keryx config lock KEY | unlock KEY           # what the running service may change
uv run keryx migrate [--dry-run] [--yes]            # move a Jarvis install (or ~/.jarvis) to Keryx

Plain settings go to KERYX_HOME/config.toml, and every secret goes to secrets.toml beside it. Both are readable only by you. KERYX_HOME is ~/.config/keryx unless you set the KERYX_HOME environment variable. A secret is refused as a command-line value, because ps and your shell history would keep it. The process environment wins over both files, and nothing is read from the working directory. The settings reference lists every setting. The PIN isn't a setting: keryx setup or the first call sets it (see Security Model).

Inside a Keryx task, config set acts as the running service, and may change only the settings the service is allowed to write. These commands refuse to run inside a task at all: import-env, migrate, lock, unlock, auth login, memory seed, plugins install|remove, and setup.

Sign-ins

uv run keryx auth status [--json] [--smoke]   # every sign-in; --smoke runs one real task per agent
uv run keryx auth login claude                # or codex; --headless on a machine with no browser
uv run keryx auth login gmail --client-file ~/Downloads/client_secret.json
uv run keryx auth login gmail --callback-url 'http://localhost:1/?…'
uv run keryx auth login google-workspace

auth status shows a coding agent that isn't in AGENTS_ENABLED as off, not as missing. With --json, it keeps the agent's state and says enabled: false.

gmail takes two steps. The first prints a link to open on any device, and the second takes the address the browser landed on. The Gmail sign-in is for the check_email plugin, which you turn on separately (keryx plugins install check_email). See Google Workspace MCP for what each Google sign-in is for.

Plugins

uv run keryx plugins [--json]                  # the four: on, off or refused, and why; same as `plugins list`
uv run keryx plugins install check_email       # turn one on, from its settings file or the defaults
uv run keryx plugins install send_to_slack --set channel_id=D0123456789
uv run keryx plugins install cluster_stats --cluster mycluster=gpu [--guard PATH]
uv run keryx plugins install check_billing --template   # write its files to edit; leave it off
uv run keryx plugins install --from-settings   # move the settings they replaced; turn on what was offered
uv run keryx plugins remove check_billing [--yes]   # off; its settings are kept aside
uv run keryx plugins hosts [--json]            # ssh hosts cluster_stats could ask, and whose master is up

The optional voice tools are plugins: send_to_slack, check_email, check_billing, and cluster_stats. Each is a one-line <name>.py and a commented <name>.toml of its settings in DATA_DIR/tools/. None is offered until you turn it on. A change doesn't need a restart; it takes effect from the next call. keryx setup → Plugins does the same thing by asking you questions.

  • --set KEY=VALUE sets one of a plugin's settings. Repeat it for more.
  • --cluster ALIAS=PARTITION sets the whole [clusters] table for cluster_stats.
  • A secret is never taken here. Use keryx config set KEY --stdin, or keryx auth login gmail.
  • install exits 1 if the plugin it turned on would be refused.
  • remove asks first, unless you pass --yes. It sets the settings aside as <name>.toml.off, so they're remembered when you turn the plugin on again.
  • hosts reads ~/.ssh/config and offers only hosts with a ControlMaster. Nothing it does reaches the network.

Your own tools

uv run keryx tools [--json]    # what DATA_DIR/tools defines, and what the next call would refuse

keryx tools loads the directory the same way a call does, checking against every built-in tool's name. It lists each tool, whether it needs the PIN, and its file. A file it refuses is listed with the reason, and the command exits 1 while any file is refused. The plugins are listed here too, because they're tools of the same kind. See Custom Tools.

Running the agent

uv run keryx serve                  # the phone server
uv run keryx serve --demo           # try the phone before an agent is set up: tasks get a sample answer
uv run keryx serve --host 0.0.0.0 --port 9000   # override HOST and PORT

If DEBUG_SKIP_TWILIO_VALIDATION is on while PUBLIC_HOST is set, keryx serve refuses to start the phone channel. See Security Model.

scripts/dev.sh runs the Cloudflare tunnel and keryx serve together. It logs the tunnel to STATE_DIR/logs/cloudflared.log, and passes any extra flags through to keryx serve. For a machine that should stay up without a terminal, see Running as a Service.

Tasks

uv run keryx tasks list                      # 20 most recent, newest first
uv run keryx tasks list --status running     # queued|running|done|failed|cancelled|all
uv run keryx tasks list --limit 50
uv run keryx tasks list --internal           # also show Keryx's own housekeeping
uv run keryx tasks show 12                   # every field, plus the written report

The TOLD column stays NO until Keryx has told you the result. Results you haven't heard come first in the next call, and retention never prunes them. --internal shows Keryx's own housekeeping tasks, such as the memory update after each call. These tasks are left out of spoken lists, the start-of-call summary, searches of past calls, the daily cap, and notifications.

What the assistant remembers

uv run keryx memory                          # print what Keryx carries between calls
uv run keryx memory --path                   # just say where the file is
uv run keryx memory seed --file facts.txt    # one standing fact per line
printf '%s\n' "…" "…" | uv run keryx memory seed --file - --json
uv run keryx memory seed --file facts.txt --force   # replace a memory that has something in it

A new install knows nothing about you until an authorized call finishes and updates the memory. To add that context now, use memory seed or the About you section of keryx setup. Either writes facts under Standing facts in DATA_DIR/memory.md, and reports the memory, project briefs, and skills that calls will receive.

memory seed exits 1 without changing the file in two cases:

  • a memory already exists, unless you pass --force;
  • the result would be longer than the 4,000 characters a call reads.

Set OWNER_NAME with keryx config set OWNER_NAME … or keryx setup. The default is "the owner".

After each call authorized with the PIN, a subagent updates the memory for the next call. The file is plain Markdown, and you can edit it by hand. Later updates keep your edits.

Restarting

uv run keryx restart --reason "picked up new code"
uv run keryx restart --status        # how the last one went, including what the logs said
uv run keryx restart --force         # even while a call is in progress
uv run keryx restart --no-callback   # quietly, with no call afterwards

keryx restart restarts the installed unit, and refuses when there's none. See Restarting Keryx for how Keryx reports on a restart that stops its own process.

The approval bridge

uv run keryx approvals              # the audit trail: what it escalated and what happened
uv run keryx approvals --limit 5
uv run keryx approvals --disable    # kill switch, effective on the next prompt
uv run keryx approvals --enable

See The Approval Bridge.

Deleting things

uv run keryx forget --older-than 30              # asks first
uv run keryx forget --yes                        # everything eligible, no window
uv run keryx forget --transcripts-only --older-than 7
uv run keryx forget --tasks-only --older-than 90

--older-than 0 means everything, and none of it can be undone. You can't combine --transcripts-only and --tasks-only. A finished task you haven't been told about yet is never deleted, by this command or by automatic pruning. See Data and Retention.

Diagnostics

uv run keryx doctor                          # is this machine set up?
uv run keryx doctor --json                   # every check, with its section and state
uv run keryx doctor --fix                    # tighten secret files to owner-only, nothing else
uv run keryx loopback --wav sample.wav       # one session from a WAV file

doctor exits non-zero only on a hard failure, so you can use it in a check script. Each check carries the keryx setup section that would fix it, and a state:

  • ok;
  • missing — nothing configured yet;
  • failed — configured, but not working.

loopback is the development harness for the realtime provider. It plays a 16-bit WAV to the model, and with --out it writes the reply audio to a file.

Related

  • Troubleshooting — what doctor checks and where to look when something misbehaves.

Clone this wiki locally