10 月 23 - 25 日,QCon 上海站即将召开,9折优惠最后1天 了解详情
写点什么

对 MCP 的批判性审视

作者:Raz

  • 2025-09-30
    北京
  • 本文字数:5110 字

    阅读完需:约 17 分钟

大小:2.55M时长:14:52
对 MCP 的批判性审视

MCP 是一个开放协议,它标准化了应用程序向 LLM 提供上下文的方式。可以把 MCP 想象成 AI 应用程序的 USB-C 端口。正如 USB-C 提供了一种将设备连接到各种外设和配件的标准化方式一样,MCP 也提供了一种将 AI 模型连接到不同数据源和工具的标准化方式。

 

—— Anthropic

概述

我希望这到头来会是我自己的技能问题,也希望我遗漏了一些东西。

 

在过去的一个月里,MCP(模型上下文协议)——它可以让 LLM 成为代理并与世界互动——真的火了起来。这个想法很简单:让我们为 LLM/代理标准化一个 API,让它们与世界互动,并定下将这些信息告知 LLM/代理的方式。

 

事情发展得非常快,IBM 最近发布了他们自己的 MCP“正交标准”,称为代理通信协议 (ACP),紧随其后,谷歌发布了 Agent2Agent (A2A)。

 

MCP 服务器和客户端每天都有新的构建和发布,可以在 mcp.so 和 pulsemcp.com 等网站上找到。

 

然而,让我惊讶的是成熟工程实践实在太少了。所有主要参与者都花费了数十亿美元来训练和微调他们的模型,但据我所知,他们最后却让实习生编写文档,提供的 SDK 质量低劣,而且几乎没有提供任何实现指导。

 

这种趋势似乎在 MCP 中延续了下来,导致了一些非常奇怪的设计决策、糟糕的文档,以及更糟糕的实际协议规范。

 

我的结论是,提案的整个 HTTP 传输设置(SSE+HTTP 和 Streamable HTTP)都应该被抛弃,取而代之的是模仿 stdio 的 Websockets。

背景

大约三周前,我决定投身 MCP 的潮流尝试一下,看看它在我们自己的环境中如何应用。我非常希望在使用抽象之前先了解底层工作原理。现在我们有了一个可以在不同传输协议上运行的新协议——真是令人兴奋!

 

Anthropic 是 MCP 标准化工作的幕后推手,而之所以 Anthropic 首席执行官认定大多数代码将在一年左右的时间内转由 LLM 编写,MCP 似乎就是主要原因之一。对编程工具的重视似乎是其标准化工作的指导原则,其核心在于使用体验。

协议

简而言之,它是一个 JSON-RPC 协议,带有预定义的方法/端点,旨在与 LLM 结合使用。这并非本文的重点,但该协议本身确实存在一些需要批评的地方。

传输

与 2005 年之后的许多应用程序号称是“本地优先”(很讽刺)一样,MCP 似乎也是如此。查看传输协议,你就能了解它们源自何方——大概他们的目的是构建在笔记本电脑上编程的 LLM 工具。他们可能正在研究本地 IDE(或者更现实地说,Cursor 或 Windsurf),以及如何让 LLM 与本地文件系统、数据库、编辑器、语言服务器等进行交互。

 

这里主要有两种(或三种)传输协议:

 

  1. stdio

  2. “得通过 HTTP 传输,Web 似乎是我们应该支持的东西。”

Stdio

使用 stdio 本质上意味着启动一个本地 MCP 服务器,连接从服务器到客户端的 stdout 和 stdin 管道,并开始发送 JSON 并使用 stderr 记录日志。这在某种程度上打破了使用这些流进行双向通信的 Unix/Linux 管道范式。当需要双向通信时,我们通常会使用 socket、Unix socket,甚至是网络 socket。

 

不过,socket 有简单易懂,在所有操作系统中开箱即用,不需要额外处理等优势。所以即使有人提出批评,我也理解。

HTTP+SSE / Steamable HTTP

HTTP 传输则是另一回事。同样的一个错误有两个版本:HTTP+SSE(服务器发送事件)传输,它正在被“Steamable HTTP”(一个杜撰的术语)取代,后者将 REST 语义与 SSE 结合使用。但这又带来了许多额外的困惑和极端情况。

 

总结下来就是:“由于我们喜欢用 SSE 进行 LLM 流式传输,所以我们不使用 WebSocket。相反,我们实际上是在 SSE 之上实现 WebSocket,并将其称为‘Steamable HTTP’,让人们认为这是一种被接受/已知的处理方式。”

 

