October 28, 2026

Forty tools is a retrieval problem

Past a certain catalog size, binding every tool on every turn stops being free. Accuracy drops, cost rises, and the model starts reaching for the fourth-best tool because it was described more confidently than the right one.

Thin amber linework on charcoal: a large grid of small tool glyphs with six of them highlighted and connected to a query node.

The fix looks obvious — bind only the relevant tools — and it has two properties that are not obvious at all, and both of them will surprise you at exactly the wrong moment.

It needs an embedding model

Relevance is measured by embedding your message and each tool's description. Same machinery retrieval and memory use. So a project with no embedding model configured gets nothing from this capability.

The awkward part is what "nothing" means here. Every other capability that cannot run degrades to nothing happening — a missing tool, a refusal, something you notice. This one degrades to everything: every tool bound on every turn, which is precisely the cost the capability exists to avoid.

There is no missing tool to notice. A caller who set the flag once and never re-read capabilities() would see a feature that appears to work perfectly.

So the turn says so, on warnings:

jsonc
{ "warnings": ["this project has no embedding model … enable_action_space was set and could
   not narrow anything, so every tool is bound on every turn instead of the relevant few —
   the cost this capability exists to avoid: configure one under Retrieval (LLM & limits) …"] }

And GET /capabilities reports the flag as effective: false with blocked: "needs an embedding model".

Two places, because the two audiences are different. The turn's warning reaches whoever is running requests; the capabilities response reaches whoever is configuring the project. A silent degradation only stays silent if neither of them is told.

Nothing is narrowed below about 8 tools

Under that, the whole catalog is smaller than the subset would be, so narrowing is skipped — and tool_search is not bound either.

That second part is the one worth understanding. A tool whose description is "there are more tools than you can see" must not appear on a turn where that is false. An agent handed a search tool over a catalog it can already see in full will use it, learn nothing, and have spent a round trip discovering what was already in front of it.

Past the threshold, roughly the six most relevant are bound, plus anything pinned or already in use.

Both numbers are deployment defaults rather than a contract, which is why they read as "about" and "roughly" — but they are written as digits so that grepping for one finds it. Somebody looking for the threshold searched for a number, found nothing, and reported that it was documented nowhere. It was, four lines from where they looked.

The narrowing is reversible by the agent

This is the part that makes the whole thing safe, and it is the part I would insist on in any implementation of this idea.

The agent always holds tool_search. When it needs something it cannot see, it searches, and whatever matches becomes callable immediately — for the rest of the turn, not just the next step.

Because the alternative is worse than a large catalog. An agent that silently lost a tool it used a moment ago, with no way to ask for it back, reasons about its own capabilities from a false picture. It will tell your user it cannot do something it can do, confidently, and there is no way for anyone in the conversation to find out otherwise.

Two more rules fall out of the same concern. Tool families that only work whole are never split — the todo tools, scheduling, the browser. And anything the agent is already mid-way through using is kept, regardless of how the current message happens to rank.

That last one matters on a multi-step task where the user's third message is "yes, do that". Four words, ranking against a catalog, matching almost nothing. Without the pinning rule, the tools the agent was halfway through using would evaporate at the moment of confirmation.

When to turn it on

If you have fewer than about ten tools, don't. It cannot help, and the threshold means it will not even try.

If you have dozens — most often because you have connected several MCP servers, each bringing its own family — it is the difference between an agent that picks well and one that picks plausibly.

And write your descriptions for it. Under narrowing, a tool's description is doing two jobs: telling the model when to use the tool, and being the text that gets matched against the user's message. A description that names the trigger rather than the topic does both well. One that reads like a filing label does neither.

Which is the same advice as for a skill's description, and for the same reason — in both cases the sentence is what stands between something existing and something being found.

Read next