How Many Tokens Do MCP Tool Definitions Cost? Testing Four Servers Against the CLI

MCP tool definition token overhead depends on whether the harness enables lazy loading: full loading puts the GitHub server at 23k tokens, while tool search reduces it to just 185.
The article quantifies MCP tool definition token costs by measuring the tools/list output of four MCP servers (gopls, terraform, github, grafana). GitHub's default 46 tools consume 11,207 tokens, the full 91-tool set reaches 23,206, and Grafana's 81 tools total 20,493. JSON Schema (83%) dominates over description text (12%). Compared with the CLI, gh help text covering equivalent functionality is actually more expensive — the real difference is eager versus lazy loading. Anthropic and OpenAI both offer defer_loading; with it enabled the model only sees a tool name list (185 tokens for GitHub), and Anthropic claims an 85%+ reduction. The article recommends server-side trimming (--toolsets/--tools) and keeping a few high-frequency tools non-deferred, and stresses measuring your own configuration rather than copying tables.
How Many Tokens Do MCP Tool Definitions Cost? Testing Four Servers Against the CLI
The most common criticism of MCP (Model Context Protocol) is that it eats up a large amount of context in every conversation turn, whether or not you actually use those tools. The counterargument is that this depends on how the agent harness loads tool definitions. A hands-on article from ImportStatic turns this debate into a measurable question with data — the conclusion is that both sides are right, and the answer lies in the harness settings.

