Your MCP Tool Works. The Model Still Won't Call It.
The server is connected. The tools are visible. The instructions beg the model to use them. And the call count is zero. Here is what a controlled study found — and what actually changes the number.
I built a tool I was sure agents would use. It solved a real, felt pain — an AI coding agent losing everything it learned the moment its context filled up — and it was one clean install away from any editor that speaks the protocol. Then I ran the honest test: I connected it, gave an agent a real task, and counted the calls. The count was zero.
Not zero because the tool was broken. Every function was reachable, every response correct, the connection verified in the session's own startup log. Zero because the model, turn after turn, simply chose to do something else. That gap, between a tool that works and a tool that actually gets used, is the most under-measured number in the whole agent stack, and it's what this piece is about.
I'm going to show you the measurements: the run where an agent ignored a tool it was told about thirty times, the control where the answers were already sitting in the store and it never looked, and the counter-evidence where the exact same tool suddenly got used the instant the harness stopped asking and started delivering. Then I'll explain the mechanism, and give you a ladder you can climb from "polite invitation" to "the model has no choice."
The Benchmark Nobody Runs
Every tool eval I've ever seen — mine included, for a while — measures the same thing: how good the tool is when it runs. Retrieval precision. Latency. Correctness on a held-out set. You tune, you publish a number, you feel good. And then that number gets multiplied by a second number nobody put on the slide: the fraction of the time the model actually decides to call the thing.
Write it out and the problem is obvious.
Shipped value = retrieval quality × adoption × good use.
A tool that is 10× better at retrieval, multiplied by zero calls, ships zero value. Every benchmark you publish about your tool measures the first factor. The model decides the second. And — this is the part that took me a full quarter to accept — the default matters more than the quality.
Here's the trap. The first factor, retrieval quality, is where all the fun engineering lives: embeddings, rerankers, chunking, graph traversal. It's legible, it benchmarks cleanly, it feels like progress. The second factor is a behavioral property of a model you don't control, in a harness you don't own, and it doesn't show up in any dashboard unless you go looking. So nobody looks. They ship the quality improvement and quietly assume adoption is 100%.
It is not 100%. In the runs I'm about to walk through, it was closer to 0%. And you can only find that out one way — by measuring it, on purpose, before you spend three months polishing a factor that gets multiplied by nothing.
Drag the three factors and watch shipped value. The point isn't the exact math — it's what happens to a beautifully-tuned tool when the middle number drops. This is an illustration to build intuition, not measured data.
The Headline Zero
The instrument for all of this is a tool I wrote called vectr — a working-memory and code-search server that speaks MCP, the Model Context Protocol. I evaluated it in a controlled, multi-arm study on a naturalistic coding task, with the full protocol and every per-run artifact archived publicly so anyone can audit them. I care about the tool, but the number below is not about the tool. It's about what agents do.
One arm ran a 63-turn task with the MCP server connected and verified — all 10 tools visible in the session's initialization — and the workspace instruction file carrying 30 mentions of the tools and exactly when to use them. Thirty. Not a passing "you have some tools"; a document that repeatedly, specifically, named the tool and the moment to reach for it.
The agent made 0 tool calls to the server. Zero, in 63 turns. A connected, correct, heavily-advertised tool, and not one call across an entire task.
Sit with how strange that is. If you had asked me to predict the number before the run, I'd have guessed something modest — maybe the agent leans on it a handful of times, maybe it forgets. I would not have guessed zero. Zero is not "under-used." Zero is the model treating a fully-wired capability as though it were not there.
A turn, here, is one cycle of the agent's loop — think, act, observe. Sixty-three of them went by. The agent read files, ran shell commands, grepped, wrote code. It reached for its defaults every single time. The one thing it never did was call the tool that had been connected specifically to help it, and described to it thirty separate times.
Before you reach for the usual explanation: this wasn't tool overload. The well-worn advice — "you've connected too many MCP servers, the model is drowning in tool schemas" — is real, but it doesn't fit here. This was one server, ten tools, cleanly connected, with nothing else competing for the model's attention. A single tidy toolset, and still nothing.
My first instinct was that I'd broken something. I re-checked the connection. Fine. I re-read the instructions. If anything they were too pushy. The tool wasn't the problem, and neither was the guidance. Something more structural was going on, and the only way to find it was to stop guessing and run the controls.
More Mentions, Same Zero
The obvious hypothesis after a zero is "the instructions weren't strong enough." So the natural fix is to turn up the guidance. I want to kill that hypothesis early, because it's where most teams sink their next month.
Across all five unseeded, tool-equipped runs of the matrix, voluntary memory writes came in at 0–1 per run. That's the whole distribution: some runs wrote nothing, the best wrote a single note. This was against 32 memory-guidance mentions spread across the workspace instruction files and a tool surface that was verified connected in every run. More words did not buy more calls.
And here's the detail that rules out the tidy "the agent is biased against third-party MCP tools" explanation. The harness has its own native memory feature — a built-in place the model is trained to write notes to itself, no MCP involved. In these runs, that native auto-memory directory was never created in any run either. The model didn't skip my tool in favor of the built-in one. It skipped voluntary memory of any kind.
"Usage is low, so my instructions must be too weak" leads straight to writing more instructions. But the failure isn't dose. Zero native-memory writes alongside zero MCP writes tells you the model isn't rejecting your tool specifically — it's declining a whole category of voluntary behavior. No amount of louder prose changes the category.
This is the moment to separate two things that feel identical from the outside. There is the quality of your tool, and there is the model's standing disposition to reach for a non-default action unprompted. Guidance density pushes on the first — it makes the tool sound better, more relevant, more clearly the right choice. It does almost nothing to the second, because the second isn't a belief the model holds about your tool. It's a groove worn into the model by training. You can't argue a groove flat.
The Answers Were Already Inside
If louder guidance can't do it, maybe the problem is that the store starts empty — an agent won't consult a memory it has no reason to think contains anything. Fair. So I ran the control that removes that excuse entirely.
In the seeded-voluntary arm, the store was pre-seeded with four task-relevant notes — not filler, but real gotchas about the exact task the agent was about to attempt. The kind of thing that, if the agent read it, would save it a wrong turn. Same connected tools. Same guidance. The only change: the answers were already sitting inside, waiting to be recalled.
The agent made zero memory calls in 114 turns. One hundred and fourteen turns, four correct answers to its own problems within reach, and it never once looked.
This is the result that changed how I think about memory tools, so let me be precise about what it does and doesn't show. It does not show the notes were useless — they were exactly on point. It shows that relevance in the store is invisible to a model that never queries the store. Knowledge that isn't delivered might as well not exist. A perfectly-stocked library with a door the reader never opens is, functionally, an empty room.
Picture a housemate who orders takeout every night while the fridge is full of food you cooked and labeled for them. You could stock it better. You could tape a bigger note to the door. None of it works, because the failure isn't the contents of the fridge — it's that opening the fridge was never part of their routine. The only thing that ever works is putting a plate in front of them.
Storage without delivery is dead weight. That sentence sounds like a slogan, but it's the literal reading of a 114-turn run. If you're building a memory tier for agents, this is the load-bearing fact of your entire product: the value was never in holding the knowledge. It's in getting it in front of the model at the moment the model needs it — a moment the model, left to its own devices, will not reach for.
Training Priors and the Agency Tax
So why does a capable model, told thirty times, with the answers in hand, still not call? Two forces stack up, and once you see them the zeros stop being surprising.
The first is training priors. Agent models are trained, and then system-prompted, toward a specific default toolset: read the file, grep the repo, run the command. They're also trained to treat disk files as the canonical place memory lives. These aren't neutral capabilities the model weighs freshly each turn; they're the well-worn path. When the model needs to know something, "read a file" is the reflex, and reflexes fire before deliberation.
The second is what I've started calling the agency tax. Look at how the things that do reliably reach the model actually get there. A CLAUDE.md instruction file isn't something the model chooses to consult — the harness reads it and pastes it into context at startup, with zero model agency. The native memory index is loaded the same way. They "work" not because they're persuasive but because a mechanism outside the model puts them in front of it unconditionally.
A third-party MCP tool has none of that. To benefit from it, the model has to perform a fresh act of choice — notice the tool is relevant, decide to call it, form the arguments — and it has to do this at exactly the moments it's most loaded: mid-task, context filling, juggling the actual work. That's the tax. Every voluntary call costs a scarce unit of deliberate agency, spent against the pull of a reflex that's free.
It's the gym membership you have but don't use. Not because you doubt exercise works — because using it demands a deliberate act at the exact moment your day is fullest. Meanwhile the couch requires no decision at all. Injected context is the trainer who shows up at your door and hands you your shoes. Same activity, but the choice has been made for you.
Put the two together and the zeros are almost overdetermined. The model's cheapest path is its trained default. Your tool sits behind a deliberate choice it must make while busy. Guidance tries to tilt that choice, but it's tilting against a slope that training carved and the harness reinforces for free on every other surface. No wonder "prefer these tools" reads, to the model, as a suggestion it's welcome to skip.
What the Docs Actually Say
You don't have to take my framing on faith — the harness vendors describe this split themselves, in their own documentation, in plain language. I pulled these quotes from the current Claude Code docs while writing this.
On what an instruction file even is, the memory documentation is blunt:
"Both are loaded at the start of every conversation. Claude treats them as context, not enforced configuration. To block an action regardless of what Claude decides, use a PreToolUse hook instead."
And, on why compliance varies: "CLAUDE.md content is delivered as a user message after the system prompt, not as part of the system prompt itself. Claude reads it and tries to follow it, but there's no guarantee of strict compliance, especially for vague or conflicting instructions."
Read that carefully. The canonical mechanism for guiding an agent is, by the vendor's own account, context, not enforced configuration, with no guarantee. That's not a bug to be fixed with better wording. It's the design. Instruction files shape behavior; they don't compel it.
And when the docs describe the thing that does compel, notice the contrast in verbs:
"Hooks are user-defined shell commands that execute at specific points in Claude Code's lifecycle. They provide deterministic control over Claude Code's behavior, ensuring certain actions always happen rather than relying on the LLM to choose to run them."
"Ensuring certain actions always happen rather than relying on the LLM to choose." That single clause is the entire thesis of this piece, written by the people who build the harness. There's a category of thing the model is invited to do, and a category the harness guarantees. Your MCP tool, by default, lives in the first category. The features that never fail to reach the model all live in the second.
So this was never a marketing problem. You can't wordsmith your way from "invited" to "guaranteed." It's an architecture problem, and it reduces to one line I'd tattoo on every MCP builder: anything that depends on the model choosing to call you loses to anything the harness delivers unconditionally.
The measured runs used Claude-family agent models from mid-2026 in an agentic CLI harness. Adoption behavior is model- and version-specific, and training toward tool use is a moving target — a future model could reach for tools more readily. The mechanism (invitation vs. delivery) is structural; the exact zeros are a snapshot.
The Adoption Ladder
Here's the useful part. Adoption isn't binary — there's a ladder from weakest to strongest, and I've operated all four rungs on this same tool. Each one buys you more reliability and costs you more integration. The mistake is starting at the top and never climbing; the other mistake is thinking rung one is a real rung.
Four ways to get an agent to use your tool, weakest at the bottom. Select a rung to see its mechanism, its measured or observed effect, and the way it fails. The gap between rung one and rung four is the whole story.
Rung 1 — Polite guidance
"Prefer these tools." This is the 30-mentions run. Measured effect: roughly zero. It is the most common thing MCP builders ship and the least effective. If your entire adoption strategy is prose in an instruction file, you are, empirically, shipping nothing.
Rung 2 — Prescriptive prohibition
Not "prefer X" but "use X for all code exploration; do not use file reads or grep for browsing." I found this early in the project: "prefer" is ignored, while "do not use the default" is what registers. Forbidding the reflex works better than praising the alternative, because it attacks the prior directly. But it's partial and fragile — it holds best in directly-driven prompts, and it re-litigates the fight against training priors on every single turn. Lean on it and you'll get compliance that quietly erodes as the task gets long.
Rung 3 — Response-packing
Make every tool response carry what the caller needs next. A search result that names the exact id to fetch for more. A write confirmation that shows, inline, how to recall what you just stored. It's deterministic and additive — you're not persuading the model, you're paving the road so the next call is the path of least resistance. This lowers the per-call agency tax meaningfully. Its limit: it can only help after the first call. It makes the second step cheap; it doesn't make the first step happen.
Rung 4 — Harness injection
Remove the choice. Don't ask the model to call you — have the harness deliver your content as context the model can't skip. This is the only rung that beats the priors, because it stops playing their game. It's also the rung that depends on your harness cooperating: Claude Code exposes hook surfaces you can inject through, but not every MCP host does, which is exactly why part of the fix belongs upstream. The next two sections are where the zeros finally break.
Injection Begets Engagement
The best evidence that delivery is the lever isn't the zeros. It's what happened when I stopped inviting and started delivering. Same tool, same task family. The only change: the harness injected the relevant notes itself, at session start and per prompt, instead of hoping the model would go get them.
And the agents didn't just passively receive. They came alive.
In one run, the agent's first three tool calls were recalls of exactly the three injected note ids — ids it could not have known from anywhere except the injection that had just landed seconds earlier. It saw the delivered context, and immediately pulled the threads. Another run issued a semantic recall about 17 seconds in. A third produced a full memory-hygiene loop on its own: recall a note by id, forget a gotcha that its own change had just made obsolete, then remember a completion note for the next session.
In a separate long-horizon probe, the injection-equipped agent voluntarily issued 11 remember calls and 9 recalls mid-run — against zero voluntary operations in the matched voluntary-only control. Same tool, same task. The difference was that one of them had been handed a plate.
Read the sequence carefully, because it inverts the intuition most people carry. You'd expect injection and voluntary use to be substitutes — if the harness is force-feeding context, why would the model bother calling the tool itself? The opposite happened. Delivery didn't replace engagement; it triggered it. Once the model had a delivered note in front of it, calling the tool became the obvious next move, and it kept calling. The plate on the table is what got the housemate to finally open the fridge for seconds.
This is worth stating flatly because it's the hopeful part: delivery is not a substitute for engagement; it is the cause of it. You are not choosing between "force it" and "let the model use it naturally." Forcing the first contact is how you unlock the natural use.
One more thing injection has to earn: it has to be safe. Content the model can't skip is exactly as dangerous as it is powerful — a mis-fired injection is noise the model can't ignore. So the trigger logic was audited. Across the gated runs, there were zero false-alarm injections across 40 and 35 audit-logged trigger evaluations, and the file-anchored gotcha fired on the first touch of its anchored file in both runs. Delivery only earns the right to be unconditional if it's also disciplined.
Match Delivery to the Stakes
"Just inject everything" is the wrong lesson. Injected context is a finite, expensive resource — every token you deliver unconditionally is a token the model can't spend on the task. The craft is matching the delivery mechanism to the stakes of the content. In a Claude Code-style harness, the hooks give you three natural tiers.
| Content type | Stakes | Delivery mechanism |
|---|---|---|
| Never-deviate directive | A miss is unacceptable — "never push to main," "never delete prod data" | Unconditional injection at every SessionStart. No similarity threshold — a semantic near-miss on a hard rule is a catastrophe. |
| File-scoped gotcha | Only matters when a specific file is in play | Trigger on file touch via PreToolUse. Fires exactly when the anchored file is opened, and stays silent otherwise. |
| Episodic finding | Useful if relevant to this turn, harmless to skip | Ranked semantic recall per prompt via UserPromptSubmit — use the user's own prompt as the query, inject the top matches. |
The mechanism has to fit the failure mode. A never-deviate rule cannot ride on semantic similarity, because the one time the retriever scores "never push to main" just below the cutoff is the one time it mattered most. That rule belongs in unconditional injection, full stop. An episodic finding, on the other hand, would be wasteful to inject every turn — ranked recall keyed to the prompt is exactly right, because a miss just means the model does what it would have done anyway.
One flat tool that says "the model can search its memory when it wants" collapses all three tiers into a single voluntary call — and then delivers none of them reliably. Standing rules become skippable. File-scoped caveats fire only if the model happens to query at the right moment. Episodic recall competes with the reflex to grep. The conflation is the bug. Three stakes levels need three delivery mechanisms.
This is the design principle the whole study points at: match the delivery mechanism to the stakes. It's more work than shipping one tool and a paragraph of guidance. It's also the difference between a memory layer that exists and one that fires.
What To Do On Monday
If you have an MCP server in the wild or about to be, here's the short list I wish someone had handed me before I spent a quarter tuning a factor that was being multiplied by zero.
Measure adoption before quality
Connect your server, give the agent a real task (a naturalistic one, not "please use the tool"), and count your tool's calls. That's the whole test. The number may be zero. Far better to learn that in an afternoon than after a quarter of retrieval tuning that never reaches a user. This is the single highest-leverage hour you can spend on your tool, and almost nobody spends it.
Don't ship guidance prose; ship defaults
Prose in an instruction file is rung one, and rung one is empirically ~zero. If the harness exposes hooks or any injection surface, integrate there. Context beats invitation, every time, by construction. Your README's tone doesn't matter; your delivery mechanism does.
Design responses for the next call, not for completeness
Every response your tool returns should carry the next affordance — the id to fetch, the command to recall, the follow-up that's probably coming. You're not writing documentation, you're paving a road. Completeness is for humans reading logs; the model needs the next step made cheap.
If your tool is a memory tier, delivery is the product
The 114-turn control settles this. Storing knowledge is table stakes and, on its own, worth nothing to an agent. The product is getting the right note in front of the model at the right moment — which means your real engineering surface is triggers and injection, not storage and indexing. I develop this argument in full in the full write-up.
Push for first-class harness support for triggered delivery
Right now, injection lives in hooks you wire up yourself. It should be a first-class harness feature — memory files with rules-style paths: and events: frontmatter, default-off, so the harness delivers them on the right trigger without every builder reinventing it. That's the substance of an upstream feature request I filed, claude-code#78795, with a related field report in claude-code#34556. If this problem bites you too, that's the thread to pile onto.
Sample sizes here are small — a controlled matrix over one task family. The claim is existence and mechanism ("adoption can be ~zero even with maximal affordance, and injection flips it"), not a universal adoption rate you can plug into a forecast. Behavior is model- and version-specific. And I'm the author of the tool under test, so the runs are self-run — which is exactly why the protocol, per-run artifacts, and graders are public. Don't trust the story; audit the runs.
The Multiplier, Again
I opened with a tool that got zero calls and a value equation with a middle term nobody measures. Those are the same story. The retrieval quality I'd been polishing was real; it just never got the chance to matter, because the factor next to it — adoption — was sitting near zero and quietly zeroing the product.
The fix wasn't a better tool or a louder pitch. It was accepting that a model reaching for its trained reflexes will not, on its own, climb over the agency tax to call you — not with thirty mentions, not with the answers already in the store. The things that reliably reach a model reach it because a mechanism outside the model puts them there. So you become that mechanism. You stop inviting and start delivering, and you match how forcefully you deliver to how much a miss would cost.
The next time you're about to publish a benchmark for your tool, run the other one first. Connect it, hand an agent a real task, and count. If the number is zero, no amount of quality was ever going to save you — and now you know precisely which factor to go fix.
↑ Back to topNotes & Sources
Every number in this piece comes from the controlled runs, whose protocol and per-run artifacts are public. The vendor quotes were pulled from the live Claude Code documentation while writing. Audit any of it below.