The coding toolset

The five tools a coding agent can't live without.

A harness with no tools is just a chatbot: it can think, but it cannot touch anything. Tools are the hands. For a coding agent, five of them do almost all of the work. But first, a more basic question.


First principles

What is a tool, actually? A schema.

Not the code that runs. To the model, a tool is just a schema: a name, a description, and a set of typed parameters. That is the entire surface it sees, and it is the unit every tool on this page is made of.

A tool is a schema. Click a line to see its job.

// all the model sees of the tool

read {

}

name

The handle. The only word the model uses to call the tool, so it should be short, unambiguous, and verb-like.

description

This is prompt text. The model decides whether and when to use the tool from this one sentence, so it has to be honest and precise.

parameters

Typed inputs, validated before the tool runs. The types tell the model what shape of argument to send, and let the harness reject a bad call early.

That is the whole tool, as far as the model is concerned. The code that actually reads the file is invisible to it. The schema is the contract.

The toolkit

Five schemas that do the work

With the shape clear, the five core tools are just five schemas, and the ones a coding agent leans on hardest. One of them, search, is the discovery step: it finds what to read before read can see it. Pick any tool to see its schema, an example call, and what comes back.

Read-only · safe

schema

read { path: string }

an example call

read { path: "src/app.ts" }

what comes back

"export function app() { ... }"

Mutating · needs a permission gate

schema

write { path: string, content: string }

an example call

write { path: "notes.md", content: "# Notes" }

what comes back

wrote notes.md (7 bytes)

Mutating · needs a permission gate

schema

edit { path: string, old: string, new: string }

an example call

edit { path: "app.ts", old: "v1", new: "v2" }

what comes back

applied 1 edit to app.ts

Mutating · needs a permission gate

schema

bash { command: string }

an example call

bash { command: "npm test" }

what comes back

Tests: 12 passed, 0 failed

The line that matters

Two kinds of tool: looking and changing

Notice the split in the explorer. read and search only look. They observe the codebase and change nothing, so they are harmless by default and rarely need a gate. Rarely, not never: reading a secrets file or anything outside the workspace is how data leaks, so good harnesses gate those reads too. write, edit, and bash change the world, and those are the ones that can do real damage.

That line is the first thing a harness cares about, because it decides what needs a permission gate. A coding agent can be trusted to read and search the project on its own all day. The moment it wants to write, edit, or run a shell command is where a human or a policy gets a say. It is the same boundary the execution environment draws, seen from the tools' side.

The escape hatch

Why bash does not make the others redundant

Here is the strange part. bash can already do everything the other four can. cat reads a file, a redirect writes one, sed edits in place, grep searches. So why keep four dedicated tools when one shell tool covers them all?

Safety, structure, and reliability. A call like edit(path, old, new) is narrow: it does exactly one well-defined thing, its arguments can be checked before it runs, and it is easy to gate behind a permission. Raw shell is the opposite: unconstrained power, where a single wrong command can do real damage.

So the five are not redundant. read, search, write, and edit are the narrow, well-lit paths the agent takes by default. bash is the escape hatch it reaches for when nothing narrower will do.

structured · narrow · predictable general · powerful · broad
  • read
  • search
  • write
  • edit
  • bash
bash sits at the powerful end: it can already do everything the other four can. The narrow tools exist because a typed, single-purpose action is safer to run, easier to validate, and easier for the model to use without making a mess.

Remove these tools and the coding agent collapses back into a chatbot. Swap them for search and fetch and it becomes a research agent. The tools are not the harness and not the model: they are the hands you bolt on to make it a coding agent in the first place.

Next: the context window Where the gates go: oversight See the primitives underneath Back to the overview