Build MCP servers

What happens when an AI agent has too many tools

Every MCP server an agent connects to adds its tools to the model's context before the agent does anything. Past a few servers, that cost shows up as a slower, less accurate agent.

By
Dan Flanagan
Updated
October 15, 2026
Checked against
the MCP specification (modelcontextprotocol.io, revision 2026-07-28), Anthropic's Advanced Tool Use documentation and Claude Code's MCP reference, and tools/list measured against @modelcontextprotocol/server-filesystem 1.0.0 and @modelcontextprotocol/server-everything 1.0.0 (Python MCP SDK 2.3.0), October 2026
Reading time
5 min

New to MCP? What is an MCP server? covers the basics first.

Connect an agent to one MCP server and it gets one tool list. Connect it to ten servers and it gets ten tool lists, merged into one, read before the agent does anything. Past a handful of servers, that merged list costs real context, confuses the model about which tool to call, and sometimes hands it two tools with names close enough to pick the wrong one.

The context cost of tool definitions

A client builds its tool list by calling tools/list on every connected server and sending the model the result: each tool's name, description and input schema. None of that is free. It is text the model reads on every turn, before it reads your message.

To see how much, I ran tools/list against two of the official MCP reference servers over stdio, using the Python MCP SDK. The filesystem server, which offers read, write and directory operations, returned 14 tools as 13,909 characters of JSON, around 3,500 tokens by the usual rough estimate of four characters per token. The everything server, a small demo server built to exercise the protocol rather than do real work, returned 13 tools as 8,229 characters, around 2,000 tokens. Those are two servers with a dozen or so tools each. Connect a few more and the numbers compound.

Anthropic's own figures, from its November 2025 write-up on advanced tool use, show where that compounding goes in practice. A setup with five servers, GitHub (35 tools, about 26,000 tokens), Slack (11 tools, about 21,000 tokens), Sentry (5 tools, about 3,000 tokens), Grafana (5 tools, about 3,000 tokens) and Splunk (2 tools, about 2,000 tokens), comes to 58 tools and roughly 55,000 tokens before the conversation starts. Add Jira, which the same post says uses about 17,000 tokens on its own, and you are past 70,000. Anthropic says it has seen tool definitions reach 134,000 tokens internally before optimizing. That is context spent before the model has read your request, let alone acted on it.

Worse tool selection

The token cost is the easy part to measure. The harder cost is that a long tool list makes the model worse at picking from it. Anthropic's post states this directly: "the most common failures are wrong tool selection and incorrect parameters, especially when tools have similar names like notification-send-user vs. notification-send-channel." It also reports internal accuracy numbers on MCP evaluations with large tool libraries: Opus 4 went from 49% to 74%, and Opus 4.5 from 79.5% to 88.1%, after enabling the Tool Search Tool rather than loading every tool definition upfront. Those gains came from hiding tools the model did not need for the task. The tools themselves did not change.

The protocol gives a client no help here. The MCP specification says a server's tools/list response "MUST NOT vary per-connection or as a side effect of other requests on the connection," so for a given caller a server hands back its whole catalog every time, and nothing in the spec tells a client which of those tools matter for the task in front of the model right now. Deciding that is left to the client or to whoever operates the agent.

Name collisions

MCP tool names only have to be unique inside one server. The specification is specific about this: "Tool names SHOULD be unique within a server," with no requirement across servers. Connect a filesystem server and a cloud storage server and you can end up with two tools both named list_directory, each doing something different, both offered to the same model in the same turn.

Clients handle this differently. Claude Code, for one, namespaces every tool it registers to the server that offered it, so a filesystem server's tool is callable as mcp__filesystem__list_directory and a second server's tool of the same name becomes a distinct mcp__other-server__list_directory. That avoids a literal name clash inside one client. It does not fix the Anthropic example above: a model choosing between notification-send-user and notification-send-channel isn't facing a collision. It's facing two distinct tools that read as near-synonyms, and namespacing does nothing for tools that merely sound alike.

Fixes that work

A few things reduce this cost without needing an agent to lose capability:

Connect fewer servers per agent. A triage agent needs the issue tracker. It doesn't need the deploy pipeline or the wiki. Every server you leave off is tool definitions the model never has to read.

Build the tool set for the task, not for the agent's whole job. An agent that occasionally needs a tool can be given it for that session rather than carrying it in every conversation it has.

Use tool search or deferred loading where the client supports it. Anthropic's Tool Search Tool marks tools with defer_loading: true so they are discoverable on demand instead of loaded upfront; only the search tool itself and a handful of frequently used tools stay in context by default. Claude Code turns on an equivalent form of tool search by default for current models, so a configured server's tools are found through search rather than listed in full at session start.

Put a gateway in front of servers that exposes only the tools a given agent has been granted. This does not require the agent or the model to do anything differently. It changes what the gateway hands back from tools/list in the first place.

Where Statio fits

Statio sits between agents and the MCP servers they connect to, and grants are per tool, not per server. An agent connects to Statio and gets back only the tools it has been granted. A tool it cannot call does not appear for the model to weigh against the ones it can. A deny on a specific tool overrides a grant on the server it belongs to. Nobody has to trust the model to ignore the tools it should not use, because those tools are not part of the list it reads in the first place.

Next

What is an MCP server? covers tools/list and tools/call from the start. MCP vs APIs explains why a server exists in front of an API at all. How to turn an OpenAPI spec into an MCP server and How to build an MCP server in Python cover building one that keeps its tool count sane from the start. MCP permissions covers the five ways teams narrow down which tools an agent can call.

Questions

Anthropic's tool search docs suggest using it once you have 10 or more tools or more than 10,000 tokens of tool definitions, and say plain tool calling fits better under 10 tools. The protocol itself sets no limit, and the cost grows gradually.

It adds tokens the model reads before it starts working, which adds to every inference pass in that session. The MCP specification does not require a server to limit how many tools it exposes.

Yes, if the client supports it. Anthropic's Tool Search Tool and Claude Code's equivalent default behavior keep most tool definitions out of context until the model searches for them. A gateway in front of the servers can do the same by only ever returning the tools a given agent is allowed to call.

The protocol does not require tool names to be unique across servers, only within one. A client has to handle the case itself, for example by namespacing each tool to its server, which Claude Code does.