Measurement Method: Running tools/list with the Official SDK
The author wrote a small Go program that launches MCP servers over stdin/stdout, calls tools/list to get the tool list, serializes each tool's name, description, and input schema in the format the model API receives, and finally counts tokens with the o200k_base tokenizer. This tokenizer corresponds to GPT-4o, GPT-4.1, GPT-5, and the o-series models.
There are two caveats to the measurement. Claude models have their own tokenizer and require Anthropic's token counting endpoint, but that step needs an API key, which the author didn't have. In addition, model providers may render tool definitions into their own format, so the JSON sent is not exactly what the model sees. These numbers should be treated as close approximations, not exact values.
All four servers were built from source, using the latest tagged versions, and launched with fake credentials — tools/list doesn't require real authentication.
MCP (Model Context Protocol) is a protocol open-sourced by Anthropic in November 2024, designed to standardize how AI models connect to external tools and data sources. It uses a client-server architecture: MCP servers expose tools, resources, and prompt templates over stdin/stdout or HTTP, and clients (such as Claude Desktop, IDE plugins, or agent harnesses) connect to list and invoke these capabilities. tools/list is one of the protocol's core endpoints, returning the name, description, and JSON Schema input parameter definitions for all tools a server provides. Because model APIs are stateless, these definitions must be retransmitted with every request, so the more tools there are and the more complex the schemas, the more input tokens are consumed. This is the technical root of the MCP context overhead debate.
The Token Bill for Four Real Servers
| Server | Tool Count | Definition Tokens | Average per Tool |
|---|---|---|---|
| gopls v0.23.0 | 8 | 878 | 109 |
| terraform-mcp-server v1.3.0 | 9 | 1,718 | 190 |
| github-mcp-server v1.14.0 default | 46 | 11,207 | 243 |
| mcp-grafana v1.6.3 | 81 | 20,493 | 253 |
| github-mcp-server full toolset | 91 | 23,206 | 255 |
Small servers are cheap; gopls gives the model 8 tools at a cost of less than a page of text. The problem lies with servers that try to mirror an entire product API: the GitHub full toolset plus Grafana comes to 43,699 tokens before the user has typed anything.
This matches what Anthropic's official documentation says. Its tool search docs give the example of a five-server configuration including GitHub, Slack, Sentry, Grafana, and Splunk, which consumes about 55k tokens of tool definitions before Claude even starts working. Different tokenizers and server versions, but the same order of magnitude.
And without lazy loading, this overhead appears on every request. Model APIs are stateless. Anthropic's pricing documentation states that tool use is billed as input tokens, including tokens in the tools parameter — that is, tool names, descriptions, and schemas. By comparison, the roughly 286-token tool use system prompt is almost negligible at this scale.
The Bulk Is JSON Schema, Not Description Text
The full output for the GitHub server's default configuration is worth breaking down: 11,207 tokens total, of which 1,368 are description text and a whopping 9,287 are input schema. The description text people imagine when they complain that "tool descriptions waste tokens" accounts for only 12%, while schema accounts for 83%.
Take issue_write as an example: its description is a single sentence of 14 tokens, but its schema is 783 tokens because it contains 17 properties, several of which carry usage rules. The parent_owner property, for instance, is described as "must be provided together with parent_repo; omitting both uses owner and repo; only used when method is create and parent_issue_number is provided."
The Grafana server goes to the other extreme, with 5,777 tokens of description versus 13,601 of schema, but schema still dominates. If you're writing an MCP server, that's where your optimization effort should go. GitHub merged "create" and "update" into a single tool with a method parameter, saving a tool slot while spending the saved budget on parameters that only apply to one of the methods — not necessarily wrong, but worth knowing which side your tokens are going to.
There's one more line that's easy to overlook: instructions. Servers can return free-text instructions when a client connects — 377 tokens for the GitHub default toolset and 1,559 for the full toolset. Terraform's is 924 tokens, more than half the total of its nine tool definitions. This should also be counted when auditing a server.
JSON Schema is a declarative specification for describing and validating JSON data structures, used in MCP to define tool input parameter names, types, required status, default values, and inter-parameter dependencies. A typical tool schema contains type: object, a properties object, and a required array, and each property can further nest descriptions, enum values, or conditional constraints. Schemas balloon faster than description text because they must be precise enough for machines to parse: each additional optional parameter adds a property definition, and each additional business rule adds a conditional description. Take GitHub's issue_write: among its 17 properties, several carry rules like "only used when method is create," and these rules must be attached to the corresponding properties as natural-language descriptions in the schema — they cannot be omitted. Tool schemas are typically based on JSON Schema Draft 7 or 2020-12, though implementations vary across servers.
The CLI Isn't Smaller, Just Lazier
The common alternative is to skip MCP and have the agent run gh commands directly. The author counted the help output of gh v2.102.0 with the same tokenizer:
gh --help: 610 tokensgh issue --help: 346 tokensgh issue create --help: 869 tokensgh issue edit --help: 1,068 tokens- MCP
issue_write(create and update combined): 807 tokens
A cold-start agent that reads through layer by layer to gh issue create would read 1,825 tokens of help text; the two help pages covering issue_write functionality total 1,937 tokens. Compared operation by operation, the MCP definition is actually more compact.
The CLI's advantage is loading timing: it isn't loaded unless called, and an agent that never files an issue will never read that page. The model might also skip the help entirely because it's familiar with gh from training data — this can't be measured, and it doesn't hold for your internal tools. So the real difference was never the format, but eager versus lazy loading — which is exactly the part the harness changes.
With Tool Search Enabled, the Bill Shrinks to a List of Names
The Anthropic API provides a tool search tool that marks tools with defer_loading: true. The documentation explicitly states that it "controls what enters the context window, not what you send in the request." Definitions are still transmitted in the tools array, but the model only sees the tools returned by the search — up to five by default each time. Anthropic says this typically reduces definition tokens by more than 85%. For MCP servers mounted through its connectors, one setting applies to the entire server.
OpenAI's Responses API follows the same idea: the tool_search tool, supported on gpt-5.4 and later, along with defer_loading for functions or MCP servers. For deferred-loading servers, the model initially sees only "the namespace or server name and description." OpenAI recommends no more than ten functions per namespace.
Claude Code enables tool search by default. Its documentation lists the cases where it doesn't apply: a custom ANTHROPIC_BASE_URL, setting ENABLE_TOOL_SEARCH=false, and older models on Google Cloud. When enabled, Claude Code shows the model a list of the server's tool names, and the model uses them via ToolSearch calls.
How small is the tool name list? For GitHub's 46 default tools, the name list measured 185 tokens, versus 11,207 for the definitions. Each harness has its own list format, so this is a lower bound. Add in what the search pulls in: five average-sized GitHub tools at about 1,200 tokens, and only in the turns that need them.
That's the answer to the debate: in a harness that supports lazy loading, MCP's resident cost is a few hundred tokens; in one that doesn't, it's the entire table above, billed again on every call.
defer_loading is a lazy-loading flag introduced by Anthropic and OpenAI in their tool-calling APIs. It works like this: tool definitions are still sent to the API in the request's tools array, but tools marked for deferred loading don't immediately enter the model's context window — the model initially sees only the tool's name or its namespace. When the model decides it needs a tool, it first calls a built-in search tool (called tool search by Anthropic and tool_search by OpenAI), the API returns matching tool definitions based on the search terms, and only then are those definitions injected into the current turn's context. Because model APIs are stateless, each request must still carry the full definitions so the server can parse them, but billing and context usage only apply to what actually enters the model's view. This turns "load everything" into "load on demand" — an optimization at the harness level rather than the protocol level.
What to Do If Your Harness Loads Everything
First, confirm the current state. If you call the model API yourself and pass the results of tools/list in as-is, you're loading everything. The stateless revision of the spec changes how clients get the list, not the size of the list.
Then trim on the server side. GitHub's README says it plainly: enabling only the toolsets you need helps the LLM choose tools and reduces context size. The measured effect of each flag: --toolsets all gives 91 tools and 23,206 tokens; default is 46 tools and 11,207 tokens; --read-only is 27 tools and 6,492 tokens; --toolsets issues is 10 tools and 3,281 tokens; specifying three tools is 1,693 tokens. An agent that only routes issues doesn't need 91 tools — a server launched with --tools costs just 7% of the full set.
Use tool search if you can, and keep a small number of frequently used tools non-deferred — Anthropic recommends three to five. The suggested threshold for enabling it is more than ten tools or definitions over 10k tokens — the GitHub server crosses that line in its default configuration.
Finally, measure your own configuration rather than trusting anyone's table, including this one. If you have an Anthropic key, send the real tools array to count_tokens and count with the model you actually run. The documentation also notes that Claude Opus 4.7 and later generate about 30% more tokens for the same text than earlier Claude models, so old counts go stale. Without a key, a short Go program plus a public tokenizer will tell you which three tools are eating your context.
An agent harness is the runtime framework wrapped around the model API, responsible for assembling the system prompt, managing the tool list, maintaining conversation history, executing tool calls, and handling returned results. Common harnesses include Claude Code, OpenAI's Agents SDK, LangChain's AgentExecutor, and vendors' in-house frameworks. The token overhead of an MCP server is ultimately determined by the harness: the same GitHub server occupies only a 185-token name list in Claude Code (because tool search is enabled by default), while in a simple script that stitches together tools/list results and sends them straight to the API, you pay 11,207 tokens on every request. So when assessing MCP cost, the server itself is only half the story — the other half is the harness's loading strategy. This is also why the article emphasizes that "the answer lies in the harness settings" — same protocol, different loading approach, and the bill can differ by two orders of magnitude.
One-line Summary
MCP tool definition token overhead depends on whether the harness enables lazy loading: with full loading, the GitHub server comes to 23k tokens, but with tool search enabled it's just 185.
Paragraph Summary
By measuring the tools/list output of four MCP servers (gopls, terraform, github, grafana), the article quantifies the token cost of MCP tool definitions. GitHub's default configuration of 46 tools consumes 11,207 tokens, the full toolset of 91 tools reaches 23,206 tokens, and Grafana's 81 tools total 20,493 tokens. The bulk of the overhead is JSON Schema (83%), not description text (12%). A comparison with the CLI finds that gh help text covering the same functionality is actually more expensive, and the real difference is eager versus lazy loading. Both Anthropic and OpenAI offer a defer_loading mechanism; with it enabled, the model only needs to see a list of tool names (185 tokens for GitHub), and Anthropic says it can cut definition tokens by more than 85%. The article concludes by recommending server-side trimming (--toolsets/--tools) and keeping a small number of high-frequency tools non-deferred to control cost, and stresses that you should measure your own configuration rather than copying tables.
Related articles

AI-Powered SRC Vulnerability Hunting: A Hands-On Guide to Building the Hermes Agent Workbench
Based on a hands-on Bilibili video: how to build an AI-powered SRC vulnerability hunting workbench—three-step method, four report elements, Agent mode vs web chat, and tool selection.

CLI-Anything Complete Beginner's Guide: How AI Operates Software — Principles and Practice
A complete beginner's guide to CLI-Anything: how AI Agents operate professional software via the command line, covering the three-layer architecture, CLI Hub installation, DrawIO practice, generator principles, and limits.

Carbon-X: A 14.8B Open-Source Model That Handles DNA and Text Simultaneously
Carbon-X is a 14.8B open-source multimodal model on Hugging Face where DNA and text share a token stream. 6-mer tokenization, 302B token mid-training, deployable on a single 80GB GPU, 66.7% average on five DNA benchmarks, Apache 2.0 license.