The protocol that standardises how a model talks to external tools deliberately leaves the application side unspecified — so unlike a package manager, there is no convention for where servers are declared or whether a human ever sees a tool call before it fires. Across 1,723 open-source applications, the easy parts have converged: 85.2% keep server definitions in a config file, 81.1% use an official client library. Oversight has not. 90.8% log tool activity and 77.2% let you switch servers on and off, but only 37.2% stop a tool call and wait for a human — in the other 62.8% the model invokes any enabled tool unconditionally.
The study finds exactly three oversight mechanisms in the wild, and they are independent — an application can have any combination. Only one of them is actually in the execution path. Logging tells you what happened once it already has. An enable/disable list bounds which tools are live but says nothing about any particular call. A blocking approval step is the only one that sits between the model's decision and the effect. Switch them on and see what you have actually built.
The adoption order is telling. The mechanism that is easiest to add and cannot stop anything is at 90.8%; the one that actually interrupts execution — and costs a user interaction to build — is at 37.2%. Oversight got built in order of implementation cost, not in order of what it prevents.
Collapsing the combinations, four postures account for the ecosystem, and the modal one is not the safe one. The most common single configuration is logging plus an on/off list with no approval step — a fifth of applications have neither an on/off list nor a prompt, and 3.5% have nothing at all. Step through them with the same injected instruction and watch where it stops.
The attack in each panel is the ordinary one: a document, a web page or an issue comment the model reads contains an instruction naming a tool the user has already enabled. No exploit, no privilege escalation — the model just does as it is told, and in three of these four postures nothing in the application is positioned to stop it.
An enable/disable list is genuinely useful — it is how you keep a server you rarely need out of the model's reach. But its protection is fixed while its exposure grows: every server you turn on adds its whole tool surface to what an injected instruction can name, and none of those additions is individually reviewed. Add servers and watch the reachable surface climb while the number of gates stays where it was.
This is the argument for gating on the verb rather than the tool count. Approval fatigue is real and prompting on every read is how a gate gets switched off — but the writing, spending and sending subset is small, and that is the subset where a blocking prompt is worth its interruption.
The second half of the finding is duller and will cost you more time. 85.2% of applications declare their servers in a config file, which sounds auditable until you look for it: only 30.7% of those use the obvious filename, another 12.8% use the next most obvious, and 69.1% merely contain the protocol's initials somewhere in the name. The remainder use something you would never guess, and a separate 14.8% keep server definitions in a database where no file scan will ever see them. Add matching rules and watch the ceiling.
Even the most permissive rule — any filename containing the initials — tops out at 58.9% of all applications. If you are building anything that inventories which servers an application depends on, key it to the client library's call sites rather than to a filename.
If you maintain an application that consumes these servers, the useful exercise is honest self-classification against the same taxonomy. Pick what you have and where you sit; the percentile is against the study's population, the recommendation is the paper's implication.
The protocol will not solve this for you. It specifies the wire format between a client and a server and says nothing about whether your application blocks — which means the gate is your code, on your side, and the ecosystem default is that it does not exist.