如果应用代码已经知道要调用哪项操作,应使用 API 或 SDK。如果模型需要在运行时发现并选择能力,应使用 MCP。生产环境中的 MCP 工具大多仍会调用底层现有 API,因此两类接口通常相互配合。
MCP 增加了发现能力和面向模型的契约,但不会取代后端 API、授权、数据模型或 MCP 服务器周围的身份验证边界。
区别在于由谁选择操作
固定代码可以调用 POST /refunds,因为开发者已经选定端点并完成字段映射。Agent 调查客服案例时,可能需要在阅读证据后,从 get_invoice、explain_charge、request_refund 和 escalate_case 中选择下一项任务。MCP 会向模型提供这些任务及其 schema 的最新列表。
MCP 工具规范将工具发现和调用纳入协议。OpenAPI 可以描述 HTTP API,但无法自行决定哪些端点应该成为 agent 任务。
API、SDK 与 MCP 对比
| 问题 | API 或 SDK | MCP 服务器 |
|---|---|---|
| 主要调用方 | 路径已知的应用代码 | 在运行过程中选择能力的模型 |
| 发现方式 | 开发期间使用文档、类型或 OpenAPI | 运行时使用 tools/list、资源和协商后的能力 |
| 契约形式 | 端点或方法的输入与输出 | 工具意图、输入 schema 和可选输出 schema |
| 身份验证 | 由 API 决定 | MCP 传输授权,以及独立的上游身份验证 |
| 授权 | 由后端强制执行 | 仍由后端强制执行 |
| 最适合 | 确定性工作流和内部服务调用 | 动态工具选择和可移植的 agent 客户端 |
| 主要失败方式 | 集成代码错误调用 API | 模型选择了含糊或权限过大的工具 |
在这个选择中,GraphQL 属于 API。Schema introspection 可以帮助开发者或客户端构造查询,但不受限制的图通常并不适合作为 agent 工具集。
什么时候直接调用 API 更清晰
以下情况应直接使用 API:
- 调用总是发生在工作流中的同一位置;
- 代码已经拥有所有必需值;
- 操作对延迟敏感,再增加一层协议跳转不会提供决策价值;
- 集成需要使用 MCP 尚未公开的提供商特有功能;
- 精简且类型明确的 SDK 已经为应用提供所需契约。
例如,结账处理程序应通过经过审核的应用代码调用支付 API。用户提交确定性的结账表单后,不应再由模型决定是否创建扣款。
什么时候应该使用 MCP
以下情况适合使用 MCP:
- 模型必须从多项能力中做出选择;
- 工具需要支持多个兼容的 agent 客户端;
- 工具列表或可用资源可能在会话期间发生变化;
- 用户需要通过标准 agent 流程连接自己的账户;
- 客户端可以利用结构化内容、资源链接或服务器提供的提示词。
REST 转 MCP 教程从一项任务出发,在其背后封装 API,避免常见的“每个端点对应一个工具”式转换。
MCP 并不是安全边界
从 tools/list 中隐藏 API 端点,并不会撤销端点背后的凭据。MCP 服务器必须验证客户端身份、授权其代表的用户,并使用为目标 API 签发的上游凭据。后端随后仍需再次对资源执行授权。
MCP 授权规范也禁止 token passthrough。为 MCP 服务器签发的 token 不应转发给下游服务。
避免机械封装
为每个 REST 端点生成一个 MCP 工具,往往会产生相互重叠的选项并暴露内部实现细节。应从用户任务出发:
User task: "Where is order 1842?"
Weak toolset:
get_order_row
get_shipment_row
translate_status_code
Better tool:
get_order_status
服务器可以在内部调用多个 API,只返回最精简且有用的结果。除非协调内部数据关联本身就需要 agent 判断,否则不应让模型负责这项工作。
审计永远不变的步骤
列出一条工作流中的所有 MCP 调用。如果应用代码总是使用相同的参数映射选择同一个工具,那么除非 MCP 还能带来其他明确收益,否则应将这一层替换为类型明确的 API 或 SDK 调用。
下方的提示词会找出这些多余的封装,同时在确实需要模型做出选择的地方保留 MCP。