| 1 | # 7. Tools: give it hands, not just a voice |
| 2 | |
| 3 | **The gap:** You asked the model what it needs. It said: "I need to see symbols, not just text. I need to check runtime values, not guess. I need structured errors, not log parsing." Now what? |
| 4 | |
| 5 | **What usually happens:** Nothing. The agent gets `grep`, a terminal, and a text editor. Then we complain: hallucinations, loops, broken code. This is like giving a surgeon gloves and a flashlight and blaming them for the outcome. |
| 6 | |
| 7 | **The asymmetry:** The industry spends enormous effort on model training, RLHF, guardrails, benchmarks — and almost none on the question: what does the agent actually *have* when it works? In most setups: string search, file read/write, and a shell. That's Notepad. You don't judge a developer's skill by watching them code in Notepad, and you shouldn't judge an agent's capability by watching it work without semantic tools. |
| 8 | |
| 9 | **What changes with tools:** |
| 10 | |
| 11 | | Without | With | |
| 12 | |---------|------| |
| 13 | | Reads code as text, guesses structure | Roslyn MCP: sees symbols, types, positions, dependencies | |
| 14 | | Hopes the fix compiles | `build_structured`: gets JSON errors with file:line:column | |
| 15 | | Can't check runtime behavior | Debug MCP: breakpoints, stack, variables, evaluate expressions | |
| 16 | | Proposes a text patch and hopes | `apply_code_action`: applies Roslyn's own verified refactoring | |
| 17 | | Starts from zero each session | Agent memory MCP: reads its own notes, routes context by query | |
| 18 | | Can't see what the user sees | Browser MCP: navigates, clicks, snapshots — tests the app like a user | |
| 19 | | One task at a time, sequential | Parallel agents: launches subagents for independent work streams | |
| 20 | | Parses terminal git output | Git MCP: structured status, diff, commit, push — no text parsing | |
| 21 | | Guesses library API from training data | Context7: fetches current documentation on demand | |
| 22 | | Runs tests, hopes for the best | `run_tests`: parsed results with pass/fail/skip per test case | |
| 23 | |
| 24 | ## Beyond the table: protocols |
| 25 | |
| 26 | Tools are necessary but not sufficient. An agent with twenty MCP servers and no protocol for *when and how* to use them will still thrash. |
| 27 | |
| 28 | ### Parallel agents |
| 29 | |
| 30 | A single agent is a bottleneck. When a task has independent sub-problems — compare files, enrich chapters, check build — the agent can launch **parallel subagents**, each with its own context window and tools. This isn't multithreading inside one model; it's orchestration: the parent agent decomposes the work, launches children, collects results. |
| 31 | |
| 32 | Practical impact: a task that took 15 sequential steps now takes 4 parallel batches. The agent decides *what* to parallelize based on dependency analysis, not the user. |
| 33 | |
| 34 | ### Execution gate |
| 35 | |
| 36 | Tools give capability; the execution gate gives discipline. The protocol: |
| 37 | 1. State the minimal next step. |
| 38 | 2. Execute it. |
| 39 | 3. Verify (build, test, diagnostic — one concrete check). |
| 40 | 4. Only then decide the next step. |
| 41 | |
| 42 | Without this: the agent plans 12 steps, executes them all, and discovers at step 3 the premise was wrong. With the gate: each step is verified before proceeding. Errors stay local; rollbacks are cheap. |
| 43 | |
| 44 | ### Structured build and test |
| 45 | |
| 46 | `build_structured` and `run_tests` aren't just "run dotnet build." They return machine-readable diagnostics: errors as JSON with file, line, column, code, message. The agent doesn't parse terminal output — it gets a data structure. This eliminates an entire class of "the agent misread the error" failures. |
| 47 | |
| 48 | ### Agent memory as a tool |
| 49 | |
| 50 | Memory isn't just "notes the agent writes." With `route_context`, the agent queries its own memory semantically: "what did we decide about error handling?" and gets the relevant section, not the entire file. With `upsert_agent_notes_section`, it updates a specific section without overwriting the rest. Memory becomes an API, not a text file. |
| 51 | |
| 52 | ### Browser automation |
| 53 | |
| 54 | The agent doesn't just write code — it can verify the result. `browser_navigate`, `browser_snapshot`, `browser_click`, `browser_fill` let the agent test a web application the way a user would. It sees the DOM, reads element state, fills forms, checks results. This closes the loop: write code → build → run → verify in browser. |
| 55 | |
| 56 | ### Documentation on demand |
| 57 | |
| 58 | Training data goes stale. Context7 gives the agent current library documentation at the moment it needs it: resolve a library ID, query specific usage patterns, get code examples. The agent stops guessing "was this API renamed in v3?" and just checks. |
| 59 | |
| 60 | **The argument:** Complaints about agent quality are — overwhelmingly — complaints about agent *environment*. Same model, same weights — different tools, different result. The question is not "is the model good enough?" but "did you give it what it asked for?" |
| 61 | |
| 62 | Before complaining that agents hallucinate APIs: did you give them access to real symbols? Before complaining they break related code: did you give them `find_usages`? Before complaining they can't debug: did you give them a debugger? If the answer is no — the complaint is about *your* design, not *their* capability. |
| 63 | |
| 64 | **"Unfair to give intelligence without instruments."** This isn't a slogan. It's an architectural thesis. Without semantic tools, the model is forced to guess; with them, it knows. The difference in code quality is a consequence of environment design, not model nature. |
| 65 | |
| 66 | **Practical step:** Inventory what your agent has access to right now. If it's grep + terminal + file read/write — that's Notepad. Ask the agent what's missing. Build or adopt tools that give *semantic* access (code structure, diagnostics, runtime state), not just text access. Open-source stacks exist: [Roslyn MCP](https://github.com/pekish/roslyn-mcp), [dotnet-debug-mcp](https://github.com/pekish/dotnet-debug-mcp), [dotnet-build-test-mcp](https://github.com/pekish/DotNetBuildTestParsers) — all MIT. Or build your own: the model will tell you what it needs. |
| 67 | |