MCP vs CLI:AI Agent 的协议之辩
2026年2月底到3月,AI 开发者社区爆发了一场关于 AI Agent 工具调用方式的激烈争论。一方说"MCP 已死,CLI 万岁",另一方说"MCP 没死,我们只是太早了"。而飞书、钉钉、企业微信在同一周内开源各自的 CLI,用实际行动给出了第三种答案。
一、争论的起点:一句"MCP 是个错误"
2026年1月,OpenClaw 创始人 Peter Steinberger 在 X 上发了一条推文:
"mcp were a mistake. bash is better."
这条推文在 AI 开发者社区埋下了一颗种子。一个月后,Eric Holmes 发布博文《MCP is dead. Long live the CLI》,从六个维度系统论证 CLI 优于 MCP,引发了广泛讨论。随后 Jannik Reinhard 发布实测数据,Matt Hall 发布反驳文章,中文社区的掘金、头条上也出现了大量分析——这场争论在钉钉、飞书开源 CLI 时达到高潮。
二、唱衰 MCP 的三个核心论点
2.1 Token 吞噬:上下文效率的致命差距
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%。
2.2 调试地狱:看不见的工具
Eric Holmes 指出了 MCP 的可调试性问题:CLI 对人类可见,而 MCP 工具只存在于 LLM 对话内部。
# CLI:出问题了,我自己跑一遍就知道
$ gh pr view 123
# 看到和 Agent 一样的输出
# MCP:出问题了,你得翻 JSON 传输日志
# 工具调用隐藏在 LLM 对话流里
# 没有 "自己跑一遍" 的选项
这个痛点很真实。MCP 把工具调用封装在协议层后面,人类开发者失去了"复现 Agent 行为"的能力。
2.3 工程摩擦:部署之痛
- 初始化不稳定:MCP Server 启动失败、Claude Code 里冒出 100+ 僵尸 Node 进程
- 认证繁琐:每个 MCP Server 单独认证,没有 SSO
- 权限粗暴:all-or-nothing,无法区分"查看"和"删除"的风险等级
- 协议动荡:从 STDIO → SSE → Streamable HTTP,兼容性混乱
三、为 MCP 辩护:我们只是太早了
Matt Hall 的反驳文章《MCP Isn't Dead. We're Just Early.》代表了另一派观点。
3.1 CLI 自身的问题被低估了
- 输出不稳定:CLI 输出格式随意、版本间无警告就变更,Agent 误读时没有契约可验证
- 管道的脆弱性:
grep | jq | awk对人类来说灵活,但无类型管道容易静默失败,Agent 链式调用时边缘情况频发 - 认证无法延伸:
gh auth login对单个开发者够用,但无法支持多 Agent 协作、权限委派、Token 撤销
3.2 MCP 的价值在于结构化契约
Matt Hall 的核心论点是:MCP 的价值不是传输层,而是契约层。
类比 OpenAPI 对 REST 的作用:在 OpenAPI 之前,一千个 API 有一千种风格;OpenAPI 给了 REST 一个标准契约,让工具链、文档、测试都变得可用。MCP 在做同样的事——给 Agent-工具交互一个机器可验证的结构化契约。
当 MCP Server 暴露一个接口时,Agent 能获得:可用操作列表、参数结构、返回值类型。这比"读一段文档然后猜"要可靠得多。
3.3 从本地守护进程到托管基础设施
Matt Hall 还指出了 MCP 的演进方向:Streamable HTTP + OAuth 2.0。
早期 MCP 的问题是 Server 跑在本地——需要安装、管理、排障。但当 MCP Server 变成托管服务(像 Linear、Granola 已经在做的),用户不需要安装任何东西,指向一个 URL 完成 OAuth 就连上了。维护负担消失了。
这就像 REST API 早期也被吐槽"太多开销",但最终证明底层抽象值得标准化。
四、实践中的答案:MCP 是协议,CLI 是实现
如果只看社区争论,你会觉得这是非此即彼的选择。但飞书、钉钉、企业微信的 CLI 开源给出了一个更务实的答案——MCP 和 CLI 不在同一层,它们是协议与实现的关系。
4.1 重新理解分层
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
- MCP 负责 integration(集成层):标准化暴露能力、治理权限、工具发现
- CLI 负责 execution(执行层):面向用户和 Agent 的命令行壳、结构化输出、本地脚本
4.2 三家平台的实际架构印证了这一点
钉钉 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 透传调用。本质上也是"协议层 + 实现层"的分层。
4.3 回看社区争论:两边都没错,但都只说了一半
| 论点 | "CLI 派"说得对的部分 | "MCP 派"说得对的部分 |
|---|---|---|
| Token 效率 | ✅ CLI 不注入 Schema,上下文更轻 | ⚠️ 但如果 CLI 文档不好,Agent 会猜错 |
| 可调试性 | ✅ CLI 对人类可见,可复现 | ⚠️ MCP 的结构化契约让错误可验证 |
| 可组合性 | ✅ 管道是 Linux 五十年的积累 | ⚠️ 无类型管道对 Agent 容易静默失败 |
| 认证 | ✅ CLI 的 auth 已经很成熟 | ⚠️ 无法延伸到多 Agent、多租户场景 |
| 部署复杂度 | ✅ 本地 MCP Server 确实不稳定 | ⚠️ 托管 MCP 会消除这个问题 |
两边说的都是真实的痛点,但解决方案不是二选一——而是分层组合。
五、Token 效率:这场争论中最硬的数据
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 长什么样?
这场争论催生了一个建设性的产出——Trevin Chow 在构建多个为 Agent 优化的 CLI 后,总结了七个设计原则:
- 默认非交互:不要弹交互式提示,Agent 无法处理
- 结构化可解析输出:
--format json是标配,不要只给人类可读的表格 - 快速失败 + 错误可操作:报错要告诉 Agent 怎么修,而不是只说"失败了"
- 安全重试 + 明确变更边界:幂等操作、dry-run 预览
- 渐进式帮助发现:
--help和子命令帮助让 Agent 按需获取信息 - 可组合 + 可预测结构:输出格式一致,可被管道串联
- 有界 + 高信噪比响应:限制输出量,不要把整个数据库 dump 出来
这些原则的核心洞察是:每一条同时让 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
- MCP 不会死,但会退到它该在的位置——作为集成层的标准化协议,负责能力暴露、权限治理、工具发现
- CLI 不是万能的,但它是面向 Agent 和人类的最佳执行入口——轻量、可调试、Token 高效
- 最优架构是两者组合:MCP 负责 integration,CLI 负责 execution
飞书、钉钉、企业微信已经在实践这个分层了。它们的 CLI 外壳下面跑的都是 MCP 协议(或等价的 OpenAPI 元数据驱动),只是把 MCP 的能力"翻译"成了更友好的命令行格式。
社区争论了一个月,最后发现大厂早就想清楚了——协议和实现从来就不是对立的。
参考资料
- Eric Holmes, "MCP is dead. Long live the CLI", 2026-02-28 ejholmes.github.io/2026/02/28/…
- Matt Hall, "MCP Isn't Dead. We're Just Early.", 2026-02 matthewhall.com/posts/mcp-i…
- Jannik Reinhard, "Why CLI Tools Are Beating MCP for AI Agents", 2026-02-22 jannikreinhard.com/2026/02/22/…
- Trevin Chow (@trevin), Agent 友好型 CLI 设计原则, 2026-03 x.com/trevin/stat…
- Peter Steinberger (@steipete), "mcp were a mistake. bash is better.", 2026-01 x.com/steipete/st…