Pi and the Minimal Agent Harness: Can Four Tools Be Enough?
Your agent has thirty tools, four MCP servers, and a plan-mode toggle. It still fumbles a routine refactor, and when it does, you cannot tell whether the…

Key topics
Your agent has thirty tools, four MCP servers, and a plan-mode toggle. It still fumbles a routine refactor, and when it does, you cannot tell whether the model reasoned badly, picked the wrong tool, or got buried under its own definitions. The tool surface itself has become the noise.
That is the problem a minimal harness like Pi is built to answer. Pi gives the model four tools — read, write, edit, bash — and pushes everything else out to skills, prompt templates, extensions, and packages. The interesting question is not "how few tools can I ship." It is: which capabilities must be tools, and which should be composed at runtime from a general-purpose one?
What the Four Tools Actually Are
Before arguing about the surface, pin down what it is. In Pi, the model's entire native action vocabulary is four calls:
| Tool | Job |
|---|---|
read | Pull file contents into context |
write | Create or overwrite a file |
edit | Apply a targeted change to an existing file |
bash | Execute a command in the environment |
That is it. Subagents, MCP, plan mode, todos, permission popups, background bash — all deliberately absent. When you want them, you supply them through skills, prompt templates, extensions, or installed packages. A community package, for example, bundles a subagent extension that adds single, parallel, and chain delegation modes on top of the four-tool core, precisely because Pi ships no built-in subagents.
Here is the distinction that keeps the rest of this article honest: a minimal tool surface is not a minimal harness. Pi still owns the loop, context assembly, session state, compaction, and provider auth. The tool surface is what the model can call. The harness layer is what the runtime does around those calls — when it compacts history, how it orders the cached prefix, which provider it routes to. You can shrink the first and still carry a heavy second. Confusing the two is how people conclude that "minimal" means "toy."
Knowledge check
Check your understanding
Answer this question before you continue.
The Design Bet: General Tools Beat Enumerated Tools
The bet behind four tools is that a general-purpose action space outperforms an enumerated one.
bash plus a text editor is exactly that: a general-purpose space. The model does not wait for you to register a tool. It writes the code that builds the tool it needs, runs it, and reads the result. Need to parse a log format nobody anticipated? Write a five-line script. Need to diff two directory trees? bash already knows how.
This is not a new idea dressed up as a philosophy. In late 2024, Claude 3.5 Sonnet reached 49% on SWE-bench Verified — then state of the art — with only a bash tool and a text editor tool for viewing, creating, and editing files. Claude Code is grounded in that same pair. The general tools came first, and the specialized capabilities were later composed from them: Agent Skills, programmatic tool calling, and memory tooling are all built on top of bash and the editor rather than shipped as separate primitives.
The mechanism is worth stating plainly. A bash tool gives the model a computer and lets it figure out the rest. A registered tool gives the model one pre-approved move. The first scales with the model's reasoning; the second scales with your foresight.
The tradeoff is real. Generality shifts work from the harness author to the model's runtime reasoning. That is cheaper to build — you write fewer tool definitions, fewer schemas, fewer handlers — but less predictable to operate. A registered tool has a contract. A bash command has a string. You are trading determinism for reach.
Knowledge check
Check your understanding
Answer this question before you continue.
What Four Tools Cost You
Every omission is an engineering task, not a philosophical stance. Budget for it.
No built-in subagents. Delegation has to come from somewhere: tmux for parallel shells, an extension, or an installed package. If your tasks need clean context windows per subtask, you are building that plumbing yourself.
No MCP. Tool-server integration becomes a skill, a CLI with a README the model can read, or an extension. Protocol-based tool discovery is one option among several, not a default you inherit.
No permission popups and no plan mode. Safety boundaries and task definition become the operator's responsibility. There is no modal that blocks the loop until a human confirms a hard-to-reverse action. You either containerize, write a confirmation extension, or accept the risk.
No built-in todos or background bash. The memory schema is yours to design. Observability is yours to instrument. If you want a TODO.md that survives compaction, you write the convention that maintains it.
The pattern: Pi hands you primitives and expects you to own the scaffolding. That is the deal. If you wanted the scaffolding pre-assembled, you wanted a different product.
Debuggability: The Strongest Argument for a Small Surface
Here is where minimalism pays for itself.
A four-tool trace has a small, fixed vocabulary of action shapes. When a run fails, the failure is attributable to the model's reasoning or to the environment. It is rarely a tool-selection mistake, because there are only four tools to select from. Compare that to a thirty-tool harness, where "the agent chose the wrong tool" is a first-class failure mode and often the actual cause.
There is a second effect, subtler and more expensive. Every tool definition sits in the cached prefix. Adding or removing a tool invalidates that cache and changes the model's decision space in the same stroke. A tool is not free just because it is unused — it occupies context, it shifts the prefix, and it widens the space the model reasons over. This is why tool count is a context-engineering decision, not a feature-list decision.
The counterpoint matters too. Structured tool arguments are loggable, traceable, and replayable. A bash command string is one shape for every action — cheap to log, weak to gate. You get a clean trace and a blunt interception point. That asymmetry is the whole tension of the minimal design.
A concrete drill: take a task your agent currently fails. Run it twice — once with your full tool set, once with four tools. Compare where the traces diverge. If the four-tool run fails later, or fails more legibly, the extra tools were noise. If it fails earlier because it could not reach a capability, you have found a promotion candidate.
Where Minimalism Breaks Down
Four tools stop paying when an action needs something a bash string cannot provide.
The clearest case is a security boundary. A raw bash command gives the harness nothing action-specific to intercept. If you need to gate a hard-to-reverse action — an external API call, a destructive write — a dedicated tool gives you a typed hook with arguments you can inspect before execution. Reversibility is a good criterion here: hard-to-reverse actions are natural candidates for promotion.
The second case is user-facing surface. Actions that must be presented to a person — confirmations, choices, blocking questions — want a dedicated tool that can render as a modal and halt the loop until the human responds. You cannot cleanly render a bash string as a decision.
The third case is capability, and the evidence is directional rather than decisive. A controlled comparison of a minimal research agent (4 tools, a short prompt, standard library only, 20 max turns) against a sophisticated one (6 tools, a longer prompt with reasoning patterns, richer libraries, 40 max turns) showed a large gap on GAIA and FACTS: roughly 19.5% versus 43.7% on GAIA, and 54.7% versus 64.7% on FACTS. Read that carefully. Tool count is not the only variable — prompt structure, available libraries, and turn budget all moved with it. And it measures a research agent on benchmark tasks, not a coding harness on a repository. Treat it as evidence that capability is multi-dimensional, not as a verdict on Pi.
The failure boundary is not "too few tools." It is "an action that needs a boundary, an audit hook, or a human surface, expressed as a string the harness cannot see into."
Knowledge check
Check your understanding
Answer this question before you continue.
The Decision Rule: When Four Tools Are Enough
Start minimal when three conditions hold: the task is code-shaped, the environment is a real filesystem and shell, and the operator can inspect the trace. Under those conditions, bash and an editor cover the action space, and the small surface buys you attribution and cache stability.
Add a dedicated tool when any of these is true:
- The action needs a security boundary the harness must enforce.
- The action needs a typed argument the harness must audit.
- The action must be presented to a user.
- The model repeatedly composes the same bash incantation.
That last one is the signal I trust most. Repetition is the model telling you a capability has earned promotion. When you see the same three-line script in every trace, stop making the model rediscover it. Promote it to a tool with a schema.
Then re-evaluate. A tool that was necessary for one model generation may be redundant for the next. Models get better at composing general tools, and a tool sitting in the cached prefix is not free. Promotions are not permanent.
And do not adopt a minimal harness to save effort. You will not. Adopt it to own the scaffolding and keep the failure surface small.
Knowledge check
Check your understanding
Answer this question before you continue.
Build the Smallest Version First
Let reality answer the design question.
Implement the loop with four tools and no extensions. Run one real task from your own backlog — not a demo, something with a genuine failure mode. Log every tool call with its arguments and the resulting observation. That log is your evaluation harness; you will read it more than any dashboard.
Then add exactly one capability — a subagent, a permission gate, or a skill — and measure whether the trace got clearer or muddier. Keep the comparison honest: same model, same task, same turn budget, only the tool surface changes. If the new capability makes failures harder to attribute, it did not earn its place yet.
Four tools are enough when the task is code-shaped, the environment is inspectable, and you are willing to own the scaffolding. They are not enough when an action needs a security boundary, a typed audit hook, or a user-facing surface. Build the four-tool loop, run one real task, and let the trace tell you which capability has earned promotion to a tool.
Knowledge check
Final check
Finish the article by checking the ideas you just learned.
References
- The Anatomy of an Agent Harness
- Agent Harness Design: 3 Patterns for Harnessing Claude's Intelligence | Claude by Anthropic
- How to Build a Custom Agent Harness
- VeRO: A Harness for Agents to Optimize Agents
- GitHub - baryonlabs/pi-agent-harness: pi-agent-harness — a pi coding-agent plugin/package that turns one domain sentence into a multi-agent team: specialist agents (.pi/agents), their skills (.pi/skills), and orchestration prompts (.pi/prompts). A team-architecture factory with 6 patterns and a bundled subagent (single/parallel/chain) delegation tool. · GitHub
Research updated Sep 11, 2026


