作者对主流MCP服务器进行了标准化token计数实测,发现Claude计数比tiktoken高64%,并提供可复现的测量工具。
上个月我跑了 72 次试验来确定一个 MCP tool 应该返回什么,因为一位维护者拒绝接受观点作为答案。但这还剩另一半悬而未决:在 agent 开始任何工作之前,所连接的服务器吃掉了多少上下文窗口?
各大厂商在 2026 年发布了相关数据。我查了被引用最多的六个:其中只有一个是真正的测量研究——StackOne 在 2026-03-31 做的,测量了 GitHub 和 Atlassian,并穿透了 Cloudflare 的 code-mode 案例。剩下五个里,一个用的是假设的未命名服务器,三个根本没有任何针对服务器的 token 研究,还有一个我在任何域名下都找不到。因此,发表出来的最新水平只是一张快照,而且还是三月的数字。一个不重新测量的数字就是一张截图,而 MCP 服务器每隔几周就会变化。所以我建立了一个持续测量系统,叫 loadline:14 台服务器,方法论 0.2.0,一次运行日期为 2026-08-18,往后每月一次,每一行都可以用你自己的凭证从仓库复现。入口是一个堆栈计算器,不是一张表:真正有用的问题是,我的堆栈在我使用的客户端里要花多少。
三个计数器都统计同一个固定字符串,即方法论 1.5 节中的规范序列化结果。同样的字节,三个计数器。
在产生计数的 12 行中,溢价从 47.0%(github)到 70.5%(kubernetes),中位数 64.1,12 行中有 8 行在 60 到 66 之间。Gemini 与 o200k 的偏差在每一行都保持在 11% 以内,所以这不是"更大的模型计数更多"的效果。这是 Claude 的 tokenizer 对 schema 文本的特有问题。
我见过的每一份 MCP 成本研究都用 tiktoken 计数——这三者中唯一能离线免费运行的。如果你用 Claude 运行 agent,那些研究描述的上下文负载比你用相同 schema 实际付出的要少约 60%。它们对字节的计数没有错。它们是为循环中不同模型做的计数。
github 行测量了 47 个 tool,在 o200k_base 下为 59,084 tokens,在 claude-opus-5 下为 86,843。后一个数字是 200k 窗口的 43%,花在了第一个用户消息之前。
有两个限定词比这个数字更重要。首先,47 个 tool 是该服务器向这次运行使用的经典个人访问令牌公开的数量,而规范允许一个 surface 随提供的授权不同而变化,所以真实的 GitHub surface 更大。Auth scope 随每行发布,因为这是这里最大合法分歧的来源。
其次,没有人在 tool-search 客户端里会付这个代价。Claude Code 自 2026 年 1 月起默认采用渐进披露,在这个 surface 上模型化后约为 4,300 到 6,800 tokens:500-token 的 stub 加上 3 到 5 个 tool,按测量的平均 1,257-token 计算。这么大一个波动,完全由客户端驱动,就是为什么没有一行会发布一个成本数字的原因。永远是三种模式。而且"模型化"在里面是承载性的——这点我下面会讲到。
Cloudflare 的聚合端点用三个 tool 响应 tools/list:docs(362 tokens)、search(572)、execute(660)。o200k 下总计 1,596,比 github 朴素加载小 37 倍,而且卫生度保持在 B(85.19),所以压缩不是来自删除描述。
限定词:这是把聚合端点作为一台服务器测量的。Cloudflare 这次运行还交付了 16 个产品作用域端点,没有被枚举或汇总。
Chrome DevTools MCP,Google 官方出品,本次运行新测量,暴露了 52 个 tool,仅次于 linear 的 53 个,o200k 下为 7,984 tokens:每个 tool 153 tokens,语料库中最精简的平均值。Playwright 的 24 个 tool 每个 167,filesystem 的 14 个每个 192,linear 的 53 个每个 335。卫生度保持在 B(80.28),所以,和 Cloudflare 一样,精简不是来自删除描述。一台服务器可以携带比语料库中几乎所有其他服务器都多的 surface,同时仍然落在便宜的那一端。
fetch(参考实现)和 postgres 在运行执行时(2026-08-18 15:38 UTC)从全新安装都无法启动。两者都声明了对 MCP Python SDK 的无界依赖,fetch 为 mcp>=1.1.3,postgres 为 mcp[cli]>=1.5.0,所以两者都接受 resolver 交给它们的任何版本。Resolve 到 mcp 2.0.0 会以两种不同方式破坏两者。
fetch 导入了一个 2.0.0 改名的符号:
ImportError: cannot import name 'McpError' from 'mcp.shared.exceptions'.
Did you mean: 'MCPError'?
postgres 在更早一个导入处就死了,因为 2.0.0 不再从那个路径发布模块:
ModuleNotFoundError: No module named 'mcp.server.fastmcp'
然后,大约一小时后,在同一台机器上强制刷新 resolver 缓存重新检查这两行,fetch 恢复了。一次干净的 resolve 交给了它 mcp 1.29.0 而不是 2.0.0,它启动了。没有上游被撤回:2.0.0 仍是最新 release,没有被撤回。同样的命令,在同一台机器上,在同一个下午,以不同方式 resolve 了。postgres 仍然失败。
所以这篇文章所基于的 fetch: unreachable 行在写成后约一小时就过期了,而我按原样发布它,标记清楚,并在更正文日志中有一条记录,而不是悄悄地重新生成数据集直到它与正文一致。下个月的运行会说下个月真实的情况。
更有用的结果是,它发现了我自己仪器里的一个漏洞。Harness 记录了服务器包是否被 pinned,但从未记录 resolver 实际产生了哪个 SDK 版本,所以 artifact 无法解释为什么 15:38 和 16:45 不一致。这在下次运行前会修复。
我本来可以花一分钟 around the breakage 搞定它,但决定不这样做。Pinning 改变了这里"fetch server"的含义——发布一个受限的旧版本,同时暗示它描述的是你今天会安装的东西。Server rot 是这个主题的一部分,所以它是数据集的一部分。
figma 根本不出现在本次运行的行中:它没有通过公布的 selection rule 的 gate 2(免费层凭证下完整 surface 可枚举),因为它的 auth 是纯 OAuth 的,可复现的 harness 没有凭证来执行那个流程。它被排除在语料库之外而不是作为 auth 行发布,chrome-devtools 被晋升到释放的槽位。
Notion 重新设计的服务器很便宜:24 个 tool,o200k 下 5,180 tokens。它的卫生度得分 D(54.79),可检索性分数 0.5417,排名前三中的最低,MRR 为 0.4527。让它沉下去的是:when_to_use_signal 0,disambiguation 0,parameter_descriptions 44.03。Context7,2 个 tool 和 1,052 tokens,卫生度 A(97.22),前三 1.0,MRR 1.0。
在朴素的客户端下这个差异是不可见的:两种 surface 都只是提示中的文本。在 tool-search 客户端下这就是全部——因为搜索无法呈现的 tool 是 agent 得不到的 tool,无论它有多便宜。仅按 schema 大小排名,制胜招是 gutting descriptions。
每个单元格都带有 MEASURED 或 MODELED 标签。朴素全加载是测量的:规范序列化的 token 计数。tool-search 列中的 per-tool 成本是测量的,但其总计是模型化的,因为 k——一个 session 拉取的 tool 数量——是一个假设,这就是为什么它发布为 3-to-5 范围而不是一个点。Code mode 端到端都是模型化的,并保持该标签直到 Tier 2 运行验证它。
可检索性查询源自每个 tool 自己的描述,所以该指标衡量的是服务器内 disambiguation——兄弟 tool 是否相互遮蔽——而不是真实措辞是否能找到一个 tool。它与卫生度等级共享输入文本,所以两者不是独立证据。
美元数字是估计值,由价格表计算有待验证,仅作为冷写和缓存读取对显示。Token 始终是主要单位:一个单一的美元数字是作为冷启动数字呈现的,就好像它会重复出现,高估了稳态约 10 倍,因为 tool 定义是一个近乎完美的缓存前缀。其余内容在 docs/methodology-v0.md 0.2.0 中,每个判断调用都有被拒绝的替代方案。
中立性不是靠我的话说的,所以这里是可检查的部分。
Selection 运行遵循公布规则:五个二元 gate(协议合规、免费层凭证下完整 surface 可枚举、可验证的采用证据、过去六个月内发布、没有官方继承者),加上类别分布和 15 个槽位上限。覆盖率不是这个项目做出的声明。任何人都可以通过公开 issue 提交服务器,得到 gate 结果(通过或失败),并附上失败的 gate 名称。
更正文日志是公开的和仅附加的,在第一次排名之前有两条记录:一条是方法论说的 harness 做什么和实际上做什么之间的不匹配,在任何发布前的 review 中被 catch;另一条是上面的 fetch 行。在服务器的数字首次发布之前,其维护者有 14 天时间查看这些行、artifact 和方法论版本;回复逐字发布在行旁边,不回复记录为"未收到回复",而不是同意。
每一行都附带三个 SHA-256 哈希的工具 surface 加上原始 wire artifact,所以有争议的计数可以对照它来自的字节检查,而不是对照我的话。回避在第一次排名前发布,我自己的项目按规则被排除在排名之外。
Repo: github.com/lopster568/loadline。计算器: loadline-dev.netlify.app。
下一次运行会增加 slack,一旦其 operator 凭证落地,并开始 Tier 2:通过调用日志代理运行脚本化任务,测量真实的调用和响应流。Tier 2 是能力轴,如果它停止运行,排行榜暂停,因为仅成本的排名比没有更糟糕。
如果这里的数字有误,告诉我并带上那一行。Harness、语料库文件、artifact 和派生查询集都在仓库里,所以分歧可以是具体的,更正会记入日志并附上你的名字。
lopster568 / loadline
状态:预发布草稿。未发布。所有文本有待所有者审核。
loadline 是对 MCP 服务器成本(对 agent 上下文窗口)的持续性、版本化测量。它按月节奏运行——今天按 docs/pc-sweep-runbook.md 手动运行——跨越一组精选的服务器,用三个 tokenizer 适配器计数工具 schema tokens,并通过堆栈计算器报告结果:选择服务器、客户端模式和模型,得到总上下文占用、窗口份额、per-server 归属和一对冷写/缓存读取美元数字。发布的行携带所有三个 tokenizer 的计数(OpenAI o200k 本地、Claude 和 Gemini 通过其 token 计数 API);无法获得计数的单元格发布为 available: false,从不作为估计。成本始终按客户端模式报告(朴素全加载、tool search / 渐进披露、code mode),从不折叠成一个数字,因为同一堆栈根据客户端的使用方式成本不同……
我做这个工作是有报酬的:在你的 agent 的工具 surface 花任何工作之前审计它花费多少,并在不 gutting 搜索仍然可以找到的内容的情况下削减它。范围和定价在 roshansingh.systems/#hire,或写信到 inbox@roshansingh.systems 告诉我你的 agents 在加载什么。