Install the CLI and create an account
This page covers setup of the uno CLI: install, check, update, create or sign in to an account, back up the account key, and pin the account for agents. It is for developers and AI agents. At the end you have a working account that every command can name by UUID. The page is self-contained.
Use --format json on every command that an agent runs. Read stdout and the shell exit code. Do not parse human output.
Install
Supported systems
| System | Install route |
|---|---|
| macOS, Apple silicon | curl installer or Homebrew |
| Linux, x86_64 | curl installer |
| Linux, arm64 | curl installer |
Windows and Intel macOS are not supported. The installer stops with an error on them.
Install with curl
curl -fsSL https://uno.fun/install.sh | shThe installer downloads one release archive, checks it against the SHA256SUMS file of the same release, and installs it. A wrong checksum stops the install before it writes the install directory. The installer needs curl and sha256sum or shasum.
The installer puts the launcher at ~/.uno/bin/uno. The install root is ~/.uno. The environment variable UNO_INSTALL_DIR changes the root.
The installer adds ~/.uno/bin to the startup file of your shell, so new terminals find uno. It adds nothing, and prints the export PATH=... line to run yourself, when any of these is true:
- You set
UNO_NO_MODIFY_PATH=1. - The
CIenvironment variable is set. - You run as root.
- Your shell is not zsh, bash or fish.
In a sandbox or CI job, call ~/.uno/bin/uno directly, or add ~/.uno/bin to PATH for that process:
export PATH="$HOME/.uno/bin:$PATH"To skip the startup-file change:
curl -fsSL https://uno.fun/install.sh | UNO_NO_MODIFY_PATH=1 shInstall with Homebrew
Homebrew works on macOS with Apple silicon only.
brew install --cask officialunofficial/tap/unoHomebrew owns its own files. uno update runs brew update and then brew upgrade --cask uno on this route.
Check the install
uno doctor --format jsonuno doctor reads local state only and sends no request. It reports the install route (curl, launcher, homebrew or other), the executable path, the auto-update state and a list of checks. Each check has a status of ok, warn, fail or note. The command exits with code 1 when a check fails.
Update
uno update --check --format json
uno update --format json--check reports the newest version and changes nothing. Without a flag, the command installs the newest release on the curl route. On the Homebrew route it runs the Homebrew commands and the result has status: "managed". On the launcher route it installs nothing and returns status: "deferred" with the command to run.
The environment variable UNO_DISABLE_UPDATES=1 blocks manual updates and checks. The variable UNO_NO_AUTO_UPDATE=1 stops automatic checks and notices.
Install the agent skill
uno skills addThe command writes one file, ~/.agents/skills/uno/SKILL.md. It changes no agent configuration. Pass --dir <dir> to write <dir>/uno/SKILL.md instead. Run it again after an update to refresh the skill.
Create an account
An account created from the CLI is unverified. It has a key on your machine and no email or passkey.
uno account create --username <name> --accept-terms --operation <id> --format json--username <name>is optional. Without it, the server generates a username.--accept-termsaccepts the Terms of Service and the Privacy Policy. Every create needs it. Without it, the command exits 2 with a message that names the URLs of both documents. Show them to the person and get agreement first.--operation <id>is required in agent mode. Use 1 to 128 letters, digits, dots, underscores or hyphens, starting with a letter or digit. After a lost reply, rerun the same command with the same operation and the same inputs.
Read the account UUID from data.account_id in the result. Read the key file path from data.key_path. Creating an account saves its session and makes it the active account. Other saved accounts stay saved.
Run this command without account pins. uno account create rejects --expect-account.
To list the accounts on this machine without a network request:
uno account list --format jsonThe UUIDs are in data.accounts[].account_id.
Back up the account key
The account key is the only way into an unverified account. If you lose it, you lose the account and any storage you paid for. There is no recovery for a lost key.
Anyone who holds the key file controls the account. Never print it or put it in an upload folder.
Write a backup to a new path:
uno account key export <path> --account <uuid> --expect-account <uuid>In agent mode this command needs a pin (see Pin the account). The command refuses an existing path. It writes the copy with mode 0600 and never writes the key to stdout. Store the backup outside disposable runtimes.
Restore the key on another machine:
uno account key import <path>The import source must be a regular file, not a symlink, with mode 0600, owned by you. It must be an account key file, such as one that uno account key export wrote. Import copies the key into the key file of the API origin. It does not sign in. Pass --api <origin> if the key belongs to an origin other than the one in use. The default origin is https://api.uno.fun; a key for another origin is refused with an error that names the --api value to use.
After you import a key, sign in with it:
uno account login <uuid> --expect-account <uuid> --format jsonuno account login signs in to an unverified account with the key on this machine. It creates no key.
Verify the account
Verification adds an email and a passkey through uno.fun. Verify while you still hold the key. Start it:
uno account verify --start --format jsonGive the url in the result to the person. They approve in the browser. The page shows an 8-digit code. Pass it back with --code <code>. --status prints the state of the saved hand-over. --no-wait with --code exits after the approval.
After the state is verified, the key no longer signs in. Sign in with uno login:
uno login --expect-account <uuid> --format jsonuno login uses a native passkey on local macOS. It uses browser approval on SSH and other platforms. --web forces the browser. uno login acquires an identity, so it rejects --account. It accepts --expect-account.
Pin the account
A pin names the account that a command must use. Agents need a pin for account work.
Set both variables for the whole session:
export UNO_ACCOUNT=<uuid>
export UNO_EXPECT_ACCOUNT="$UNO_ACCOUNT"
uno account current --format jsonOr pass both flags on each command:
uno account current --account <uuid> --expect-account <uuid> --format json| Pin | Effect |
|---|---|
--account <uuid> or UNO_ACCOUNT | Selects an existing local account by UUID |
--expect-account <uuid> or UNO_EXPECT_ACCOUNT | Requires that UUID. It never selects an account |
A command whose selected account differs from the expected account exits with code 25.
Get the UUID from the person, from trusted job configuration, or from the data.account_id of an account you were authorized to create. A username, the active account or a folder binding does not establish what the person intended.
Agent mode
The CLI runs in agent mode when any of these is true:
- You pass an explicit
--formator--json. UNO_AGENT=1is set.CLAUDECODEorCODEX_THREAD_IDis set.- A CI environment is detected.
- Stdout is not a terminal.
In agent mode, a command that needs an account exits with code 27 (ACCOUNT_PIN_REQUIRED) when it has no pin. The message says to pass --account <uuid> or a matching --expect-account <uuid>. Supply the pin and run the command again.
Commands that need a pin include uno account key export, uno account verify, uno account switch, uno logout and the uno kit commands that act as your account. uno logout --all is the exception: it exits 2 if any pin is set, so unset the pins first. Commands that need no pin include uno account list, uno account create, uno account current, uno account key import, uno account login, uno login, uno doctor, uno update and uno skills add. A folder binding made with uno account bind does not replace the pin.
For exit codes and the full agent rules, see Agent mode and exit codes.