An agent decides what to do, but something has to actually do it. A model on its own can't open a file, run a command, or remember what happened three steps ago. The harness is the program that wraps the model and turns its decisions into real actions.
Brain vs. body
Think of the model as a brain in a jar: brilliant at deciding, but with no hands, eyes, or memory of its own. Everything it produces is text. It can write "run the tests", even in the exact format of a tool call, but writing it doesn't run anything. And every call starts from nothing: the model knows only what's in the text it was just handed.
The harness is the body. It feeds the model what it needs to see, watches its output for actions it wants to take, carries them out, and reports back. Same brain, different body, and you get very different behavior.
How it works
On each turn the harness does the same few jobs:
- Build the context. It assembles the context window: your goal, the conversation so far, relevant files, and the list of tools the model may use.
- Call the model. The model replies with plain text for you, or with a request to use a tool.
- Check the request. Before anything runs, the harness checks the request against its permissions: allowed, ask first, or denied.
- Run it and feed back the result. It carries out the action, captures the output, adds it to the context, and starts the next turn.
Step through one task below: getting a failing test suite green. When the model asks to delete a folder, predict what the harness does before you look. Then flip to Model alone to replay the same task with no harness at all.
In our stack — Claude Code is the harness. It manages the context window, sends each turn to Anthropic's Claude model, runs the tools Claude asks for — editing files, running tests, calling MCP servers — and asks you before anything risky.
A chat model with no tools tells you, "I ran the test suite and everything passes." What should you conclude?
What the harness is responsible for
Pull the jobs apart and a harness is a handful of distinct responsibilities:
- Context. What goes into each call, and what gets summarized or dropped when the window fills up. Good context engineering lives here.
- Tools. Which actions exist at all, and how each one is described to the model. A harness for code review might offer only read tools; one for building features offers editing and running too.
- Permissions. For each action: allow it, ask first, or deny it. Often there's also a sandbox, so even an allowed command can only touch the project folder.
- Loop control. How many turns or how much budget a task gets, and when to stop and hand back to you.
- Execution and records. Actually running each action, capturing its output, and keeping a log of everything that happened, so a person can review it later.
Why the harness matters
The harness decides what the agent can see and what it's allowed to touch, so it's where safety lives. Permission prompts, sandboxing, and which tools exist at all are the harness's job, not the model's. That's why the same model can feel like a careful pair-programmer in one harness and a free-roaming automaton in another.
It also explains a point people often miss: an instruction in the prompt is a request, and a rule in the harness is a guarantee. Write "never delete files" in the prompt and the model will usually comply, but it might misread a situation, or be talked out of it by text it reads along the way. Make deleting an ask-first action in the harness and it can't happen without you, whatever the model decides.
Approving everything defeats the point. If every action asks permission, people start clicking Allow without reading, and the one prompt that mattered gets waved through. Tune the rules instead: allow safe, reversible actions like reading files and running tests; ask first for anything destructive or outward-facing, like deleting, pushing or sending; deny what should never happen. Watch out for broad allow rules too. "Allow any shell command" quietly allows deletes as well.
You want to be sure an agent can never push to your main branch. Where should that rule live?