Kato and local models: what works today
Kato's memory files live on your Mac: the journal is on-device and encrypted at rest, and the memory itself is plain files you own. Their content is what travels. By default the distilling (turning raw observation into commitments and briefs) and the drafting that reads back your notes both run on a hosted Claude model, because that's where the quality is. What goes is secret-scrubbed, the app logs its calls in the egress ledger, and what Kato files under a sealed client is excluded from it.
Today the menu-bar app can't use a local model. It stays paused without a license, and a license picks the hosted brain first. The kato command line can run on Ollama, which is what this page sets up. In the app, a call you leave unfiled stays off the hosted brain. So does one filed under a sealed client, and sealing erases that client's transcripts (how).
Setup
# 1. install Ollama and pull a model
brew install ollama
brew services start ollama
ollama pull qwen3.5:9b← scrolls sideways →
Then get the command line, if you haven't: right-click Kato in the menu bar, open Settings and choose Install the kato command-line tool. It links kato into ~/.local/bin, so add that to your PATH if your terminal can't find it. The same click registers Kato as an MCP server in Claude Code, Cursor, Codex and OpenCode, whichever are on your Mac, and a folder bound to no client gets nothing from it. Tell it to use the model with a prefix on the command, where ~/kato is the folder that holds your memory:
env -u ANTHROPIC_API_KEY KATO_OLLAMA=1 KATO_OLLAMA_MODEL=qwen3.5:9b kato note ~/kato "I told Acme I would send the revised quote by Friday" --space acme
kato brief ~/kato← scrolls sideways →
kato note reads one sentence through the model and files the promise it finds. kato brief then prints what's filed and uses no model. If the model doesn't answer, kato note says so and writes nothing.
The command line reads only what you hand it: it captures no call and no screen. That is the menu-bar app's work, and the app uses the hosted brain.
Read what it files. Our run of this command on qwen3.5:9b on October 30, 2026 filed the promise in about 20 seconds, wrote it in Spanish and set its due date in 2024.
The knobs, exactly as the code reads them:
| env var | meaning | default |
|---|---|---|
KATO_OLLAMA=1 | opt in to the Ollama provider (or set the model var; either enables it) | off |
KATO_OLLAMA_MODEL | which pulled model to use | llama3.2:3b |
KATO_OLLAMA_HOST | the Ollama server | http://localhost:11434 |
← scrolls sideways →
Ollama is strictly opt-in: without one of the first two vars set, Kato never constructs the provider at all.
One thing to know about precedence. The real order is kato-hosted → anthropic → ollama → apple-fm (with your own key first if you prefer BYOK), and kato-hosted exists whenever your workspace holds a verified Kato license. The menu-bar app needs that license to run at all, and it has no Ollama control. A local-first preference is a product decision we have not made. The kato command line has no hosted path (the app wires that seam at launch and the command line never routes it), but it does read ANTHROPIC_API_KEY, and that key beats Ollama. That's why the command above unsets it: with the key exported and no env -u, your text goes to Anthropic.
Thinking models (qwen3 and friends) reason out loud by default, which is slow and buys nothing for schema-following extraction. Kato sends think: false automatically, measured at 25s → 1.5s per call. Nothing to configure.
What to expect, honestly
We measure this instead of guessing. The 2026-08-04 eval (golden corpus, same referee as the hosted lanes):
Concretely: expect more missed commitments, more misfiled items, and occasional schema slips that hosted Claude doesn't make. Either way your memory files stay on your Mac. What changes is where their content is read.
What still leaves the Mac
With that key unset, the command line on Ollama on localhost sends your text nowhere. The menu-bar app keeps its own hosted brain while it runs, and it also makes these calls to installkato.com:
- Update check: fetches a signed
updates/manifest.json. The request carries no identifiers: the URL plus your Mac's standard request headers, which include the app version, and the manifest is Ed25519-verified against a key pinned in the app. The site has a counter for distinct addresses per day, off today (how). - License refresh: periodically re-verifies your subscription and picks up a fresh token. Sends only the current license token, nothing from memory.
There is a third, in the app with call capture on: Kato downloads the transcription model once from huggingface.co. After that it is on your disk and inference is local.
CI runs an egress guard over the brain library (scripts/egress-guard.sh against scripts/egress-allowlist.txt), and only four files in that library may touch the network: the hosted adapter, the Anthropic adapter, the Ollama adapter and the eval harness. Update check and license refresh are pure seams inside the brain; the actual network call is injected from the app shell and lands in the same egress ledger as LLM calls.
One caveat worth naming: KATO_OLLAMA_HOST can point at a remote machine, so Kato treats the Ollama path as egress and guards it like any other. On the localhost default, "local" means local.