MCP图解:AI Agent如何连接你的应用
MCP图解:AI Agent如何连接你的应用
MCP用公共集成边界把AI与工具的M×N连接压缩为M+N,但不提供记忆与安全。
文章从电商客服机器人的真实场景出发,解释为什么在已有 REST API、GraphQL 和 SDK 的情况下仍需 MCP。直连集成会陷入 M×N 困境:每个 AI 应用都要为每个工具写定制连接器,换模型、换工具版本或多团队复用时成本急剧上升。让 LLM 直接调用 REST 接口同样不现实,冗长响应浪费 token、污染上下文,422 之类的错误码对模型也不友好。MCP 在 API 前加一层翻译,对外暴露带 schema 校验的高层工具,并通过动态发现把工具定义挪到 server 端。但协议本身不提供对话记忆、访问控制或凭证保护,这些必须在 host、server 和后端各层显式实现。文章最后拆解 M、C、P 三个字母、Host/Client/Server 三层架构与一次请求的完整路径,并给出是否自建 server 的判断标准。
为什么有了API还需要MCP?
大多数工程师第一次听说 MCP(Model Context Protocol)时,反应都差不多:我们已经有 REST API、GraphQL 和 SDK,服务之间连了这么多年,为什么 AI 一来就要发明一个新协议?
这个问题不能靠背定义回答。用一个电商客服机器人的场景走一遍,答案自然就出来了。假设你要给公司做一个 AI 客服,用户的问题是「我的订单 12345 到哪了?能退款吗?」。LLM 本质上是训练数据里泡大的语言模型,它知道怎么写礼貌的回复,但对你的订单库、支付网关、工单系统一无所知。要让它真正干活,就得把这些系统接进来。
API 就像餐厅的点单柜台:你发一个定义好的请求,系统返回一个定义好的响应。订单查 ERP 或 Shopify,退款走 Stripe,工单记到 Zendesk,物流问 FedEx,紧急情况再拉个 Slack 通知人工。问题不在于能不能接,而在于怎么接、接多少个、以后怎么维护。
直连集成的隐性成本:M×N 问题
用传统 API 的做法很直接:在应用后端给每个服务写集成代码。读 Stripe 文档、拉 SDK、写 wrapper 函数,再为 LLM 的 function calling 定义一个 schema;Postgres 写一套连接和查询逻辑;Zendesk 和 Slack 把同样的流程再重复一遍,各自处理认证、解析 JSON、写工具定义。
接三四个工具,工作量虽然繁琐但还扛得住。真正的麻烦在于规模化和变化:
- 换模型:从 GPT 切到 Claude,或者换成本地开源模型,各家 tool calling 的格式和 SDK 不一样,迁移意味着改代码加测试。
- 换工具版本:Zendesk 新增一个
check_warranty_status工具,或某个接口加了必填参数,硬编码在应用里的旧 schema 就会让请求失败。 - 多团队重复:另一个团队也要接同样的系统,只能重写一遍,或者勉强复用共享库。
把视角拉到整个行业:M 个 AI 应用(Claude Desktop、Cursor、各家自研 chatbot)× N 个工具和数据源(GitHub、Slack、Postgres、Stripe),就形成了经典的 M×N 集成困境。每个 AI 应用开发者都在为每个工具写定制连接器,代码重复、脆弱、难维护。MCP 要解决的就是把它压缩成 M+N:定义一层公共集成边界,应用和工具各自对协议负责。
为什么不直接让LLM调用REST API?
一个合理的反问是:REST API 已经是标准了,让 LLM 直接调 HTTP 接口不行吗?
技术上可以,但体验上很糟糕。以从 Stripe 或 Shopify 拉一个订单为例,真实响应往往有上百个字段:内部数据库 UID、嵌套 metadata、分页游标、弃用标记、各种时间戳、系统级配置。这些字段对 LLM 来说全是噪音,带来三个实际后果:
- Token 消耗与延迟:冗长的响应烧掉大量 token,成本上升,响应变慢。
- 上下文污染:无关字段挤占 context window,模型更容易困惑甚至幻觉。你可以把 context window 想成模型的工作桌面,放相关文件有用,堆满杂物就是负担。
- 错误语义不友好:REST 面向开发者,返回 422 之类的 HTTP 状态码和晦涩的错误码。人类工程师查文档能懂,但运行时 LLM 需要的是自然语言解释——「什么错了、该怎么修正」,而不是一个数字。
MCP 的思路是在 API 前面加一层翻译。MCP server 内部照样调 Stripe 的 REST API 或查 SQL 数据库,但对外暴露的是 AI 原生语义的高层工具,比如「查询订单退款资格」这种把订单状态和物流信息组合好的操作,并附带 schema 校验(订单 ID 必填、类型为字符串,格式不对直接拒绝)。协议本身不是 AI 大脑,也不提供魔法权限——真正的实现和权限,仍然要靠 server 背后的 API、数据库和文件系统。
function calling 是理解这一节的前提:它是主流 LLM 提供的一种结构化输出能力,开发者把可用的工具(名称、用途描述、参数 schema)随 prompt 一起交给模型,模型在需要时不再生成自然语言,而是返回一个符合 schema 的调用意图,例如 {"name": "get_order_status", "arguments": {"order_id": "12345"}}。模型本身并不执行任何函数,真正调用由宿主应用完成,再把结果回填给模型继续推理。正因为 function calling 的输入是文本化的工具定义与 JSON 参数,工具描述的冗长程度、参数 schema 的严格程度、错误信息的可读性都会直接影响调用准确率——这正是原始 REST 响应在 LLM 场景下表现糟糕的根本原因。
工具发现与状态管理:MCP改变了什么
直连集成里,工具定义写死在应用代码中。MCP 把这些定义挪到了 server 端,通过动态发现机制解决维护问题。兼容的 client 可以向 server 请求能力列表,拿到每个工具的确切名称、自然语言描述(告诉 LLM 这个工具做什么、什么时候该调用)、以及精确的输入 schema。server 在上线新能力后,工具列表刷新就能看到。
但这不意味着零改动。host 的审批策略和兼容性测试依然必要。这里适合用 USB 类比:共享接口让设备能连上,但每个设备的版本和能力并不会自动兼容。
另一个常见误解是把「连接」当成「记忆」。MCP 的连接和对话是两回事——线连着,不代表 chatbot 记得上一句话。真实的客服场景是多步工作流:用户说键盘坏了,AI 查到订单 987,核对退货政策,用户要求换货并寄到新地址,AI 再发起换货、生成退货标签、更新工单。中间选中的订单、确认的地址、流程进度,都需要应用自己显式存储。据该视频对协议演进的说明,2026 年 7 月的修订版中请求模型有变化,旧教程里的初始化握手和 session 概念可能已过时,实现时务必核对协议版本。部分 server 会实现工作流存储和通知,但 MCP 本身不自动提供对话记忆。
JSON-RPC 是 MCP 消息格式的骨架,理解它有助于看懂动态发现为何可行。它是一种轻量远程调用协议:每条请求包含 jsonrpc 版本、唯一 id、method 和 params,服务端返回带有相同 id 的 result 或 error,因此同一连接上可以并发多个请求而不串号。MCP 在此之上定义了工具列表、调用工具、读取资源等具体 method,并借 initialize 阶段交换协议版本与双方能力声明。动态发现本质上就是 client 发送一次列举工具的请求,server 返回当前可用工具及其 schema;由于 method 是标准的,任何兼容 client 都能与任何兼容 server 对话,无需为每个工具预先写死代码。
安全边界:认证、授权与凭证放置
当工程师意识到要把生产数据库、Stripe 账户和 Slack workspace 交给 LLM 时,警报立刻响起:模型会看到数据库密码吗?Stripe 的 secret key 会被塞进 prompt 发给模型厂商的服务器吗?
答案取决于设计。凭证不应该出现在模型 prompt 里,而应放在受保护的 host 或 server 环境中。host 可能持有授权 token,后端服务自己保管数据库凭证。MCP 并不保证 secret 永不泄漏——工具结果、日志和配置中的敏感数据,需要开发者主动约束并测试。
当 LLM 决定查订单时,它输出的只是一个结构化意图:「调用 get_order_status,参数 order_id 12345」。server 负责验证调用方权限、使用受保护的凭证、显式移除未授权字段。这些都是实现层面的选择,不是协议自带的魔法。
几个具体的安全抓手:
- 区分认证与授权:认证回答「你是谁」,授权回答「你能做什么」,两者边界不同。
- 防 prompt injection:返回的文档内容不应被赋予指令权限。权限要在 host、server 和后端三层强制,光在 prompt 里写「不要退款」不构成可靠访问控制。
- 数据库层兜底:配置正确的只读数据库角色能从边界上阻断写操作。但要审计实际的 grant 和暴露的函数,别只信「只读」这个标签。
- 高风险操作走人工:例如金额超过 50 美元的退款进入人工审批队列,金额与归属校验在 server 端完成,不交给模型的判断;改变状态的操作前,host 可以要求用户确认,即便确认了,server 仍要执行自己的策略检查。
prompt injection 是指攻击者把指令藏在模型会读到的数据里,例如订单备注、工单正文、网页内容或工具返回的文档,诱导模型偏离原任务去执行攻击者意图,比如把数据发往外部地址或调用高权限工具。它与传统注入的区别在于没有清晰的数据与指令分隔:对模型而言,工具返回的文本和系统提示可能同处一个上下文。防御重心不在提示词措辞,而在架构——对返回内容做来源标记与清洗、限制工具权限到最小集合、对不可信内容禁止触发副作用操作、在高风险动作前引入人工确认,并假定模型可能被说服而由 server 侧独立校验每次调用。
MCP三个字母拆开看
M(Model):核心的 LLM,比如 Claude、GPT、Gemini 或 Llama,擅长推理和生成,但孤立于你的私有系统。
C(Context):让模型真正有用的那部分信息。MCP 把它标准化为 server 能提供的三类原语:Tools(可调用函数,模型提出调用,应用批准后路由执行)、Resources(只读数据源,比如退款政策文档、客户档案、日志、数据库 schema)、Prompts(可复用指令模板,比如客服升级话术的结构;选模板不会自动执行整个工作流)。
P(Protocol):两端通信的规则与消息格式,类似 Web 的 HTTP 或邮件的 SMTP。MCP 消息采用 JSON-RPC 风格——可以理解成带编号的信封,请求 ID 与响应匹配,method 说明要做什么。通信还需要兼容的协议版本、声明的能力和授权。
三层架构与一次请求的完整路径
每个 MCP 部署都由三层组成:
- Host:用户面对的应用,比如 Claude Desktop、Cursor、Windsurf、VS Code + Copilot,或自研客服系统。它负责和 LLM 对话、管理 UI、编排整个应用。
- Client:host 内部的协议连接器,你通常不会直接接触。host 为每个连接的 server 启动一个 client 实例,形成一对一关系,负责 JSON-RPC 通信、工具发现、把 host 的工具执行请求转发给 server,再把响应带回。
- Server:坐在具体数据源前面的轻量程序,比如 GitHub MCP server、Postgres MCP server、Stripe MCP server,把 MCP 请求翻译成原生 API 调用、SQL 查询或本地文件操作。
用订单 550 的退款查询走一遍:
- 应用把用户问题和已发现的工具列表、schema 一起发给 LLM。
- LLM 读完问题,不执行任何操作,只回一个意图:需要调用 get_order_status 和 check_refund_status,参数 order_id 550。
- host 做策略检查,通过对应的 MCP client 把工具调用发给 server。
- server 用自己安全存储的凭证查询 Postgres、调用 Stripe API。
- server 精选相关事实返回——已入仓、退款已处理。过滤逻辑由开发者实现。
- host 把结果交给模型,模型基于事实生成回复。遇到错误或不确定,应当诚实处理,而不是猜测。
传输层方面,本地 server 通常走 stdio,作为 host 同机的子进程运行,不需要网络端口,适合访问本地文件、跑本地 git 命令、查本地 SQLite,或让 AI 编码助手操作本地开发环境;远程 server 常用 streamable HTTP,适用于生产 Web 应用、几十名工程师或大量用户共享的中心化 server,以及云端 SaaS 集成。旧教程中的 HTTP+SSE 方案与当前版本不同,不要混淆。
stdio 与 streamable HTTP 是当前两种主流传输方式,选择它们取决于部署形态而非功能差异。stdio 指标准输入输出:host 把 server 作为子进程启动,双方通过管道按行交换 JSON-RPC 消息,天然没有网络监听端口,凭证和文件访问都局限在本机,适合个人开发工具与本地数据源,代价是无法被多台机器共享。streamable HTTP 则是面向远程的标准做法,client 向单一端点 POST 请求,服务端可用流式响应逐步回传结果,并支持会话标识以维持跨请求状态,便于放在反向代理、网关和统一鉴权之后,适合多用户共享的中心化 server。旧方案 HTTP+SSE 使用两个独立端点分别承担请求与事件推送,已在新版规范中被取代,迁移时需注意端点与握手方式都已变化。
要不要自己写Server?
多数情况下不必。开放标准的意义正在于此:Postgres、Slack、GitHub、Stripe 等大量服务已有官方或社区维护的 MCP server。但每一份列表都不自动可信,使用前要检查发布方、维护状态、权限范围和协议兼容性,理解清楚再运行配置中的命令。
值得自建的场景有两类:一是公司内部的专有微服务或内部 API,比如自研的遗留库存系统、内部部署流水线;二是需要把多个内部业务规则和 API 调用组合成带护栏和数据过滤的、经过策展的高层工具时。官方提供 Python、TypeScript、Java、Go 的 SDK。
回到最初的疑问:传统 API 不会消失,它仍是软件系统通信的骨干。MCP 只是在应用和 server 之间加了一层公共边界,减少重复的集成劳动,而后端集成、测试和安全这些工作依然要做。它不是万能适配器——host 决定问什么,server 实现被允许做的事。用一句话复盘:发现能力、发起工具请求、强制执行权限、返回有用结果;至于记忆、过滤和安全,都得靠实现。
相关推荐

Claude Agent SDK实战:一步步搭建你的首个AI代理
基于Claude Agent SDK的完整实战教程:从环境配置、代理循环原理、权限模式选择到自定义工具与MCP集成,并用三层防护(最小权限、deny规则、pre-tool-use hook)挡住提示注入,最后设置轮次与预算上限控制成本。

MCP协议详解:从N×M到N+M的AI集成革命
MCP(Model Context Protocol)是什么?本文用USB-C类比讲清MCP协议原理,拆解Host/Client/Server架构、Tools/Resources/Prompts三大构建块、stdio与SSE传输方式,并对比Function Calling与LangChain Tool,附Python实现与生产实践建议。

TheySaid 4.0:在开发工具中预判用户反应
TheySaid 4.0 让你在 Claude、Cursor、Jira 中直接获取真实或合成用户的反馈,几分钟内预判用户反应,不再靠猜发布产品。Product Hunt 排名第一。