MCP Has a Tool-Selection Problem — Vectoralix
The Model Context Protocol is often explained as a standard way for AI applications to connect to tools, data, and external systems.
That part is useful. Before MCP, every AI application had to invent its own way to talk to files, APIs, databases, calendars, issue trackers, logs, and internal services. A shared protocol is a real improvement.
But once you connect more than a few servers, a different problem appears.
The hard part is no longer “can the model call a tool?”
The hard part becomes:
Which tool should the model even see?
That sounds like a small detail. It is not.
The naive version works
The simple MCP workflow is easy to understand.
A client connects to a server. The client asks for the tools. The server returns a list of tools. Each tool has a name, a description, and an input schema. The model can then decide which tool to call.
For a demo, this works well.
A server with three tools is easy:
get_weather
search_files
create_ticket
The model sees all three. The user asks a question. The right tool is usually obvious.
This is the happy path most examples show.
The problem starts when the system succeeds.
Success means too many tools
A useful AI assistant does not stay connected to one tiny server.
It gets connected to GitHub. Then Slack. Then Google Drive. Then Jira. Then a database. Then internal logs. Then billing. Then a deployment system. Then a few company-specific tools nobody outside the team understands.
Suddenly the model is not choosing between three tools.
It is choosing between 30, 80, or 200.
Each of those tools needs a name. Each needs a description. Each needs a schema. Many need nested properties, enums, examples, constraints, and warnings.
All of that must be represented somehow for the model.
This creates a context tax.
Before the model answers the user, before it reads the actual task, before it reasons about anything useful, the context window is already filled with tool definitions that may not matter for the current turn.
Most of the time, the user does not need 200 tools.
They need one.
Tool definitions are not free
Tool definitions look small when viewed one at a time.
A name here. A description there. A JSON schema. A few parameters.
But LLMs do not experience tool definitions one at a time. They experience the whole available tool surface as context.
That matters for two reasons.
First, tool definitions consume tokens. The model has less room for the actual conversation, project files, logs, code, or documents.
Second, too many tools make selection harder. A larger tool list does not only cost more. It also creates more opportunities for the model to choose a plausible but wrong tool.
This is especially painful because many real tools are semantically close.
Is the right tool search_documents, search_files, query_knowledge_base, find_resource, list_pages, or get_record?
A human can ask a clarifying question or inspect the system. A model often picks the tool that sounds closest.
Sometimes that is enough. Sometimes it is not.
MCP standardizes listing, not relevance
This is the core weakness.
MCP gives clients a standard way to ask a server what tools it has.
It does not give the client a standard way to ask:
Which tools are relevant to this user request?
Which tools should be shown for this intent?
Which tool schemas can be loaded later?
Which tools are commonly confused with each other?
Which tools are safe to expose in this context?
Which tools should be hidden unless specifically requested?
The protocol has tools/list.
What many LLM applications need is closer to tools/search.
Not search as a product feature. Search as a context-management primitive.
A model should not need to carry every possible tool definition in its active context just because the user might need one of them later.
Anthropic already worked around this
A good sign that something is missing at the protocol layer is when people solve it outside the protocol.
Anthropic’s Tool Search/deferred-tools pattern is exactly that kind of signal.
Instead of loading every tool definition upfront, the model sees a small search tool. When it needs a capability, it searches for relevant tools. Only then are the matching tool definitions loaded into context.
That is a sensible design.
It treats tool discovery as its own step instead of assuming every tool must be present from the beginning.
But this also highlights the gap: if every host or model provider solves tool discovery differently, MCP becomes a standard for exposing tools, while relevance remains vendor-specific.
That is not fatal. It is normal for young protocols.
But it is the next problem to solve.
Tool search should be boring
A protocol-level tool search primitive does not need to be complicated.
It could start with something simple:
"method": "tools/search",<br>"params": {<br>"query": "create a GitHub issue for this bug",<br>"limit": 5
The server...