Tools
This guide is for Opair users. If you want to write or maintain a tool definition, see the tools reference instead.
- What are tools?
- Where tools live
- Which tools you get
- Approvals
- Adding your own
- Customising shipped tools
What are tools?
Tools are everything the agent can actually do:
read files, edit files, run go test, call MCP servers and so on.
There is no tool that grants shell access
and no way for the agent to run an arbitrary executable.
Each tool is scoped to one restricted job.
Most tools are just JSON files on disk.
If you can write a bit of JSON,
you can give the agent a new tool.
A handful are implemented in Go inside Opair itself,
notably askQuestion
and the sub-agent entry points like plan and reviewDiff.
Where tools live
Each tool is one JSON file in your Opair config directory:
- MacOS:
~/Library/Application Support/opair/tools/ - Linux:
$XDG_CONFIG_HOME/opair/tools/
The location can be overridden
with OPAIR_TOOLS_DIR.
Edits to tool files take effect while Opair is open. New tool files need a restart before they can be called.
Which tools you get
Opair ships with a set of tools
covering common file operations, git and GitHub,
and popular language toolchains.
Tools that run external commands
are only offered when their binary exists in $PATH.
Opair checks at startup.
If Go isn't installed,
the agent never sees goTest.
Install the toolchain, then start a new session.
There's no availability configuration to maintain: if the binary is there, the tool is offered.
Which loops can call which tools is a separate matter, covered in Adding your own.
Approvals
Every tool declares what it reads and writes using a small set of categories (project files, gitignored files, build outputs and so on). The full list is in the reference.
Reads of project files and git history are auto-approved. Reads of dotfiles, gitignored files and paths outside the project prompt for approval.
Build outputs are auto-approved too. Writes inside the project prompt, with an option to auto-approve for the remainder of the session. Dotfiles and gitignored paths can't be session-approved, and neither can anything that mutates git state.
Tools that can execute third-party code,
like npm and npx,
always prompt,
whatever their write category.
MCP tools always prompt as well, unless a loop grants the server. See the MCP guide.
The defaults can be overridden per loop
in config.json.
See the configuration doc.
Adding your own
Add a JSON file to your tools directory
and it shows up alongside the shipped tools.
For example, markdownlint.json:
{
"internal": false,
"schema": {
"function": {
"description": "Run `markdownlint` from the project root to lint markdown files. All markdownlint args are supported.",
"name": "markdownlint",
"parameters": {
"properties": {
"args": {
"description": "Arguments for markdownlint.",
"items": { "type": "string" },
"type": "array"
}
},
"required": [],
"type": "object"
},
"strict": true
},
"type": "function"
},
"writes": "none",
"handler": {
"type": "exec",
"bin": "markdownlint"
}
}
The file name is the snake_case form
of the tool's name:
markdownlint lives in markdownlint.json.
Tools are also filtered per loop
by each loop's toolWhitelist,
so add the tool's name to the whitelists
of the loops that should use it
(e.g. driver in loops/driver.json).
Then restart Opair
and the tool is available to the agent.
Since writes is "none",
the agent can run it without approval.
A tool that writes anything
needs an honest write category
so that approvals work correctly.
A file that fails validation stops Opair starting. That's deliberate: a typo shouldn't silently drop a tool.
The reference documents every field.
Customising shipped tools
Upgrades overwrite the shipped tools with the canonical set from the release. If you've edited shipped tools, your changes will be lost.
To keep your own set,
copy the tools directory somewhere else,
edit freely
and point OPAIR_TOOLS_DIR at it.