[控场AI]
· 10 分钟阅读· 5,344 字

MCP工具定义要花多少Token?实测四款服务器与CLI对比

MCP工具定义要花多少Token?实测四款服务器与CLI对比

MCP工具定义的token开销取决于harness是否启用延迟加载,全量加载下GitHub服务器达23k token,开启tool search后仅185 token。

文章通过实测四款MCP服务器(gopls、terraform、github、grafana)的tools/list输出,量化了MCP工具定义的token成本。GitHub默认配置46个工具消耗11,207 token,全工具集91个工具达23,206 token,Grafana 81个工具为20,493 token。开销大头是JSON Schema(占83%)而非描述文本(占12%)。与CLI对比发现,gh帮助文本覆盖同等功能反而更贵,真正差异是急切加载与惰性加载。Anthropic和OpenAI均提供defer_loading机制,开启后模型仅需看到工具名称列表(GitHub为185 token),Anthropic称可减少85%以上定义token。文章最后建议通过服务器端裁剪(--toolsets/--tools)和保持少量高频工具非延迟加载来控制成本,并强调应实测自己的配置而非照搬表格。

MCP工具定义要花多少Token?实测四款服务器与CLI对比

围绕MCP(Model Context Protocol)最常见的质疑是:它会在每一轮对话里吃掉大量上下文,无论你是否真的用到这些工具。反方观点则认为,这取决于agent harness如何加载工具定义。ImportStatic的一篇实测文章用数据把这场争论变成了可测量的问题——结论是双方都对,而答案藏在harness的设置里。

MCP token开销实测

测量方法:用官方SDK跑一遍tools/list

作者写了一个小型Go程序,通过标准输入输出启动MCP服务器,调用tools/list拿到工具列表,再按模型API接收的格式序列化每个工具的名字、描述和输入schema,最后用o200k_base分词器计数。这个分词器对应GPT-4o、GPT-4.1、GPT-5及o系列模型。

测量有两个需要说明的边界。Claude模型有自己的分词器,需要用Anthropic的token计数端点来算,但这一步需要API密钥,作者没有。另外,模型提供商可能把工具定义渲染成自己的格式,因此发送的JSON与模型实际看到的并非完全一致。这些数字应当看作接近值,而非精确值。

四款服务器均从源码构建,使用最新tag版本,启动时使用假凭据——tools/list并不需要真实认证。

MCP(Model Context Protocol)是Anthropic于2024年11月开源的协议,旨在标准化AI模型与外部工具、数据源之间的连接方式。它采用客户端-服务器架构:MCP服务器通过标准输入输出或HTTP暴露工具、资源和提示模板,客户端(如Claude Desktop、IDE插件或agent harness)连接后可以列出并调用这些能力。tools/list是协议定义的核心端点之一,返回服务器提供的所有工具的名称、描述和JSON Schema格式的输入参数定义。由于模型API是无状态的,每次请求都需要重新传输这些定义,因此工具数量越多、schema越复杂,消耗的输入token就越多。这正是MCP上下文开销争议的技术根源。

四款真实服务器的token账单

服务器工具数定义token每工具均值
gopls v0.23.08878109
terraform-mcp-server v1.3.091,718190
github-mcp-server v1.14.0 默认4611,207243
mcp-grafana v1.6.38120,493253
github-mcp-server 全工具集9123,206255

小服务器很便宜,gopls给模型8个工具,开销不到一页文本。问题出在那些试图镜像整个产品API的服务器上:GitHub全工具集加上Grafana,在用户还没输入任何内容之前就是43,699个token。

这与Anthropic官方文档的说法吻合。其tool search文档举例称,一个包含GitHub、Slack、Sentry、Grafana和Splunk的五服务器配置,在Claude开始工作前就会消耗约55k token的工具定义。分词器不同、服务器版本不同,但数量级一致。

而且,如果没有延迟加载机制,这些开销会出现在每次请求中。模型API是无状态的。Anthropic的定价说明指出,工具使用按输入token计费,包括tools参数中的token,即工具名称、描述和schema。相比之下,固定约286 token的工具使用系统提示词在这个量级面前几乎可以忽略。

大头是JSON Schema,不是描述文本

GitHub服务器默认配置的完整输出值得拆开看:定义总计11,207 token,其中描述部分1,368 token,输入schema高达9,287 token。人们抱怨"工具描述浪费token"时想象的描述文本只占12%,schema占了83%。

以issue_write为例,它的描述只有一句话、14个token,但schema有783个token,因为它包含17个属性,其中若干属性还附带一段使用规则。比如parent_owner这个属性,其描述写着"必须与parent_repo一起提供,省略两者则使用owner和repo,仅在method为create且提供了parent_issue_number时使用"。

Grafana服务器走向另一个极端,描述5,777 token对schema 13,601 token,但schema依然占主导。如果你在写MCP服务器,优化重点应该放在这里。GitHub把"创建"和"更新"合并成一个带method参数的工具,节省了工具槽位,又把省下的预算花在了只对其中一种方法生效的参数上——这不一定是错的,但值得知道你的token花在了哪一边。

还有一行容易被忽略:instructions。服务器在客户端连接时可以返回自由文本指令,GitHub默认工具集是377 token,全工具集是1,559 token。Terraform的是924 token,超过其九个工具定义总量的一半。审计服务器时这项也该计入。

JSON Schema是一种用于描述和验证JSON数据结构的声明式规范,在MCP中用来定义工具输入参数的名称、类型、是否必填、默认值以及参数间的依赖关系。一个典型的工具schema包含type: object、properties对象和required数组,每个属性还可以嵌套描述、枚举值或条件约束。schema之所以比描述文本膨胀得快,是因为它必须精确到机器可解析的程度:每增加一个可选参数就多一个属性定义,每增加一条业务规则就多一段条件描述。以GitHub的issue_write为例,17个属性中多个带有"仅当method为create时使用"之类的规则,这些规则在schema中必须以自然语言描述的形式挂在对应属性上,无法省略。工具schema通常以JSON Schema Draft 7或2020-12为基准,但各服务器实现会有差异。

