刚接触 AI 工具的开发者常卡在一个点上:明明已经有 REST API 了,为什么还要搞一个 MCP?反过来,看到别人说 MCP 能自动连数据库、连编辑器,又以为它能替代所有接口调用。这篇不堆概念,先用几个日常类比把两者的定位摆开,再给一套选型对照表和接入前的排查顺序,让你在真实项目里能判断该用哪个、怎么组合。
刚接触 AI 工具的开发者常卡在一个点上:明明已经有 REST API 了,为什么还要搞一个 MCP?反过来,看到别人说 MCP 能自动连数据库、连编辑器,又以为它能替代所有接口调用。这篇不堆概念,先用几个日常类比把两者的定位摆开,再给一套选型对照表和接入前的排查顺序,让你在真实项目里能判断该用哪个、怎么组合。
先把结论压成一句话:普通 API 解决的是「程序怎么调到你的服务」,MCP 解决的是「模型怎么知道你的服务有哪些能力、并在运行时把能力交给它」。前者是通信契约,后者是能力暴露与调用的约定。两者不是替代关系,做 AI 应用时大概率会同时用到。下面按这个基准往下拆。
先用两个类比把定位摆开
把普通 API 想成餐厅点菜单:你得先知道菜名、份量、加料规则,每次点单都要按固定格式报一遍,报错了厨房就退单。把 MCP 想成给助理配的工牌:助理进门先知道有哪些房间能进、能拿什么,你只说要办的事,具体走哪个门由它自己判断。差别不在传输层,而在「谁负责描述能力、谁负责决定调用」。
- 普通 API:能力清单写在文档和 OpenAPI 描述里,改一次要同步一次文档和客户端代码
- MCP:服务端在运行时把可用工具和参数结构暴露出来,客户端先拉一遍再决定调什么
- 普通 API:调用方必须提前知道接口细节,是「我知道我要什么,直接报参数」
- MCP:调用方需要先被告知有什么,是「我知道我要什么,但让模型选工具」
- 分界线记住一句:API 管「怎么调」,MCP 管「模型能调什么、怎么把结果讲回给模型」
能力描述:写死在文档里 vs 运行时自描述
普通 API 的接口清单通常写在文档或 OpenAPI 描述文件里,属于「离线描述」;MCP 强调服务端把可用工具、参数结构暴露出来,客户端启动时先拉一遍再决定调什么,属于「在线自描述」。这个差别会直接落到你的发版频率上:走 API 要发版,走 MCP 往往只是服务端加一个工具声明。
| 对比项 | 普通 API | MCP |
|---|---|---|
| 能力描述位置 | 文档/描述文件,离线 | 服务端运行时暴露,在线 |
| 新增一个能力 | 客户端和服务端都可能要改 | 通常只动服务端工具声明 |
| 发现时机 | 接入前人工阅读 | 客户端启动时拉取 |
| 改结构的代价 | 要同步文档和调用方 | 只改工具声明,但要防旧客户端不认 |
| 适合的团队 | 调用方固定、版本需严格锁定 | 调用方多、模型侧频繁尝鲜 |
不适用的情况也说清楚:如果接口需要严格版本锁定、对外承诺兼容性,自描述反而带来不可控——模型看到的是「当前有什么」,不是「我们承诺了什么」。这种情况把稳定接口留在普通 API 侧,MCP 只做一层薄的包装。
鉴权与边界:Key 交给谁、权限多大
普通 API 的 Key 通常直接给调用方,权限范围靠服务端策略和参数校验兜。MCP 的凭据一般由宿主客户端持有,服务端按工具粒度授权,越权面更小,但前提是客户端本身没被滥用。接入前先问三件事:凭据存在哪、能碰哪些资源、出错时能否单独吊销。
- 确认凭据存放位置问自己 Key 是落在前端、脚本还是服务端进程里;如果落在浏览器可见的位置,就别接能花钱或能删数据的能力。
- 列资源白名单把每个工具能碰的表、目录、外部服务写出来,越具体越好;写不出来的工具先别上。
- 设计吊销路径确认换 Key 或停用某个工具时,不用改客户端代码,只改服务端配置就能生效。
- 验证越权行为手动用超范围的参数调一次,确认被拒的提示能返回给模型,且不会让模型反复重试到超时。
判断标准:如果这个能力能删数据或花钱,优先考虑放在 MCP 侧托管凭据,而不是把 Key 塞进前端。反过来,纯读、公开数据的接口,两种方式差别不大,选维护成本低的那个。
选型对照表:什么活该给谁
选型不需要纠结「谁更先进」,只需要回答两个问题:调用方是不是模型?这个能力需不需要被动态发现?两个都偏「是」,走 MCP;只要有一个偏「否」,普通 API 更省事。实际项目里两者并存非常常见:MCP 做模型侧的入口,底层仍然转调你自己的 HTTP 接口。
| 场景 | 优先选择 | 原因 |
|---|---|---|
| 老系统兼容、非 AI 程序调用 | 普通 API | 调用方不会读工具描述,自描述没价值 |
| 浏览器直连、前端直接调 | 普通 API | 模型不在这条链路上 |
| 多客户端复用同一份工具定义 | MCP | 工具声明改一处,客户端都受益 |
| 模型需要动态发现能力 | MCP | 自描述是这个协议的核心收益 |
| 高频批量任务、服务间调用 | 普通 API | 多一层协议只增加延迟和维护面 |
| 能删数据/花钱的能力 | 偏向 MCP 侧托管凭据 | 缩小 Key 散落范围,便于吊销 |
不适用的判断:如果调用方根本不是模型,上 MCP 只是多一层要维护的协议,没有收益。同理,如果你只需要一次性的脚本调用,直接写 HTTP 请求比配一套工具声明快得多。
接入前的落地检查清单
选型定完之后,真正容易翻车的是工程细节。下面这份清单按顺序过一遍,能在动手前挡掉大部分返工。前几步是判断题,后几步是配置题,别跳着做。
- 先确认调用方是谁:模型、脚本、前端还是别的服务,这个答案直接决定选型
- 再确认错误处理路径:超时、限流、鉴权失败分别由谁重试,别让模型负责重试
- 日志要能对上:一次模型请求里到底触发了哪几个底层调用,串不起来就没法复盘
- 工具描述要写到「另一个开发者看完就能填对参数」的程度,含糊的描述会变成填错参数
- 超时和并发参数先按基线设一遍,具体数值到 /tools/speed-test 量出你自己的延迟基线后再定
- 权限最小化:每个工具只开完成该任务需要的资源范围,不要图省事共用一个宽权限凭据
补充一条容易忽略的:模型侧的重试和业务侧的重试要分开计数,否则一次超时可能被放大成好几倍的底层调用。日志里最好带上「模型请求 ID」和「底层调用 ID」两层标识,排查时能直接串起来。
从纯 API 迁到带 MCP 的路径怎么走
已有 HTTP 接口的项目想接 MCP,最常见的错误是一上来就重写。更稳的路径是加一层包装,先让模型能调通,再逐步收拢凭据和能力。下面三步按顺序做,每步都能独立验证。
- 包一层工具声明不改已有 HTTP 接口,只在外面加工具声明,让模型能调到;验证方式是手工发一次模型请求,确认底层接口被正确触发。
- 把凭据收回到宿主侧把原本散在调用方的 Key 收到宿主进程里,服务端按工具粒度授权;验证方式是拿掉调用方本地 Key,确认功能仍然可用。
- 收敛重复能力把多个零散接口合并成少数几个语义清晰的工具;验证方式是让模型在新旧两套描述下各跑一遍典型任务,比较参数填错率。
- 补日志与重试边界给每次工具调用打上模型请求 ID,明确超时和限流由谁处理;验证方式是人为制造一次超时,看日志能否还原链路。
不适用的情况:接口本身不稳定、还在频繁改结构的阶段,先别包 MCP,否则每改一次都要同步工具描述,维护成本反而更高。等接口结构稳定一两个迭代周期再动。
常见踩坑与能力边界
把 MCP 当成万能代理是最常见的误解:它管的是能力暴露,不管业务逻辑和事务一致性。模型选对了工具、参数也填对了,不代表你的业务规则就自动成立,该做的校验一条都不能少。
- 工具描述写得含糊,模型会把参数填错,这类问题先在工具声明里改,不要先去调提示词
- 别假设所有客户端都支持同一套能力,具体服务器清单和能力差异到 /mcp 对照
- 不要让模型承担重试和补偿逻辑,它既看不到底层错误细节,也不适合做幂等判断
- 纯内部服务间调用、高频批量任务,直接用普通接口更省事,多一层协议只增加排查面
- 涉及资金或不可逆操作的能力,先加人工确认环节,再谈自动化
哪些场景干脆别用:调用方不是模型、能力不需要动态发现、或者链路对延迟极其敏感,这几种情况下 MCP 带来的收益抵不过维护成本。判断标准就是前面那句——调用方是不是模型、能力要不要被发现。
下一步想知道各家 MCP 服务器的实际表现和接入注意事项,可以到站内 MCP 导航页对照能力清单,再结合自己的调用方类型做选型。→常见问题
已经有 REST API 了,还有必要上 MCP 吗?
看调用方是不是模型。如果只有模型在用,而且你希望它能动态发现能力、多个客户端复用同一份定义,MCP 省事;如果是脚本、前端或其他服务在调,普通 API 就够了,包一层 MCP 只是多维护一套协议。
MCP 能替代普通 API 吗?
替代不了。MCP 解决的是「怎么把能力讲给模型听、怎么管住它的权限」,真正干活的那层 HTTP 接口通常还在,只是被包在了工具声明后面。把它当成模型侧的入口,而不是底层实现的替代品。
两者可以同时用在一个项目里吗?
可以,而且很常见。典型做法是 MCP 只暴露少数几个语义清晰的高层工具,底层仍然转调你原来的接口。这样模型侧简单,老系统也不用动,出错时还能按原来的方式排查。
接 MCP 之后最该先配什么?
先配超时和凭据归属,再配日志。超时没设好会拖垮整条链路,凭据散在调用方不好吊销,日志串不起来就没法复盘一次请求到底触发了哪些底层调用。
怎么判断工具描述写得够不够清楚?
拿几条真实任务跑一遍,看模型有没有填错参数类型、有没有多包一层。如果有,先改工具声明的参数说明和示例,而不是先去调提示词。改完记得留一组固定用例回归。