01 Install
Pick one. All three install the same program.
# the installer: puts uno in ~/.local/bin
curl -fsSL https://unocode.motiontic.com/install.sh | sh
# Homebrew
brew install motiontic/tap/uno
# npm (Node 18 or later)
npm i -g @motiontic/uno
- The installer checks the download against the release's checksums, and against its signature when minisign is installed. Set
UNO_VERSION=0.2.0to install a particular version, orUNO_INSTALL_DIRto install somewhere other than~/.local/bin. If that folder is not on yourPATH, it tells you the line to add. - Works on macOS and Linux, on Apple Silicon, Intel, arm64 and x86_64 machines. The Linux build runs on any distribution. Windows is not supported yet.
- On Linux the sandbox needs
bubblewrapfrom your package manager (sudo apt install bubblewrap,sudo dnf install bubblewrap). Without it, shell commands ask before they run.
02 First run
Uno talks to the model provider with your own API key. Put the key in ~/.config/uno/.env so it works in any folder:
mkdir -p ~/.config/uno
echo 'ANTHROPIC_API_KEY=sk-ant-...' >> ~/.config/uno/.env
chmod 600 ~/.config/uno/.env
Keys are read from the environment first, then from a .env file in the folder you run uno in, then from ~/.config/uno/.env. The names are ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY, and OPENAI_COMPAT_API_KEY for other servers.
cd your-project
uno # open a chat
uno -p "add a test for parse_date" # run one task and print the answer
uno --model gpt-6-luna # another model
uno --provider openai-compat --base-url http://localhost:11434/v1 --model qwen3
The default model is claude-sonnet-5. The provider is worked out from the model's name: Anthropic, OpenAI, Gemini, or any OpenAI-compatible server with --provider openai-compat and --base-url.
03 Commands
| Command | What it does |
|---|---|
uno | Open a chat. Type /help inside it for commands and keys |
uno -p "<prompt>" | Run one task and print the answer. A prompt piped in works too |
uno --resume [id] -p "…" | Continue a session; the newest one if no id is given |
uno --fork <id> -p "…" | Copy a session and continue the copy |
uno sessions | List this folder's sessions |
uno undo [--all] [--force] | Put back files the model changed |
uno trust [--status|--remove] | Let this folder's own settings, hooks and MCP servers take effect |
uno settings | Show the settings in effect and where each came from |
uno mcp login|logout <name> | Sign in to an HTTP MCP server in the browser, or forget the sign-in |
uno mcp status | Show each MCP server and how it signs in |
uno spend | Show spending against the cap |
uno update | Install the newest release, when uno came from the installer |
uno --version, --help | The version, or every option |
Useful options: --model, --mode (see Permissions), --allow "bash(cargo test)", --max-cost 0.50 for one run, --max-turns, --no-search, --no-memory, --image <path>, --output json and --screen dot|chat. uno --help lists them all.
04 In the chat
| Command | What it does |
|---|---|
/help | Commands and keys |
/mode [name] | Show or set the mode |
/model [name] | Show or set the model for the next turn |
/undo [all] | Put back the last file change, or all of them |
/sessions, /resume, /fork | Earlier conversations |
/compact | Shorten the conversation now, keeping a summary |
/cost | Spending in this chat and in total |
/status, /context, /budget | The agent's state, the context window, the spending |
/trust, /mcp, /skills, /memory | Trust, MCP servers, skills, long-term memory |
/reload | Read settings, skills, MCP servers and instructions again |
/quit | Leave |
| Key | What it does |
|---|---|
| Enter | Send |
| \ then Enter | A new line |
| Esc or Ctrl-C | Stop the turn |
| Ctrl-D | Leave |
| ↑ ↓ | Earlier prompts |
| PgUp PgDn | Scroll back |
| Ctrl-V | Paste a picture from the clipboard |
@path, or drag a file in | Attach an image |
To start a prompt with a slash, write two: //etc/hosts.
05 The screen
The chat fills the window: the conversation on the left, and on the right three cards showing what Uno is doing, how full the context window is, and what has been spent. A permission question opens at the bottom of the conversation. Choose with ← → and Enter, or press y, a or n. When you leave, the conversation is printed into the terminal, so its scrollback keeps it.
If you prefer the terminal's own scrollback, selection and search while you work, use the scrolling chat. It has the same look, and /status, /context and /budget print the cards into it. Choose it with --screen chat, UNO_SCREEN=chat, or in settings:
{ "ui": { "screen": "chat", "accent": "yellow" } }
accent is red (the default) or yellow. Windows smaller than 100 × 32 get the scrolling chat. NO_COLOR turns colour off.
06 Permissions
When a tool call needs your say-so, the chat asks. y allows it once, a for the rest of the session, n refuses. a on a file change covers every file change in the project for the session; on a shell command, it covers commands that start the same way.
| Mode | Edits | Shell commands | Meant for |
|---|---|---|---|
default | ask | ask | everyday work; the chat starts here |
accept-edits | go ahead inside the project | ask | when you will review and undo if needed; -p starts here |
plan | refused, except the plan file | refused | reading and thinking only |
bypass | go ahead | go ahead | folders you trust completely; deny rules still hold |
Set the mode with --mode or /mode. --dangerously-skip-permissions is the same as --mode bypass. With -p there is no one to ask, so anything that needs a say-so is refused, and the run exits with code 2.
Rules are tool or tool(pattern), in allow, ask and deny lists. deny beats ask, which beats allow:
{
"permissions": {
"allow": ["bash(cargo test)", "bash(npm run lint)", "web_fetch(docs.rs)"],
"deny": ["bash(git push)"]
}
}
The tools are read, write, edit (apply_patch on OpenAI models), grep, glob, bash, web_fetch, and MCP tools as mcp__<server>__<tool>. Files under .git/, .uno/ and .claude/ are never changed, and .env and key files are never read.
07 The sandbox
Shell commands run in the operating system's sandbox: Seatbelt on macOS, bubblewrap on Linux. Inside it, a command can write to the project and temporary folders only. It cannot read .env files or credential folders such as ~/.ssh and ~/.aws, and it has no network.
- A command that needs more, such as installing packages, can ask to run outside the sandbox. That always asks you first.
- An allowed command (
--allow "bash(cargo test)", or a rule) runs unconfined on your machine, so keep rules narrow. --no-sandboxturns the sandbox off for a run; every command then asks.
08 Spending
Every model call is priced and recorded before it can push spending past the cap. The cap is $5.00 in total unless you set another with UNO_SPEND_CAP_USD, for example export UNO_SPEND_CAP_USD=50. uno spend and /cost show where you are, and --max-cost 0.50 limits a single run.
A model missing from the price table is charged at a deliberately high rate, so the total can overstate what you really spent. Your provider's own dashboard has the real figures.
09 Sessions and undo
Every conversation is saved per folder. uno sessions lists them, uno --resume continues the newest, and uno --fork <id> continues a copy. Long conversations are shortened before they outgrow the model's window, keeping a summary.
Every file change the model makes is recorded. uno undo (or /undo) puts back the newest change, and --all puts back the whole session's. If something else changed the file since, undo stops and says so; --force puts it back anyway.
10 Settings
Settings are JSON, read from:
~/.config/uno/settings.json: yours, for every project;.uno/settings.jsonand.claude/settings.jsonin the project, which count only afteruno trust, and stop counting when they change until you trust the folder again.
{
"model": "claude-sonnet-5",
"mode": "default",
"permissions": { "allow": [], "ask": [], "deny": [] },
"sandbox": { "enabled": true },
"web": { "search": true },
"memory": { "enabled": true },
"skills": { "claude_home": false },
"ui": { "screen": "dot", "accent": "red" },
"hooks": {},
"mcpServers": {}
}
uno settings prints what is in effect and which file each value came from. Data such as sessions, memory and the spend record live in ~/.local/share/uno.
11 Instructions, memory, skills
- Instructions.
AGENTS.mdin the project (orCLAUDE.mdwhere there is none) is read at the start of every session. - Long-term memory. Markdown notes Uno keeps between sessions, one set for all projects and one for each project, read at the start and updated as it learns.
/memoryshows them;--no-memoryor"memory": {"enabled": false}turns memory off. - Skills. Folders with a
SKILL.md(anameanddescriptionup top, then instructions) in.agents/skillsor.claude/skills, in the project or your home folder. The model sees each skill's name and description, and reads the whole file when a task matches./skillslists them.~/.claude/skillsis used only with"skills": {"claude_home": true}.
12 Web and images
- Search. On Anthropic, OpenAI and Gemini models, the model can use the provider's own web search, which the provider bills at about a cent a search. The pages an answer cites are listed after it. Turn it off with
--no-searchor"web": {"search": false}. - Reading pages.
web_fetchreads one public page as text. It refuses private and local addresses, and asks unless a rule covers the site:web_fetch(docs.rs),web_fetch(*.github.com). - Images. Attach PNG, JPEG, GIF or WebP files: drag them in, type
@path, press Ctrl-V for the clipboard, or pass--imagewith-p. Large images are shrunk, and location data is removed before sending. The model can also read images in the project.
13 MCP servers
Declare servers under mcpServers, in the same shape as Claude Code, in your settings, the project's .mcp.json or .uno/settings.json:
{
"mcpServers": {
"files": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "."] },
"github": { "type": "http", "url": "https://api.githubcopilot.com/mcp/" }
}
}
- However many servers you add, the model sees two small tools, one to find an MCP tool and one to call it. So adding servers costs almost nothing, and nothing starts until the model first uses one.
- Each call asks. In the chat you can allow it once, the tool, the whole server, or every MCP tool for the session. As rules:
mcp__github__create_issue,mcp__github, ormcp. - A project's servers load only after
uno trust. Your API keys are never passed to a server. - Servers that sign in through the browser need
uno mcp login <name>once (--no-browserprints the address instead). A browser never opens by itself during a run. Tokens are kept in~/.config/uno/mcp-tokens.json, readable by you only, and never shown to the model.
14 Hooks
Your own commands, run at five points, on Claude Code's contract: PreToolUse, PostToolUse, UserPromptSubmit, Stop and SessionStart.
{
"hooks": {
"PreToolUse": [
{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "~/bin/no-rm.sh", "timeout": 10 }] }
]
}
}
- The hook gets the event as JSON on standard input, and runs in the project folder without your API keys.
- Exit code 2, or
"decision": "block", blocks: the tool call is not run, the prompt is not sent, or the model keeps going instead of stopping. - A hook can only make things stricter. A
PreToolUsehook that times out or cannot start blocks the call. - Project hooks count only after
uno trust.
15 Update and uninstall
| Installed with | Update | Uninstall |
|---|---|---|
| the installer | uno update | rm ~/.local/bin/uno ~/.local/bin/.uno-installed |
| Homebrew | brew upgrade uno | brew uninstall uno |
| npm | npm i -g @motiontic/uno | npm rm -g @motiontic/uno |
uno update checks the new release's signature with the key built into uno, and makes sure it starts before replacing the old one. Your settings and data are in ~/.config/uno and ~/.local/share/uno; delete those too to remove everything.
16 Check a download
Every release file on GitHub has a minisign signature beside it, and the public key is in minisign.pub:
minisign -V -p minisign.pub -m uno-aarch64-apple-darwin
The signed comment names the version and the machine type, for example uno 0.2.0 aarch64-apple-darwin.
uno is free to use; see the licence.