CLI并不更小,只是更懒

常见的替代方案是跳过MCP,让agent直接跑gh命令。作者用同样的分词器统计了gh v2.102.0的帮助输出:

  • gh --help:610 token
  • gh issue --help:346 token
  • gh issue create --help:869 token
  • gh issue edit --help:1,068 token
  • MCP issue_write(创建与更新合一):807 token

一个冷启动、逐层走读到gh issue create的agent要读1,825 token的帮助文本;覆盖issue_write功能的两页帮助合计1,937 token。逐操作对比,MCP定义反而更紧凑。

CLI的优势在于加载时机:不调用就不加载,从不提交issue的agent永远不会读到那一页。模型也可能因为训练数据熟悉gh而完全跳过帮助,这一点无法测量,而且对你的内部工具不成立。所以真正的差异从来不是格式,而是急切加载与惰性加载——这恰恰是harness改变的部分。

开启tool search后,账单只剩一串名字

Anthropic API提供了tool search工具,用defer_loading: true标记工具。文档明确说明,它"控制什么进入上下文窗口,而不是你在请求中发送什么"。定义仍然随tools数组传输,但模型只看到搜索返回的工具,默认每次最多五个。Anthropic称这通常能将定义token减少85%以上。对于通过其连接器挂载的MCP服务器,一次设置即可对整个服务器生效。

OpenAI的Responses API有同样的思路:tool_search工具,在gpt-5.4及更高版本上支持,同时支持对函数或MCP服务器设置defer_loading。对于延迟加载的服务器,模型最初只看到"命名空间或服务器名称和描述"。OpenAI建议每个命名空间下的函数不超过十个。

Claude Code默认开启tool search。其文档列出了不适用的场景:自定义ANTHROPIC_BASE_URL、设置ENABLE_TOOL_SEARCH=false、以及Google Cloud上的旧模型。开启后,Claude Code向模型展示服务器的工具名称列表,模型通过ToolSearch调用来使用它们。

工具名称列表有多小?GitHub默认的46个工具,实测名称列表为185 token,对比定义的11,207 token。每个harness有自己的列表格式,所以这只是一个下限。再加上搜索拉取的内容:五个平均大小的GitHub工具约1,200 token,且只出现在需要它们的轮次中。

这就是对那场争论的回答:在支持延迟加载的harness里,MCP的常驻成本是几百token;在不支持的harness里,就是上面整张表在每次调用中重复计费。

defer_loading是Anthropic和OpenAI在工具调用API中引入的延迟加载标记。它的工作机制是:工具定义仍然随请求的tools数组一起发送到API,但被标记为延迟加载的工具不会立即进入模型的上下文窗口,模型最初只能看到工具的名称或所属命名空间。当模型判断需要某个工具时,它先调用一个内置的搜索工具(Anthropic称为tool search,OpenAI称为tool_search),API根据搜索词返回匹配的工具定义,这些定义才被注入当前轮次的上下文。由于模型API本身无状态,每次请求仍需携带完整定义以保证服务端可解析,但计费与上下文占用只针对实际进入模型视野的部分。这就把"全量加载"变成了"按需加载",是harness层面而非协议层面的优化。

如果你的harness全量加载,怎么办

先确认现状。如果你自己调用模型API并把tools/list的结果原样传进去,那你就是在全量加载。规范的无状态修订改变的是客户端获取列表的方式,不是列表的大小。

然后在服务器端做裁剪。GitHub的README写得很直白:只启用需要的工具集有助于LLM选择工具并降低上下文体积。实测各flag的效果:--toolsets all为91个工具、23,206 token;默认46个、11,207 token;--read-only为27个、6,492 token;--toolsets issues为10个、3,281 token;指定三个工具为1,693 token。只做issue分流的agent不需要91个工具,用--tools启动的服务器成本只有全量集的7%。

能用tool search就用,同时把高频调用的少数工具保持为非延迟加载,Anthropic建议三到五个。其给出的启用阈值是十个以上工具,或超过10k token的定义——GitHub服务器在默认配置下已经越线。

最后,测量自己的配置,而不是相信任何人的表格,包括这篇里的。有Anthropic密钥的话,把真实的tools数组发给count_tokens,用你实际运行的模型来算。文档还提示,Claude Opus 4.7及之后版本对同样文本生成的token比早期Claude模型多约30%,旧计数会过时。没有密钥的话,一个短的Go程序加一个公开分词器,就能告诉你哪三个工具在吞噬你的上下文。

Agent harness是包裹在模型API外层的运行时框架,负责组装系统提示词、管理工具列表、维护对话历史、执行工具调用并处理返回结果。常见的harness包括Claude Code、OpenAI的Agents SDK、LangChain的AgentExecutor以及各厂商自研的内部框架。MCP服务器的token开销最终由harness决定:同一个GitHub服务器,在Claude Code中因为默认启用tool search而只占185 token的名称列表,在自行拼接tools/list结果并直接发给API的简易脚本中则每次请求都要付11,207 token。因此评估MCP成本时,服务器本身只是一半,另一半是harness的加载策略。这也是为什么文章强调"答案藏在harness的设置里"——协议相同,加载方式不同,账单可以差两个数量级。

#MCP token开销#MCP工具定义#tool search#defer_loading#JSON Schema token#GitHub MCP服务器#上下文窗口优化
分享:

相关推荐