恋爱邦
107.39M · 2026-04-09
2026年1月,OpenClaw 创始人 Peter Steinberger 在 X 上发了一条推文:
这条推文在 AI 开发者社区埋下了一颗种子。一个月后,Eric Holmes 发布博文《MCP is dead. Long live the CLI》,从六个维度系统论证 CLI 优于 MCP,引发了广泛讨论。随后 Jannik Reinhard 发布实测数据,Matt Hall 发布反驳文章,中文社区的掘金、头条上也出现了大量分析——这场争论在钉钉、飞书开源 CLI 时达到高潮。
Jannik Reinhard 用实测数据揭示了 MCP 最尖锐的问题——上下文吞噬。
一个 GitHub MCP Server 需要将 93 个工具的完整 Schema 注入模型上下文,总计约 55,000 tokens——还没问任何问题,上下文就没了将近一半。多个 MCP Server 叠加,轻松突破 15 万 tokens。
他在 Intune 设备合规检查任务上做了并行对比:
| 指标 | MCP 方案 | CLI 方案 | 差距 |
|---|---|---|---|
| Schema 注入 | ~28,000 tokens | 0 tokens | — |
| 推理 + 调用 | ~3,200 tokens | ~800 tokens | 4x |
| 50 台设备处理总消耗 | ~145,000 tokens | ~4,150 tokens | 35 倍 |
CLI 方案的 Agent 有 95% 的上下文窗口留给实际推理,而 MCP 方案的 Agent 大量精力花在解析 Schema 上。
为什么 CLI 更省? 因为 AI 模型在数十亿行终端交互上训练过——Stack Overflow 答案、GitHub 仓库、man page。当你说 gh pr view 123,模型天然理解。而 MCP Schema 是模型运行时第一次见到的自定义抽象,需要额外的认知开销去理解。
社区基准测试也证实了这一点:CLI 的任务完成率高出 MCP 约 28%,Token 效率得分高出 33%。
Eric Holmes 指出了 MCP 的可调试性问题:CLI 对人类可见,而 MCP 工具只存在于 LLM 对话内部。
# CLI:出问题了,我自己跑一遍就知道
$ gh pr view 123
# 看到和 Agent 一样的输出
# MCP:出问题了,你得翻 JSON 传输日志
# 工具调用隐藏在 LLM 对话流里
# 没有 "自己跑一遍" 的选项
这个痛点很真实。MCP 把工具调用封装在协议层后面,人类开发者失去了"复现 Agent 行为"的能力。
Matt Hall 的反驳文章《MCP Isn't Dead. We're Just Early.》代表了另一派观点。
grep | jq | awk 对人类来说灵活,但无类型管道容易静默失败,Agent 链式调用时边缘情况频发gh auth login 对单个开发者够用,但无法支持多 Agent 协作、权限委派、Token 撤销Matt Hall 的核心论点是:MCP 的价值不是传输层,而是契约层。
类比 OpenAPI 对 REST 的作用:在 OpenAPI 之前,一千个 API 有一千种风格;OpenAPI 给了 REST 一个标准契约,让工具链、文档、测试都变得可用。MCP 在做同样的事——给 Agent-工具交互一个机器可验证的结构化契约。
当 MCP Server 暴露一个接口时,Agent 能获得:可用操作列表、参数结构、返回值类型。这比"读一段文档然后猜"要可靠得多。
Matt Hall 还指出了 MCP 的演进方向:Streamable HTTP + OAuth 2.0。
早期 MCP 的问题是 Server 跑在本地——需要安装、管理、排障。但当 MCP Server 变成托管服务(像 Linear、Granola 已经在做的),用户不需要安装任何东西,指向一个 URL 完成 OAuth 就连上了。维护负担消失了。
这就像 REST API 早期也被吐槽"太多开销",但最终证明底层抽象值得标准化。
如果只看社区争论,你会觉得这是非此即彼的选择。但飞书、钉钉、企业微信的 CLI 开源给出了一个更务实的答案——MCP 和 CLI 不在同一层,它们是协议与实现的关系。
graph TB
subgraph PROTOCOL["MCP 层 — 协议标准"]
P1["统一接口定义"]
P2["能力发现 tools/list"]
P3["权限与审计控制"]
P4["能力目录管理"]
end
subgraph EXECUTION["CLI 层 — 执行入口"]
C1["命令行交互壳"]
C2["结构化输出 --format json"]
C3["Skills 文档 / Agent 发现"]
C4["本地脚本 / 批处理"]
end
subgraph PLATFORM["平台能力"]
A1["钉钉 API"]
A2["飞书 API"]
A3["企业微信 API"]
end
C1 & C2 & C3 -->|"通过 MCP 协议调用"| P1
P1 -->|"JSON-RPC"| A1 & A2 & A3
style PROTOCOL fill:#e3f2fd,stroke:#1976d2
style EXECUTION fill:#f0fff0,stroke:#51cf66
style PLATFORM fill:#fff3e0,stroke:#f57c00
钉钉 dws:CLI 外壳下是完整的 MCP Client。它从 MCP 市场拉取服务注册表,通过 MCP initialize + tools/list 握手发现能力,再通过 MCP JSON-RPC 执行调用。CLI 只是把 MCP 的能力"翻译"成了 dws calendar event list 这样的命令行格式。
企业微信 wecom-cli:同样是一个 MCP Client 的 CLI 壳。Rust 核心通过 JSON-RPC 与服务端通信,npm 层做跨平台分发。
飞书 larksuite/cli:虽然没用 MCP 协议名,但做的事情等价——从 OpenAPI 元数据构建命令树,服务端定义能力,CLI 透传调用。本质上也是"协议层 + 实现层"的分层。
| 论点 | "CLI 派"说得对的部分 | "MCP 派"说得对的部分 |
|---|---|---|
| Token 效率 | CLI 不注入 Schema,上下文更轻 | ️ 但如果 CLI 文档不好,Agent 会猜错 |
| 可调试性 | CLI 对人类可见,可复现 | ️ MCP 的结构化契约让错误可验证 |
| 可组合性 | 管道是 Linux 五十年的积累 | ️ 无类型管道对 Agent 容易静默失败 |
| 认证 | CLI 的 auth 已经很成熟 | ️ 无法延伸到多 Agent、多租户场景 |
| 部署复杂度 | 本地 MCP Server 确实不稳定 | ️ 托管 MCP 会消除这个问题 |
两边说的都是真实的痛点,但解决方案不是二选一——而是分层组合。
Token 效率是整个争论中最有说服力的维度。ScaleKit 的 benchmark 数据给出了量化的结论:
| 指标 | CLI | MCP | 差距 |
|---|---|---|---|
| Token 消耗 | 基准 | 9-32 倍 | MCP 多出一个数量级 |
| 成本 | 基准 | 17 倍 | MCP 贵得多 |
| 失败率 | 0% | 有明确失败率 | MCP 更不可靠 |
graph LR
subgraph MCP_TOKENS["MCP Token 消耗"]
M1["Schema 注入<br/>~28,000 tokens"]
M2["工具选择<br/>~3,200 tokens"]
M3["调用 + 解析<br/>~6,300 tokens"]
M4["50 台设备<br/>总计 ~145,000 tokens"]
M1 --> M2 --> M3 --> M4
end
subgraph CLI_TOKENS["CLI Token 消耗"]
C1["Schema 注入<br/>0 tokens"]
C2["命令组合<br/>~800 tokens"]
C3["执行 + 解析<br/>~3,350 tokens"]
C4["50 台设备<br/>总计 ~4,150 tokens"]
C1 --> C2 --> C3 --> C4
end
style M4 fill:#ff6b6b,color:#fff
style C4 fill:#51cf66,color:#fff
style C1 fill:#51cf66,color:#fff
这个差距的根本原因是:CLI 把知识放在了模型的训练数据里(数十亿行终端交互),而 MCP 把知识放在了运行时的上下文窗口里(每个 Server 的 Schema 定义)。
前者是一次性成本(训练时已经付了),后者是每次调用都要付的持续成本。
这场争论催生了一个建设性的产出——Trevin Chow 在构建多个为 Agent 优化的 CLI 后,总结了七个设计原则:
--format json 是标配,不要只给人类可读的表格--help 和子命令帮助让 Agent 按需获取信息这些原则的核心洞察是:每一条同时让 CLI 对人类更好——结构化输出、操作错误、有界响应不是对 Agent 的妥协,而是一直应该做的设计。
回到最开始的问题:MCP 和 CLI 到底谁赢了?
答案是都不完全对。正确的理解是:
graph TB
subgraph LAYERS["最优架构:MCP 协议 + CLI 实现"]
L_AGENT["AI Agent / 人类用户"]
L_CLI["CLI 层(执行入口)<br/>命令行壳 + --format json<br/>Skills 文档 + 本地脚本"]
L_MCP["MCP 协议层(集成标准)<br/>能力发现 + 权限治理<br/>结构化契约 + 审计"]
L_API["平台 API(业务能力)<br/>钉钉 / 飞书 / 企业微信"]
L_AGENT -->|"命令调用"| L_CLI
L_CLI -->|"JSON-RPC"| L_MCP
L_MCP -->|"HTTP"| L_API
end
style L_CLI fill:#51cf66,color:#fff
style L_MCP fill:#1976d2,color:#fff
飞书、钉钉、企业微信已经在实践这个分层了。它们的 CLI 外壳下面跑的都是 MCP 协议(或等价的 OpenAPI 元数据驱动),只是把 MCP 的能力"翻译"成了更友好的命令行格式。
社区争论了一个月,最后发现大厂早就想清楚了——协议和实现从来就不是对立的。