Command line
The Oatmilk CLI
Oatmilk in a terminal: a full-screen app, Ask AI, scripts, CI and a bridge for AI agents.
The Oatmilk command line, oatmilk, opens your workspace in a terminal. It has the same pages, records and actions as the web app, with Ask AI in a message box at the bottom. Scripts, CI jobs and other agents can use it without the full-screen app, and agents that can only start a command can reach Oatmilk's MCP tools through it.
It works with the hosted Oatmilk and with your own installation, and it signs in as you: your role in each company decides what it can see and do.
Try it in a minute
You need Node.js 22 or newer.
npx @getoatmilk/cliThe first time
The first time it starts, the app asks one question: how you want to use Oatmilk.
- Sign in to Oatmilk. Your account at getoatmilk.com, with nothing to install. If Ollama or LM Studio is running with a model that calls tools, it offers to run Ask AI on it, so your questions stay on your computer while your books stay in Oatmilk.
- Keep everything on this computer. Your account, books, files and AI models all on your computer, with no sign-up. It needs Docker, Bun and Ollama or LM Studio. Setup finds them, picks models that fit, downloads missing ones into Ollama, asks your name and your company's name, starts Oatmilk and signs the terminal in.
- More options. Choose for each part (sign-in, books, files, Ask AI and the agents, classifiers, reading documents, email and web research, each on your computer, in the cloud or off), use your own cloud services with AI on your computer, or connect to an Oatmilk you or your team already run.
Each step shows where you are (2/5), and the setup says how local it is in words, like 85% local.
oatmilk setup # choose again
oatmilk setup --local --yes # everything on this computer, without questions
oatmilk setup --local --cloud-for agents --yes
oatmilk status # where each part runs, the server, the models, Ask AI
oatmilk local start # also: stop, restart, logs, open, password, backup, wipe
oatmilk models # the models Oatmilk uses; models test, models pull <name>
oatmilk ai use ollama # Ask AI in the terminal on a model on this computer--local and --cloud pick where any command goes, --offline refuses an Oatmilk on the internet, --no-start leaves a stopped local Oatmilk stopped, and --no-ai opens the app without Ask AI.
Sign in
On an Oatmilk that setup made on your computer, the terminal signs itself in. Otherwise the app asks how to sign in: choose the browser, approve, and you land on Home. From a command line, the same steps are:
npm install -g @getoatmilk/cli # or keep using npx
oatmilk login # opens your browser; approve, then go back to the terminal
oatmilk # the full-screen appOn an SSH session or a machine without a browser, run oatmilk login --device and paste back the code Oatmilk shows you on any other device.
Browser sign-in is the same OAuth flow AI assistants use for MCP, and your role in each company still decides what you can do. An API key belongs to one company and keeps exactly the permissions it was given. Sign-ins are saved for your user only, and oatmilk logout revokes them. On your own Oatmilk, oatmilk login --password signs in with an account's email and password.
Your data
An administrator can take everything out, or close the company for good:
oatmilk export # every record and file, into a folder
oatmilk orgs close # offers an export, then asks for the company's name
oatmilk wipe # remove every sign-in and setting from this computer
oatmilk local backup # the Oatmilk on this computer: its database and files, to restore laterThe workspace has the same in Settings › Your data.
Moving between your computer and the cloud
Books don't move by themselves when you change where Oatmilk runs, and the app says so before you switch.
- To another computer, or your own cloud database and storage:
oatmilk local backup, then restore it with the sameself-host/.env(Operate). Nothing is lost. - Between Oatmilk Cloud and your computer:
oatmilk export --cloudoroatmilk export --localkeeps a full copy of every record and file. Bringing that copy into the other Oatmilk isn't possible yet, so keep using the one that has your books, or start fresh in the new one.
Passwords, provider keys and bank or tax numbers are left out of an export, so connections are made again in a new Oatmilk.
What you can do with it
| Use | Start with | Guide |
|---|---|---|
| Browse and act on the books in a full-screen app | oatmilk | Use the full-screen app |
| Add receipts and invoices from files | oatmilk add receipt.pdf | Add a receipt |
| Log hours and send your timesheet, as a contractor | oatmilk hours add 2h "Design review" | Log hours as a contractor |
| See where your data comes from, and connect more | oatmilk connect | Connect your data |
| Ask AI on Ollama or LM Studio, with your books in Oatmilk | oatmilk ai use ollama | Ask AI on a model on your computer |
| Ask AI one question from a script | oatmilk -p "What needs me today?" | Scripts and CI |
| Run any API action | oatmilk api entries.list '{"limit":5}' | Scripts and CI |
| Give an agent Oatmilk's tools | oatmilk mcp | Connect agents through the CLI |
Guides
- Install the CLI: npm, other package managers, standalone binaries or from source.
- Sign in and choose a company: browser, another device or an API key, against the hosted Oatmilk or your own.
- Use the full-screen app: the sidebar, lists, records, the ⌃K palette and Ask AI.
- Log hours as a contractor: log time, send your timesheet and say when you had no hours.
- Scripts and CI:
exec,api,actions,search, JSON output and exit codes. - Connect agents through the CLI: a local MCP server for Claude Code, Codex, Cursor and agents on local models.
- Command reference: every command, option, environment variable and exit code.
In scripts
Set OATMILK_API_KEY instead of signing in, and read results as JSON.
oatmilk -p "Which receipts am I missing this month?" --output-format json
oatmilk exec "Categorize the Uber rides as Travel" --yes
oatmilk api entries.list '{"limit":5}'When Ask AI needs an approval or an answer it couldn't get, exec exits with code 7, and the JSON result lists what it is waiting on. Run it again with --yes to approve. The command reference lists every exit code.