A short case study from my "building and testing MCP agents" series — it stands on its own, but the method behind it is laid out in https://dev.to/langensjonathan/the-parameters-that-actually-matter-when-youre-tuning-an-ai-agent-2agd.
TL;DR: I benchmarked two agents that are identical except for one thing — how many MCP servers they're connected to — on the exact same question. Both got the right answer, both called the same single tool. The one with more MCP servers attached still cost 28% more per question, purely from the extra tool schemas the model has to be told about on every single call, whether it uses them or not.
The setup
MAVERIK is my open-source MCP test bench: define a suite of questions with pass criteria, run it against one or more agent configurations, and compare the results on hard numbers. This post is one deliberately tiny experiment with it: change exactly one thing about an agent, hold everything else fixed, and see what the numbers attribute to that one change.
I have a small "GitHub summarizer" agent: one system prompt, one job — answer questions about my GitHub account by calling the GitHub MCP server. I duplicated its configuration (MAVERIK supports this directly — same model, same prompt, same everything) and changed one field on the copy: the set of attached MCP servers, adding deepwiki, microsoft-learn, and context7. Neither agent needs any of those three for the question I was about to ask; they were attached because that's what the "kitchen sink" version of this agent had accumulated over a few sessions of general-purpose use.
Then I wrote the simplest possible test suite — one question:
"How many repositories do I have?"
with a contains criterion checking the answer includes the correct count. No judge model, no subjectivity — it either says the right number or it doesn't. I ran both agents against it, 2 repetitions each, same model (claude-haiku) for both, and pulled up MAVERIK's Agent Comparison report.
Agent A — github only |
Agent B — github + 3 more MCP servers |
|
|---|---|---|
| MCP servers attached | 1 | 4 |
| Pass rate | 100% | 100% |
| Tool calls per question | 1 (get_me) |
1 (get_me) |
| Iterations per question | 2 | 2 |
| Avg input tokens | 16,628 | 21,467 |
| Avg output tokens | 138 | 144.5 |
| Avg peak context tokens | 8,494 | 10,919.5 |
| Avg duration | 3,659 ms | 3,061 ms |
| Token cost / question | $0.034636 | $0.044379 |
| Tool cost / question | $0.0000 | $0.0000 |
| Overall cost / question | $0.034636 | $0.044379 |
(Raw CSV, straight out of the report's export button, is at the bottom of this post if you want to check my arithmetic.)
What actually moved
Three numbers moved together, consistently, across both repetitions:
- Input tokens: +29.1% (16,628 → 21,467) — and it's exactly the same number on both repetitions for each agent. That's not noise; that's the tool catalog being serialized into every request, deterministically, regardless of which tools actually get called.
- Peak context tokens: +28.6% (8,494 → 10,919.5) — same story, since peak context is dominated by that same input payload.
- Cost per question: +28.1% ($0.034636 → $0.044379) — tracking the input-token increase almost 1:1, because output tokens barely moved (138 vs. 144.5) and no priced tools were called by either agent. The three unused MCP servers weren't free — they were billed on every single request, whether the model reached for them or not.
One caveat I want to make before someone else does: 28% is a function of how small this task is. The tax itself is absolute — ~4,839 extra input tokens on every request — so on a task with 50k tokens of real context the percentage would look much smaller. But that's the wrong comfort: the absolute tax is paid on every iteration of every run this agent ever makes, forever. Short tasks are where the tax is most visible, not where it's worst.
What didn't move — and why that's the more interesting part
- Pass rate: identical (100%/100%). Extra tools didn't confuse the model into a worse answer.
-
Tool calls and iterations: identical (1 call, 2 iterations, same tool —
get_me— both times). The model didn't waste a call poking at an irrelevant server "just in case." Having more options didn't make it indecisive here. -
Duration: actually lower for the agent with more servers attached (3,061 ms vs. 3,659 ms) — the opposite of what the token numbers would predict. Looking at the individual repetitions, agent A's first call was a slow outlier (4,402 ms) that dragged its average up; its second call (2,916 ms) was actually faster than either of agent B's. With only 2 repetitions this is provider-side latency noise, not signal — which is exactly why MAVERIK has a
repetitionsknob in the first place. I'd want a much largernbefore drawing any conclusion about latency here. Token counts, by contrast, needed zero repetitions to trust — they were bit-for-bit identical across both runs of the same agent, because they're a function of the prompt and tool schemas, not the network.
That asymmetry is the real lesson: cost is a much cleaner signal than latency. If I'd only looked at duration, I'd have concluded the bigger agent was better. It took breaking the run down by token count — something a stopwatch can't tell you — to see the actual, deterministic tax of the extra servers.
The takeaway
It's a reminder that "which MCP servers does this agent have access to" is a tunable parameter with a real, measurable cost, not a one-time architectural decision you make and forget. Every tool a server exposes gets its name, description, and JSON schema stuffed into the model's context on every call. A server with a large or verbose tool catalog is a standing tax on every request an agent makes, independent of whether that agent ever calls it.
There's a design consequence hiding in that, too. Restricting which tools an agent may use only saves you money if the host enforces the restriction before serialization: a disallowed tool has to be left out of the request entirely, not merely rejected when the model tries to call it. Enforce it at call time and you keep paying the token tax for tools the agent was never allowed to touch. The same trimming shrinks your actual attack surface, in the security sense — every unused tool schema in context is one more thing a prompt injection can try to steer the model toward.
The practical version of this: if you're building agents against MCP servers, don't default to "attach everything, it might be useful." Give each agent only the servers its job actually requires, and — if you're not sure whether a broader toolset is worth its overhead — measure it instead of guessing. That's a two-line duplication of an agent config and a one-question test suite, and the answer was sitting in a CSV five minutes later.
Reproducing this
This whole thing was: duplicate an agent config, write a one-question suite with a contains criterion, run both agents against it a couple of times, open the built-in Agent Comparison report (or export it to CSV, like I did above). If you're evaluating your own MCP servers or agent configs, the project is open source — https://github.com/langens-jonathan/maverik.
Raw CSV (Reporting → Agent Comparison → Export → To CSV)
suiteId,agentId,timestamp,sourceRunId,passRate,avgDurationMs,avgInputTokens,avgOutputTokens,avgToolCalls,avgPeakContextTokens,tokenCost,toolCost,overallCost
github-summarizer,github-test-agent,2026-07-26T10:07:18.9720785+00:00,github-summarizer-20260726-100718,1,3659,16628,138,1,8494,0.034636,0,0.034636
github-summarizer,github-test-agent-all-mcp-servers,2026-07-26T10:07:18.9720785+00:00,github-summarizer-20260726-100718,1,3061,21467,144.5,1,10919.5,0.044379,0,0.044379
Enter fullscreen mode Exit fullscreen mode
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.