Browser
Navigate, click, type, scroll, read the page, and manage tabs via a real Chromium browser.
Tools are the things Atomic Agent can actually do on your machine: open a web page, read a file, run a shell command, pull text out of a PDF, copy something to your clipboard, or pop a desktop notification. The model decides which tool to use; the runtime runs it and feeds the result back. Tools run on your machine, and risky actions pause for your approval first.
This page is a tour of the desktop tool surface — what each family can do, and where the safety rails are.
The fastest answer to “does it have a tool for that” comes from the agent itself. Type /tools in the TUI and it prints the live built-in catalog as plain text — no panel, no navigation.
/tools # the whole built-in catalog, grouped by family/tools filesystem # only the tools matching a queryThe listing is filtered through the same config gates the runtime applies, so a family you have disabled — browser, web search, vision, a memory channel — never appears. What you see is what the model sees.
/tools <query> matches on the family name, and an alias map covers the words people actually search for rather than the namespaces the tools live under. filesystem, file, files, fs, and disk all resolve to os.fs; bash, shell, and terminal to os.shell; chrome to browser; notes to memory.notes; and so on for web, http, network, git, vision, and images.
Every turn, the model emits a JSON array of one or more tool calls. The runtime looks each one up in the tool registry by its fully-qualified name (for example os.fs.read or browser.navigate), validates the arguments, checks whether the action is dangerous, runs it, and compresses the result before handing it back to the model.
flowchart TD
A["Model emits tool calls<br/>(JSON array)"] --> B["ToolRegistry.invoke(name, args)"]
B --> C{Dangerous op?}
C -->|"read-only<br/>(os.fs.read, browser.read_aria)"| D["Run immediately"]
C -->|"dangerous<br/>(shell, fs.write, http)"| E["Approval gate"]
E -->|approved| D
E -->|denied| F["ApprovalDeniedError"]
D --> G["compressToolResult()<br/>trim + summarize"]
G --> H["Result back to model"]
Two things are worth knowing up front:
./notes/todo.md resolves against the session’s working directory (--cwd), not the process CWD. ~/file.txt means your home directory.os.fs.read calls) so they fan out at once, while writes and other side-effecting tools run one at a time.Browser
Navigate, click, type, scroll, read the page, and manage tabs via a real Chromium browser.
Files
Read, write, edit, search, glob, diff, patch, and hash files. Extract text from PDFs, DOCX, XLSX, and more.
Shell
Run approved commands, inspect processes, and use git — all guarded by a command rule system.
Desktop
Clipboard, desktop notifications, web search and fetch, and window controls.
The browser tools drive a real Chromium instance (via Playwright), so the agent can use sites the way you would.
| Tool | What it does |
|---|---|
browser.navigate | Open a URL |
browser.click | Click an element |
browser.type | Type into a field |
browser.read_aria | Read a compressed accessibility snapshot of the page |
browser.search | Run a search |
browser.scroll | Scroll the page |
browser.tabs | List and switch tabs |
After a navigation or search, the agent keeps a compressed snapshot of the page’s accessibility tree so it can reason about what’s on screen without re-reading it every step.
Navigating to a non-http(s) URL is treated as dangerous and goes through the approval gate.
The filesystem family is the agent’s workhorse. All of it lives under os.fs.* and friends:
os.fs.read, os.fs.list, os.fs.glob, os.fs.grep, os.fs.hash, os.fs.diffos.fs.write, os.fs.edit, os.fs.patch, os.fs.trash, os.fs.restoreos.fs.watch for file changesos.fs.read_document extracts readable text from a document fileos.fs.archive.list, os.fs.archive.read_entry (read-only), os.fs.archive.extract (approval-gated)os.fs.locate_project finds the project root for a pathThe agent can also pull readable text out of common document formats (PDF, DOCX, legacy DOC, XLSX, PPTX, RTF, ODT and plain text), so it can work with documents, not just source files. Archives are handled by the os.fs.archive.* tools.
Write-family tools (os.fs.write, os.fs.edit, os.fs.patch, trashing and restoring files, extracting archives) are dangerous and require approval.
os.shell.run runs commands, but every command passes through a shell command guard first. The guard has a safe-allow list, hard blocks for destructive commands, and pattern checks for risky constructs (such as piped command chains). Commands it recognises as harmless (a short safe list such as pwd, date, whoami, <tool> --version, plus read-only gh, gog and icalBuddy calls) run without a prompt. Everything else asks for approval, unless agent.approvalLevel is 4 or higher. Hardline blocks (rm -rf /, mkfs, dd to a block device, fork bombs, shutdown and similar) are refused at every level.
A command without its own time limit waits up to tools.shell.defaultTimeoutMs (600000 ms by default). When that elapses the command is not killed: it keeps running as a background job the agent can wait on or kill.
os.proc.list inspects running processes (read-only) and os.proc.kill terminates one. Killing a process is a dangerous action and goes through the approval gate.
os.git.* has three groups:
os.git.status, os.git.log, os.git.diff, os.git.show, os.git.blame, os.git.branch. They run through the same bounded command runner with a tighter timeout than general shell commands.os.git.init, os.git.add, os.git.checkout, os.git.commit.os.git.fetch, os.git.pull, os.git.push, os.git.clone, and adding or re-pointing a remote (os.git.remote with add or set-url). These are refused unless you set git.remoteSync: true (off by default), and then ask for approval up to level 4. os.git.remote with no action just lists remotes.Every gated git verb runs solo, never in a parallel batch.
os.web.search and os.web.fetch let the agent reach the open internet. os.http.request makes raw HTTP requests. These tools reach the network directly, so anything they send leaves your machine (model providers and telemetry are separate paths).
The two families are gated differently. os.web.search and os.web.fetch are classed pure_read: they’re SSRF-guarded and don’t mutate anything, so they run without an approval prompt and batch in parallel. os.http.request is approval_gated — it can issue arbitrary methods and bodies, so it always asks first and runs solo.
These tools are also “wandering-prone”: if the agent fires a lot of distinct searches or fetches without making progress, the loop detector nudges it back on track and, if needed, ends the turn gracefully rather than looping forever.
A few families only appear when their integration is set up, or in a specific mode:
github.whoami, github.pr.list and github.issue.list are read-only; github.pr.create, github.issue.create and github.issue.comment publish under your name, so they ask for approval (silenced from level 4).os.email.inbox reads the agent’s own inbox; os.email.send asks for approval at every level below 5.verify.syntax runs read-only syntax checks (node --check, tsc --noEmit, Python compile, bash -n); verify.run executes a command, server or page in a throwaway copy of the workspace and asks for approval like a shell command.fusion.delegate, which runs several worker agents in parallel after one fan-out approval. See Models.tasks.list, tasks.show, tasks.schedule, tasks.cron and tasks.cancel let the agent manage scheduled work. See Scheduling.These desktop tools let the agent interact with your environment beyond files and the browser:
os.clipboard.read — read the system clipboard (read-only)os.clipboard.write — write to the system clipboardos.notify — send a desktop notificationos.window.list — enumerate open windows (read-only)os.window.focus — bring a window to the frontvision.describe — describe an image, when vision.enabled is ontool.view and skill.view — inspect a tool’s or skill’s full definition on demandOn Linux these depend on desktop utilities (for example xclip for clipboard, libnotify/notify-send for notifications, wmctrl for windows). Atomic Agent probes for them at startup and reports what’s available in its capabilities summary — so if a tool is missing on your box, the agent knows not to reach for it.
Atomic Agent splits tools into two buckets:
readonly: true): no prompt inside the session’s working directory (and paths you named in your message). Reading files, reading a page, listing a directory. A read outside the working directory asks first; answering y widens the session’s read roots to that folder, and s allows reads anywhere for the rest of the session. Set agent.readScope: "unrestricted" to restore the old read-anywhere behaviour.readonly: false): must be approved. Shell commands, file writes/edits/trashing, HTTP requests, non-http(s) browser navigation, process kills, archive extraction, and skill scripts.When the model calls a dangerous tool, execution pauses and an approval request goes to wherever you’re driving the agent: a TUI modal, a CLI y/n prompt, an HTTP webhook, or a Telegram or Discord button. The tool only runs if you approve; deny it and the agent gets a clear error and moves on.
# Normal run — dangerous tools prompt for approvalatomic-agent run
# Auto-approve everything (testing / trusted, autonomous contexts only)atomic-agent run --no-approvalHow much gets asked is a five-step ladder, agent.approvalLevel, not an on/off switch. Level 1 is the default and asks about everything; each step up silences one broader category:
| Level | Stops asking about |
|---|---|
| 1 (default) | nothing — every gated action asks first |
| 2 | file writes, edits, and patches strictly inside the session working directory |
| 3 | file writes anywhere under your home directory, moves to Trash, archive extraction, HTTP requests |
| 4 | guarded shell commands, skill scripts, process kills, network git (push/pull/fetch/clone, adding a remote), GitHub PRs/issues/comments, Fusion fan-outs |
| 5 | everything, including non-http(s) browser navigation, reads outside the working directory, e-mail sends, MCP tool calls, and writes to the agent’s own trust config |
--no-approval is level 5. The hardline shell-guard rules are not part of this ladder — they fire before the gate and block at every level, including 5.
The older boolean agent.approvalRequired is still read for backwards compatibility: true maps to level 1, false to level 5. Prefer agent.approvalLevel in new configs.
A few honest limits worth stating plainly:
config.json and .env are not auto-redacted. Treat your state directory as sensitive.Internally, every tool is tagged with a resource class that governs how it’s scheduled in a batch:
| Class | Example tools | Batching behavior |
|---|---|---|
pure_read | os.fs.read, os.web.fetch, os.git.status | Run in parallel |
fs_write | reserved; no built-in tool uses it today | Serialized within the group |
browser | browser.navigate, browser.read_aria | Serialized (one Playwright process) |
memory_write | memory.notes.store, os.clipboard.write, os.notify | Serialized |
tasks_write | tasks.schedule, tasks.cron, tasks.cancel | Serialized |
vision | vision.describe | Serialized (bounds load on the vision slot) |
approval_gated | os.shell.run, os.http.request, os.fs.write | Solo only |
terminal | reply, finish | Runs last, alone |
unknown | anything unlisted | Rejected from every batch (fail-closed) |
You don’t configure this directly, but it explains why some calls fan out and others queue. Groups in different classes run concurrently with each other, so a step costs roughly the slowest group.
Two details are easy to get backwards. The mutating os.fs.* verbs (write, edit, patch, trash, archive.extract) are classed approval_gated, not fs_write — they require approval, which forbids them from batches entirely. And terminal tools (reply to end a turn, finish to end the session) always run after every other call in the step has settled.
The tool surface is shaped by a handful of config keys (in config.json under your state directory). Change one with atomic-agent config set <key> <value>:
| Key | Effect |
|---|---|
vision.enabled | Enable the vision.describe image tool (default true) |
memory.notes.enabled | Register the memory.notes.* tools |
agent.approvalLevel | Approval ladder, 1 to 5 (default 1) |
agent.readScope | working-dir (default) or unrestricted |
tools.shell.defaultTimeoutMs | Default time limit for os.shell.run (600000; then the command becomes a background job) |
git.remoteSync | Allow network git verbs (default false) |
A few settings are environment variables only (set them in your shell or in <stateDir>/.env, not in config.json):
| Variable | Effect |
|---|---|
ATOMIC_AGENT_BROWSER_ENABLED | Turn the browser family on/off (default true) |
ATOMIC_AGENT_BROWSER_CHANNEL | chrome (default) | msedge | chromium |
ATOMIC_AGENT_BROWSER_HEADLESS | Run the browser headless (default false) |
ATOMIC_AGENT_TASKS_AGENT_TOOLS_ENABLED | Expose the tasks.* scheduling tools to the agent (default true) |
ATOMIC_AGENT_MAX_PARALLEL_TOOL_CALLS | Cap on parallel calls per batch (default 8, max 16) |
Tools for a disabled feature simply don’t appear in the registry — the model never sees them, rather than calling them and getting an error.
Memory
The memory.* tools and how the agent remembers across sessions. See Memory.
Skills
Package reusable playbooks and scripts the agent can run. See Skills.
MCP
Add tools from external MCP servers to the registry. See MCP.
Configuration
Full config and environment-variable reference. See Configuration.