Own the control plane
The runtime, the model, the tool loop, and the data are all processes and files you control. No remote orchestrator decides what runs.
Atomic Agent runs on your computer. The language model, your conversations, your memory, your tasks — all of it lives in a folder on your machine, not on someone else’s server.
That one design choice changes what the agent can promise you. Nobody bills you per token. No conversation leaves your machine unless you point it at the internet. And because every part is on disk, you can open it up, read it, and change it.
The one thing that does leave by default is a small stream of anonymous usage stats — model name, timing, token counts, never your content. One line in config.json turns it off. See Telemetry below.
By default, the agent talks to a local llama-server (llama.cpp) running on 127.0.0.1. It does inference on your own GPU or CPU using a quantized model you downloaded once. Your prompts, the model’s replies, and everything the agent remembers stay on your disk.
Own the control plane
The runtime, the model, the tool loop, and the data are all processes and files you control. No remote orchestrator decides what runs.
Private by default
Inference is local. Memory is a local SQLite file. Your prompts, replies and files leave only when a tool you can see makes them leave. Anonymous usage stats are the one exception, and they are one flag away from off.
No per-token fees
You pay for electricity, not for tokens. Run the agent for hours; the marginal cost is your own hardware.
Hackable all the way down
Config is a JSON file. Skills are folders. Traces are NDJSON. Open any of it in your editor.
Everything the agent persists goes under one state directory — by default ~/.atomic-agent, overridable with ATOMIC_AGENT_STATE_DIR.
| What | Where | Notes |
|---|---|---|
| User config | <stateDir>/config.json | Plain JSON, versioned, edit by hand or via atomic-agent config set |
| Secrets | <stateDir>/.env | API keys, TELEGRAM_BOT_TOKEN; written with mode 0600 |
| Memory | memory.sqlite | Profile facts, notes, lessons, procedures (FTS5 + optional embeddings) |
| Sessions | sessions.sqlite | Full conversation transcripts |
| Tasks | tasks.sqlite | Scheduled and recurring task queue |
| Traces | <traceDir>/<sessionId>.ndjson | Append-only, on by default for run, tui and serve |
| Models | <dataDir>/models/, <dataDir>/backend/ | GGUF weights + the llama-server binary |
# Point the whole runtime at a different state directoryATOMIC_AGENT_STATE_DIR=/Volumes/encrypted/atomic atomic-agent tuiBecause the default backend is a local llama-server, there is no metered API in the loop. The runtime is built to make that local model affordable to run for long, multi-step sessions:
llama-server caches once per session. Each step reuses it via cache_prompt and slot affinity instead of reprocessing it.agent.tokenBudget, default 3000). Memory grows in SQLite, not in the prompt — the model only sees compact pointers.grep or test run doesn’t blow the budget.If you want a cloud model for some work, you can configure one under llm.providers[]. That is an explicit opt-in, and it is the point where tokens start costing money and data starts leaving your machine — see Egress below.
# Run fully local, managed model lifecycleatomic-agent models pull qwen-3.5-4batomic-agent models use qwen-3.5-4batomic-agent tuiLocal-first does not mean airtight. The agent is useful precisely because it can act in the world — browse, fetch, run shell commands. The honest framing is: egress is explicit and enumerable. Here is every door out.
flowchart LR
Core["atomic-agent runtime<br/>(local model, memory,<br/>sessions, tasks)"]
Core --> Browser["browser.* tools<br/>(navigate, fetch)"]
Core --> Http["os.http / os.web.fetch<br/>os.web.search"]
Core --> Shell["os.shell<br/>(inherits your env)"]
Core --> Skills["skill.run_script"]
Core --> Cloud["cloud LLM providers<br/>(llm.providers, opt-in)"]
Core --> Mcp["MCP servers<br/>(mcp.servers, opt-in)"]
Core --> Tg["Telegram channel<br/>(opt-in, single-user)"]
Core --> Tel["telemetry<br/>(on by default)"]
Core --> Upd["update check<br/>(on by default)"]
Core --> Hub["ClawHub skill registry<br/>(on by default)"]
Browser --> Net((Internet))
Http --> Net
Skills --> Net
Cloud --> Net
Mcp --> Net
Tg --> Net
Tel --> Net
Upd --> Net
Hub --> Net
style Core fill:#e8f5e9
style Net fill:#fff3e0
Each door is gated:
browser.navigate, os.web.fetch, os.web.search, os.http) reach the internet on purpose. Non-safe HTTP requests and non-http(s) browser navigation are dangerous operations and pass through the approval gate.os.shell, skill.run_script) run with the agent process’s environment and can do anything you can do at a terminal. Both are approval-gated. Shell commands additionally pass a command guard (hardline blocks for rm/mkfs, dangerous-pattern checks).llm.providers[]. When active, prompts go to that provider.mcp.servers[]. Each server has a trust level; the default is approval_gated (fail-closed), so even hallucinated tool names from a stale server land in the safe lane.telegram.enabled is true and a token is present. It is deliberately single-user (owner-pairing, fail-closed when ownerUserId is null).The last three doors are the ones that are open on a fresh install. None of them carries your content:
analytics.enabled: false — see Telemetry.ATOMIC_AGENT_UPDATE_CHECK_ON_STARTUP=false.skill browse and skill search. It is contacted only when you run those commands or open the Skills panel. Off with skills.clawhub.enabled: false.Atomic Agent sends anonymous usage stats so we can see which models people run, where the agent is slow, and what crashes. It is on by default and takes one line to turn off.
What is sent: an anonymous install id, platform, app version, and per message the model and provider name, response latency, step count, token counts and estimated cost.
What is never sent: your prompts, the model’s replies, file contents, file paths, tool arguments, memory, or your IP address. The scrubber that guards this is an allowlist — fields must be explicitly permitted to travel, so nothing leaks by omission.
// config.json — disables usage stats and crash reporting together{ "analytics": { "enabled": false }}That single flag governs both the usage stats and the crash reporter. There is no separate switch to remember.
You can also flip it without leaving the TUI. /analytics on, /analytics off, and /analytics status toggle the same setting and report its current state; /privacy analytics on|off is the same command under the Privacy panel’s namespace. Either form opens the Privacy tab, where a toggles it directly.
“Control plane” means the part that decides what runs and when. With a hosted agent, that lives on a vendor’s servers. With Atomic Agent, it is createAgentRuntime running in your process, wiring together the model provider, tool registry, memory stores, and the agent loop. You start it, you stop it, you see everything it does.
Concretely, you own:
atomic-agent run), TUI (atomic-agent tui), HTTP server (atomic-agent serve), or the Tauri sidecar — all construct the same local runtime.atomic-agent serve exposes an OpenAI-compatible API on a host and port you choose, bound to 127.0.0.1 by default. Pass --api-key (or set ATOMIC_AGENT_API_KEY) to require a bearer token. Without one the server starts unauthenticated and says so in its startup line: auth=none. Always set a key before changing --host off localhost.# Your machine becomes the API. Your prompts and files never leave it.atomic-agent serve --host 127.0.0.1 --port 8787 --api-key "$MY_KEY"Local-first only matters if you can actually reach in and change things. Every layer is a file or a documented surface:
config.json — read it, edit it, or drive it with atomic-agent config get / atomic-agent config set '<json>'.SKILL.md + optional scripts/). Install with atomic-agent skill install <path>, list with atomic-agent skill list, toggle with atomic-agent skill enable|disable.tracing.trace.enabled), then inspect with atomic-agent trace list / trace show <sessionId> or detect prompt drift with atomic-agent trace replay <sessionId>.atomic-agent models list|pull|use|start|stop|status.Being honest about the tradeoffs:
atomic-agent self-update or your package manager).For most local automation — browsing, files, shell, document extraction, memory that persists across sessions — keeping everything on your machine is the whole point.
Configuration & Secrets
Full config.json schema, .env handling, and every ATOMIC_AGENT_* env var.
Approval gates
How dangerous tools pause for your decision, and how --no-approval changes the contract.
Memory system
Profile facts, notes, lessons, and procedures — how memory grows on disk without bloating the prompt.
Local models
Managing llama-server, GPU/VRAM budgeting, and the embedding daemon.