← Context From First Principles

Tools Produce Context

Treat tool definitions, calls, outputs, errors, and observations as first-class context with their own budget and policy.

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 names the same pattern among the failures agents show: calling the wrong tool, or the right tool with the wrong parameters. The chapter treats that 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, and Chapter 25 adds a fourth: whether what was admitted arrived. The observer used in this book watches OpenCode through its plugin interface. Documentation and observation are never merged: documented behaviour is what the implementation offers, measured behaviour is what the observer sees, and the gap between them is stated wherever a claim depends on it.

Proposed experiments

The questions. Two, kept apart because each surface can fail independently. Does the design of the capability surface change tool selection and cost? Does the design of the observation surface change what the model can do with a result, and what the trajectory costs?

The design, in brief. On the capability side, hold one underlying capability and its backends fixed and vary only what the model is shown: a minimal oracle tool set; many narrow tools; the same suite plus plausible irrelevant tools; fewer composable tools with richer schemas; dynamic discovery from a small search surface; optionally a deliberately ambiguous suite. On the observation side, use deterministic tools over identical data at pre-registered small, medium and large result sizes: the raw response, a server-side filtered one, a paginated one, a bounded result plus a durable reference, hard truncation with an explicit marker, and an oracle minimum. Three hazards are built in: a decisive item near the tail of a long result, valid but irrelevant bulk, and an exact identifier that gist-preserving shaping cannot satisfy.

The measurements that matter. Definition, description and schema tokens separately; selection accuracy, invalid and redundant calls; result tokens, survival of required and exact values, follow-up counts and premature stops; and the whole trajectory, never a snapshot. Work one case to fix the habit: a suite that spends 400 definition tokens per turn and finishes in two calls, for a 3,400-token trajectory, beats a suite that spends 100 and needs five calls with two recoveries, for roughly nine thousand. Any metric that scores definitions in isolation recommends the loser.

What would change the book. If irrelevant tools change nothing, if raw responses win under matched tasks, or if one moderately rich tool beats discovery plus micro-tools, the simple design stays and the mechanism is not earned. Nothing here has been run.

What the observer can see, and what a definition is to the compiler

What the observer sees on the definition side has changed, and three states must be kept apart. Historically the first capture could not see tool definitions and recorded them as unknown, never as zero. Now the observer records each tool’s name, description and input schema for every observed model request, though not tool annotations and not the provider’s wire payload. Experimentally, none of it has been demonstrated: no genuine session has been captured, so nothing has yet measured what fraction of a real context goes on definitions. The chapter still refuses to fill the gap 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.

Two requirements travel forward to whatever builds candidates. First, every tool observation should carry its completeness status (complete, filtered, paginated, truncated, reference-only, error), so that no model or evaluator ever reads absent rows as absent facts. Second, a tool definition is the commonest kind of dependency. A reference to an artifact is useless unless the definition of the tool that resolves it is also in the bundle, and Chapter 23’s compiler prices exactly that: a 20-token reference whose resolver costs 650 tokens is a 670-token admission. The standing cost of Chapter 4 and the selection problem of Chapter 22 meet there.

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 unanswered. The fixtures answer causality, and the corpus, when it exists, will answer prevalence. Neither is asked for the other’s job.

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. 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