ᕕ( ᐛ )ᕗ Jimyag's Blog

Agent 工具该用 MCP 还是 CLI

2026 年围绕 MCP 和 CLI 的争论又热了一轮。一个常见说法是:MCP 会把大量工具 schema 塞进上下文,token 成本高;CLI 更便宜,模型也更熟悉,所以 MCP 没有必要。

这个判断有一半是对的。CLI 在本地开发工具、单人工作流、已知命令集合里确实更直接,也经常更省 token。但把这个结论推到所有 Agent 场景,就会漏掉另一个更关键的问题:

Agent 到底是在代表谁工作?

如果 Agent 只是代表开发者本人,在本机调用 gitdockerkubectlffmpeg 这类成熟工具,CLI 通常是更好的默认选择。如果 Agent 代表客户、员工或租户去访问远程系统,工具选择就不再只是 token 成本问题,而是身份、授权、作用域、审计和隔离问题。

这也是 MCP 和 CLI 最容易被混在一起讨论的地方。它们都能让模型调用外部能力,但服务的边界不同。

CLI 做得好的地方

CLI 的优势很朴素:它是现有工程系统的原生接口。

对模型来说,CLI 还有一个额外优势:大量训练材料里本来就有命令行、Shell、GitHub issue、StackOverflow 答案、CI 日志和教程。模型对这类文本接口比较熟悉,知道如何组合命令、查看帮助、过滤输出、把一个命令的结果交给下一个命令。

例如本地开发里,下面这些操作本身就适合 CLI:

1
2
3
4
5
git log --oneline -n 10
git diff --stat
docker ps
kubectl get pods -n default
ffmpeg -i input.mp4 output.mp3

这里强行套一层 MCP,通常只是把已经清楚的命令包装成 JSON schema。Agent 需要先知道有哪些工具、每个工具有哪些参数,再发起结构化调用。对于 git status 这类简单任务,schema 本身可能比任务还大。

第三方 benchmark 也能看到类似现象。Smithery 做过 MCP、CLI、raw API 的对比实验,结论不是「CLI 永远赢」,而是更细:在一些简单操作上 CLI 的 token 使用更低;但在远程服务和不熟悉 API 上,MCP 的结构化集成更容易提升成功率。1

所以 CLI 的适用边界可以先这样记:

  1. 工具已经有成熟 CLI。
  2. Agent 运行在开发者自己的环境里。
  3. 凭证继承当前用户上下文是可接受的。
  4. 任务主要是本地文件、代码仓库、容器、系统工具。
  5. 失败影响面主要限于当前操作者。

这个范围里,CLI 简单、便宜、可调试,没必要为了协议统一而替换掉它。

CLI 开始变弱的地方

CLI 的问题通常不是「不能用」,而是它默认假设调用者就是当前机器上的人。

这在单人开发环境里没问题。gh 读的是当前用户登录态,kubectl 读的是当前 kubeconfig,aws 读的是本地 profile。Agent 继承这些凭证后,就像你自己在终端里操作。

但一旦 Agent 开始代表「别人」工作,这个模型就会变得危险。比如:

  1. SaaS 产品里的 Agent 读取客户的 GitHub repo。
  2. 内部 Agent 代表某个员工查询工单、日历、文档。
  3. 客服 Agent 代表用户修改订单、退款或发送消息。
  4. 多租户系统里的 Agent 同时连接多个客户的数据源。

这些场景里,问题不再是「命令能不能跑」,而是:

  • 这次访问属于哪个用户?
  • 用户是否同意 Agent 访问这个资源?
  • token 是否只允许当前动作需要的 scope?
  • A 租户的数据是否可能进入 B 租户的上下文?
  • 事后能否追踪哪个 Agent 在什么时间访问了什么资源?

传统 CLI 并不是为这些问题设计的。它可以通过外层系统补鉴权、补审计、补租户隔离,但这些能力不是 CLI 接口本身自然表达出来的。越往产品化、多用户、合规环境走,这些补丁越容易变成主系统的一部分。

MCP 真正要解决的问题

MCP 的价值不在于替代所有 CLI,而在于给 Agent 和外部系统之间提供一个更明确的协议边界。

MCP 的基础协议使用 JSON-RPC。工具、资源、提示词、传输、授权都被放进协议模型里。尤其在远程 HTTP 传输场景下,MCP 的授权规范已经把 OAuth 2.1、PKCE、Protected Resource Metadata、客户端注册、scope 选择等机制放进设计范围。2

这意味着 MCP 更适合表达下面这些生产化问题:

  1. 用户级身份:Agent 是代表哪个 resource owner 发起请求。
  2. 作用域控制:读、写、删除、管理等能力可以拆成不同 scope。
  3. 授权与同意:用户可以看到并批准 Agent 需要的访问范围。
  4. 动态连接:Agent 可以在运行时发现授权服务器和注册方式。
  5. 审计基础:结构化请求更容易进入日志、策略系统和 SIEM。

这些能力不是 MCP 服务器一启动就自动拥有。你仍然需要实现租户隔离、日志、策略、权限映射和安全运营。但 MCP 给了这些能力一个合适的位置;CLI 则更像是在已有的人类工具外面再包一层。

schema 开销是真问题,但不是根本问题

反对 MCP 时最常见的理由是 schema 开销。

