MCP 还是 CLI + Skill?
本文主要从 AI Coding Agent(Codex、Cursor、Claude Code 等)的角度,聊聊 Skill、CLI、MCP 三者的区别,以及为什么我越来越喜欢 CLI + Skill 这种方案。
Skill 是流程,CLI/MCP 是能力
很多人第一次接触 Skill,会误以为它和 MCP(Model Context Protocol)一样,是一种扩展能力。
实际上完全不是。
可以简单理解成:
Skill = 告诉 AI 应该怎么做
CLI/MCP = 真正帮 AI 去做
Skill 本质就是一个 Markdown。
例如:
当用户询问 React、Vue、TypeScript 等第三方库时:
1. 使用 ctx7 CLI 查询官方文档
2. 阅读返回结果
3. 总结回答
它不会联网、不会执行代码、也不会调用 API,只是告诉模型:
遇到这种情况,请按照这个流程处理。
真正执行工作的,是后面的 CLI 或 MCP。
MCP 更像一个 API
MCP 更像给 AI 暴露了一组 Tool。
例如 Context7 MCP:
resolve-library-id
get-library-docs
模型调用:
get-library-docs("react")
MCP Server:
↓
查询官方文档
↓
返回结构化结果
整个过程和调用 REST API 很像,只不过协议变成了 MCP。
所以:
MCP 提供的是能力,而不是工作流。
CLI 为什么越来越受欢迎?
研究了一圈之后,我发现越来越多 AI 工具开始提供 CLI。
例如:
git
npm
pnpm
gh
docker
ctx7
这些工具都有 CLI,而 AI Agent 本身又已经拥有 Shell 能力。
于是整个流程变成:
User
↓
LLM
↓
Shell
↓
CLI
↓
stdout
↓
LLM
这条链路不依赖任何额外协议,也不需要实现 MCP 规范。
Skill + CLI 为什么体验很好?
这是我觉得最有意思的一点。
假设 Skill 写着:
如果用户询问任何第三方库:
执行:
ctx7 docs ...
以后我只需要问:
React useEffect 怎么用?
模型自己就会:
ctx7 docs react useEffect
然后读取结果回答。
整个过程,我甚至不知道它执行了命令。这就是 Skill 的价值——它改变的是模型的行为,而不是增加一种能力。
CLI 是怎么和大模型交互的?
很多人第一次看到 CLI + Skill,都会有一个疑问:
大模型怎么控制 CLI?
其实原理很直接。
假设模型决定执行:
ctx7 docs react useEffect
Agent Runtime 会真正启动一个 Shell:
ctx7 docs react useEffect
CLI 输出:
useEffect(...)
Runs after render...
Runtime 捕获:
- stdout
- stderr
- exit code
然后把 stdout 再交给模型。
于是模型继续推理:
已经获得官方文档。
下面开始总结。
整个过程和前面 CLI 的链路完全一致:
LLM → Shell → CLI → stdout → LLM
没有额外步骤。
为什么 CLI 不需要协议?
因为操作系统几十年前就已经帮我们定义好了。
所有 CLI 都遵循:
stdin
stdout
stderr
exit code
例如:
git
docker
npm
pnpm
ffmpeg
kubectl
AI Agent 只需要:
exec(command)
剩下的事情都是操作系统负责,所以 CLI 天然就是一种标准接口。
MCP 的开发成本为什么更高?
如果做过 MCP Server,就会发现需要处理很多事情。
例如:
- Tool Schema
- 参数定义
- Tool 注册
- MCP 生命周期
- Tool 返回格式
还需要遵循 MCP 协议。
例如一个 Tool:
{
"name": "get_positions",
"inputSchema": {
...
}
}
然后实现:
initialize
list_tools
call_tool
最后返回 MCP 格式的数据。
相比之下,CLI 几乎没有约束。
例如:
stock weekly-report
甚至输出 Markdown 都没问题:
# Weekly Report
## NVDA
收益:+3%
建议继续持有。
Skill 只需要告诉模型:
执行 stock weekly-report
整个集成就完成了。
两者的开发步骤对比如下:
| 步骤 | MCP | CLI |
|---|---|---|
| 协议 | 需遵循 MCP 规范 | 无,操作系统原生支持 |
| 定义 | Tool Schema + 参数 JSON | 命令 + flag/arg |
| 注册 | list_tools / call_tool | 放到 $PATH 即可 |
| 生命周期 | initialize → list_tools → call_tool | exec(command) |
| 返回格式 | MCP 结构化数据 | stdout(任意格式) |
| 接入 AI Agent | 需 Agent 支持 MCP 协议 | 任何支持 Shell 的 Agent |
CLI 可以完全自由设计
这是我最喜欢 CLI 的一点。
命令怎么设计完全由自己决定:
stock positions
stock analyze NVDA
stock weekly-report
stock export markdown
参数格式、输出格式、日志格式,全部自己控制。甚至输出 Markdown、JSON、HTML 都没有问题。
如果 AI 更适合读取 JSON:
stock weekly-report --json
如果方便人阅读:
stock weekly-report
直接输出 Markdown,没有任何协议限制。
那 MCP 还有必要吗?
当然有。
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 在线 API / 远程服务 | MCP | 天然需要认证、长连接、状态管理 |
| 数据库 | MCP | 连接池、事务、查询状态 |
| 多 Tool 协同 | MCP | 统一协议,Tool 间可编排 |
| 本地开发工具 | CLI | 零协议开销,直接 exec |
| 自动化脚本 | CLI | 灵活输出,自由组合 |
| 一次性任务 | CLI | 无需注册 Tool,写完即用 |
典型例子:
- MCP 适用:GitHub、Notion、Longbridge、Figma、Slack — 这些服务天然是远程能力
- CLI 适用:git、npm、docker、ffmpeg、kubectl — 本地已有 CLI 生态,无需再封装
我更倾向的架构
对于 AI Coding Agent,我越来越喜欢下面这种结构:
Skill
│
决定什么时候执行
│
┌─────────┴─────────┐
│ │
CLI MCP
│ │
本地能力 远程能力
Skill 负责工作流,CLI/MCP 负责真正执行——两者不是竞争关系,而是互补关系。
三者各司其职,总结如下:
| Skill | CLI | MCP | |
|---|---|---|---|
| 本质 | 告诉 AI 怎么做 | 帮 AI 执行本地任务 | 帮 AI 访问远程能力 |
| 形式 | Markdown 文件 | 可执行程序 | MCP Server |
| 谁在控制 | 模型按流程推理 | Agent Runtime exec() | Agent 调用 Tool |
| 开发成本 | 写文档 | 写命令 | 写协议实现 |
| 接入门槛 | 零 | $PATH 即可 | 需 Agent 支持 MCP |
| 输出格式 | — | 任意(Markdown/JSON/HTML) | MCP 结构化数据 |
建议:优先 CLI,按需补 MCP
如果是个人项目或者开发工具:
优先做 CLI。
原因:
- 开发成本低
- 调试方便
- 不需要学习 MCP 协议
- 能直接接入任何支持 Shell 的 AI Agent
以后如果需要支持 MCP,再基于 CLI 封装一层 MCP Server 即可——既保留了 CLI 的灵活性,也兼容了 MCP 生态。对于大多数开发者来说,这是投入产出比最高的一种方案。
