What a bloated agent pays for
- Context tokensdefinitions sent on every call
- Wrong tool chosenoverlap blurs the decision
- Latency and costmore input, more hops
- Blast radiuswrite tools it never needed
What “bloat” means, and why it happens
Capability bloat is any capability in an agent’s configuration that its job does not require: tools it never needs, tools that overlap so the choice between them is ambiguous, permissions broader than the task, verbose tool outputs, and subagents that exist because splitting felt tidy rather than because the work demanded it. It rarely starts as a decision. It accumulates — a team connects a whole MCP server because it needed one tool, wraps every endpoint of an internal API because that was quick, or lets a new subagent inherit everything because nobody wrote a tools line.
Anthropic’s context-engineering guidance names the failure directly: bloated tool sets that cover too much functionality or create ambiguous decision points. Its test is a good one to carry into the exam — if a human engineer could not say for certain which tool to use in a given situation, the agent cannot be expected to do better. The recommended target is a minimal viable set of tools, each self-contained and clear about its purpose.
| Kind of bloat | What it costs | Where you see it |
|---|---|---|
| Too many tool definitions | Tokens on every request; slower first token | Tool API docs cite about 55k tokens of definitions for a five-server setup |
| Overlapping tools | Wrong or redundant tool calls | search_orders and find_order and get_order_by_ref all present |
| Endpoint-per-tool wrapping | Many calls where one would do; more context per task | list_users + list_events + create_event instead of schedule_event |
| Over-broad permissions | A mistake or injected instruction can do real damage | A read-only reporting agent with delete_record enabled |
| Verbose outputs | Context filled with IDs and fields nobody reads | Tools returning full JSON records, UUIDs and MIME types |
| Agent sprawl | Extra hops, extra tokens, mis-delegation | Nine subagents whose descriptions overlap |
The numbers matter because they tell you when bloat stops being theoretical. The tool search documentation says Claude’s ability to pick the right tool degrades once more than 30–50 tools are available, and that a typical five-server setup (GitHub, Slack, Sentry, Grafana, Splunk) spends roughly 55k tokens on definitions before any work begins. Anthropic’s research-system write-up adds the agent-side number: agents use about four times the tokens of a chat, and multi-agent systems about fifteen times. Every capability has a price; the architect’s job is to make sure it buys something.
An audit you can run on any configuration
This task statement asks you to evaluate, so think of it as a review against the job description. Write down the tasks the agent must perform, then walk the configuration and ask four questions of every capability: is it needed for a real task, is it distinct from every other capability, is its permission the narrowest that works, and does it need to be loaded on every request?
Auditing a bank’s card-support agent
- Passes:
freeze_card,open_dispute,get_card_statuseach maps to a task in the brief - Fails: Whole core-banking MCP server enabled (62 tools)wire transfers and account closure are not in scope
- Check:
search_transactionsandlist_transactionsboth onoverlap — merge into one searchable tool - Check: Policy lookup loaded on every requestused in 1 in 20 chats — defer it
- Missing: Scope of the OAuth token behind the servernobody could say — see 3.2
- Fails: Tool results return full card recordsreturn only the fields the answer needs
Four remedies, and when each applies
Bloat has more than one shape, so there is more than one fix. Choosing the wrong one is a classic distractor: tool search does nothing about a dangerous permission, and deleting a tool is wrong if a real task needs it once a week.
Which remedy fits this capability?
- No task needs itRemove or disableallowlist, not denylist
- Overlaps another toolMerge and namespaceone tool per job
- Needed, but rarelyDefer loadingfound via tool search
- Needed by one subtaskScope to a subagentmain agent never sees it
Remove or disable. On the Claude API’s MCP connector, an mcp_toolset accepts a default_config and per-tool configs. Setting enabled: false by default and switching on named tools is an allowlist; leaving the default on and switching a few off is a denylist. Prefer the allowlist: when the server adds a new tool next month, an allowlist keeps it out until someone decides it belongs.
Merge and namespace. Anthropic’s tool-writing guidance recommends a few thoughtful tools aimed at high-impact workflows rather than one tool per API endpoint: schedule_event instead of listing users, listing events and creating an event; get_customer_context instead of three separate fetches; search_logs instead of read_logs. Where several services offer similar actions, a prefix such as asana_search versus jira_search makes the boundary explicit.
Defer loading. Tool search lets you keep a large catalogue while loading only what a request needs. You mark tools with defer_loading: true, keep the three to five most used tools loaded, and Claude searches for the rest. The documentation suggests it once you pass about ten tools or 10k tokens of definitions, and advises against it for small sets where every tool is used on every request. The wider “load up front or discover as needed” decision is covered in 3.8.
response = client.beta.messages.create(
model=MODEL,
max_tokens=2048,
betas=["mcp-client-2025-11-20"],
mcp_servers=[{
"type": "url", "name": "crm",
"url": "https://crm.example.com/mcp",
"authorization_token": crm_token, # obtained by your app (see 3.2)
}],
tools=[
{"type": "tool_search_tool_bm25_20251119", "name": "tool_search_tool_bm25"},
{
"type": "mcp_toolset",
"mcp_server_name": "crm",
"default_config": {"enabled": False}, # allowlist: off unless named
"configs": {
"find_customer": {"enabled": True}, # hot path: always loaded
"get_customer_context": {"enabled": True},
"list_contracts": {"enabled": True, "defer_loading": True}, # rare
},
},
],
messages=messages,
)Scope to a subagent. When one subtask needs a heavy capability — a browser, a database console — give it to a subagent rather than the main agent. In Claude Code a subagent’s tools field is an allowlist and disallowedTools a denylist; if tools is omitted the subagent inherits every available tool, MCP tools included. An mcpServers entry defined inline on a subagent keeps that server’s tool descriptions out of the main conversation entirely.
---
name: contract-reviewer
description: Reviews contract drafts against the clause library. Read-only.
tools: Read, Grep, Glob # allowlist: no Edit, Write, Bash or MCP
---
Compare the draft to the clause library and list deviations with line numbers.Agent bloat is the same problem one level up
The objective says tool/agent configuration, and agents bloat too. A coordinator with nine specialist subagents whose descriptions overlap has the same ambiguous-choice problem as nine overlapping tools, plus a hop, a fresh context and a summary for every delegation. Anthropic’s research system scaled effort to the query — one agent with a handful of tool calls for simple fact-finding, many subagents only for genuinely broad research — and warned that multi-agent designs fit poorly where agents must share context or depend on each other heavily. (Designing multi-agent systems is 1.4; here you are judging whether an existing configuration carries more agents than its work needs.)
Designing for the workflow, not the API
One tool per endpoint
list_users,list_events,create_eventget_customer_by_id,list_transactions,list_notesread_logsreturns the whole file- Every subagent inherits every tool
One tool per job
schedule_eventfinds a slot and books itget_customer_contextreturns what a support reply needssearch_logsreturns matching lines with context- Each subagent gets an explicit
toolsallowlist
Traps the wrong answers are built from
| Tempting but wrong | Do this instead |
|---|---|
| Connecting a whole MCP server because one tool was needed | Enable only the needed tools with an allowlist (default_config off, named tools on). |
| Adding prompt rules to steer between overlapping tools | Merge the overlap into one tool with a clear name, description and parameters. |
| Using tool search to “hide” a risky tool | Disable it or narrow its permission; deferral only saves tokens. |
Leaving tools unset on subagents | Give every subagent an explicit allowlist; unset means it inherits everything. |
| Adding a routing agent to cope with too many specialists | Merge specialists whose work overlaps and scale agent count to task complexity. |
You should now be able to
- Audit an agent configuration against its task list and classify each surplus capability.
- Explain the costs of bloat: context tokens, selection accuracy, latency, blast radius and upkeep.
- Choose between removing, merging, deferring and scoping a capability for a given finding.
- Configure an MCP toolset allowlist and deferred loading on the Claude API.
- Recognise agent sprawl and judge when subagents should be merged or given narrower tools.