Agent Engineering
Module 02 · Concepts/Lesson 2.7/3 min

Tools, permissions, and the environment

The agent perceives your machine only through tool results. Designing that surface is design work.

A tool is a function the harness exposes for the model to call: read a file, write a file, search, run a shell command. A tool call is structured output naming a tool and its arguments. A tool result is what the harness sends back after executing it.

This is the agent's entire sensory apparatus. It does not see your screen, your running app, or your intent. It sees text that came back from tools — which means the quality of your tool results is the quality of the agent's perception.

Tool results are context, and they are big

Everything a tool returns lands permanently in the window. A few consequences worth acting on:

  • A test runner in verbose mode can cost more context than the code it tests. Configure quiet output and fail-fast.
  • Long build logs, dependency-install output, and full directory trees are almost pure noise. Pipe them through tail or grep.
  • A tool that returns "OK" costs nothing. A tool that returns a 2000-line diff costs the rest of your session.
tuning a check command for agents
# noisy: prints every passing test, full stack traces, progress bars
npm test

# agent-friendly: quiet, stops at first failure, no colour codes
npm test -- --run --reporter=dot --bail=1 2>&1 | tail -40

MCP and extra tools

MCP is a protocol for plugging external tool servers into a harness — a database client, an issue tracker, a documentation server. It genuinely expands what an agent can do.

It also has a cost people underestimate: every connected server's tool definitions are injected into the system prompt of every session. Five chatty servers can consume tens of thousands of tokens before you have typed anything, permanently, in every session you run. Connect tools you actually use for the work at hand; disconnect the rest.

Permissions and sandboxes

A permission request is the harness asking you before a tool call it is not pre-approved to make. The permission mode decides which calls need one. A sandbox — a container, VM, or restricted shell — limits what a call can reach even when approved.

The useful framing from Lesson 1.3 applies here: these are two separate dials. Approving everything inside a container with no secrets and no production access is reasonable. Approving everything on your laptop, logged into everything, is not. Raise autonomy only in proportion to how contained the environment is.

Watch out

Approval fatigue is real and it is a security problem. If your permission mode prompts you forty times an hour, you will start approving without reading, which is strictly worse than auto-approving thoughtfully. Pre-approve the safe, frequent things — reads, your check command, git status — so the prompts that remain are rare enough to actually read.

Try it

Audit your setup: list every MCP server connected and every pre-approved command. For each, ask whether you used it this week. Disconnect what you did not. Then measure a fresh session’s starting token count before and after.

Takeaways

  • Tool results are the agent’s only perception, and they consume context permanently.
  • Quiet, fail-fast commands are worth real effort to configure.
  • Every connected MCP server taxes every session; connect deliberately.
  • Pre-approve frequent safe actions so the remaining prompts get read.
Why can adding a useful MCP server make an agent worse at an unrelated task?

Because its tool definitions sit in the system prompt of every session, spending context and attention budget on capabilities irrelevant to the current job. It is the signal-to-noise problem from Lesson 2.3, paid up front in every session rather than accumulated during one.

A course by Pieter Zandbergen