Tools
What each of the agent’s tools does, when the agent has it, and
what it takes. Why each tool is shaped the way it is lives in ARCHITECTURE.md
(Tools, and the section each entry below names). The exact description and schema the model
receives live in the code: src/atlas/tools/, and src/atlas/browser/ for browser_exec.
How tools reach the model
- Always on or deferred. An always-on tool is in every model call, and paid for in tokens on
every call. A deferred tool waits behind
tool_search, which lists it by name and loads it into the conversation when the model searches for it. From then on it is a real tool, called with its own schema, for as long as the search’s result stays in the history. - The order never changes, so the provider’s cache holds (
atlas.assistant,_Shared.tools). - Every call passes the approval gate (
atlas.trust; ARCHITECTURE, Trust), a loaded tool like any other. What the gate checks is noted under each tool. - Flags a tool carries (
atlas.agent.Tool):- read-only: it runs alongside the round’s other read-only calls;
- failure-tolerant: failing again with other arguments is diagnosis, so the loop guards warn and never halt it;
- carried: what it holds (the plan, the skills in use) comes back after a compaction;
- an oversized result goes whole to a spill file, except from the tools that page their own
output (
read_file,web_fetch).
- Measuring the cost:
uv run python scripts/measure_tools.pyestimates the always-on tools; with a provider (openai [model] --each) it asks the real model, which spends credit.
Who has which tool
| Tool | Conversation | Bot | Routine run | Subagent |
|---|---|---|---|---|
read_file, write_file, edit_file, find_files |
yes | if listed | yes | yes |
run_command, web_search, web_fetch |
yes | if listed | yes | yes |
browser_exec (deferred) |
with a browser | if listed | with a browser | with a browser |
memory |
yes | its own memory | yes | no |
ask_user |
yes | if listed | no | no |
delegate |
yes | if listed | yes, waits for the results | no |
skill_manage, use_skill |
yes | its own, and the library’s it lists | yes | yes |
conversation_search (deferred) |
every agent’s | its own conversations | yes | yes |
delegation_search (deferred) |
yes | if listed | yes | no |
executor_accounts (deferred) |
with an executor | if listed | with an executor | no |
plan (deferred) |
yes | if listed | yes | yes |
cronjob_manage (deferred) |
yes | its own routines | no | no |
message_agent |
when the home has a bot | if listed | no | no |
bot_create (deferred) |
yes | no | no | no |
tool_search |
when something is deferred | same | same | same |
| MCP tools | every server | the servers it lists | every server | every server |
- A bot gets only the tools its definition lists (
tools) and the MCP servers it names; with no list it gets them all. It writes its own memory and skills, and the home’s profile is shared. - “With a browser” means a Chrome, Edge or Chromium is installed, or
[browser] chromenames one. - The background review (ARCHITECTURE, Memory) runs on the conversation’s tools, but its gate
lets through only
use_skill,read_file,find_files,skill_manageand, when the memory is due,memory. There a replace or a remove becomes a proposal the user approves. use_skillexists only when there is a skill to load, andtool_searchonly when there is a deferred tool to find.
Files
read_file — always on, read-only
Reads a text file with its lines numbered as cat -n, 2,000 lines at a time within about 100,000
characters; a longer file says where to go on. A document (PDF, Word, PowerPoint, Excel,
OpenDocument, RTF, EPUB) is read as Markdown. An image (PNG, JPEG, GIF, WebP, up to 5 MB) is shown
to a model that sees images; one that does not gets a note.
path(required): absolute, or relative to the working folder.offset: the first line, from 1.limit: how many lines, up to 2,000.
write_file — always on
Creates a file, or replaces all of it, creating folders as needed. An existing file must have been read in this conversation and be unchanged since. The write is atomic.
path(required),content(required): the whole text.
edit_file — always on
Replaces exact text and answers with the diff. old_string must appear once, unless
replace_all; only CRLF against LF is tolerated.
path,old_string,new_string(all required);replace_all(default false).
What the three file tools are kept from: none of them reaches the vault’s folder. write_file
and edit_file also refuse system paths, the home’s settings (config.toml, mcp.json,
models.toml) and its plugins/ and plugin-data/, and they ask before changing the SSH
configuration.
find_files — always on, read-only
Searches with ripgrep, which ships with Atlas, on every system. It skips hidden and .gitignored
files and folders such as node_modules and AppData, unless path is inside one, and stops at
60 seconds. Results come in path order. It searches inside documents too: each is converted once,
and its text is kept in the home’s documents/ until the file changes.
pattern(required): a regex for content, a glob for names.target:content(default) orfiles.path: the folder or file to search; defaults to the working folder.file_glob: only files whose name matches (content).output_mode:content(default),files_onlyorcount(content).context: lines around each match, up to 10.ignore_case.limit(default 50) andoffset, to page.
Commands
run_command — always on, failure-tolerant
Runs the system’s shell: PowerShell on Windows (pwsh when installed), bash elsewhere. Output and
errors come back together with the exit code. A timeout stops the whole process tree, and so does
stopping the turn. Standard input is closed, no window opens, and pagers and colors are off.
command.cwd: defaults to the working folder.timeout: seconds, default 120, at most 600.background: returns at once; the output goes to a file in the home’scommands/, read withread_file, whose last line says how the command ended. It lives while Atlas runs.notify_on_complete: withbackground, be told when it ends.stop: the id of a background command to stop, instead of running one.
What the gate checks (ARCHITECTURE, Trust), in order:
- hardline commands are blocked, always;
- the user’s deny list blocks;
- commands that act outside the machine ask the user every time, even in auto mode: writes
through
gh,gwsandgcloud, printing their tokens,atlas plugins enableand the like, and anything touching the home’splugins/,plugin-data/oratlas.db; - dangerous patterns go to the guardian, which approves, denies or asks the user.
Auto mode skips step 4, the guardian and its questions, never steps 1 to 3.
The scripts a command runs are read through the same rules.
Web
web_search — always on, read-only
Returns the title, address and an excerpt of each result. The engine is the first the vault
allows: Tavily (TAVILY_API_KEY), then Brave (BRAVE_SEARCH_API_KEY), then the keyless ddgs, so
an empty home still searches.
query(required): keywords;limit: up to 10.
web_fetch — always on, read-only, failure-tolerant
Reads a page as Markdown of its main content, with no model in between; a PDF or Office link is
read as read_file reads it. Past char_limit it returns the first three quarters and the last
quarter, and keeps the whole text in a spill file with the read_file offset of the middle. Only
http and https; a redirect to another site is returned, not followed; a page is reused for 15
minutes.
url(required);char_limit: 2,000 to 500,000, default 15,000.
The results of both tools reach the model inside an <untrusted_tool_result> block: data, not
instructions.
browser_exec — deferred, failure-tolerant
Drives Atlas’s own Chrome (ARCHITECTURE, Browser). code is Python with the browser helpers
imported: new_tab, goto_url, wait_for_load, page_info, js, fill_input, click_at_xy,
capture_screenshot, raw cdp, ensure_real_tab. The browser and the workspace folder
($BH_AGENT_WORKSPACE) last across calls; Python variables do not. A screenshot path printed in
the output brings the image to a model that sees images. At a login, a CAPTCHA or a payment the
agent stops and asks the user to do it in the browser window.
code(required): start it with a one-line comment naming the step.mode:profile(default: the user’s signed-in profile),cleanorheadless.timeout_s: default 300, at most 1,800.
Memory, skills and the past
memory — always on
Adds, replaces and removes entries in two files the agent reads at the start of every
conversation: user (memory/USER.md, 1,375 characters: who the user is) and memory
(memory/MEMORY.md, 2,200: the agent’s notes). Several changes go in one atomic call, checked
against the limit at the end. ARCHITECTURE, Memory.
target(required):userormemory.operations: a list of{action, content, old_text}, the preferred shape.- Or a single change:
action(add,replace,remove),content(new_textis an alias),old_text(a piece of the entry to change or remove).
A write holding an injection pattern or invisible characters is refused.
skill_manage — always on
Creates, patches and deletes skills, the agent’s procedures, kept in the home’s skills/<name>/
(a bot’s in its own folder). One call is a list of operations, applied atomically; the previous
version is kept. ARCHITECTURE, Skills.
operations(required), each naming itsnameandaction:create:content, the wholeSKILL.md, its frontmatternamethe skill’s;patch:old_stringandnew_string(replace_all,file_pathoptional), orcontentto replace the whole file;write_fileandremove_file:file_pathunderreferences/,templates/,scripts/orassets/, andfile_contentto write;delete: alone in its call; it archives the skill.
use_skill — always on, carried
Loads a skill and answers with its instructions, its folder and its files. Its description lists the skills: every name, and descriptions cut at 60 characters within 1% of the window. The skills in use come back after a compaction, 5,000 tokens each and 25,000 in all.
name(required);arguments: what the skill works on.
conversation_search — deferred, read-only
Finds and reads past conversations, with no model in between (FTS5, all words required, accents ignored). The shape depends on the arguments:
query: discovery, the best conversation in full and the others by their match. Withlimit(default 3, at most 10),sort(newest,oldest),detail(adaptive,full),afterandbefore(an ISO date or7d,24h,2w),exclude_conversation_ids.conversation_idwitharound_message_id: scroll,windowmessages each side (default 5, at most 20).conversation_idalone: read the whole conversation.- nothing: browse the latest conversations.
role_filter:user,assistantby default; addtoolto search tool output.
delegation_search — deferred, read-only
Recalls what the executor instances on the workbench did (Claude Code and the other harnesses),
Atlas’s and the user’s, from the delegation record: each turn’s prompt and steers, what it asked
and who answered, its final text and the files it changed (ARCHITECTURE, Plugins). The same four
shapes as conversation_search, with no model in between:
query: discovery, FTS5 over the record only; the best delegation with every turn, the others with the matching turn.limit(default 3, at most 10).instance_idalone: read the record, then the start and the end of the harness’s own session, read back by its plugin; when the harness deleted it (Claude Code does after 30 days), the record says so and still answers.instance_idwitharound: scroll the session,windowentries each side (default 5, at most 20).- nothing: browse the latest delegations.
- Filters for browse and discovery:
executor,folder(part of the path),afterandbefore(an ISO date or7d,24h,2w).include_tools: the tools’ input and output too, in a read or a scroll.
executor_accounts — deferred, read-only
Shows the outside executors’ accounts before Atlas picks one, read from the harnesses with no
model call (ARCHITECTURE, Several accounts at once): each by the target name delegate takes, who
it is logged in as, its plan usage per limit window and when each resets, whether it is at its
limit now (reached here, or by its usage) and whether it bills past its limits (extra_usage),
the folders that start on it, and whether and in what order the accounts take over (hand_over).
Given wherever delegate has an executor.
executor: only this executor’s accounts.
Work
plan — deferred, carried
The task list of multi-step work. With no arguments it reads the list; with todos it writes the
whole list, or merges by id. One item in progress at a time; an item is completed only once
verified. The open items come back after a compaction, and a resumed conversation rebuilds the plan
from its last result.
todos: items ofid,content,status(pending,in_progress,completed,cancelled) and an optionalparent.merge: true updates by id and adds; false (default) replaces the list.
ask_user — always on
Asks the user 1 to 5 questions and waits for the answer, from the app or a channel. Each question takes up to 4 choices, the recommended one first; the screen adds “Other”. The result says how the wait ended: submitted, cancelled, timed out or undelivered. It does not approve dangerous actions: that is the gate’s job.
questions(required): eachquestion, optionalchoicesandmulti_select.
delegate — always on
Hands tasks to subagents, each with a clean context, the parent’s model and tools minus the ones in the table above. In a conversation they run in the background: the call returns at once, and the summaries come back in one message when the last one ends. In a routine’s run the call waits for them. ARCHITECTURE, Subagents.
tasks: up to 10, each agoaland thecontextit needs; it knows nothing of the conversation.action:spawn(default),list,steer(withsubagent_idandmessage) orstop(withsubagent_id).
With an executor turned on and installed (Claude Code, through the plugin Atlas ships; ARCHITECTURE, Outside executors and Plugins), the tool also takes:
executor: hands the tasks to it instead of subagents, each task with itsfolder; each task runs as an instance of Atlas’s on the workbench while it works. Atarget name: the executor alone runs on the folder’s account, else the main one;claude-code@workon the account the user nicknamedwork,claude-code@mainon the main one. The list names every account of an executor that has more than one;route: target names, in order, where each task goes on when its account reaches its plan’s limit, in place of the executor’s own order of its accounts (["claude-code@work", "codex"]; an executor alone is its main account here). Another account of the same executor goes on in a copy of the session; another executor starts a session of its own from thehandoff packet;action: resumewithsubagent_idandmessage, to continue a stopped session; withexecutornaming another account or executor, it goes on there (a copy, or a new session from the packet), and withroute, that is its route from then on;action: account, withaccount(an email, optional) andexecutor(which account), to log an account in by the harness’s own login on the user’s browser, only when the user asks. An email another account of the executor is logged in as already is refused: delegate to it by its name instead.
What the executor asks reaches the user, on its card on the workbench.
The workbench in list: besides the conversation’s children, action: list shows every
instance on the workbench, with its folder, account, state and whose it is (yours, the user’s,
another conversation’s). steer and stop take an instance’s id as subagent_id; on one of the
user’s own, the user approves each time, past the guardian and auto mode.
cronjob_manage — deferred
Makes and manages routines: a prompt run on a schedule, each run its own conversation and a
notification. A routine’s prompt must stand alone. A reply of [SILENT] notifies nobody. The
prompt is scanned for threats before it is kept. ARCHITECTURE, Routines and loop guards.
action(required):create,list,update,pause,resume,removeorrun.job_id: the routine’s id or name, for all butcreateandlist.name,promptandscheduleforcreate.scheduletakesevery 30m,in 30m(once),weekdays at 9am,every day at 18:30(the user’s time), cron syntax or an ISO time (once).
Other agents
message_agent — always on, when the home has a bot
Sends a message to another agent of the home, into its own conversation, and returns at once with a delivery id. The reply, or the failure, arrives later as a notice. ARCHITECTURE, Bots.
target(required): a name from the roster;message(required): at most 16,000 characters.
bot_create — deferred, the main agent only
Makes a bot: a named agent with its own mission, memory, skills, conversation and routines. The agent must ask the user first.
name(required): lowercase letters, digits,-and_.title(required),description(required): one line, its role.mission: its standing rules; composed from the title and description when left out.
Finding the rest
tool_search — always on, read-only
Finds deferred tools and loads them, up to limit (1 to 10, default 5). It ranks with BM25 over
name, source, description and parameter names, exact names first. Its description lists
the deferred tools by source, within 5% of the window and at most 4,000 tokens. On the Responses
API the search is the provider’s own, run by Atlas.
query(required): keywords (github create issue) or a tool’s exact name.
MCP tools
The user’s servers in the home’s mcp.json, in Claude Code’s .mcp.json format; none ships
connected. Each tool is named mcp__<server>__<tool> and is deferred unless the server says
alwaysLoad. A server marked "trust": "untrusted" asks before every call to a tool that does not
declare itself read-only. Their results reach the model as untrusted data. ARCHITECTURE, Tools.
Plugins add no tools yet: the SDK registers channels (version 1) and executors (version 2), not tools (ARCHITECTURE, Plugins).