An analytics platform we built for an IoT product once carried 200+ hardcoded tool definitions in the agent's context window. Every one of them rode along on every single turn, needed or not. We replaced the lot with one generic tool plus a compressed catalog of available operations that fits in roughly 9k tokens. Per-turn context cost dropped, and adding an operation became a catalog entry instead of a schema deployment.
That swap is the most concrete demonstration I have of context engineering, a term that usually gets defined in the abstract. My working definition takes one sentence: the context window is a budget, and every token in it is rent paid on every call. The model attends to everything you load, relevant or dead weight, and you are billed for all of it. The rent comes due twice, once in dollars and once in attention.
This post uses the catalog diet as the worked example, then follows the budget where it leads: deciding what an agent should see out of everything it could see, and choosing what to move into the space you clear.
A tool definition is a recurring cost
Start with why 200 definitions were a problem at all. A human developer reads your API docs once and then calls the endpoints they need. An agent has no such persistence. It re-reads whatever sits in its context on every turn, and tool definitions sit in that context by design, because the model can only call what it can currently see.
A 200-definition catalog therefore behaves nothing like 200 endpoints in an OpenAPI spec. The spec is read at development time, once. The catalog is read at inference time, per turn. A ten-turn agent run pays for those definitions ten times, and a fleet of agents pays for them on every run of every task, indefinitely. When I say context is rent, this is the mechanism: the charge recurs, and it recurs on your hottest path.
Dollars are the visible half. The quieter half is attention. A window stuffed with schemas the task will never touch is noise the model has to attend past to find the actual question, and a smaller, focused context is consistently more reliable than a stuffed one. Reliability was the argument that convinced the team; the bill was the argument that convinced the spreadsheet.
From 200 schemas to one tool and a catalog
The fix was a level of indirection. Instead of 200+ first-class tools, the agent gets exactly one generic tool. Alongside it rides a compressed catalog of the operations the platform supports, roughly 9k tokens for the whole thing. The model reads the catalog, picks an operation, and invokes the generic tool with the operation name and its arguments.
Two properties fell out. The billing one first: per-turn context cost dropped, because the window now carries one schema plus a dense index instead of 200 full definitions. The operational one mattered just as much: adding an operation stopped being a schema deployment and became a catalog entry. New capabilities land as data.
The catalog is also where progressive disclosure lives. The window holds a map at all times; detail loads on demand. The agent does not need the full specification of an operation it will never call this turn, so the upfront context carries just enough for the model to know each operation exists and roughly what it does. The system this sits inside, a cheap router in front of expensive specialists, is drawn out in the anatomy of a multi-agent platform; the catalog diet is one section there, and this post is that section given the room it deserved.
What the agent could see versus what it should see
The diet generalizes, and scale forces it. A financial-analytics platform we work on exposes 22 MCP hubs with more than 850 tools. No model reliably picks the right tool from 850 raw definitions: near-neighbor tools blur together on names and descriptions, and the context bill compounds turn after turn. That platform's answer is semantic reranking over the catalog. Embed the task, shortlist candidate tools, and hand the model a page instead of a phone book. I walked through the full server anatomy in inside an MCP tool server.
On the IoT platform the same question gets answered with scope rather than ranking. Regular users connect to a user-scoped MCP server that does not contain the admin tools at all, so a prompt injection cannot invoke a tool that was never in the catalog. Scoping is usually filed under security, and it is, but it is also context engineering: tokens describing tools this caller may never use are rent with negative return.
Both mechanisms enforce one distinction. What the model could see is every tool the platform owns. What it should see is the short list relevant to this task, for this caller, on this turn. Context engineering is the practice of keeping that gap wide by machinery instead of by hope.
Spend the reclaimed budget on judgment
Cutting tokens is half the job. The reason to evict schemas is that some tokens are worth loading upfront, and on our platforms those are skills: roughly 85 semver-versioned SKILL.md files that agents and MCP servers load before the first tool call. When an agent starts an energy or environmental task on the IoT platform, the domain framework loads before any query tool runs, so the model reasons with our methodology instead of whatever its training data suggests for "energy efficiency."
A skill earns its rent because it changes how every downstream token gets interpreted. A schema for a tool the agent will not call this turn earns nothing. Same budget, opposite return.
Governance keeps the investment honest. Every skill carries an ADOPT/FORK/BUILD classification, semver is mandatory, and per-skill version pinning fails the build in CI when a workflow pins a skill that has since moved on. An agent never quietly reasons with mismatched assumptions, because the pipeline breaks first. The storage and versioning architecture underneath all of this is in how AI agents remember.
The meter is always running
None of this requires a platform team to start. The first budget review is cheap: dump what actually rides in your agent's context on a typical turn and read it line by line, asking of each block what it contributes to this call. In the systems we run, tool definitions were the largest line item nobody had chosen deliberately. They accreted, one reasonable schema at a time, until the window was mostly furniture.
Then work the two sides of the ledger. Shrink what the model sees to what the turn needs, through a catalog, a reranker, or a scoped server. Spend the reclaimed space on context that compounds, which for us meant versioned skills loaded before the tools.
The systems in this post are summarized in the operator brief. The live demo is the single-service end of the same discipline: a RAG pipeline rather than a tool catalog, where the budget question becomes how many retrieved chunks earn their place in the window. The meter is identical everywhere an LLM runs. Every token in the window pays rent on every call, so collect from tokens that work and evict the ones that only take up space.
