Cutting Agent Token Costs in .NET: Tool Search, Output Gating and What the Numbers Really Say A hands-on C# experiment using llama.cpp's llama-server with the Qwen2 tokenizer found that replacing a full MCP-style tool catalog with two meta tools (tool_search and call_tool) cut tool-definition tokens by 85.8% at 15 tools, 91.8% at 30 tools, 95.3% at 60 tools and 97.8% at 120 tools, with the meta-tool pair costing a flat 278 tokens against 1,952 to 12,617 for the full lists. The author reports that some savings reproduced, one technique made costs worse in the configuration commonly recommended, and another broke when an unnamed detail changed, and notes the test model used random weights so results measure prompt layout cost only, not whether a real model would select the correct tool. The post cites Microsoft's own benchmark, as reported by Nithin, of over 60% fewer input tokens at 50 tools and over 97% at 1,000 tools, measured against a prompt-cached baseline. Every few days another post tells me I can cut my agent’s token bill by 60%, 90%, 98%. I believe most of these numbers are real in the setup where they were measured. What I never know is whether they survive contact with my setup. So I tried to build the stack myself in C , layer by layer, and measure each layer with token counts that come from the runtime, not from a chars / 4 guess. Some savings reproduced. One made things worse in the configuration everyone recommends. One fell apart the moment I changed a detail nobody talks about. Here is what I tried, what I measured, and what I could not test at all. Every number in this post is one of three kinds, and I say which: If a source only reached me through a newsletter, I say that too. I wanted the counts to come from a real tokenizer and a real KV cache, so I used llama-server from llama.cpp, which reports two numbers on every response: That second number is the closest local analogue to “uncached input tokens” on a paid API. Now the confession. The machine I ran this on could not download model weights. So I took the Qwen2 tokenizer that ships inside the llama.cpp repo, wrapped it in a tiny random-weight model with the Qwen2 architecture, and served that with the official Qwen2.5 chat template. The model’s text output is garbage. That’s fine for this experiment, because: What this means in practice: my numbers tell you what a prompt layout costs . They tell you nothing about whether a real model would pick the right tool with that layout. I’ll come back to that, because it’s the biggest hole in this post. The session is eight turns of an on-call scenario: check crashing pod logs, find the Jira ticket, look at slow queries, read a README, check CI runs, grep for timeouts, post to Slack, find a meeting slot. Two of the tool outputs are real files from the llama.cpp checkout its README and a real grep -rn -i timeout over the server sources . The rest are synthetic but sized like what those servers return. The pod log is 600 lines of noise with one real crash in the middle. The tool catalog is 60 MCP-style tools across eight servers GitHub, Jira, Postgres, filesystem, Slack, Kubernetes, calendar, Confluence . For the 120-tool test I duplicated them as legacy tools, which is ugly but honestly not far from what I've seen in real orgs that run two versions of the same MCP server. Before any session logic, I sent the same one-word prompt hi with different tool lists and subtracted the bare prompt. TOOLS IN LIST FULL LIST TOKENS tool search + call tool TOKENS CHANGE---------------------------------------------------------------------------------15 1,952 278 -85.8%30 3,399 278 -91.8%60 5,975 278 -95.3%120 12,617 278 -97.8% Measured by me, Qwen2 tokenizer, Qwen2.5 chat template. This is the number that makes tool search look like a no-brainer. Roughly 100 tokens per tool definition, and two meta tools cost a flat 278. I first read about this in Nithin’s article on Toolboxes and Tool Search in Microsoft Foundry https://www.c-sharpcorner.com/article/cut-agent-token-costs-with-toolboxes-and-tool-search-in-microsoft-foundry . The Microsoft Learn page https://learn.microsoft.com/en-my/Azure/foundry/agents/how-to/tools/tool-search confirms the mechanics: The headline numbers, as Nithin reports them from Microsoft’s own benchmark, are over 60% fewer input tokens at 50 tools and over 97% at 1,000. Two things matter about that claim. It’s Microsoft’s benchmark, not something Nithin or I measured. And the baseline was prompt-cached. Hold on to that second detail. Here is my local version. First, plain BM25: // Bm25.csusing System.Text.RegularExpressions;namespace TokenStack;// Plain Okapi BM25. Same family Foundry says it uses for toolbox search.public sealed class Bm25