这个问题真实存在。早期 MCP server 往往把大量工具定义一次性暴露给模型。连接几个大型服务后,上下文里可能塞满工具名、参数、描述和返回结构。任务还没开始,token 已经花掉一截。

MCP 在 Agent 里容易花 token,通常不是因为一次 tools/call 本身有多复杂,而是成本叠在了几个地方:

  1. 工具目录预加载:Client 往往会先把 MCP Server 暴露的 tools 列表、名称、说明、参数 schema 放进上下文。工具越多,启动成本越高。
  2. 参数 schema 很详细:为了让模型知道怎么调用工具,schema 里会包含字段名、类型、枚举、必填项、描述和嵌套结构。复杂 API 的参数说明可能比实际任务大很多。
  3. 多个 server 叠加:Agent 同时接 GitHub、Slack、Notion、数据库、工单系统时,每个 server 都带一套工具说明。单个 server 看起来还能接受,叠起来就会挤占上下文。
  4. 调用结果也会进入上下文:MCP 返回的结构化结果通常会被模型继续读取和推理。如果工具返回了大量 JSON、列表、日志或文档片段,后续对话还会继续为这些内容付 token。
  5. 工具选择也要消耗上下文:模型需要在一堆工具里判断该用哪个、参数怎么填。工具越多,选择空间越大,提示词和推理成本也会增加。

CLI 的成本结构不同。模型不需要一开始看到完整的 gitkubectl 命令全集;它可以先执行一个小命令,再根据 stdout 继续下一步。比如 git status 的上下文成本主要是命令和输出,而不是整套 Git API 的结构化说明。

但这更像是实现方式问题,不是协议本身的死结。

Cloudflare 的 Code Mode 就是一个例子。它没有把大量 API endpoint 全部展开成工具,而是把访问能力收敛到 search()execute() 两个工具,让 Agent 先搜索再执行,避免把完整 API schema 预加载进上下文。Cloudflare 官方文章把这个模式描述为用大约 1000 token 暴露整个 API,并把工具发现变成渐进式过程。3

Anthropic 也提出过类似的 code execution with MCP 模式:不要让模型在上下文里背完整工具目录,而是通过代码执行环境按需加载工具、过滤数据、组合调用。它解决的是同一个问题:减少一次性工具暴露,把上下文留给当前任务。4

所以更准确的说法不是「MCP schema 开销太大,所以 MCP 不适合 Agent」,而是:

把所有工具 schema 一次性塞进上下文,是不适合大规模 Agent 的 MCP 使用方式。

合理的 MCP 设计会走向渐进发现、工具搜索、代码执行、按需加载,而不是无限扩展工具列表。

选择标准:看 Agent 代表谁

可以把选择压缩成一个问题:

这次工具调用的影响面是否超出当前开发者自己?

如果答案是否,CLI 通常够用。
如果答案是,MCP 或类似的结构化远程工具协议就应该进入设计。

  flowchart TD
    A["Agent 需要调用外部能力"] --> B{"是否只是代表当前开发者本人?"}
    B -->|是| C{"是否已有成熟本地 CLI?"}
    C -->|是| D["优先 CLI:低成本、易调试、符合现有工作流"]
    C -->|否| E["考虑 API SDK 或轻量工具封装"]
    B -->|否| F{"是否涉及用户数据、租户、权限或审计?"}
    F -->|是| G["优先 MCP / 结构化远程协议:身份、scope、授权、审计"]
    F -->|否| H["按服务复杂度选择 API、MCP 或专用工具"]

更具体一点:

场景 更适合
本机代码修改、Git 操作、容器调试 CLI
单人自动化脚本、可信环境里的批处理 CLI
已有成熟 CLI,且凭证继承当前用户可接受 CLI
SaaS Agent 访问客户资源 MCP
企业内部 Agent 代表员工访问业务系统 MCP
多租户、合规、审计敏感场景 MCP
不熟悉的远程 API,需要结构化发现和参数约束 MCP 或 API SDK

一个更实际的混合形态

最终大概率不会是 MCP 或 CLI 谁消灭谁,而是混合使用:

  1. 本地开发工具继续走 CLI。
  2. 远程服务优先提供清晰 API。
  3. 面向 Agent 的访问层用 MCP 或类似协议做结构化封装。
  4. 大型 API 不直接暴露完整工具列表,而是使用搜索、执行、按需加载。
  5. 授权、scope、审计、租户隔离放到协议和平台层统一治理。

这也符合工程系统的常识:不要为了统一接口替换掉已经稳定的工具,也不要把人类 CLI 当成多租户 Agent 平台的安全边界。

结论

MCP 和 CLI 不是同一个层面的替代关系。

CLI 适合开发者本地环境:工具成熟、模型熟悉、token 低、调试简单。它的问题是默认继承人的身份和凭证,不擅长表达用户级授权、租户隔离和审计。

MCP 适合 Agent 产品化后的远程服务访问:它能把工具、资源、授权、scope 和结构化调用放进一个协议边界里。它的问题是早期实现容易一次性暴露过多 schema,需要用渐进发现、代码执行、工具搜索等方式降低上下文成本。

所以真正的问题不是「MCP 还是 CLI 更先进」,而是:

Agent 是在替你操作本机,还是在代表别人访问系统?

前者优先 CLI。后者要认真考虑 MCP。

#AI Agent #MCP #CLI #OAuth #Tooling