他们在这个 PR:modelcontextprotocol/pull/206 中讨论了 WebSockets 的问题(以及 Steamable HTTP 的原因),并提出了一些非常奇怪的扭曲和不切实际的论点来反对使用 WebSockets。该帖子中至少还有一个人似乎同意我的观点:modelcontextprotocol/pull/206#issuecomment-2766559523。

陷入疯狂

我打算用 Golang 实现一个 MCP 服务器。目前没有官方的 Go SDK,而且我想了解这个协议。结果证明,这是个会影响心理健康的错误……

警告信号……

我查看了 https://modelcontextprotocol.io,发现其文档写得很糟糕(所有 LLM 供应商似乎都在内部竞争,争相编写令人困惑的文档)。该规范掩盖或忽略了协议的一些重要方面,并且没有提供任何对话流程的示例。事实上,整个网站似乎都不是用来阅读标准规范的;相反,它引导你去学习如何实现他们的 SDK 的教程。

 

所有示例服务器都是用 Python 或 JavaScript 实现的,目的是让你下载并使用 stdio 在本地运行它们。如果你想在别人的电脑上运行程序,Python 和 JavaScript 可能是最糟糕的语言选择之一。作者似乎意识到了这一点,因为所有示例都以 Docker 容器的形式提供。

说实话……你上次运行 pip install 而没有陷入依赖地狱是什么时候?

我是不是太自命不凡/武断了,认为人工智能领域的从业者只懂 Python,而且“嗯,它在我的电脑上能用就行”这种做法仍被认为是可接受的?对于任何尝试过运行 Hugging Face 某一功能的用户来说,这一点都应该是显而易见的。

 

如果你想在本地运行 MCP,难道你不想选择 Rust、Go 这样的可移植语言,或者像 Java 或 C# 这样基于虚拟机的语言吗?

问题

当我开始实现该协议时,我立刻就觉得必须对其进行逆向工程。文档中缺少 SSE 部分的重要内容,而且似乎还没有人实现“Steamable HTTP”;甚至连他们自己的工具,例如 npx @modelcontextprotocol/inspector@latest,都没有。(公平地说,这可能是我自己搞出来的技术问题,可能是拉错了版本,因为几周后我再次检查时它已经可用了。你也可以在 inspect.mcp.garden 上找到版本,这可能更方便。)

 

一旦你掌握了架构,很快就会意识到实现 MCP 服务器或客户端可能是一项繁重的工作。问题在于 SSE/Streamable HTTP 实现试图像 socket 一样工作,模拟标准输入输出 (stdio),但实际上并非如此,它们会试图同时在任何地方执行所有操作。

HTTP+SSE 模式

modelcontextprotocol.io/specification/2024-11-05/basic/transports

 

HTTP+SSE 模式下,为了实现全双工,客户端会建立一个 SSE 会话,例如通过 GET /sse 来读取。第一次读取会提供一个可以提交写入操作的 URL。然后,客户端会继续使用指定的端点进行写入操作,例如发送 POST /a-endpoint?session-id=1234 的请求。服务器会返回 202 Accepted 状态码,且不包含任何正文,此时应该从 /sse 上预先存在的打开的 SSE 连接读取该请求的响应。

“Streamable HTTP” 模式

modelcontextprotocol.io/specification/2025-03-26/basic/transports

 

“Streamable HTTP”模式下,他们意识到无需在第一个请求中提供新的端点,而是可以使用 HTTP 标头作为会话 ID,并使用 REST 语义作为端点。例如,GET 或 POST /mcp 可以打开一个 SSE 会话并返回 mcp-session-id=1234 的 HTTP 标头。要发送数据,客户端会向 POST /mcp 发出请求,并添加 mcp-session-id=1234 的 HTTP 标头。响应可能:

 

  • 打开一个新的 SSE 流并发布回复

  • 返回 200 状态码,并在正文中包含回复

  • 返回 202 状态码,表示回复将被写入任意一个现有的 SSE 流

 

要结束会话,客户端可以发送或不发送带有 mcp-session-id=1234 标头的 DELETE /mcp 消息。服务器必须维护状态,除非客户端正常结束会话,否则无法明确知道客户端何时放弃了会话。

SSE 模式会有什么影响?

这是一个问题百出的设计,我都不知道该从何说起。

 

虽然 SSE 模式的一些关键特性尚未编写文档,但只要对其进行逆向工程,就会发现它相当简单。但这仍然会给服务器实现带来巨大且不必要的负担,服务器实现需要在调用之间“join”连接。实际操作几乎都会迫使你使用消息队列来回复任何请求。例如,以任何冗余方式运行服务器都意味着 SSE 流可能从一个服务器发送到客户端,而请求却被发送到完全不同的服务器。

