项目介绍
Agent 智能体 · 2026-11-09 更新 · 本站尚未实测
Atomic Agent 是一个本地优先(local-first)的 AI 智能体(Agent),控制循环与全部状态都运行在用户自己的机器上,而不是托管服务中。README 明确写道:"A local-first AI agent that runs the control loop and all state on your machine",并说明它可驱动浏览器、读写文件、执行经审批的 shell 命令、检查文档、跨会话记忆上下文、安排后续任务,并通过 MCP 调用外部工具。
它通过自有的 TurboQuant llama.cpp 构建运行本地量化模型,也支持云端模型;还可以在 Fusion 模式下由一个大模型规划、多个 worker 执行。项目定位为开发者预览(Developer preview),README 提示:"APIs, commands, config, and behavior are still moving",如需稳定集成点应固定发布版本。
核心能力
点击能力名称查看输入、输出和原文依据。
- 浏览器操作:通过
playwright-core驱动 Chrome / Edge / Brave / Chromium,支持导航、点击、输入、搜索、标签页管理,并读取精简的 ARIA 页面状态。 - 文件与命令:读、写、编辑、补丁、glob、grep、diff、哈希、归档解压等;shell 命令需经审批后执行。
- 文档解析:在本地从 PDF、DOC、DOCX、XLSX、PPTX、ODT、RTF 和纯文本中提取文本。
- 网络与检索:可配置搜索提供方(Exa、DuckDuckGo、Brave、SearXNG),抓取页面或发起 HTTP 请求,项目方称均带 SSRF 防护,本站未进行安全审计。
- 记忆:本地可检查的记忆库,包含档案事实、笔记、关联、经验与流程,存储于 SQLite + FTS5,可选用嵌入做混合召回。
- 任务调度:持久化的延后轮次、cron 计划、间隔、webhook 和智能体自建提醒。
- 技能:可查看并运行 Markdown 技能剧本,脚本需审批;可从 ClawHub 或 GitHub 技能仓库安装更多。
- MCP:连接外部 MCP 服务器,其工具、资源与提示并入同一注册表。
- Fusion 模式:一个编排模型规划、把独立批量工作交给 worker 池完成,再检查合并结果。
- 远程控制:可通过 Telegram 与 Discord 从手机控制会话,含审批按钮和双向文件传输。
- 集成:在集成页配置后可使用 GitHub、邮件(Atomic Mail)、Composio 等 SaaS 工具集。
实际应用场景
适用场景
适合希望在自有硬件上运行、对数据外流有控制要求的用户,例如:多步骤的文件整理与代码库阅读、基于浏览器的资料收集与表单操作、本地文档批量抽取、跨会话的长期项目跟踪,以及用本地小模型处理较长的工具调用型任务。也适合需要把智能体嵌入自有应用、通过 HTTP 或 Tauri sidecar 调用的开发者。
README 中给出的 GAIA 基准成绩为该仓库自述评测,读者不应将其视为本站实测结论。
安装与接入
README 提供以下安装方式(命令原文照录):
macOS / Linux:
curl -fsSL https://atomicagent.io/install | sh
Windows(PowerShell):
irm https://atomicagent.io/install.ps1 | iex
Debian / Ubuntu 等系统还提供软件包仓库,Fedora / RHEL 系提供 dnf 源,Arch 可用 AUR(yay -S atomic-agent-bin);桌面版为同仓库的 atomic-agent-desktop。安装完成后运行:
atomic-agent
或使用别名 atag。首次运行会提供从 Claude Code、Codex 等来源导入数据的选项。详细安装步骤、卸载与排查以 README 和官方文档为准。
使用条件与限制
- 是否需要部署
- 需自行准备运行环境,具体要求见正文
- 是否需要注册
- 账号和认证要求见正文;未明确说明的项目仍待核验
- 是否需要 API Key
- 待核验
- 费用与额度
- 费用边界见正文,项目许可不代表模型或托管服务免费
- 所需权限
- 待核验
- 许可证与服务条款
- 待核验
权限费用与限制
- 审批机制:危险操作走审批流程;模式包括
default、只读的plan、自动放行工作区内写入的auto,以及不询问但硬性 shell 防护仍生效的bypass permissions。 - 状态与密钥:会话、记忆、任务、追踪、技能、浏览器配置和
.env密钥存放在本地状态目录。README 提及隐私与外发说明文档,但具体外发项需以该文档为准。 - 费用:README 标注本地模型下无 API 成本、"free with local models";云端提供方与 Fusion 为可选,其计费方式需向各服务商核验,本项目未给出价格。
- 平台:当前构建为 macOS(Apple Silicon)、Linux x64 / arm64、Windows x64;Intel Mac 暂不支持,Windows on ARM 以 x64 模拟运行。
- 其他依赖:搜索提供方、GitHub token、邮件服务、Composio 等集成均为可选配置,是否需要外部账户与额度待核验。
- 本项目为开发者预览,接口与行为可能变化。
国内使用情况
网友核验 用户经验分享
与站长实测独立,不代表官方认证或本站已实测。
最近核验:暂无有效核验。参与人数按当前项目有效身份去重;不同核验项分别统计,不合并成用户总结果。仅统计审核通过且未过期的记录。
分项统计、有效期与样本量
| 核验项目 | 有效人数 | 成功 / 部分 / 失败 / 无法判断 | 成功率 | 最近核验 / 有效期 |
|---|---|---|---|---|
| 官方网站访问 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 7 天 |
| GitHub 仓库访问 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 7 天 |
| 安装与运行 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 官方服务国内连接 / MCP 连接 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 国内网络情况 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 7 天 |
| 国内模型兼容性 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 自定义 API | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 海外服务依赖 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 海外账号要求 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 中文界面 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 客户端兼容性 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
| 账号及费用信息 | 0 | 0 / 0 / 0 / 0 | 样本不足 | 暂无 / 30 天 |
成功率 = 成功 ÷(成功 + 部分成功 + 失败);无法判断不计入分母。至少 5 份可判断结果才显示成功率。账号、费用、海外依赖与语言等事实项,成功表示核查结论与资料吻合,具体观察另行统计;不表示免费或没有海外依赖。不同网络、客户端和版本的结果不能直接等同。
最近有效核验
暂无审核通过且未过期的网友核验。欢迎提交真实使用记录。
查看全部有效核验 →国内实测状态:国内可用性待核验。协议兼容和官方资料说明不等于国内网络可用。
- 官方网站访问
- 尚未实测 待核验
- GitHub 仓库访问
- 尚未实测 待核验
- 官方服务国内连接
- 尚未实测 待核验
- 国内网络情况
- 尚未实测 待核验
- 国内模型兼容性
- 尚未实测 待核验
- 自定义 API
- 尚未实测 待核验
- 海外服务依赖
- 尚未实测 待核验
- 海外账号要求
- 尚未实测 待核验
- 中文界面
- 尚未实测 待核验
- 国内最后核验时间
- 尚未实测
许可与国内使用
仓库代码采用 MIT 许可证(README 声明及 LICENSE 文件均为 MIT)。需注意:开源许可仅覆盖仓库中的代码,不自动覆盖第三方模型、云服务、Composio 等外部服务或其条款;这些内容的许可与计费需分别核验。
README 未说明在中国大陆网络环境下的安装可用性、镜像或合规情况,国内使用是否顺畅、安装源是否可达应自行核验。资料中出现的本地模型示例包含 qwen 系列量化版本,但未对国内云服务的兼容性作结论,相关适配情况待核验。
项目资料与来源
字段依据与待核验事项
access:来源确认 · curl -fsSL https://atomicagent.io/install | sh
project_type:来源确认 · A local-first AI agent that runs the control loop and all state on your machine
原始 README(折叠技术参考)
<div align="center">
<img src="assets/logo.svg" alt="Atomic Agent" width="120" />
# Atomic Agent
### A local-first AI agent that runs on your machine, with local or cloud models.
Drives your browser, edits files, runs approved commands, and remembers context across sessions. Open source, running on our TurboQuant `llama.cpp` so long sessions with small local models fit in less memory.
[](#benchmarks)
[](https://github.com/AtomicBot-ai/atomic-agent/actions/workflows/release.yml)
[](https://github.com/AtomicBot-ai/atomic-agent/releases)
[](package.json)
[](LICENSE)
[](https://nodejs.org/)
[](https://www.typescriptlang.org/)





**[Quick Install](#quick-install) · [Uninstall](#uninstall) · [Benchmarks](#benchmarks) · [Why Local-First](#why-local-first) · [Ways to Use It](#ways-to-use-it) · [Docs](#development)**

</div>
---
A local-first AI agent that runs the control loop and all state on your machine. It works across your machine: browse the web, read and edit files, run approved shell commands, inspect documents, remember context across sessions, schedule follow-ups, and call external tools over MCP. Run it on a local model, a cloud model, or both at once in **Fusion** mode, where one model plans and a pool of workers executes. Embed it in your own apps over HTTP or a Tauri sidecar. `llama.cpp` first, so small quantized models stay useful for long, multi-step work on consumer hardware.
## Quick Install
macOS / Linux:
```bash
curl -fsSL https://atomicagent.io/install | sh
```
Windows (PowerShell):
```powershell
irm https://atomicagent.io/install.ps1 | iex
```
The installer downloads the release archive, verifies the checksum, and installs the CLI plus support assets (`grammars/`, native prebuilds, and bundled `ripgrep`). Atomic Agent updates itself in place; after an update the TUI prompts you to restart. Outside the TUI, run `atomic-agent update` (or `atag update`) to check for a newer release and re-run the installer in place; `atomic-agent update --check` probes without installing, and `--version <tag>` pins a specific release. Only the installed binary can self-update; a dev checkout updates via git, and a Linux package (below) updates with the package manager.
### Linux packages
On Debian, Ubuntu, Fedora, RHEL-compatible systems and Arch, Atomic Agent also comes as a package, and the package manager then updates it with the rest of the system. A package carries the same release bundle as the installer, under `/usr/lib/atomic-agent`, with `atomic-agent` and `atag` in `/usr/bin`. The repository and the rpm packages are signed with the Atomic Chat packages key in [`packaging/atomic-chat.asc`](packaging/atomic-chat.asc), fingerprint `1047 F119 58C6 442D D472 E497 E4C3 D361 FB7F F123`.
Debian, Ubuntu (x86-64, arm64):
<!-- install:apt -->
```bash
curl -fsSL https://atomic-agent-packages.fsn1.your-objectstorage.com/atomic-chat.gpg | sudo tee /usr/share/keyrings/atomic-chat.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/atomic-chat.gpg] https://atomic-agent-packages.fsn1.your-objectstorage.com/deb stable main" \
| sudo tee /etc/apt/sources.list.d/atomic-agent.list
sudo apt update && sudo apt install atomic-agent
```
Fedora, RHEL, Rocky, Alma (x86-64, aarch64):
<!-- install:dnf -->
```bash
sudo curl -fsSL -o /etc/yum.repos.d/atomic-agent.repo https://atomic-agent-packages.fsn1.your-objectstorage.com/rpm/atomic-agent.repo
sudo dnf install atomic-agent
```
Arch Linux: `yay -S atomic-agent-bin`, or any other AUR helper.
Updates come with `sudo apt upgrade`, `sudo dnf upgrade` or `yay -Syu`; on a packaged install `atomic-agent update` refuses and names the command to use, and the TUI does not offer its in-app update. A copy left by `install.sh` in `~/.local/bin` runs ahead of the package on the usual PATH and keeps its own updates; `atomic-agent update` names both copies when that happens, and removing the copy hands the command to the package. `sudo apt remove atomic-agent`, `sudo dnf remove atomic-agent` or `sudo pacman -R atomic-agent-bin` removes the program and leaves your data; `atomic-agent uninstall` then lists only the data. The repository keeps the last ten releases; older ones are on the [releases page](https://github.com/AtomicBot-ai/atomic-agent/releases) as `.deb` and `.rpm` files. A package states the glibc its binary needs (2.34 today: Debian 12, Ubuntu 22.04, RHEL 9 and newer), and the package manager refuses where the system's is older.
#### Desktop app
The desktop app is in the same repository as `atomic-agent-desktop` (on Arch `atomic-agent-desktop-bin`). It has releases of its own (`desktop-vX.Y.Z`), carries its own copy of the agent under `/opt/Atomic Agent` and leaves a packaged or installed `atomic-agent` alone, so the two can be installed side by side. Once installed it is in the applications menu, and `atomic-agent-desktop` starts it from a terminal.
Debian, Ubuntu (x86-64, arm64):
```bash
curl -fsSL https://atomic-agent-packages.fsn1.your-objectstorage.com/atomic-chat.gpg | sudo tee /usr/share/keyrings/atomic-chat.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/atomic-chat.gpg] https://atomic-agent-packages.fsn1.your-objectstorage.com/deb stable main" \
| sudo tee /etc/apt/sources.list.d/atomic-agent.list
sudo apt update && sudo apt install atomic-agent-desktop
```
Fedora, RHEL, Rocky, Alma (x86-64, aarch64):
```bash
sudo curl -fsSL -o /etc/yum.repos.d/atomic-agent.repo https://atomic-agent-packages.fsn1.your-objectstorage.com/rpm/atomic-agent.repo
sudo dnf install atomic-agent-desktop
```
Arch Linux: `yay -S atomic-agent-desktop-bin`, or any other AUR helper.
Installed as a package, the app is updated with the rest of the system (`sudo apt upgrade`, `sudo dnf upgrade` or `yay -Syu`) and its Settings say so instead of offering an in-app update; the AppImage from the [releases page](https://github.com/AtomicBot-ai/atomic-agent/releases) updates itself. `sudo apt remove atomic-agent-desktop`, `sudo dnf remove atomic-agent-desktop` or `sudo pacman -R atomic-agent-desktop-bin` removes the app and leaves your data.
> [!NOTE]
> Developer preview. APIs, commands, config, and behavior are still moving, so pin a release if you need a stable integration point. Current builds: macOS (Apple Silicon), Linux x64 / arm64, and Windows x64. Intel Macs are not supported yet; Windows on ARM runs the x64 build under emulation.
### Run
```bash
atomic-agent
```
Both installers also drop a short alias next to the binary, so this is the same thing:
```bash
atag
```
> [!TIP]
> Need a second agent? Press **Ctrl+N** (or run `/window`) inside the TUI: it opens a new terminal window with a fresh atomic-agent in the same directory.
> [!TIP]
> Want to go through first-time setup again? Run `/onboarding` (or `/setup`) in the TUI, or start it with `atomic-agent tui --onboarding`. Your providers, keys, sessions and memory are kept.
> [!TIP]
> Coming from another agent? The first run offers to bring your data over: tick the sources it found and the import runs, without overwriting anything already here and without touching the source. What moves depends on the source:
>
> - **Claude Code:** skills, memory, MCP servers, sessions, and (opt-in) provider keys
> - **Codex:** skills, memory, sessions, and (opt-in) provider keys
> - **Oh-My-Pi:** skills, MCP servers, and sessions
> - **Pi:** skills and sessions
> - **Hermes:** sessions, cron jobs, and (opt-in) provider keys
> - **OpenClaw:** sessions and cron jobs
>
> Later, run `/import` in the TUI or `atomic-agent import <hermes|openclaw|claude-code|codex|pi|oh-my-pi>` from the shell.
### Uninstall
One command removes everything: the state directory (config, memory, sessions, tasks, traces, downloaded models), the binary and its `atag` alias, the asset directories beside them, and the PATH line the installer added to your shell rc file:
```bash
atomic-agent uninstall
```
It prints exactly what it will delete, with sizes, and then asks you to type the word `uninstall`. Nothing is uploaded and nothing is kept; this cannot be undone. Preview it with `atomic-agent uninstall --dry-run`, keep your data with `--keep-data`, keep the binary with `--keep-binary`, leave your shell rc file alone with `--keep-path`, or skip the prompt in a script with `--yes`. The same flow is the last entry in the TUI's own menu (**Esc → Danger zone**, or `/uninstall`). The desktop app (0.0.3 and later) shares the same `~/.atomic-agent` folder. When uninstall finds it, an interactive run asks a separate question before deleting that folder (answer no to remove only the terminal program), and a `--yes` run keeps the folder and says why; add `--include-desktop-data` to delete it in a script.
### Troubleshooting
If something isn't working:
1. Copy your error logs and system specs.
2. Open an issue on [GitHub](https://github.com/AtomicBot-ai/atomic-agent/issues).
3. Or ask for help in our [Discord](https://discord.gg/DCqtG8WZX8).
## Talk to Us
Building something with Atomic Agent, stuck on setup, or just want to share what you are working on? Grab a slot and talk to the team directly: **[cal.com/atomicagent/demo](https://cal.com/atomicagent/demo)**. No agenda required. Questions, feedback, feature requests, or a plain hello all count. We read every issue and every Discord message too, but sometimes a 15-minute call beats a week of comments.
## Benchmarks
On the public **GAIA validation Level 1** split (53 tasks), Atomic Agent and Hermes drove the **same** local `qwen-3.6-35b-a3b` (`llama-server`, UD-Q4_K_XL), with the same step budget and timeout. The only variable is the agent loop.

| Metric | Atomic Agent | Hermes |
|---|---|---|
| **Accuracy** | **37/53 = 69.8%** | 31/53 = 58.5% |
| Avg wall / task | **~217 s** | ~351 s |
| Head-to-head wins | **+15 atomic-only** | +9 Hermes-only |
<details>
<summary><b>Charts (accuracy & speed)</b></summary>
```mermaid
%%{init: {"themeVariables": {"xyChart": {"backgroundColor": "transparent", "titleColor": "#0b63f6", "plotColorPalette": "#0b63f6"}}}}%%
xychart-beta
title "GAIA L1 accuracy (higher is better, %)"
x-axis ["Atomic Agent", "Hermes"]
y-axis "Accuracy (%)" 0 --> 100
bar [69.8, 58.5]
```
```mermaid
%%{init: {"themeVariables": {"xyChart": {"backgroundColor": "transparent", "titleColor": "#0b63f6", "plotColorPalette": "#0b63f6"}}}}%%
xychart-beta
title "Avg wall time per task (lower is better, s)"
x-axis ["Atomic Agent", "Hermes"]
y-axis "Seconds / task" 0 --> 400
bar [217, 351]
```
</details>
### Model Scaling
The same loop holds up as the local model shrinks. Same GAIA L1 split, Atomic Agent alone:
| Chat model | Accuracy | Avg wall / task |
|---|---|---|
| `qwen-3.6-35b-a3b` (UD-Q4_K_XL) | **37/53 = 69.8%** | ~217 s |
| `qwen-3.5-9b` (Q4_K_M) | **28/53 = 52.8%** | ~152 s |
| `gemma-4-12b` (it-qat UD-Q4_K_XL) | **24/53 = 45.3%** | ~423 s |
Even a 9B model clears half of GAIA L1 through the same context-frugal loop. (Different Atomic Agent versions per row; see the write-up for provenance.)
Full reproducible write-up: [`GAIA-L1-EXPERIMENT.md`](eval-agents/docs/GAIA-L1-EXPERIMENT.md) · Raw artifacts (matrices, NDJSON traces, logs): [gaia-l1-eval-2026-06-11 release](https://github.com/AtomicBot-ai/atomic-agent/releases/tag/gaia-l1-eval-2026-06-11).
## Why Local-First
The control loop and all state run on your machine, not a hosted service:
- **State lives on your disk.** Sessions, memory, tasks, traces, skills, browser profile, config, and `.env` secrets live under `<stateDir>` as plain files and SQLite databases. See [Privacy and Egress](#privacy-and-egress) for what can leave the machine and how to switch it off.
- **No API costs with local models.** Run quantized models locally through `llama.cpp`. Bring your own `llama-server` or let the CLI manage one. Cloud providers and Fusion are opt-in.
- **Nothing is hidden.** Inspect the prompt, replay trace drift, edit skills, and swap parts without waiting for a vendor. Plain local models, SQLite files, and NDJSON traces.
- **Runs on your hardware.** Small quantized models run on everyday consumer GPUs and CPUs, no datacenter needed.
## Core Idea
### How the Agent Loop Works
An agent is a loop: the model picks an action, something runs it, the result feeds back in, and it repeats until the job is done. The catch is cost. Every turn re-sends the growing context through the model, so a naive loop gets slower and pricier each pass, and small local models choke on it fastest.
Atomic Agent keeps the loop cheap. One inference produces one JSON array of tool calls, and it runs them without re-encoding the whole world every turn:
```mermaid
flowchart LR
A[Prompt] --> B[Decide]
B --> C[Run]
C --> D[Compress]
D -->|not done| A
D -->|done| E[Reply]
```
1. **Prompt:** a compact prompt goes to the local model.
2. **Decide:** the model returns one JSON array of tool calls. On a local `llama-server` the output is grammar-constrained (GBNF) so the format is always valid; cloud providers use native tool calling.
3. **Run:** the core executes them; independent reads run in parallel, risky actions ask first.
4. **Compress:** results and state are summarized, not pasted back in full.
5. **Repeat:** loop again until reply, finish, or cancel. Long jobs keep going past 25-step checkpoints while they make progress, bounded by a per-task ceiling (1000 steps or 2 hours by default), and end with a summary rather than a cut-off.
The model chooses actions. Atomic Agent owns the loop, the state, the approvals, the traces, the stop conditions, and the failure boundaries.
### Built to Make Local Models Work
We run local models on our own TurboQuant `llama.cpp` ([`AtomicBot-ai/atomic-llama-cpp-turboquant-nightly`](https://github.com/AtomicBot-ai/atomic-llama-cpp-turboquant-nightly)):
- **TurboQuant KV-cache:** WHT-rotated low-bit quantization compresses the KV-cache up to ~6.4× versus F16, with a fused Metal decode kernel, so long-context sessions fit in far less memory.
- **TurboQuant weights:** Lloyd-Max weight quantization with WHT rotation and fused Metal/Vulkan kernels keeps quality usable while small models fit on consumer hardware.
- **Curated quantized models:** hand-picked GGUF quants that keep quality usable while fitting real VRAM budgets.
- **Managed mode:** the CLI downloads, keeps up to date, and runs the backend and models for you, no manual `llama.cpp` setup. Set `localModels.managed.autoUpdate: false` to pin the backend.
### Tuned for Small Local Models
Atomic Agent's prompt is engineered so a small model never wastes tokens or breaks format:
- **Stable prefix:** persona, rules, tools, skills, capabilities, and instructions stay byte-stable inside a session so, on a local `llama-server`, `cache_prompt` and slot pinning can reuse KV-cache instead of re-encoding the prompt every turn.
- **Bounded tail:** conversation, memory, world state, recalled notes, lessons, procedures, and loaded skill bodies are clipped into a predictable prompt budget.
- **Externalized state:** sessions, memory, tasks, skills, traces, browser snapshots, and model config live outside the prompt.
- **GBNF tool calls:** on local backends, completions are constrained into a JSON array of tool calls, including the solo case `[{...}]`.
- **Parallel read batches:** independent read-only calls can run concurrently after a single inference; dangerous actions remain approval-gated.
- **Compact browser view:** ordinary web operation uses accessibility / ARIA snapshots clipped to a character budget (24k by default) instead of screenshot-heavy page dumps.
This is why small local models can stay useful across long, tool-heavy work.
## What It Can Do
Atomic Agent drives a full desktop tool surface. Dangerous actions are routed through approvals; independent read-only calls run in parallel.
| Area | Capabilities |
|---|---|
| **Browser** | Navigate, click, type, search, manage tabs, scroll, and read compact ARIA state via `playwright-core` (Chrome / Edge / Brave / Chromium). |
| **Web & HTTP** | Web search with configurable providers (Exa, DuckDuckGo, Brave, SearXNG); fetch and extract pages or make arbitrary HTTP requests, both SSRF-guarded, separate from the browser. |
| **Filesystem & shell** | Read, write, edit, patch, glob, grep, diff, watch, hash, list, archive extract, run approved shell commands, and inspect or kill processes. |
| **Desktop** | Clipboard read/write, desktop notifications, and window list/focus. |
| **Documents** | Extract text locally from PDF, DOC, DOCX, XLSX, PPTX, ODT, RTF, and plain text. |
| **Git** | Read-only status, log, diff, show, blame, and branch inspection, plus local write tools (init, add, commit, checkout, merge) behind the same approval ladder as file writes. Remote sync (clone, fetch, pull, push, remote) is off by default; turn on `git.remoteSync` in the Integrations tab and every sync is approval-gated. |
| **GitHub** | Act on GitHub as you once a token is saved in the Integrations tab: list pull requests and issues, create them, and comment on issues. Writes are approval-gated. `/report` files a bug report with your logs at the privacy level you pick and sends nothing until you confirm. |
| **E-mail** | Give the agent its own `@atomicmail.ai` inbox from the Integrations tab (Atomic Mail) to list its inbox (sender, subject, preview) and send plain-text messages; sends are approval-gated and cannot be granted for the session. Background model downloads can mail you when they finish. |
| **Verify** | `verify.syntax` checks files by type and never reports an unchecked file as passing; `verify.run` runs a command, a service or a page against a throwaway copy of the working directory (off macOS, build and dependency folders are linked rather than copied, and a tree over 2 GB runs in place), with checks like `exit 0` or `status 200`. |
| **Memory** | Profile facts, notes with hybrid recall, links, lessons, procedures, voting, and reflection. |
| **Tasks** | Durable deferred turns, cron schedules, intervals, webhooks, and agent-created reminders. |
| **Skills** | View and run Markdown skill playbooks (scripts are approval-gated), install more from ClawHub or GitHub skill repos. Ships with 18 starter skills (Docker, GitHub, Notion, Obsidian, PDF, and more; 15 outside macOS, where the Apple ones are skipped), auto-installed on first run. |
| **Vision** | Optional `vision.describe` for multimodal models with `mmproj`, kept outside the text transcript. |
| **MCP** | Connect external MCP servers; their tools, resources, and prompts join the same registry. |
| **Fusion** | One model plans and hands the independent bulk of a job (wide reads, drafts, tests) to a pool of workers via `fusion.delegate`, then checks and merges their results. Usually a cloud orchestrator with local workers; either side can be any configured provider. |
| **Providers** | Local `llama-server` by default; OpenAI-compatible, [OpenRouter](https://openrouter.ai), AI/ML API, and Gemini providers when configured, plus one-click presets for Anthropic, Groq, DeepSeek, Mistral, xAI, Together, Ollama, LM Studio, Atomic Chat and more, with live model catalogs and mid-session switching. Your existing **Claude Code and OpenAI Codex subscriptions** work too, driven through their own signed-in CLIs with no API key. Reasoning-only completions from reasoning models are recovered instead of failing the turn. |
| **Telegram & Discord** | Remote control from your phone: a session per chat, approval buttons, files both ways, and opt-in scheduled-task reports on Telegram. Run several bots at once from the Swarm tab (`/swarm`), each with its own token and owner. |
| **[Composio](https://composio.dev)** | Connect 1500+ SaaS toolkits (Gmail, Slack, Notion, Linear, and more) with OAuth handled for you. Set up from the Integrations tab; tools arrive as `mcp.composio.*` and every write to a real account stays approval-gated. |
### Memory That Grows Outside the Prompt
Atomic Agent's memory is not a giant chat log pasted back into the prompt. It's a local, inspectable store: durable identity, episodic notes, associations, distilled lessons, and reusable procedures. The prompt sees compact pointers, and full bodies are recalled by tool call only when the agent needs them.
- **Profile facts** render into `### profile` with contextual keyword gating; facts are versioned, with queryable history.
- **Notes** are stored in SQLite + FTS5, optionally paired with embeddings for hybrid recall.
- **Links** connect related memories into a bounded graph.
- **Lessons** distill repeated episodes into reusable principles.
- **Procedures** distill how-to templates without auto-executing them.
- **Voting** lets useful or harmful memories, lessons, procedures, and profile facts drift up or down.
- **Dedup and eviction** merge near-duplicate memories and evict by usefulness, not age, on by default.
- **Reflection** runs after turns, off the main agent slot, and writes memory without blocking the reply.
- **Obsidian export:** `atomic-agent memory export --vault <dir>` writes notes, lessons and procedures into a vault as linked Markdown files.
- **Re-embedding:** with local embeddings on, switching the embedding model (or turning embeddings on over existing notes) gives older notes vectors for the new model in the background; `atomic-agent memory reindex` does it right away.
New to this? [MEMORY_GUIDE.md](docs/user/memory.md) walks the whole loop end to end: what gets stored when, where the SQLite file lives, how recall shows up in prompts, worked example transcripts, and how to inspect or wipe it all.
## Ways to Use It
<details>
<summary><b>TUI and CLI</b></summary>
Use the CLI for simple sessions, automation, and debugging. Use the TUI for an interactive control console: approvals, logs, models, skills, tasks, memory, MCP, channels, and traces.
```bash
atomic-agent run --cwd /path/to/work
atomic-agent tui --cwd /path/to/work
atomic-agent skill list
atomic-agent task list
atomic-agent trace list --limit 10
```
**Context.** The chip at the right of the composer shows the transcript against its ceiling and the model's window. History is limited in tasks, not tokens: one task is a thing you asked plus everything the agent did answering it, and `agent.conversationMaxPairs` (1-1000, default 200) sets how many the prompt carries. Click the chip or run `/context` to change the count and see the cost before you send.
| Mode | What it does |
|---|---|
| `default` | Approvals follow `agent.approvalLevel`. |
| `plan` | Read-only; the agent presents a plan, then you can run it in `auto` or `bypass permissions`. |
| `auto` | File writes inside the workspace stop asking. |
| `bypass permissions` | Nothing asks this session; hardline shell-guard rules still block. |
Switch modes with `/mode`, `ctrl+g M`, or the composer chip. On an approval prompt, `ctrl+y` approves, `ctrl+d` denies, `ctrl+f` grants the category, `ctrl+b` retargets a write or grants a shell command's shape, `ctrl+z` pages through the full command when the preview is cut, `esc` aborts, and typing answers the agent in words. `/theme` switches between six palettes: `classic-dark`, `classic-light`, `toxic-green`, `khorne-red`, `darky-dark`, `moon-yellow`. The TUI is clickable; to select text, drag over plain text, or turn the mouse off with `/mouse off` or `--no-mouse`. Handy slash commands: `/help`, `/tools`, `/model`, `/privacy`. A failed or long turn raises a desktop notification, sessions are named from their first prompt, and inside a [herdr](https://github.com/herdrdev/herdr) pane the TUI labels the pane with its state.
Full TUI guide: [TUI.md](docs/user/tui.md).
</details>
<details>
<summary><b>Run modes: Local · Cloud · Fusion</b></summary>
`local` and `cloud` are the two routes the composer always offered. **Fusion** adds a third: one model orchestrates and a pool of workers executes the parts it delegates. The usual pairing is a cloud orchestrator with local llama-server workers, but neither leg is tied to a kind: a local model can plan for cloud workers, and `/runmode swap` trades the two legs. The only rule is that the legs are two different providers. The block is additive and `llm.activeTextProvider` stays authoritative:
```json
"llm": {
"activeTextProvider": "openrouter",
"runMode": {
"mode": "fusion",
"fusion": { "orchestratorProvider": "openrouter", "workerProvider": "local-llama", "workers": 3 }
}
},
"localModels": { "managed": { "parallel": 3 } }
```
`workers` (1..8, default 2) is the default fan-out width when the orchestrator does not name one; it is not a ceiling, and the orchestrator can ask for more on a given call. What bounds the width on a local leg is `localModels.managed.parallel`, the llama-server `--parallel` slot count (default `"auto"`, sized from the daemon's context; a number pins it; applied on the next daemon start). On a cloud worker leg the width is capped by `cloudWorkers` (1..32, default 4). The orchestrator model is the provider's `defaultChatModel`; on a local leg the worker model is the one the managed daemon serves. `reviewStallSteps` (default 6, `0` disables) nudges an orchestrator that keeps reading instead of delegating or replying.
In the TUI, fusion is the last row of the composer's **Where it runs** switch (`ctrl+r`, or click the backend word): it needs two providers that can answer, one per leg, and says which one is missing otherwise. While it is on, the backend word is an orange chip and the composer and the chat bubbles take the same tint. `/runmode local|cloud|fusion` and `ctrl+g 1/2/3` pick a mode from the keyboard; `/runmode swap` trades the orchestrator and worker legs; `/runmode status` says what the mode resolves to.
On the fusion route the strip gains a fourth control, **Workers** (`→` past the model, or click the worker count): it picks the worker model and the default fan-out width, and `/runmode workers N` does the same from the keyboard. The provider and model controls address the orchestrator leg. On a local worker leg the worker count also sets `localModels.managed.parallel`, so restart the local daemon to apply it.
Once fusion is on, the orchestrator gains one tool, `fusion.delegate`, and prompt guidance telling it to plan first and hand the independent bulk down: reading many files, first drafts, boilerplate, tests, wide searches. Each part it delegates runs as its own throwaway worker turn (several at a time), and their replies come back into the same call for the orchestrator to check and merge; you see each worker start and finish in the chat feed. The orchestrator itself does not run mutating tools. Workers cannot delegate further, cannot reach you, and cannot schedule tasks or write memory. Approving a fan-out lets its workers write and run commands inside the directories it names; anything outside them comes back as a named path, and the orchestrator sends the task out again with that path so you can approve the wider scope.
</details>
<details>
<summary><b>Managed local models</b></summary>
The CLI can manage a paired `llama.cpp` setup for chat and embeddings:
```bash
atomic-agent models update
atomic-agent models list
atomic-agent models pull qwen-3.5-4b
atomic-agent models use qwen-3.5-4b
atomic-agent models list-embeddings
atomic-agent models pull-embedding <model>
atomic-agent models use-embedding <model>
atomic-agent models start
atomic-agent tui --cwd /path/to/work
```
Managed mode downloads the backend, pulls GGUF models, selects the active model, and starts detached chat / embedding daemons when configured.
The default engine is Atomic Chat Core, which installs and runs our TurboQuant `llama.cpp` build for your computer. The first start installs it with progress. If that fails, the error says what happened and how to retry: `atomic-agent models update` (TUI: `R` in Models). The standalone `llama.cpp` server remains a support-only fallback that the app does not show: `atomic-agent models engine llama-server` selects it and `atomic-agent models engine atomic-core` switches back; both engines use the same model files.
`embeddinggemma-2` (Google's EmbeddingGemma 2, multilingual, 768-dim) runs only on the Atomic Core engine: Core serves it from its embedding module and the first `models start-embedding` installs the newer stock `llama.cpp` build it needs.
Big models can download in the background, detached from the terminal that started them:
```bash
atomic-agent models pull --background qwen-3.5-35b # returns at once; keeps running after the terminal closes
atomic-agent models downloads # list background downloads, progress, interrupted ones
atomic-agent models pull qwen-3.5-35b # follow a running download in the foreground (Ctrl+C detaches)
atomic-agent models downloads cancel qwen-3.5-35b # stop it; what was fetched stays on disk
```
The TUI runs every model download through the same worker. Quit mid-download (Ctrl+C, closing the window) and the download continues; open the TUI again and the chip picks it up where it is, and when the file lands the model is activated and the daemon started as if you had waited. A worker that died mid-way is resumed automatically on the next launch; one you cancelled is not. On the LLM tab's Local pane, `x` stops the download in flight and keeps what it fetched, and Enter on the row resumes it.
The worker is a detached copy of the CLI writing its progress to `<stateDir>/models/downloads/<job>.json` and its log next to it, the same arrangement as the managed `llama-server` daemon. A worker that dies mid-way (a reboot, a `kill -9`) shows as `interrupted` in `models downloads`, and running the same `pull` again, with or without `--background`, resumes from the partial file. `pull --mmproj` also fetches a vision model's projector; `pull-embedding --background` works the same way for embedding models.
Model downloads resume. An interrupted pull (a dropped connection, Ctrl+C, a closed terminal) keeps what it has fetched next to the destination as `<file>.part`, and the next `models pull` of the same model continues from that point with a `Range` request rather than starting over. The downloader validates the partial against the server's `ETag` before appending, so a file re-uploaded under the same name is fetched afresh; within one pull, transport errors and stalls retry from the partial with backoff before giving up.
The managed chat daemon stops when the last session exits, freeing the RAM and VRAM the model was holding; set `localModels.managed.stopOnExit: false` in `config.json` to keep the model warm between sessions. Daemons started standalone with `models start` are never touched.
On Windows the backend zip is picked per machine (the CUDA 12.4 build when the NVIDIA driver supports CUDA 12.4 or newer, Vulkan on RTX 50-series cards and everywhere else). If the GPU build cannot serve a model on your hardware (typical for iGPU-only boxes), the start falls back to the CPU build automatically and records `localModels.managed.backendVariant: "cpu"` in `config.json`; set it to `"auto"`, `"vulkan"`, `"cuda-12.4"` or `"cuda-13.3"` to pick a build yourself (for example after a driver update; the CUDA 13.3 build currently needs the CUDA Toolkit installed).
On Linux arm64 there is a single build and it is used on every machine. It bundles the CUDA runtime and cuBLAS for the NVIDIA GB10 superchip in DGX Spark, and it also carries the dispatched CPU backends (armv8.0 through armv9.2); the GPU backend is loaded at runtime, so a box with no NVIDIA driver runs the same build on its CPU. That bundle makes the download large, ~554 MB against ~30 MB on x64. It needs glibc 2.38 or newer (Ubuntu 24.04, Debian 13, DGX OS 7); on an older or musl system managed mode says so before downloading anything and external mode is the way to run.
Cloud models are searchable from the same command: by id, vendor, or capability, across every configured cloud provider:
```bash
atomic-agent models search claude vision
atomic-agent models search free tools --json
atomic-agent models search "1m cache" --provider openrouter --limit 10
atomic-agent models search kimi --refresh # pull live /models lists first
```
Every term has to match (`claude vision` is not a substring of any id), a size term names a whole-unit bucket whatever the row displays (`1m` finds windows from 1M up to 2M, including the 1,048,576-token ones that render as `1.0M`; a 2M window answers to `2m`; `128k` finds 131,072), results are ranked best-first, and the same query works in the TUI Cloud pane (press `f`). If `--refresh` cannot load a live OpenRouter or AI/ML API list, the search answers from the bundled list and prints one `warning:` line on stderr with the provider, the reason (network error, timeout, HTTP status, a body that is not JSON) and how long the attempt took.
</details>
<details>
<summary><b>External <code>llama-server</code></b></summary>
Already have your own `llama.cpp` process? Point `atomic-agent` at it with `localModels.url` in `<stateDir>/config.json` (external mode; the default is `http://127.0.0.1:9931`, llama-server's own default port since llama.cpp v0.7.0), or save the URL in the TUI's LLM tab, External pane:
```jsonc
// <stateDir>/config.json
{
"localModels": { "mode": "external", "url": "http://127.0.0.1:8080" }
}
```
```bash
./llama-server -m Qwen3.5-9B-Q4_K_M.gguf \
--slots 4 \
--parallel 4 \
--port 8080 \
--cache-reuse 256
atomic-agent tui --cwd /path/to/work
```
The LLM tab in the TUI has an External pane for this setup. Saving a URL runs an honest health probe: it validates the `/health` body, reports llama.cpp's 503 answer while a model loads as loading rather than dead, and recognizes when the URL is a different OpenAI-compatible runner that should be added as a cloud provider instead.
</details>
<details>
<summary><b>Ollama, LM Studio and Atomic Chat (local)</b></summary>
Running models under [Ollama](https://ollama.com), [LM Studio](https://lmstudio.ai) or Atomic Chat? All three are OpenAI-compatible servers, and all three are presets in the provider wizard, so there is no base URL to type.
```bash
ollama serve
ollama pull qwen2.5:0.5b
atomic-agent tui --cwd /path/to/work
```
In the TUI, open the LLM tab, add a provider, and pick **Ollama (local)** (or **LM Studio (local)**, **Atomic Chat (local)**). A local server has no API key, so the wizard skips the key screen and goes straight to the model choice: two screens, service then model.
Model ids are the tags the server reports, `qwen2.5:0.5b` or `llama3.2:latest` for Ollama, so use the same name you passed to `ollama pull`. The list comes from the server's own `/v1/models`, which means anything you have pulled shows up without a restart.
The preset is a fixed `http://localhost:11434` endpoint; it does not probe for a running server. If `ollama serve` isn't up when you reach the model step, the list fails to load (`could not list models from Ollama (local)`), and the wizard falls back to letting you type a model id by hand; in the LLM panel the list shows `model list unavailable` and only the current model. Start the server (`ollama serve`, then `ollama pull <model>` for anything you want) and re-open the preset.
| Preset | Endpoint |
| --- | --- |
| Ollama (local) | `http://localhost:11434` |
| LM Studio (local) | `http://localhost:1234` |
| Atomic Chat (local) | `http://127.0.0.1:1337` |
For Atomic Chat, the endpoint is the desktop app's Local API Server (Settings › Local API Server). The app only raises it while a model is loaded, so start a model first or the model list will not load. It needs no key unless you set one in those settings; if you did, put the same value in `ATOMIC_CHAT_API_KEY` in the state dir's `.env`. An External llama.cpp URL on `:1337` is recognized and offered this preset, the same way `:11434` is offered Ollama.
Two things to know. Ollama's OpenAI-compatible surface lives under `/v1`, but the base URL is stored without it, since every call site appends `/v1/...` itself. And **Ollama (local)** is a different entry from **Ollama Cloud**: the first is the server on your machine and needs no key, the second is the hosted endpoint.
Tool calling works over this path, so the agent loop runs normally, but it is only as reliable as the model you picked. Very small models emit malformed tool calls more often; if the loop stalls, try a larger one before assuming the provider is at fault.
</details>
<details>
<summary><b>OpenAI-compatible HTTP</b></summary>
Run `atomic-agent` as a local HTTP service:
```bash
atomic-agent serve \
--host 127.0.0.1 \
--port 8787 \
--cwd /path/to/work \
--api-key "$ATOMIC_AGENT_API_KEY"
```
Without a key, anyone who reaches the port can run the agent and its tools, so `serve` refuses to start on a host other than loopback (`0.0.0.0`, a LAN address) unless `--api-key` or `ATOMIC_AGENT_API_KEY` is set. On loopback it still starts without one and prints a one-line warning.
`POST /v1/chat/completions` maps one request to one full macro-turn: `user -> 0..N tool steps -> reply`. Atomic-specific routes expose sessions, approvals, tasks, webhooks, events, skills, config, and capabilities.
`serve` boots the same runtime the TUI does, so enabled Telegram and Discord bots, and every enabled Swarm bot that has a token, come up in this process too. That makes `serve` the way to keep the bots answering with no TUI open; it stays in the foreground until you stop it and does not restart itself. Each bot runs in one process at a time; see Channels below.
**`serve` does not outlive whoever started it.** When the process that started it goes away, the server finishes any turn still running and then shuts down, the same way it would on `SIGTERM` — so a killed editor, a crashed desktop app or a closed test harness cannot strand a server that holds its port and its database handles for weeks.
**To daemonise it, pass `--no-parent-exit`** (or set `ATOMIC_AGENT_SERVE_NO_PARENT_EXIT=1`). That is the supported way to run `serve` in the background from a shell — including under `nohup` and with `& disown`, neither of which detaches the process from the shell, so neither survives on its own. A `serve` started with no parent at all, as under `launchd` or `systemd`, needs no flag.
Each server records itself under `<stateDir>/serve/` and sweeps strays left by earlier runs; `atomic-agent serve --reap` does the same sweep by hand and prints what it found. The sweep signals a process only when it has positive evidence the server was abandoned — the exact process that started it is gone — *and* `/health` on the recorded port identifies it as that same atomic-agent, reparented and idle. A server marked as a daemon is never touched, no matter how long it runs; anything still working, and anything the sweep cannot confirm, is left alone and keeps its record.
</details>
<details>
<summary><b>Tauri sidecar</b></summary>
The sidecar speaks newline-delimited JSON over stdio, making it easy to embed in desktop apps:
```json
{"kind":"request","id":"r-1","type":"start_session","payload":{"workingDir":"/home/me"}}
{"kind":"request","id":"r-2","type":"send_message","payload":{"sessionId":"s-1","text":"Check the inbox and summarize urgent mail."}}
```
Events stream back as the turn runs:
```json
{"kind":"event","id":"e-1","type":"turn_started","correlationId":"r-2","payload":{"sessionId":"s-1","turnIndex":0}}
{"kind":"event","id":"e-2","type":"tool_call_result","correlationId":"r-2","payload":{"sessionId":"s-1","stepIndex":0,"tool":"browser.read_aria","status":"ok","summary":"url: https://mail.google.com/ ..."}}
{"kind":"event","id":"e-3","type":"assistant_reply","correlationId":"r-2","payload":{"sessionId":"s-1","text":"You have 3 urgent threads."}}
```
</details>
<details>
<summary><b>Channels: Telegram · Discord · Swarm</b></summary>
Drive the same agent from a Telegram or Discord bot. Tokens live in `<stateDir>/.env`, never in `config.json`:
```jsonc
// <stateDir>/config.json
{
"telegram": { "enabled": true, "ownerUserId": null },
"discord": { "enabled": true, "ownerUserIds": ["123456789012345678"] }
}
```
```bash
# <stateDir>/.env
TELEGRAM_BOT_TOKEN=123456789:AA-your-bot-token
DISCORD_BOT_TOKEN=your-discord-bot-token
```
Both can be set up from the Integrations tab in the TUI. Each bot answers only its owner: in a DM, or in a group or server channel when you @mention it or reply to it. Every chat, forum topic, Discord channel and thread gets its own session, and both bots understand `/status`, `/sessions`, `/switch <id>`, `/new`, `/model [provider] [model-id]` and `/cancel`. Approvals arrive as buttons in the chat the turn came from; only an owner can press them. Messages and files pass through Telegram's or Discord's servers.
Channels belong to the runtime, not to the TUI: `atomic-agent serve` boots them the same way, so the bots keep answering with no terminal UI open. Each bot is guarded by its own lockfile in the state dir; a second process that tries to start the same bot leaves it down with `already running in another atomic-agent (pid N)` and does not retry, so start bots from `serve` or from the TUI, not from both.
**Telegram.** Pair from the TUI (**p** in Integrations, or `/telegram pair`): it shows a one-time 6-digit code, and the account that sends the bot `/start <code>` within 5 minutes becomes the owner; any other message is ignored. Replacing an existing owner asks you to confirm first, and after pairing the TUI names the new owner's @username. In groups, turn off the bot's privacy mode in @BotFather, or plain @mentions are not delivered to it. While a turn runs, the bot keeps one silent progress bubble updated with step labels only, never tool output; turn it off with `"telegram": { "progressIndicator": false }`. Files you send in the DM are saved under `<stateDir>/inbox/telegram/`, one folder per day, and the agent gets the path with your caption (albums arrive as one message; Telegram lets bots fetch up to 20 MB). Files the agent attaches to a reply follow the text, images inline and the rest as documents, up to Telegram's 50 MB bot limit. Scheduled tasks can report back: `atomic-agent task create --cron "0 9 * * *" --message "morning digest" --notify telegram` (or `notify: "telegram"` when the agent schedules it) posts each run's result to your paired DM. Reporting is per task, Telegram only; if the channel is down the report is skipped with a logged warning.
**Discord.** There is no pairing: put your user id (as a string) in `ownerUserIds`; an empty list refuses every message. The bot needs no privileged intents, because Discord delivers DMs and @mentions without them. Inbound files up to 50 MB go to `<stateDir>/inbox/discord/`; reply attachments are uploaded one message each, within your server's upload limit. There is no progress bubble.
**Swarm.** Run extra Telegram or Discord bots beside the two above, each with its own token, owner, lockfile and sessions. Manage them in the Swarm tab (`/swarm`), which writes `swarm.units` and the token for you:
```jsonc
"swarm": { "units": [
{ "id": "ops", "kind": "telegram", "label": "Ops", "role": "on-call triage",
"enabled": true, "tokenEnv": "TELEGRAM_BOT_TOKEN_OPS", "ownerUserId": null }
] }
```
The Swarm tab names the token key `<KIND>_BOT_TOKEN_<ID>`. Each unit has one owner; Telegram units pair from the Swarm tab, Discord units take the id directly. `role` is a free-text note shown in the tab and does not change what the bot does.
</details>
<details>
<summary><b>Composio toolkits</b> (1500+ SaaS apps)</summary>
[Composio](https://composio.dev) is a hosted catalogue of 1500+ SaaS toolkits (Gmail, Slack, Notion, Linear, and more) that also brokers each app's OAuth, so you never register an OAuth client yourself.
Open the **Integrations** tab in the TUI and follow the setup, or drop a key into `<stateDir>/.env`:
```sh
COMPOSIO_API_KEY=ck-your-key
```
The key is the real gate: with no key the runtime opens no connection and registers no tool. Set `"composio": { "enabled": false }` in `config.json` to keep the key on disk with the toolkits off.
Under the hood this is not a new subsystem. Composio's tool router speaks Streamable HTTP MCP and authenticates with a static header, which is exactly the transport the MCP client already supports, so the agent treats it as one more MCP server. Tools land as `mcp.composio.*`.
Rather than loading 1500 toolkits into the prompt, the session exposes four meta-tools: the agent searches for a tool by use case, fetches its schema, then executes. Discovery is annotated read-only and flows without prompting; `COMPOSIO_MULTI_EXECUTE_TOOL` and `COMPOSIO_MANAGE_CONNECTIONS` are marked destructive, so every write to a real account still hits the approval gate.
Connected accounts are scoped by a random install id minted once and stored in `config.json`, never your email. Losing it means re-authorising every connected app.
Note that Composio is a hosted service: your OAuth tokens for connected apps live on Composio's infrastructure, and tool calls are executed through their servers rather than from your machine.
</details>
<details>
<summary><b>MCP client</b></summary>
Configure MCP servers in `config.json`, and their tools join the same registry as local tools. Trusted read-only servers can batch with other reads; untrusted servers default to approval-gated execution.
```jsonc
{
"mcp": {
"servers": [
{
"name": "docs",
"enabled": true,
"transport": {
"kind": "stdio",
"command": "npx",
"args": ["-y", "@example/mcp-server"]
},
"trust": "pure_read"
}
]
}
}
```
To offer only some of a server's tools, list their raw names: `"enabledTools": ["get_issue", "list_issues"]` keeps just those, and `"disabledTools": ["delete_repository"]` drops tools on top of that (or on its own, from the full list). Turned-off tools never reach the prompt and cannot be called; a change applies when the server reconnects.
The TUI MCP panel supports live add / remove without restarting the process. When a stdio server fails to connect, the tail of its stderr is surfaced in the error instead of a bare disconnect message.
</details>
## Safety and Observability
Everything Atomic Agent does is inspectable and interruptible:
- **Approval gates:** shell, filesystem writes, patches, archive extraction, process kill, HTTP requests, skill scripts, untrusted MCP tools (except ones the server marks read-only), git writes and remote sync, move, trash and restore, GitHub and e-mail sends, reads outside the working scope, Fusion fan-out, and non-web browser navigation are gated by policy.
- **Append-only traces:** prompts, completions, tool invocations, outcomes, failure categories, votes, and lifecycle events recorded as local NDJSON.
- **Prompt drift replay:** `atomic-agent trace replay <sessionId>` compares current stable-prefix hashes against recorded traces.
- **Failure taxonomy:** transport, grammar, model, tool, and cancellation failures classified across events, traces, metrics, TUI, sidecar, and HTTP.
- **No-progress guard:** repeated identical tool calls draw a warning at 3 repeats and a hard veto at 5; after 3 consecutive vetoes the agent is forced into a graceful reply.
- **Per-session FIFO:** every surface enters the same `TurnController`; one session stays ordered while different sessions run concurrently.
- **Explicit state:** sessions, memory, tasks, skills, browser profile, MCP config, and traces are ordinary local files or SQLite databases.
- **Replaced files come back:** before a write replaces a file the agent did not create this session, the previous content is copied to `<stateDir>/restore/` (the last 20 copies per working directory, files up to 5 MB), and `os.fs.restore` puts it back.
- **Deletes go to the Trash:** `os.fs.trash` moves files to the system Trash or Recycle Bin instead of deleting them, behind approval.
- **Moves without the shell:** `os.fs.move` moves or renames files and folders, creating missing folders, as one approval for a whole batch; it never replaces an existing file unless asked, and its result lists the moves to undo it.
- **Long commands detach:** a shell command still running after 10 minutes becomes a background job the agent can wait on or kill; it stops when the turn ends unless kept (1-hour cap from start, 3 jobs per session).
- **Reads stay in the workspace:** with `agent.readScope` at its default, `working-dir`, a read outside the working directory asks first; `unrestricted` turns this off.
> [!IMPORTANT]
> Treat traces and `<stateDir>/.env` as sensitive local artifacts. Secret redaction and per-tool environment filtering are not complete isolation layers.
### Privacy and Egress
By default, Atomic Agent does not require a hosted agent provider. Model calls go to your configured backend, and local artifacts stay under `<stateDir>`.
Anonymous usage analytics is on by default. Every event carries a random install id shared by the terminal and desktop apps on the same machine (stored in `~/.atomic-agent-install-id`; the desktop app reuses the terminal's existing id unless analytics is off in the terminal's config), your OS platform and CPU architecture, the app version, the desktop app version when it comes from the desktop app, which surface sent it (terminal UI, command line, or desktop), and the install channel (the install script, a Linux `deb`, `rpm` or AUR package, or the desktop `dmg`, `exe`, `AppImage`, or `deb` package). It sends the provider and model names exactly as configured, including a custom provider's name and, for a model added from Hugging Face, its repository id, plus turn-shape numbers (latency, step count, outcome, token counts, estimated cost). It also records that the app launched, which first-run screen was reached (a fixed list of screen names, never anything you typed), and that a backend was set up: the provider name and whether it is local or cloud, never the key, the URL, or the host. The desktop app adds these event groups: launch and health (startup timings, agent start failures and restarts, window crashes, app close), onboarding screens, model downloads and backend start, chat turn timing, approval answers, button and menu usage by action id only, and feature usage counts (settings panes, sessions, voice, tasks, skills, MCP servers, Telegram setup, import). If you turn analytics off, one last event records that it was switched off and how many days after install. Message content, file paths, tool arguments, full URLs, keys, and your IP address are never sent.
Crash reports go to Sentry on the same switch. They carry path-stripped stack frames, the error type and category, safe scalar codes, a bounded tool name, the surface, install channel and app versions as tags, and, for a failed connection, only the class of the endpoint host (`localhost`, `private`, `known_cloud`, or `other`), never the host itself. A failed model turn also reports the provider id when it is a built-in one, which local engine served it (`atomic-core`, `llama-server`, or `external`), how long and how many times the turn waited for the provider, and, for the engine the agent manages, whether its process was alive (`alive`, `dead`, `no_pid`, or `unknown`). No native memory dumps are sent. Turn both off with `/privacy analytics off` in the TUI, the Privacy switch in the desktop app, or `"analytics": { "enabled": false }` in `config.json`. The TUI toggle applies live; an edit to `config.json` applies to processes started after it. In the desktop app the switch stops the app's own reporting at once, and the bundled agent stops after its runtime restarts. Setting `ATOMIC_AGENT_ANALYTICS=off` in the environment turns both off for that process whatever the config says.
Local-first bounds where control lives, not where packets go. Network egress happens when:
- the browser navigates to a website;
- an HTTP tool calls a requested endpoint;
- a web search provider answers a query;
- a configured cloud LLM or embedding provider receives its request;
- a `subscription-cli` provider is active and the vendor CLI (`claude` or `codex`) receives your prompt on its stdin, then sends it on under its own account;
- an MCP server receives a tool call you routed to it;
- the Telegram or Discord channel (or a Swarm bot) is enabled and exchanges messages with your paired chat, including opt-in scheduled task reports;
- Composio is set up and its tools run through Composio's servers;
- the agent's e-mail integration reads or sends mail;
- the GitHub tools open issues or pull requests, or `git.remoteSync` is on and a repository syncs;
- managed mode downloads a model from Hugging Face or the `llama.cpp` backend from GitHub Releases;
- you install a skill from ClawHub or a GitHub skill repo;
- the TUI checks GitHub Releases for a newer version at startup (set `ATOMIC_AGENT_UPDATE_CHECK_ON_STARTUP=false` to skip), or `atomic-agent update` fetches the installer;
- analytics or crash reporting is enabled, as described above.
> [!NOTE]
> Skills and shell commands inherit the agent process environment, including `.env` secrets, so anything you run can itself reach the network.
The promise is not magic secrecy. The promise is that the agent control plane does not need to be remote.
## Requirements & Configuration
<details>
<summary><b>Requirements</b> (Node, llama-server, browser, git) + Linux notes</summary>
- Node.js for development; release bundles ship as Node SEA binaries.
- A reachable `llama-server`, either managed by `atomic-agent models` or launched externally.
- Managed mode picks the GPU backend automatically: Metal on Apple Silicon, CUDA on Windows when `nvidia-smi` reports a supported driver (including the reworked driver 610+ headers) with Vulkan as the fallback, Vulkan on Linux, a single CUDA-enabled build on Linux arm64 (tuned for the NVIDIA GB10 in DGX Spark) that uses the GPU when an NVIDIA driver is present and the CPU otherwise, CPU when no GPU is usable.
- Chrome, Microsoft Edge, or another configured Chromium-family executable. Browser binaries are not bundled.
- `git` for git tools.
- macOS workflows may need Accessibility, Screen Recording, Automation, or Reminders permissions.
**Linux notes:**
- **Desktop tools** (install via your package manager): `ripgrep` (file search; bundled binary used when present), `xclip`/`xsel` (X11) or `wl-clipboard` (Wayland) for clipboard, `libnotify-bin` for notifications, `wmctrl` for window control (X11/XWayland only), `gio` (glib2) or `trash-cli` for `fs.trash`.
- **Browser:** Chromium-family sandboxing can fail under some Linux setups (containers, certain kernels). If Chrome refuses to launch, set `ATOMIC_AGENT_BROWSER_NO_SANDBOX=1` so the agent starts it with `--no-sandbox` (containers and CI only).
- **GPU acceleration (managed mode):** the backend always starts and falls back to CPU when no GPU driver is available. For GPU offload install a Vulkan driver. Intel/AMD: `mesa-vulkan-drivers` (+ `vulkan-loader`/`libvulkan1`); NVIDIA: the stock proprietary driver bundles its Vulkan ICD. Device auto-selected at start; override with `atomic-agent models use-device <auto|cpu|Vulkan0>`, inspect with `atomic-agent models devices`, or press `G` on the TUI LLM tab's Local pane. Multi-GPU: set `localModels.managed.tensorSplit` in `config.json` (e.g. `[3, 1]` for a 75%/25% layer split) to launch llama-server with `--split-mode layer --tensor-split` across every visible GPU; combine with `use-device Vulkan0,Vulkan1` to restrict which devices join the split.
</details>
<details>
<summary><b>How long a reply may run</b> (output ceilings)</summary>
Cloud models are **uncapped by default**: the service applies the model's own maximum, so one turn can write a whole file. To bound it (spend, or a service that requires the field) set `maxOutputTokens` on the provider entry:
```json
"llm": { "providers": [{ "id": "openrouter", "kind": "openrouter", "maxOutputTokens": 64000 }] }
```
Reasoning models spend that same budget on thinking, so a low ceiling can be used up before any answer appears.
Local models use `localModels.completionMaxTokens` (llama.cpp's `n_predict`, default `16384`). Set it to `0` in `config.json` for no cap; generation then stops at a stop token or when the context window fills. That knob bounds time and runaway loops, not memory: what your machine commits is decided at daemon start by the model and `--ctx-size`, and does not grow with the length of one reply.
If a small local model keeps repeating itself, `localModels.drySampler: true` turns on llama.cpp's DRY anti-repeat sampler (it looks at the last 256 tokens of prompt plus reply) for every `/completion` request (Atomic Core or llama-server only; off by default, not yet measured on our task set).
</details>
<details>
<summary><b>Models that need strict tool schemas</b> (<code>strictTools</code>)</summary>
Some models call tools reliably only when the provider constrains decoding to the tool's schema: OpenAI's **strict mode**. Set `strictTools` on the provider entry to send every function as `strict`:
```json
"llm": { "providers": [{ "id": "mercury", "kind": "openai-compatible", "strictTools": true }] }
```
Off by default, and only for OpenAI-compatible kinds (`openai-compatible`, `qwen-openai-compatible`, `openrouter`, `aimlapi`, `gemini`). `strict` is a field on each tool, so `extraBody` cannot reach it; `tools` is a reserved key that is re-applied after that merge.
With the flag on, every tool schema is rewritten into the subset strict mode accepts: objects are closed, every property is listed in `required` (an optional one becomes nullable instead of being omitted), and value-range keywords the runtime validators enforce anyway (`minItems`, `minLength`, `pattern`, `format`, `default`, …) are stripped. A handful of tools take a free-form map (`os.http.request`'s headers and body, `mcp.prompt.get`'s arguments), and those cannot be expressed strictly; they are sent unconstrained (`strict: false`) rather than silently losing their arguments.
Because optionals become nullable, a strict model sends `"pinned": null` where it used to omit the key; on these providers a top-level `null` argument is dropped again before the call runs, so tools that check for presence behave as they always did.
The flag also sends `parallel_tool_calls: false`. Strict decoding and parallel calls do not compose (OpenAI's guidance is that a parallel call "may not match supplied schemas"), so a provider asked for strict tools is asked for one call per response. `agent.maxParallelToolCa历史前置条件说明(补充参考)
Node.js 需 >=25.7(README 徽章标示,但安装器是否另带运行时待核验);macOS(Apple Silicon)或 Linux x64/arm64 或 Windows x64;本地模型模式需磁盘空间与相应硬件,具体显存要求待核验;云端模型与 Fusion 需配置相应提供方账户或 API Key;GitHub、邮件、Composio、搜索提供方等集成需各自账户与授权;费用、国内网络可用性待核验。
项目来源与清单版权许可
https://github.com/AtomicBot-ai/atomic-agent
整理来源:https://github.com/slavakurilyak/awesome-ai-agents
清单版权与许可:
MIT License
Copyright (c) 2024 Slava Kurilyak
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.