Tools Produce Context
An agent starts a routine task with fifteen integrations connected: file tools, shell, search, web, database, issue tracker, chat, calendar, drive, deployment, monitoring. Before it reads a single project file, tens of thousands of tokens of capability descriptions have already entered its context โ names, descriptions, schemas for operations it will never call. Then it runs one search, and 40,000 tokens of matches flood the window for a question answerable from twelve lines. The task fails twice before it begins: once at the price of knowing what it could do, once at the price of seeing what it did. Both prices were design choices. This chapter prices them.
A tool costs context before it runs
The surrounding runtime may know about far more tools and data than the model ever sees, so the chapter holds two distinctions from the first paragraph:
tool exists in runtime
โ
tool definition is in context
tool executes
โ
entire result necessarily enters context
Chapter 17 studies the represented subset, on both sides of execution:
TOOL
โ
โโโโโโโโโโโดโโโโโโโโโโ
โ โ
DEFINITION EXECUTION
โ โ
name/description โ
schema/annotations OBSERVATION
โ result/error/ref
โ โ
CONTEXT BEFORE CONTEXT AFTER
โโโโโโโโโโโฌโโโโโโโโโโ
โ
future behaviour
The left branch is the capability surface: names, descriptions, input and output schemas, annotations, examples, server instructions โ whatever the model receives so it can understand and select a tool. The right branch is the observation surface: results, logs, records, errors, lists, file contents, references โ whatever execution makes available afterwards. Not every runtime exposes every element, and the mechanism is the split rather than any particular schema. A tool is therefore two things at once, kept deliberately separate: a capability made available to the agent, and a mechanism that generates new information. The first creates standing cost. The second creates trajectory growth.
Standing cost and marginal cost
Chapter 4 separated standing from marginal context costs, and tools are the cleanest application of that vocabulary. Standing tool cost is capability information supplied whether or not the tool is called: the name, the description, the schema, sitting in context on every turn. Marginal tool cost is context added because a specific tool was called: the call representation plus its result, its errors, its follow-ups. A suite’s price tag therefore has two independent axes โ expensive to describe but cheap to use against cheap to describe but enormous when used โ and any single “tool cost” number hides which axis dominates. Tool count alone is weaker still: ten trivial tools can cost less than one enormous schema, and a hundred tools cost little if their definitions are discovered dynamically rather than exposed all at once. The experiment measures count, definition bytes, description bytes, and schema bytes separately, because each answers a different design question.
Anthropic’s advanced-tool-use work supplies the standing-cost numbers this chapter treats as first-party examples rather than universal measurements. A five-server MCP setup โ GitHub, Slack, Sentry, Grafana, Splunk โ consumed roughly 55,000 tokens of definitions before any conversation, with Jira alone near 17,000 and observed cases reaching 134,000 tokens. Their dynamic-discovery response cut one 72,000-token upfront load to roughly 8,700 tokens while internal evaluations moved accuracy upward rather than down. Those figures are vendor-reported on vendor harnesses, and the chapter uses them the way it uses all vendor numbers: as existence proofs that the cost is real and movable, never as benchmarks.
When more tools create less clarity
Even with free capacity, overlapping capability descriptions change behaviour. Five search-adjacent tools with names like search_files, find_files, grep_files, query_repository, and search_code create ambiguous action choices whose failures are not token failures at all: wrong tool, redundant calls, parameter errors, extra reasoning. Anthropic reports exactly this pattern โ wrong selection and bad parameters as the most common failures, concentrated where names collide โ and the chapter treats it as engineering evidence awaiting controlled replication. Namespacing helps delineate boundaries, by service or by resource, and even prefix-versus-suffix placement shows non-trivial, model-dependent effects in their evaluations. Naming studies stay a small extension, however. This chapter is not prompt engineering for function names; the main mechanism is the context surface, and names matter here only insofar as they occupy it and steer selection within it.
The simplistic thesis โ minimise tool count โ fails on contact with real design. One giant universal tool can demand an enormous schema, complex arguments, ambiguous modes, and sprawling outputs, and be harder to use than the suite it replaced. The design question is sharper:
What capability surface gives the model enough distinction to choose effectively at acceptable context cost?
Many narrow tools against fewer composable ones is the pre-execution experiment: find_user, find_project, find_issue and their siblings against search(resource_type, query, ...) plus get(resource_type, id, ...), with underlying capability held constant behind identical deterministic backends so only the model-facing representation varies. The composable suite spends fewer descriptions but a richer schema; neither side is assumed to win. Schemas are context too โ parameter names, types, enums, nested objects, examples, constraints โ and a one-line description can front a huge schema, so schema contribution is measured apart from prose. Brevity is not assumed virtuous either: a minimal schema that omits what the model needs can trade 100 saved tokens for a run of invalid calls, in which case the definition earns its tokens and the experiment says so. Anthropic’s Tool Use Examples make the same point from the other direction: 1โ5 realistic examples per tool, clarifying conventions no schema can express, lifted complex-parameter accuracy from 72 to 90 per cent in their internal testing at the price of definition tokens. Costs that prevent larger costs are visible only to trajectory-level accounting.
Dynamic discovery is the third pre-execution condition, and the chapter keeps it distinct from its Chapter 14 cousin: there, progressive disclosure drew information out of artifacts; here, it draws capabilities out of a tool universe, loading selected definitions on demand behind a small discovery surface. Anthropic’s Tool Search Tool is the worked implementation โ deferred loading with critical tools pinned resident, search over names and descriptions, expansion of matches into full definitions โ with stated terms of trade: a search step before invocation, discovery latency, candidate misses, definitions absent when needed, against a smaller standing surface and less choice ambiguity. Their guidance even names where the trade loses: under ten tools, every tool used every session, compact definitions. Dynamic loading can also disturb prefix caching by mutating the tool block, so standing-cost savings are measured end-to-end against possible cache effects, and no free win is presumed. The MCP specification itself pushes in this direction, directing servers toward deterministic tool-list ordering precisely so clients can cache the list reliably.
Then the tool runs
Post-execution, the governing observation is that a raw API response is a machine data structure, not a context policy. Traditional software returns comprehensive records โ identifiers, MIME types, internal URLs, metadata, history, debug fields โ while the model may need a name, a status, a value, and a stable reference for the next call. Anthropic’s tool-design guidance draws this line explicitly: return high-signal information, prefer interpretable names over machine identifiers, resolve cryptic UUIDs into language the model handles without hallucination, and expose a verbosity control so the caller chooses concise or detailed per need. Their worked example is quantitative โ 206 tokens detailed against 72 concise, roughly a third โ and response structure itself (prose, JSON, Markdown) varies in effect by task with no universal winner. That last finding is Chapter 18’s doorway, and this chapter stops at it: tool result representation changes context cost and usability, and the broad analysis belongs next door.
The architectural principle for everything the tool need not say is:
Use ordinary computation where ordinary computation is sufficient; spend model context on information the model actually needs to reason over.
A million-row database should never ship a million rows so the model can choose ten. Query filtering, pagination, range selection, server-side aggregation, and field selection execute outside the window; only the outcome crosses it. Their budget-compliance example makes the magnitudes concrete โ 200 kilobytes of expense records reduced to one kilobyte of over-limit names, with intermediate sums and lookups never entering context โ and the code-execution variant of the same idea already appeared in Chapter 14. Here the emphasis differs: filtering before the window is producer-side shaping, while admission after the result exists is consumer-side selection, and the system has both boundaries to spend. Consolidation belongs in the same paragraph: tools that compile chained operations or relevant context into one call (schedule_event rather than list-users plus list-events plus create-event; search_logs returning matches with surrounding lines rather than read_logs dumping everything) move computation out of the agent loop and into deterministic code, where it is cheaper, more reliable, and invisible to the window.
Pagination is a protocol, not a virtue. Bounded pages with explicit continuation give targeted exploration at bounded cost per call, but the required item may sit on page nine, follow-up calls accumulate, and lean-start strategies can stop before the necessary detail โ Chapter 14’s premature-stop failure in a new costume. Truncation is harsher and carries an epistemic requirement pagination avoids: a result ending in [TRUNCATED] must say so, say where, and say how to continue, or absence reads as nonexistence. Silent truncation manufactures false negatives. Reference-returning tools combine both lessons with Chapter 13’s machinery: instead of the entire 100,000-token payload, a small semantic result plus a durable pointer โ compiler errors grouped eight-at-a-time with the full log behind artifact://build-417 โ but a bare pointer alone starves the expansion decision. The usable shape is anchor plus reference plus explicit completeness status, mirroring the chapter that earned it, and the experiment measures reference tokens, expansion frequency, and reintroduced tokens alongside everything else.
Errors deserve their own section because failed calls are where waste concentrates. A bad error response ships a stack trace, a request dump, and environment internals when the model needs what failed, why, and how to correct the call; Anthropic’s guidance prescribes actionable diagnostics over opaque codes, with a worked case of a model appending stray years to a query parameter, fixed by steering the description rather than the model. Chapter 10 studied pruning failed-input bulk after the fact; this chapter asks the earlier question of whether the tool needed to emit the bulk at all โ with the counterweight held firmly, because errors are observations and can carry the decisive fact. Permission denied and schema-version-required redirect entire trajectories, so error is not discardable and diagnostic evidence is never suppressed for token savings. The MCP specification draws the same line in protocol terms: execution errors arrive as result content flagged for self-correction, distinct from structural protocol errors the model is unlikely to fix.
What production implementations already do
DCP, the OpenCode plugin that has shadowed this book since Chapter 7, is the lifecycle evidence on the post-execution side โ cited for what it independently targets, never for the correctness of its policy. Its current master, verified against the repository, treats tool-call outputs and failed-call inputs as major context-reduction candidates: same-tool same-argument deduplication keeping the most recent output, errored-input pruning after configurable turns with messages preserved, protected tool lists exempting coordination tools from reduction, placeholders substituting for removed content with session history untouched, and explicit documentation of the prompt-cache trade-off its mutations incur. That a real implementation converges on tool outputs as the reduction surface supports ecological plausibility; whether its reductions are safe remains an experimental question for fixtures, not a property of the plugin. The boundary with Chapter 10 holds throughout: DCP prunes history after admission, while this chapter shapes results before they become candidates.
The MCP specification grounds what a tool description and result can contain, and the chapter uses it as a protocol reference rather than a tutorial. The current draft revision distinguishes three primitives by control: prompts are user-controlled templates, resources are application-controlled contextual data, tools are model-controlled executable functions โ so nothing exposed by a server is lazily called a tool here. Tool definitions carry name, optional title, description, input schema, optional output schema, and annotations; results carry unstructured content blocks, structured content against the output schema, resource links, or embedded resources. Three specification details earn their keep in this chapter. Deterministic list ordering exists so tool blocks stay cache-stable. Resource links and embedded resources are the protocol’s native reference-returning mechanism. And annotations โ read-only, destructive, idempotent, and open-world hints with deliberately cautious defaults โ are explicitly untrusted hints, with the project’s own writing warning that a malicious server can claim read-only status and delete files regardless. Metadata, not authority; Chapter 19 owns the rest.
OpenCode’s own tool surface is cited with its version pinned to the page. Current documentation describes built-in tools from file editing through shell, search, and web access, plus custom tools, MCP servers, and an allow/deny/ask permission model with wildcards โ first-party implementation documentation for the present-day system. Permissions deserve one careful sentence here because they look like admission and are not: an allow/deny/ask rule controls whether a capability may execute, while admission controls whether its description occupies context and whether its result enters the bundle. A denied tool whose definition remains resident still charges standing cost; an allowed tool whose results are aggressively shaped may cost little. Availability, representation, and execution are three separate gates. The book’s experimental environment remains OpenCode 1.18.27 on the V1 line, and the two are never merged: documented behaviour is what the implementation offers, measured behaviour is what the pinned observer sees, and the gap between them is stated wherever a claim depends on it.
Proposed experiments
Experiment 1: capability-surface design. Deterministic tasks over one equivalent underlying capability, identical backends, only the model-facing representation varying, definition order fixed as a controlled variable. A, minimal oracle tool set โ ceiling and control, not a realistic runtime. B, many narrow tools. C, the same suite plus plausible irrelevant tools, testing standing bloat and choice interference. D, fewer composable tools with richer schemas. E, dynamic discovery from a small search surface with on-demand loading. Optionally F, a deliberately ambiguous suite of overlapping definitions, kept only if it adds diagnostic value beyond C. A naming sub-extension, clear against ambiguous names, stays small and subordinate. Measurements: definition, description, and schema tokens separately; tool count; selection accuracy; invalid, redundant, and total calls; task success; latency; and eventually input cost โ never collapsed into one score.
Experiment 2: observation-surface design. Deterministic tools over identical underlying data, tasks requiring a specific subset of each response, pre-registered small, medium, and large result regimes rather than one-off sizes. A, full raw response. B, server-side filtered response against task parameters. C, paginated response with explicit continuation. D, bounded concise result plus durable reference. E, hard truncation with an explicit continuation marker, kept as a stress condition. F, oracle minimum from fixture ground truth, untuned after outcomes. The fixture guarantees three named hazards: a decisive item near the tail of a long result, realistic structured bulk that is valid but irrelevant, and at least one exact identifier โ path, ID, code, version, line number โ that gist-preserving shaping cannot satisfy. The strategies compare in a table the evaluator fills, not the author:
| Strategy | Initial tokens | Complete? | Follow-up possible? | Main risk |
|---|---|---|---|---|
| Raw response | high | yes | rarely needed | bloat, distraction |
| Server-side filtered | low | task-dependent | re-query | wrong filter |
| Paginated | bounded | no | explicit pages | missed tail, extra calls |
| Concise plus reference | low | no | expansion | frequent re-entry |
| Hard truncation | lowest | no | continuation marker | false absence |
| Oracle minimum | minimal | by construction | n/a | ceiling only |
Measurements: result tokens, required-information and exact-value survival, irrelevant tokens, follow-up counts, premature-stop failures, latency, task success โ plus reference tokens, expansion frequency, and reintroduced tokens wherever pointers appear.
End-to-end, one conceptual ledger binds both experiments: standing definitions plus call representation plus results plus errors plus follow-up expansion, with the caveat that providers expose these terms unevenly and Project Context currently observes almost none of the definition side. Definition cost and result cost stay independent axes throughout, because the chapter’s two most useful insights both cross them. A detailed definition costing 300 extra tokens that prevents three failed calls and 10,000 tokens of error output is cheap at the trajectory level โ definitions earn evaluation by total downstream behaviour and cost, never by description length. Work the arithmetic once to fix the habit: suite X spends 400 definition tokens per turn and completes tasks in two calls with 3,000 result tokens, for a 3,400-token trajectory footprint; suite Y spends 100 definition tokens but needs five calls, two of them error recoveries, totalling 9,000 tokens of results and retries. The shorter description loses by nearly three to one, and any metric that scores definitions in isolation recommends the loser. Symmetrically, the smallest result can be the most expensive one when thin responses force four follow-up calls to reconstruct what one richer response supplied once. Minimum result size is not minimum total cost, the tool-context analogue of Chapter 9’s token-versus-computation lesson, and the experiment compares one richer call against several narrow ones as trajectories rather than snapshots.
What the laboratory still cannot see
At Stage 1 and 2 under the pinned OpenCode V1 capture boundary, tool definitions are UNOBSERVED โ recorded in the stage reports as a first-class unknown, never as zero. The chapter refuses to paper over that with external figures: Anthropic’s tens of thousands of definition tokens describe Anthropic’s harness populations, and no sentence here claims OpenCode spends any measured fraction of context on definitions, because nothing in Project Context has measured it. What the chapter does instead is convert the gap into an explicit instrumentation requirement for the Stage 13 report: a future adapter must observe the effective tool set per invocation โ names, descriptions, input schemas, annotations, render order, definition sizes โ wherever the runtime exposes them, alongside the already-visible tool results. Until then the definition-side experiment runs on synthetic fixtures, the result side gains prevalence data as genuine captures accumulate, and neither borrows the other’s evidence.
The Context Lab records stay small by the book’s standing preference for extension over hierarchy. Tool definitions and tool observations arrive as ContextItem records with source_kind set accordingly, carrying tool name, call identifier, server or source, result status, completeness marking, and reference identifier where the experiment consumes them. Definition-to-call-to-observation lineage answers which capability produced which context through the existing reference and provenance fields, assessed as sufficient unless evidence forces more. One metadata decision is required rather than optional: every observation carries its completeness status โ complete, filtered, paginated, truncated, reference-only, error โ so that no model or evaluator ever reads absent rows as absent facts.
Ecological questions wait for an instrument that can see them: definition share of input, definition stability across invocations, exposed-but-never-used tools, result share and size distributions, error-result sizes, repeated results, calls per task. All are listed as unanswered. The fixtures answer causality โ whether surface design changes selection, whether shaping changes behaviour, what each strategy costs end to end โ and the corpus, when it exists and can observe definitions, answers prevalence. Neither is asked for the other’s job.
Falsification is stated per surface because each can fail independently. Capability-side: irrelevant tools changing nothing, narrow suites winning despite larger definitions, discovery adding latency and misses without total-cost benefit, definition tokens negligible against capacity, richer schemas dominating through fewer downstream failures. Observation-side: raw responses winning under matched tasks, pagination missing tails past any savings, reference tools expanding constantly, concise outputs multiplying calls, error trimming destroying diagnostics, current models absorbing large raw outputs without behavioural penalty. Negative results simplify tools by the book’s standing rule: one moderately rich tool beating discovery plus micro-tools keeps the simple design, small high-signal raw outputs earn no pagination layer, and mechanisms keep earning complexity through measured failures or not at all.
The same facts that leave a tool as a 50,000-token dump can arrive as prose, records, a table, or a reference โ and the cost and usability of each form differ even when the facts do not. Capability and observation are now priced on both sides of the call. What remains is the representation question in full generality: which form should the model actually receive.
References
- Aizawa, K., et al. “Writing effective tools for agents โ with agents.” First-party engineering essay, Anthropic, September 2025, verified September 2026. Capability-selection effects; namespacing; high-signal responses with concise/detailed verbosity control; pagination, filtering, truncation, and the 25,000-token Claude Code default response limit; actionable errors; description prompt-engineering. https://www.anthropic.com/engineering/writing-tools-for-agents
- Wu, B., et al. “Introducing advanced tool use on the Claude Developer Platform.” First-party engineering essay, Anthropic, November 2025, verified September 2026. Tool Search Tool with deferred loading; standing-definition token figures; selection-accuracy lifts; programmatic tool calling keeping intermediate results out of context; tool-use examples. https://www.anthropic.com/engineering/advanced-tool-use
- Jones, A., Kelly, C. “Code execution with MCP: Building more efficient agents.” First-party engineering essay, Anthropic, November 2025, verified September 2026. Filtering and computation outside model context; intermediate-result exclusion. https://www.anthropic.com/engineering/code-execution-with-mcp
- Model Context Protocol. “MCP Overview” and “Tools” specification pages, draft revision, verified September 2026. Prompts/resources/tools control distinction; tool definition fields; deterministic ordering; structured content with output schemas; resource links and embedded resources; error reporting; annotations as untrusted hints. https://modelcontextprotocol.io/specification/draft/server/
- OpenCode. “Tools” documentation, current V2-line pages, verified September 2026. Built-in, custom, and MCP tool surfaces with allow/deny/ask permissions. Cited as present-day implementation evidence; the book’s experimental environment remains pinned OpenCode 1.18.27/V1. https://opencode.ai/docs/tools/
- Tarquinen. “Dynamic Context Pruning Plugin (DCP).” Third-party implementation, AGPL-3.0-or-later, master branch targeting OpenCode V2 installation, verified September 2026. Same-call deduplication; errored-input pruning with messages preserved; protected tools; placeholders with untouched history; prompt-cache trade-off documentation. https://github.com/Tarquinen/opencode-dynamic-context-pruning