Agents that ask before they act.
Configure in a UI, preview the plan, approve. Multi-step automation
across Telegram / Slack / Discord / WhatsApp / files / shell — gated
by capability, sandboxed in containers or gVisor, audited end-to-end.
No CLI required.
Compared to • Install • Quickstart • Features • Stack • Roadmap • Contributing
90s demo. Type a goal · review the plan · approve · run. Recorded against a local Ollama.
Today's agents are split between two failure modes. Autonomous ones (Hermes, OpenClaw) act first and explain later — sometimes never. CLI-only ones (Claude Code, Pi) demand a terminal and yaml. Neither shows you what the agent is about to do.
Nomi is reviewable agents: a desktop platform that always surfaces the plan before any tool fires, gates every call through a capability engine, sandboxes execution in containers or gVisor, schedules runs in plain English, and learns with your approval. Set up an agent in a form, install a recipe with one click, or watch Nomi propose a new skill from your own runs. For team-scale structured knowledge, Mnemos drops in as an optional plugin.
- Local-first by default — self-hosted by choice. On a laptop the
data, conversations, and secrets stay on your machine (SQLite, OS
keyring, no telemetry, no account). On a homelab box or a cloud VM
the same
nomiddaemon runs headless behind your reverse proxy — seedocs/headless.md. - Plan review before execution. Every multi-step task is laid out in full before any tool runs. You see the plan; you approve the plan. Inspectable, editable, replayable.
- Capability engine, not a coding-safety knob.
filesystem.write,command.exec,network.outgoing, custom capabilities from plugins — every tool is bound by an explicit permission rule. Allow, confirm, or deny. Per-assistant. Same primitive whether you're writing code, triaging email, or driving a browser. - Persistent memory you can read. Workspace-scoped SQLite next to your runs. Queryable, exportable, inspectable — a real database, not a vector blob. The agent accumulates context across runs so the next task starts with the last one's lineage. For team-scale structured knowledge (decisions / claims / evidence / contradictions), the Mnemos plugin is one capability grant away.
- Bring any LLM. Ollama for free + private. Anthropic / OpenAI when you want frontier models. LM Studio, vLLM, Together — anything that speaks the OpenAI or Anthropic wire format. Per-assistant overrides ship out of the box.
- Daemon-not-IDE-plugin.
nomidis a long-running runtime, not a sidecar. Desktop UI, CLI, headless server — all clients of the same daemon. Real plugins (Telegram today, WASM marketplace next), real isolation, no bypass paths.
Nomi is a runtime + interaction model, not another coding-agent. The coding wedge today is Claude Code with local Ollama — but the same daemon, capability engine, and persistent memory underneath every other workflow you'll run next.
| Alternative | What's different about Nomi |
|---|---|
| Claude Code / Cursor agents / Cline | Same goal-driven coding flow (read repo, plan changes, write files, run commands), but every step is laid out as an approveable plan first, every tool call is gated by an explicit capability, and every event is persisted to a hash-chained audit log. Point it at Ollama and your repo never leaves your laptop. |
| Goose / OpenInterpreter / Aider | Same local-first stance, but with a real state machine (Run → Plan → Step), a real permission engine, real multi-step plans the user can edit, and a desktop UI built around the approval moment instead of around the chat box. |
| OpenClaw / Hermes Agent | Same personal-AI-with-memory framing, broader connector list shipping today. Both act the moment the model decides; Nomi inserts a plan_review state before any tool runs and gates every tool through an explicit capability rule. Nomi's memory is SQLite you can read, edit, and export — Hermes's "self-improving" memory is opaque by design. Nomi trades connector breadth today for inspectability everywhere. |
| NanoClaw / container-isolation products | NanoClaw isolates agents with Docker / micro-VM / Apple Container — the wall is around the process. Nomi gates at the capability layer — the agent never reaches the tool it shouldn't because the rule blocked the call. The two compose: you could run nomid inside a NanoClaw container and stack both defenses. NanoClaw is Anthropic-SDK-biased; Nomi is provider-agnostic. |
| Pi (Inflection AI) | Category boundary. Pi is a thoughtful conversational companion — cloud-only, closed, no tool execution. Use Pi when you want an AI to talk to. Use Nomi when you want an AI that takes action you approved. |
| LangChain / AutoGPT / CrewAI | Those are kits — you assemble the agent. Nomi is the finished product: a working state machine, a permission engine, a memory subsystem, a Tauri shell, all wired up. |
| Bespoke agent stacks | Stop reinventing scaffolding. The runtime, the audit trail, the approval workflow, and the plugin model all ship today. Bring your assistants and your prompts. |
Full feature-by-feature breakdown:
docs/comparison.md.
Desktop app (Tauri shell + bundled nomid daemon):
| Channel | Command |
|---|---|
| Homebrew Cask (macOS) | brew install --cask felixgeelhaar/tap/nomi |
| DMG / MSI / AppImage / DEB | Releases page |
CLI (nomi — drives a local or remote daemon over REST):
| Channel | Command |
|---|---|
| Homebrew (macOS / Linux) | brew install felixgeelhaar/tap/nomi |
| Direct download (Windows) | Releases page — nomi-*-windows-amd64.zip |
go install |
go install go.klarlabs.de/nomi/cmd/nomi@latest |
Headless daemon (nomid):
| Channel | Command |
|---|---|
| Docker | docker run -p 8080:8080 -v nomi-data:/data ghcr.io/klarlabs-studio/nomi |
go install |
go install go.klarlabs.de/nomi/cmd/nomid@latest |
The desktop bundle ships the nomid runtime as a Tauri sidecar — one
installer, both binaries. Docker / go install give you just the
daemon — drop it on a homelab box, a VPS, a Kubernetes pod, anywhere
that runs Linux. Configure via a YAML seed manifest at first boot, or
drive the REST API directly. Full guide:
docs/headless.md.
For headless interaction without the desktop UI, the nomi CLI
talks to the daemon over the same REST surface:
nomi status # health + version + active default LLM
nomi run "summarize notes.md" # submit, drive, print output
nomi list runs # most recent runs as a table
nomi list approvals # pending approval cards
nomi tail # follow the SSE event stream live
nomi seed examples/seed.yaml # apply a YAML manifest
nomi export -o nomi.yaml # snapshot full config (commit to git)
nomi import nomi.yaml # reproduce that config on another box
# Drive a remote daemon over SSH-fetched token
NOMI_TOKEN=$(ssh server 'docker exec nomi cat /data/auth.token') \
nomi --url=https://nomi.example.com run "what changed today?"The CLI auto-resolves URL + token from $NOMI_DATA_DIR/api.endpoint
and $NOMI_DATA_DIR/auth.token when it runs on the same host as the
daemon.
# examples/seed.yaml — mounted at /data/seed.yaml or pointed at via NOMI_SEED.
# Idempotent: edit + restart picks up the diff.
provider:
name: Ollama
type: local
endpoint: http://host.docker.internal:11434
model_ids: [qwen2.5:14b]
assistants:
- template_id: research-assistant
workspace: /data/workspace
settings:
safety_profile: balanced
onboarding_complete: trueYou're a developer who works on code your security team doesn't want in someone else's cloud. You'd use Claude Code or Cursor agents if the model ran on your machine. Ollama on a 14B model is enough for the edits you actually make; you just want a real agent surface — plans, approvals, audit log — wrapped around it.
If that's not you, Nomi probably still runs your inbox, your research
folder, or a Telegram bot — see examples/ for other
recipes — but the wedge it's built around is the dev who won't paste
source into a remote LLM.
# 1. Local LLM (or skip and use Anthropic / OpenAI from the wizard)
# qwen2.5-coder is the recommended model for the Coding Agent
# flagship recipe; swap in qwen2.5 for general-purpose chat.
brew install ollama
ollama serve &
ollama pull qwen2.5-coder:7b
# 2. Install Nomi
brew install --cask felixgeelhaar/tap/nomi
# 3. Open Nomi → wizard sets provider + assistant + workspace in <60s
# 4. Type a goal in chat → review the plan → approve → watch it run$ nomi run "Add a JSON tag to the User struct in models.go"
✓ run.created id=r_8a2 goal="Add a JSON tag to the User struct in models.go"
✓ plan.proposed steps=3
1. filesystem.read path=models.go
2. filesystem.patch path=models.go ← needs your approval
3. command.exec cmd="go test ./..." ← needs your approval
[plan-review] Approve? [y/n/edit]: y
✓ approval.granted step=2 by=user
✓ step.completed tool=filesystem.patch diff=+1 -1
✓ approval.granted step=3 by=user
✓ step.completed tool=command.exec exit=0
✓ run.completed duration=11s
Three places to land next:
- Try the flagship recipe —
examples/coding-agent/walks the read → unified-diff preview → approve →go testloop above against a tiny sample repo.examples/code-reviewer/is the read-only sibling. - Talk to other people — GitHub Discussions for questions, issues for bugs.
- Watch where v0.2 lands — the v0.2 flagship is real LLM-backed multi-step plans + Anthropic streaming; subscribe via GitHub Releases → Watch → Custom → Releases.
Every task becomes a plan with explicit tool calls. Edit the plan, branch from any step, or reject it entirely.
More features (click to expand)
Confirm-mode capabilities pause the run and surface a plain-language card. "Remember this choice for 24 hours" if the same kind of action keeps coming up.
Workspace, profile, and preferences scopes. The agent saves what it learns; you keep control of what's there.
Each plugin declares its capabilities and runs through the same permission engine as the core tools. Connect what you need; nothing else loads.
Ollama, Anthropic, OpenAI, vLLM, LM Studio, Together, Groq — anything on the OpenAI or Anthropic wire format. Set a global default; override per assistant.
Three profiles for the default permission stance on new assistants. Balanced is recommended; Cautious confirms everything; Fast trades safety for iteration speed.
Pick local, docker (rootless, capped memory + CPU + PIDs,
--network=none by default), or gvisor (runsc — user-space kernel
boundary) per assistant from the UI. Boot-time probe; only registered
backends appear in the dropdown.
Versioned, SHA-256-signed YAML bundles: assistant config + permission
policy + executor backend. Built-in catalog ships coding-agent,
research-assistant, ops-runbook. One-click install; export-as-recipe
button on every assistant. No other agent tool ships shareable bundles.
Type "every weekday at 8am" or "first Monday of the month"; the configured LLM translates to cron, the parser validates before save, and the background ticker fires Runs on cadence through the same plan-review + approval surface as any manual run.
After successful runs, Nomi extracts short preference statements ("Run tests before committing") into a Preferences memory the planner reads on the next plan. Embedding-based clustering surfaces candidate skills from your past runs; LLM synthesis proposes a Recipe shape; you review and promote. Every learned preference and proposed skill is visible — and deletable — in the Memory tab.
Every state transition emits an event. Hash-chained, exportable, queryable by run id. The runtime is observable without any external integration.
Each assistant carries its own persona, capability ceiling, permission policy, folder context, model override, and bound plugin connections.
Nomi is built from composable cognitive-stack libraries you can use independently. Each is Apache-2.0, documented, releasable on its own:
statekit— finite state machines for Go (powers everyRun/Plan/Step).mnemos— knowledge graph for agent organizations (events, claims, evidence, relationships). Reachable from Nomi via an optional plugin (plugin in flight).scout— browser automation built for agents.roady— spec-driven planning + task tracking with hash-chained audit log.
Full architecture and the case for each library:
docs/architecture.md.
┌─────────────────────────────────────────────────────────────┐
│ Nomi.app (Tauri shell) │
│ React 19 + shadcn/ui · IPC bridge · macOS menu-bar tray │
└──────────────────────────┬──────────────────────────────────┘
│ REST + SSE (Authorization: Bearer …)
┌──────────────────────────▼──────────────────────────────────┐
│ nomid (Go runtime daemon) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Run / Plan / Step state machines → statekit │ │
│ ├────────────────────────────────────────────────────┤ │
│ │ Permission engine + approval workflow │ │
│ ├────────────────────────────────────────────────────┤ │
│ │ Tool registry · LLM resolver · Local memory │ │
│ ├────────────────────────────────────────────────────┤ │
│ │ Plugin registry · Browser → scout │ │
│ │ WASM host (wazero) │ │
│ ├────────────────────────────────────────────────────┤ │
│ │ Event bus → SSE stream + hash-chained audit │ │
│ ├────────────────────────────────────────────────────┤ │
│ │ SQLite (WAL) · embedded migrations · OS keyring │ │
│ └────────────────────────────────────────────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
│ OpenAI-compat / Anthropic / Ollama
▼
LLM provider(s)
ADRs under docs/adr/ cover the big decisions
(plugin architecture, permission engine, state machine).
# Backend (Go)
make build # builds bin/nomid
make test # go test -race ./...
make sidecar # builds bin/nomid-<host-target-triple> for Tauri bundling
make migrate-up # runs embedded migrations against ~/.config/Nomi/nomi.db
# Desktop app (Tauri + Vite)
make app-dev # dev server at :5173, daemon spawned automatically
make app-build # produces a signed DMG / MSI / AppImage / DEB
# End-to-end user-journey tests (real Ollama required)
test/journeys/run.sh # 22 journeys; pass j1 j7 j20 to scopeThe full developer surface — including the user-journey definitions
every release ships against — is in
docs/user-journeys.md.
v0.2.3 (current) — "Reviewable agents + hard sandboxing."
Shipped: plan-review-before-execute state machine, capability-gated
tools, hash-chained audit log, sandboxed execution backends (local +
Docker + gVisor), three-layer network egress isolation
(--network=none default → DNS allowlist via docker --add-host +
--dns=127.255.255.255 → optional eBPF cgroup_skb filter, IPv4 +
IPv6, both docker cgroup drivers), browser automation as a first-
party plugin via Scout
over MCP, signed Recipe registry with built-in catalog, scheduled
runs with natural-language cron, auto-extracted preference learning
loop, skill induction with embedding clustering + LLM synthesis,
four messaging channels (Telegram + Slack + Discord + WhatsApp),
Gmail / Calendar / GitHub / Obsidian / Mnemos plugins, markdown
chat rendering with Shiki per-hunk diff highlighting, OS push
notifications for pending approvals, macOS menu bar integration
(new chat / pause all / quit), SQLite FTS5 memory search,
Prometheus /metrics for plan / step / executor / replan
attribution per provider, make eval-live-providers matrix
against real LLM providers.
Backlog (post-v0.2.3, in priority order — not committed):
- Generic any-MCP-server plugin (Scout-style client glue generalised — config-driven, not code-driven, per server).
- Quick-approval inline in the menu bar (don't open main window for trivial confirms).
- Cross-machine recipe sync (opt-in, end-to-end-encrypted).
- Hosted Mnemos for visibility-scoped team memory.
- Approval delegation across devices.
- WASM plugin marketplace catalog growth (signing + verification already shipped).
Live spec, plan, and task state in .roady/ (142
features, 267 tasks closed at release). Ideas and bug reports on
the issues page.
Pull requests welcome. Read the docs/adr/ entries before
changing a load-bearing subsystem (permission engine, plugin
architecture, runtime state machine), then open an issue to discuss.
Smaller fixes — typos, doc edits, plugin polish — can land straight as
a PR.
Look for good first issue
labels on the issues board.
The project follows the Contributor Covenant Code of Conduct.
Apache-2.0. See LICENSE.