“Steamable HTTP”会有什么影响?

Steamable HTTP 方法将其提升到了另一个层次,带来了一系列安全问题和令人困惑的控制流。 Streamable HTTP 虽然保留了 SSE 模式的所有缺陷,但它似乎更像是 SSE 模式的复杂扩展集。

 

就实现而言,我只是略知皮毛,但根据我对文档的理解……

 

可以通过 3 种方式创建一个新会话

 

  • 一个空的 GET 请求

  • 一个空的 POST 请求

  • 一个包含 RPC 调用的 POST 请求

 

一个 SSE 可以通过 4 种不同方式打开

 

  • 一个用于初始化的 GET 请求

  • 一个用于加入先前会话的 GET 请求

  • 一个用于初始化会话的 POST 请求

  • 一个包含请求并使用 SSE 响应的 POST 请求

 

一个请求可以通过 3 种不同方式响应

 

  • 一个作为对包含 RPC 调用的 POST 请求的 HTTP 响应

  • 一个作为对 POST RPC 调用的响应而打开的 SSE 中的事件

  • 一个作为之前打开的任何 SSE 的事件

总体影响

由于它有多种方式来发起会话、打开 SSE 连接和响应请求,因此带来了显著的复杂性。这种复杂性有几个普遍的影响:

 

  • 复杂性提升:执行同一件事(会话创建、SSE 开启、响应传递)的多种方式增加了开发人员的认知负担。代码的理解、调试和维护变得更加困难。

  • 不一致的可能性:由于实现同一结果的方式多种多样,不同服务器和客户端之间实现不一致的风险更高。这可能导致互操作性问题和意外行为。客户端和服务器只会实现它们认为必要的部分。

  • 可扩展性问题:虽然 Streamable HTTP 旨在提高效率,但从另一方面来说,其复杂性将带来需要克服的可扩展性瓶颈。服务器可能难以管理大量机器上的各种连接状态和响应机制。

安全隐患

Streamable HTTP 的“灵活性”带来了一些安全隐患,以下仅列举其中几项:

 

  • 状态管理漏洞:跨不同连接类型(HTTP 和 SSE)管理会话状态非常复杂。这可能导致会话劫持、重放攻击或 DoS 攻击等漏洞,因为服务器会创建需要管理并保存的状态,直到会话恢复。

  • 扩大攻击面:会话创建和 SSE 连接的多个入口点扩大了攻击面。每个入口点都代表着一个攻击者可能利用的潜在漏洞。

  • 困惑和混淆:发起会话和传递响应的多种方式可用于混淆恶意活动。

授权

最新版本的协议包含一些关于如何进行授权的非常主观的要求。

 

modelcontextprotocol.io/specification/2025-03-26/basic/authorization

使用基于 HTTP 的传输方式的实现应该符合此规范。

使用 STDIO 传输的实现不应遵循此规范,而应从环境中获取凭据。

我理解的意思是,对于 stdio,随便你。对于 HTTP,你最好还是去实现 OAuth2 吧。如果我使用 HTTP 作为传输方式,为什么还需要实现 OAuth2,而 stdio 用 API 密钥就够了?

应该怎样改进

我不知道,只是有点难过……目前业界似乎无计可施——“现在还凑合,但以后处理起来会很困难。”

 

JSON RPC 协议只有一个,而 Stdio 显然是首选的传输协议。那么我们应该尽量让 HTTP 传输方式接近 Stdio,只有在真的非常需要的情况下才引入变化。

 

  • 在 Stdio 中我们有环境变量;在 HTTP 中我们有 HTTP 标头。

  • 在 Stdio 中我们有类似 socket 的行为,包含输入和输出流;在 HTTP 中我们有 WebSocket。

 

就是这样。我们应该能够在 WebSocket 上完成与在 Stdio 上相同的操作。WebSocket 是通过 HTTP 进行传输的理想选择。我们可以省去会话中复杂的跨服务器状态管理。我们可以消除大量的极端情况,等等。

 

当然,有些事情,比如授权,在某些情况下可能会更复杂一些(而在某些情况下则更容易);有些防火墙可能会阻止 WebSocket;小型会话可能会有额外的开销;恢复中断的会话可能会更困难。但正如人们所说:

客户端和服务器可以根据其特定需求实现额外的自定义传输机制。该协议与传输无关,可以在任何支持双向消息交换的通信通道上实现。

 

modelcontextprotocol.io/specification/2025-03-26/basic/transports#custom-transports

作为一个行业,我们应该针对最常见的用例进行优化,而不是只优化一些特殊情况。

附注:替代方案和补充

