Claude Code Token 开销优化:MCP 瘦身实战指南
适用:Claude Code(或其他带 MCP 的 agent CLI)重度使用者。核心结论:input ≫ output 是常态,不必焦虑;但 MCP 工具 schema 可能让 2-3 成 input 在”陪跑”,且完全可以瘦下来。
1. 先聊一个问题:一天 input 上亿 token,正常吗?
正常。 agent 类负载的 input:output 在 100:1 ~ 1000:1 都常见(实测案例:一天 103M : 746k ≈ 138:1)。原因是 LLM API 无状态——每一轮请求都完整重发上下文:
| 组成部分 | 说明 | 量级 |
|---|---|---|
| 系统提示 + 环境信息 | CLI 内置 prompt、git 状态等 | ~5k token,固定 |
| CLAUDE.md 系列 | 全局/项目/rules 的指令文件 | 数 k,固定 |
| Skills 元数据 | 所有已安装技能的 description | 数 k,固定 |
| MCP 工具 schema | 所有已连 server 的全部工具定义,不管用不用 | 可达数十 k,固定 |
| 历史消息 + 工具结果 | 之前所有轮次 | 持续增长 |
会话滚到 15 万 token 上下文后,你说一句”继续”就是一次 15 万 token 的 input。而且输出 token 单价通常是输入的 ~5 倍——输出少是好事。
真正该看的三个指标:
- 缓存命中率:prompt caching 的缓存读约 0.1× 原价、写约 1.25×(5 分钟 TTL)。同样 input,90% 走缓存和全量冷读成本差近 10 倍。
- **单位输入的”有用功”**:有多少 input 是陪跑的——比如你改 bug 时,接口文档类 MCP 的 schema 也在每次请求里跟着跑。
- 上下文窗口占用:无用 schema 挤占有效上下文,会话更早触发 compact。
2. MCP 是怎么吃 token 的
- server 连接后,全部工具定义(name + description + 参数 JSON Schema)注入每次请求,与本次任务是否相关无关。
- 重量大头是 description——带大段描述 + 参数说明 + 示例的工具,一个定义几百上千 token;中文内容分词更重。
- 工具数 × 描述长度 = 每 server 固定开销。实测一个重度配置:14 个 server、~150 个工具、每请求 35-50k token 的固定 schema 开销,占全天 input 的 2-3 成。
2.1 关键对照:Skill 的”发现机制”便宜两个数量级
让 AI”知道有东西可用”,MCP 不是唯一方式。skill(如浏览器自动化类技能)只把 frontmatter 的 name + description(~百来 token)常驻上下文,正文按需加载、用完即走;执行走普通 Bash。
| MCP | Skill | |
|---|---|---|
| 常驻上下文 | 全部工具完整 schema | 仅 description,~0.1k |
| 细节加载 | 永远在场 | 任务匹配时才读正文 |
| 执行通道 | MCP 工具调用 | Bash / CLI |
实测案例:移除某浏览器类 MCP(29 个工具,~7k/请求)后,由 browser skill + CLI 完全接管(同期该 skill 触发 854 次,早就是主力)。
选型推论:一个能力若有 skill + CLI 形态,就别常驻它的 MCP。MCP 留给确实需要结构化工具协议的场景(如项目管理平台这类几十个对象的 CRUD)。
3. 盘点自己的 MCP(可复制的三步)
3.1 看配置来源
1 | |
作用域优先级:user(全局)→ project(.mcp.json,可进 git)→ local(本机本项目)→ 启动参数 --mcp-config(加 --strict-mcp-config 时只认它)。
3.2 实测”哪些工具真的在用”(关键一步)
配置文件只会告诉你挂了什么,调用记录才告诉你什么在用。Claude Code 的会话转录在 ~/.claude/projects/<项目路径-斜线变横线>/*.jsonl,直接统计:
1 | |
输出形如 178 mcp__tapd__,就是各 server 的真实调用分布。
进阶:统计到具体工具级,找出”只用了几个工具却挂着几十个”的 server:
1 | |
技巧:转录里有固定的工具名注入基线(每个工具名可能出现 N 次,与真实调用无关)。计数明显高于基线的才是真实使用。
3.3 得出判断
把数据排成一张表:server × 工具数 × 调用次数 × schema 估算,通常会发现三类问题:
- 死配置:连接失败的 server,白耗启动时间
- 作用域错配:低频 server(如某系统的接口文档导出,只在写 service 时用)挂在全局,跟着每个会话跑
- 单点超重:某个 server 几十个工具、超长描述,独占一半 MCP 开销
4. 优化四板斧(按收益排序)
4.1 删死配置(零风险)
1 | |
4.2 作用域下沉
低频 server 从 user 挪到真正用它的项目:
1 | |
4.3 分级启动(核心方案)
--strict-mcp-config 让本次启动只加载指定文件、忽略全局和项目配置。把日常高频 server 抽成一个独立文件:
1 | |
1 | |
| 档位 | 内容 | 适用 |
|---|---|---|
claude(全套) |
全部 server | 少数需要跨系统查资料的场景 |
cg(日常) |
2-3 个高频 server | 大多数开发会话 |
cm(最小) |
0-1 个 | 纯编码,不碰外部系统 |
注意:
--strict-mcp-config会连项目.mcp.json一起忽略,项目专属 server 要复制进日常文件。验证用会话内/mcp(claude mcp list看不到启动参数文件)。
4.4 用 skill + CLI 替代 MCP
见 2.1。移除前先确认:该能力的 skill 版触发正常、且你实际用到的工具子集 skill 都能覆盖(用 3.2 的工具级统计验证)。
预期收益(实测案例)
全套 ~150 工具 / ~40k schema 的配置:删死配置 + 移除 1 个冗余 server + 日常档启动后,**日常每请求省 15-20k schema token,占 MCP 固定开销的 40-50%**;最小档接近清零。按 600 请求/天折算,每天省 10M+ input(大部分走缓存读时成本收益打折,但上下文占用与延迟改善是实打实的)。
5. 验证收益
1 | |
6. 常见坑
--strict-mcp-config忽略项目.mcp.json→ 项目专属 server 要复制进日常文件- 别名只对交互 shell 生效,IDE 插件/脚本启动不走
claude mcp list只反映注册配置,不反映启动参数文件- MCP 配置改动要重启会话才生效(server 在启动时连接)
.mcp.json进 git 会团队共享——含 token 的 server 别放 project 作用域,放 local- MCP 之外的固定开销同样可瘦:精简 CLAUDE.md、清理低频 skill
- 换任务记得
/clear——历史消息是 input 的另一大头来路
附:命令速查
1 | |