如上所述,似乎有更多协议正在涌现。MCP 实际上是“向 LLM(可以创建代理)公开 API 的协议”。IBM 和谷歌的较新协议(ACP 和 A2A)实际上是“向 LLM(可以创建代理的代理)公开代理的协议”。

 

纵观 A2A 规范,似乎对它们的需求非常有限。尽管它们声称是正交的,但 A2A 中的大多数功能都可以使用 MCP 原样或通过少量添加来实现。

 

归根结底,它们就是两个完整的协议,它们也可以作为 MCP 服务器中的工具。甚至 IBM 似乎也承认他们的协议并非真正必要:

“代理可以被视为 MCP 资源,并进一步作为 MCP 工具调用。这种 ACP 代理的视角允许 MCP 客户端发现并运行 ACP 代理……”

 

—— IBM / agentcommunicationprotocol.dev/ecosystem/mcp-adapter

我一开始的感觉是,ACP 协议更像是 IBM 推广其“代理构建工具”BeeAI 的一种尝试。

 

这两个 A** 协议都提供了一个合理的传输层和一种发现代理的方法。



原文链接:

https://raz.sh/blog/2025-05-02_a_critical_look_at_mcp

2025-09-30 16:001

评论

发布
暂无评论

为什么很多产品经理,做不了产品管理?

LigaAI

产品经理 敏捷开发 产品管理 产品功能 12 月 PK 榜

Web前端培训机构有哪些?

小谷哥

面对庞大复杂的身份和权限管理,企业该怎么办?

华为云开发者联盟

后端 开发 数字化 华为云 12 月 PK 榜

跟我学Python图像处理丨带你入门OpenGL

华为云开发者联盟

Python 人工智能 华为云 12 月 PK 榜

功能强大的国产API管理神器 Eolink,亲测好用

海拥(haiyong.site)

开发工具 API API测试

什么是IT资产?如何保障IT资产安全?

行云管家

网络安全 数据安全 IT资产

“零代码”的瓴羊Quick BI即席分析,业务人员也能轻松上手

夏日星河

java程序员培训好就业吗

小谷哥

FL Studio正式推出全新21版首发新版DAW(数字音乐工作站)工具

茶色酒

FL STUDIO20.9 FL Studio 21 FL Studio21

NFT盲盒质押分红挖矿dapp系统开发源码搭建

开发微hkkf5566

RISC-V SIG 推出基于openEuler 的下游发行版 Eulaceura

openEuler

Linux 开源 操作系统 openEuler risc-v

不足10人的创业团队,怎么在半个月内上线一个新产品?

LigaAI

创业 敏捷开发管理 创业公司 远程开发 12 月 PK 榜

应用瓴羊Quick B,可以有效地提升企业的数据化分析能力

对不起该用户已成仙‖

RTS超低延时直播技术:保障大型赛事直播零时差互动

阿里云CloudImagine

云计算 阿里云 世界杯

CorelDRAW2023永久和谐版本下载安装教程

茶色酒

CorelDraw2023

如何将传统 Web 框架迁移部署到 Serverless 架构?

Serverless Devs

Python 架构 前端

纷繁复杂见真章,华为云产品需求管理利器CodeArts Req解读

华为云开发者联盟

云计算 需求管理 华为云 12 月 PK 榜

SpringBoot内置tomcat启动过程及原理

京东科技开发者

tomcat 后端 tomcat源码解读 编程‘ spring-boot

多样化功能助力企业精准决策,瓴羊Quick BI数据看板解析

对不起该用户已成仙‖

HMS Core 6.8.0版本发布公告

HarmonyOS SDK

HMS Core

linux高可用小知识点汇总-行云管家

行云管家

高可用 ha 双机热备

云安全系列5:2023 年需要了解的 40个云安全术语

HummerCloud

云计算 云安全

武汉大数据培训机构怎么样

小谷哥

前端培训学习就业前景怎么样?

小谷哥

如何利用A/B实验提升产品用户留存?看字节实战案例给你答案!

字节跳动数据平台

大数据 AB testing实战 12 月 PK 榜

专访|开源之夏最佳质量奖 Apache RocketMQ Committer 黄章衡

Apache RocketMQ

#开源 消息列队

想学习大数据怎么选择培训机构

小谷哥

cleanmymac2023免费绿色版下载安装教程

茶色酒

CleanMyMac2023

BI智慧仓储行业应用方案,让你的仓储物流不再复杂

葡萄城技术团队

前端 数据可视化 仓储 智慧仓储 大屏

LED电子显示屏加速在生活中的应用

Dylan

LED LED显示屏 led显示屏厂家

对 MCP 的批判性审视_AI&大模型_InfoQ精选文章