当前位置: 首页 > news >正文

为什么MCP不使用HTTP或gRPC?

摘要:随着 Anthropic 推出 MCP(Model Context Protocol,模型上下文协议),AI 社区迎来了大模型时代连接外部上下文与工具功能的“USB-C 标准”。然而,许多习惯了传统微服务架构的开发者不禁产生疑问:在 HTTP REST 和 gRPC 已经统治分布式系统的今天,MCP 为什么没有直接选择它们,而是采用了基于 JSON-RPC 2.0 的 stdio 与 SSE 传输方案?

本文将从本地 IPC 通信安全、双向交互能力、开发者体验(DX)、JSON Schema 天然兼容性以及架构演进哲学等多个维度,深度剖析 MCP 协议背后的设计决策与权衡,并带你领略 AI Agent 时代全新的系统设计范式。

前言:AI 接入层的新统一标准 —— MCP

在 MCP 出现之前,大语言模型(LLM)想要调用外部工具或读取私有数据,面临着极其繁琐的M×N 接入难题

  • 不同的 LLM 应用(如 Claude Desktop、Cursor、VS Code 插件、自定义 Agent)都有各自的 Tool Calling 定义和客户端插件格式。

  • 不同的数据源和工具(如 GitHub、PostgreSQL、本地文件系统、Slack)需要为每一个 AI 客户端单独编写适配器。

为了打破这种碎片化局面,Anthropic 于 2024 年底开源了MCP(Model Context Protocol)。它定义了一套通用的客户端-服务器架构:

┌───────────────────────────────────────────────────────────┐ │ MCP Host (Client) │ │ (例如: Claude Desktop, Cursor, Custom Agent) │ └─────────────────────────────┬─────────────────────────────┘ │ MCP Protocol (JSON-RPC) │ ┌─────────────────────┼─────────────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Git Server │ │ Postgres Server│ │ Slack Server │ └──────────────┘ └──────────────┘ └──────────────┘

然而,打开 MCP 的技术规范,你会发现它的底层技术选型非常“特别”:

  1. 消息格式:采用JSON-RPC 2.0

  2. 传输层(Transport):本地首选stdio(标准输入输出),远程支持SSE(Server-Sent Events)+ HTTP POST(以及 WebSocket)。

很多人第一反应是:为什么不直接用更加成熟、性能更强、生态更广的 HTTP REST API 或者 gRPC 呢?

这绝非 Anthropic 架构师的“凭空发明”,而是面对 AI 特有应用场景做出的极具远见的技术权衡(Trade-off)。

一、 核心解构:MCP 的真实协议栈

在回答“为什么不用”之前,我们需要先看清 MCP 的真实协议分层:

┌───────────────────────────────────────────────────────────┐ │ 应用层 (Application) │ │ Prompts (提示词) | Resources (资源) | Tools (工具) │ ├───────────────────────────────────────────────────────────┤ │ 消息层 (Message Layer) │ │ JSON-RPC 2.0 规范 │ ├───────────────────────────────────────────────────────────┤ │ 传输层 (Transport Layer) │ │ 本地进程: stdio | 远程网络: SSE / HTTP POST │ └───────────────────────────────────────────────────────────┘

从分层设计可以看出,MCP 实现了消息格式与底层传输方式的解耦

标准 JSON-RPC 2.0 报文示例

当 MCP Client 想要调用 Server 提供的工具时,发送的交互数据如下:

Client 发起工具调用请求 (Request):

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "query_database", "arguments": { "sql": "SELECT * FROM users WHERE active = true;" } } }

Server 返回执行结果 (Response):

{ "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "[{\"id\": 101, \"name\": \"Alice\"}]" } ] } }

了解了底层机制后,我们来逐一拆解:为什么传统的 HTTP 和 gRPC 不适合作为 MCP 的核心标准?

二、 深度对比一:为什么不使用传统的 HTTP (REST API)?

HTTP/REST 是目前互联网上最普及的通信范式,但将它直接作为 MCP 的通用底层传输协议,会遇到以下几个致命的架构痛点。

2.1 本地进程间通信(IPC)的零配置需求与端口冲突

在目前 MCP 的核心应用场景中,超过 80% 的 MCP Server 是以本地子进程(Subprocess)的形式运行在用户的桌面终端上(例如 Cursor 调用本地 Git 工具、Claude Desktop 读取本地 SQLite 数据库)。

如果采用 HTTP 架构:

  1. 端口冲突问题(Port Collisions):每一个本地运行的 MCP Server(可能同时跑着十几、上百个)都需要在本地监听一个 TCP 端口(如http://localhost:8080)。当端口被占用时,需要复杂的自动重试与端口协商逻辑。

  2. 本地网络安全威胁(DNS Rebinding & Local Authorization):在本地开辟 HTTP Server 会带来严峻的安全性隐患。恶意网页可以通过浏览器发起的 CSRF(跨站请求伪造)或 DNS 重定向攻击,向http://localhost:8080发送请求,非法读取用户的私有数据。

MCP 选择stdio的降维打击:
  • 零网络开销与零端口占用:MCP Client(主进程)直接通过 OS 级的spawn创建 Server 子进程,通过标准管道(stdin/stdout)进行文本流传输。

  • 物理级安全隔离:子进程不监听任何网络端口,外部网络没有任何侵入路径,天然防范了网络攻击。

  • 生命周期强绑定:父进程挂掉时,操作系统会自动清理子进程(管道断开收到 SIGPIPE),彻底避免了本地 HTTP 服务遗留僵尸进程的问题。

【HTTP 本地通信架构】 (脆弱且复杂) Browser / Attacker ──(CSRF/DNS Rebinding)──► Localhost:8080 ──► [HTTP Server] 【MCP stdio 通信架构】 (绝缘且优雅) [MCP Client 主进程] ◄─── OS Pipe (stdin / stdout) ───► [MCP Server 子进程] (完全不经过网络栈)

2.2 双向交互与状态保持(Stateful & Bi-directional)

传统的 HTTP/1.1 REST 是标准的单向请求-响应模式:只能由 Client 发起 Request,Server 被动返回 Response。

但在 AI Agent 的应用场景中,通信模式绝不仅仅是“客户端调工具,服务端给结果”这么简单,它存在大量服务端主动回调客户端的高级模式:

  1. 采样(Sampling)/ 递归推理:MCP Server 在执行工具的过程中,可能需要借助大模型进行二次思考。这时 Server 会向 Client 发起sampling/createMessage请求,反向调用 Client 绑定的 LLM 能力。

  2. 上下文变更通知(Notifications):当本地文件被修改、数据库表结构变更时,MCP Server 需要主动推送通知给 Client,刷动上下文(Context)。

  3. 根目录与权限协商(Roots/Elicitation):Server 询问 Client:“我需要读取/path/to/project的权限,请让用户进行授权。”

如果采用传统的 HTTP REST,要实现服务端主动向客户端发请求,就必须:

  • 客户端自身也搭建一个 HTTP Server 供服务端回调(复杂度翻倍);

  • 或者是采用低效的轮询(Polling)机制。

MCP 采用JSON-RPC 2.0配合双向管道(或 SSE + POST),原生支持了客户端与服务端的对等双向调用(Peer-to-Peer RPC)

2.3 协议头开销与序列化开销

在本地通信场景下,HTTP 请求头(Headers)通常包含Host,User-Agent,Accept,Content-Type,Content-Length,Cookie等数百字节的元数据。

对于频率极高的本地工具调用(例如每秒读取几十个小文件片段),HTTP 协议头的传输开销甚至远超 Payload 本身。而基于stdio的换行符分隔(Newline-delimited)JSON-RPC 报文,没有任何多余的 HTTP 封装开销。

三、 深度对比二:为什么不使用高吞吐的 gRPC?

gRPC 拥有基于 HTTP/2 的多路复用、基于 Protocol Buffers 的极小二进制体积以及强类型定义,在微服务架构中是绝对的技术王者。

那么,MCP 为什么没有抱紧 gRPC 的大腿呢?

3.1 开发者体验(DX)与 AI 生态的严重冲突

AI 领域的开发者生态,与传统微服务/后端工程存在极大的性格差异。

AI 领域的工程师、数据科学家乃至自动化脚本编写者,绝大多数使用PythonTypeScript / JavaScript。他们追求的是快速原型验证(Rapid Prototyping)、开箱即用和极低的开发门槛。

gRPC 的开发流程是典型的“契约先行(Contract-First)”:

定义 .proto 文件 ➔ 使用 protoc 编译生成 Stub 代码 ➔ 编写业务逻辑 ➔ 处理复杂的依赖构建

这套流程在企业级微服务中非常严谨,但在 AI 领域却构成了巨大的开发摩擦力(Developer Friction)

  • 想写一个仅有 20 行 Python 代码的简单 Git 读取工具,却不得不配置protoc工具链与编译步骤。

  • 动态脚本语言(如 Python / JS)无法充分享受编译型语言的静态桩代码红利,反而被类型编译打乱了工作流。

MCP 的极简 DX 范式:

在 MCP 中,创建一个完整的 Server 只需要写一个简单的 Python 函数,加上装饰器即可:

from mcp.server.fastmcp import FastMCP mcp = FastMCP("My Quick Server") @mcp.tool() def add(a: int, b: int) -> int: """Add two numbers together.""" return a + b if __name__ == "__main__": mcp.run(transport="stdio")

无需任何.proto编译,没有任何前置构建步骤,直接运行!

3.2 JSON Schema 是大模型的“母语”

这是 MCP 拒绝 Protobuf / gRPC 最核心的底层原因:大语言模型(LLM)的 Function Calling 原生基于 JSON Schema。

无论是 OpenAI 的tools字段、Anthropic 的tools规范,还是 Gemini 的 Function Declaration,其入参和出参的定义格式全部是标准 JSON Schema

{ "name": "get_weather", "description": "获取指定城市的天气", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "城市名称" } }, "required": ["location"] } }
  • 如果采用 gRPC:MCP Server 的开发者需要先写 Protobuf 描述,运行时再通过复杂的转换层,将 Protobuf Schema 翻译成 LLM 能看得懂的 JSON Schema。在这个过程中,许多 JSON Schema 独有的表达能力(如oneOf,anyOf,pattern正则校验等)会在 Protobuf 的强类型限制下丢失。

  • 如果采用 JSON-RPC:MCP 中的工具定义直接透传 JSON Schema,不需要任何中转与损耗,直接 1:1 投递给 LLM

3.3 可观测性、调试难度与纯文本红利

AI 工具调用(Tool Calling)本质上是一个高度非确定性(Non-deterministic)的探索过程。大模型生成的工具参数经常会出现幻觉或格式错误,因此可观测性(Observability)与可调试性至关重要。

  • gRPC:底层基于 HTTP/2 帧与 Protocol Buffers 二进制流。如果不借助 Wireshark、Postman 等特定反序列化工具,人类无法直接用肉眼阅读管道中传输的任何数据。

  • MCP (JSON-RPC over stdio):纯文本 UTF-8 编码!开发者可以极其方便地将交互日志重定向到文件,或者直接用jq工具在命令行进行流式过滤与排查:

# 直接打印并查看 MCP 通信报文 python my_mcp_server.py | jq .

3.4 传输层的通用性(Transport Agnosticism)

gRPC 强绑定于 HTTP/2 协议。要想在 OS 的标准输入输出管道(stdio)上运行 gRPC,就必须在管道上完整实现一套 HTTP/2 的帧解析与多路复用状态机。这无疑是极其重型且极不自然的架构“硬套”。

JSON-RPC 2.0 只是纯粹的文本字符串规范,它对传输介质零依赖

  • 它可以运行在stdio上(用于本地子进程);

  • 它可以运行在SSE + HTTP POST上(用于远程轻量 Web 服务);

  • 它可以运行在WebSocket上(用于长连接交互);

  • 它甚至可以运行在PostMessage/WebWorker上(用于浏览器沙箱内部)。

四、 综合多维对比矩阵

为了更加清晰地展现各协议在 AI 场景下的优劣,我们整理了如下横向对比大表:

评估维度MCP (JSON-RPC over stdio/SSE)HTTP (REST API)gRPC (HTTP/2 + Protobuf)WebSockets
消息序列化JSON / JSON-RPC 2.0JSON / XML / TextProtocol Buffers (二进制)自定义 / JSON
本地 IPC 适宜度极大 (极佳,无网络栈与端口开销)差 (需绑定 localhost,端口易冲突)差 (需在 Pipe 上封装 HTTP/2)中等 (仍需监听网络端口)
双向通信能力原生支持 (Client/Server 对等请求)极差 (仅单向 Request-Response)支持 (Streaming)支持 (纯双向流)
开发者体验 (DX)极简 (零编译,开箱即用)简单 (熟悉度高)复杂 (必须定义与编译.proto)中等 (需自行设计消息路由)
LLM 兼容度原生契合 (1:1 匹配 JSON Schema)良好 (需要手动解析 JSON)较差 (需 Protobuf ➔ JSON 转换)良好
调试与肉眼可读性极佳 (纯文本,jq直接排查)极佳 (Postman / Curl)较差 (二进制编解码需专用工具)良好
本地安全性绝对安全 (无网络端口暴露)有风险 (容易受 DNS Rebinding 攻击)有风险 (需要端口暴露)有风险 (需验证 Origin)
网络吞吐性能中等 (文本解析)中等极高 (二进制压缩与多路复用)

五、 MCP 远程传输的工程精妙:为什么选择 SSE?

在看完本地通信后,可能会有人问:如果 MCP 部署在远程服务器上,它又是怎么处理的呢?

MCP 规范定义了远程传输的标准模式:SSE(Server-Sent Events) + HTTP POST

【MCP 远程传输流程】 MCP Client MCP Server │ │ │ ─── 1. HTTP GET (Header: Accept: text/event-stream) ───►│ │ ◄─── 2. 建立 SSE 长连接 (推送 endpoint URI) ───────────────│ │ │ │ ─── 3. HTTP POST (发送 JSON-RPC 请求到 endpoint) ─────────►│ │ ◄─── 4. 通过 SSE 通道流式异步返回 JSON-RPC 响应 ───────────│

为什么远程不选普通的 REST,也不选复杂的 WebSocket?

  1. 为什么不用纯 REST?

    前文提到,MCP 需要服务端具备主动推送通知(Notifications)和发起采样(Sampling)的能力。纯 REST 无法实现服务端主动推流。

  2. 为什么首选 SSE 而不是 WebSocket?

    • 防火墙与 HTTP/1.1 友好性:SSE 本质上就是标准的 HTTP 响应,使用普通的长连接流(Chunked Transfer Encoding),极易穿越企业级防火墙、反向代理(如 Nginx、Envoy)以及各种 Cloud Gateway。而 WebSocket 升级协议(Upgrade: websocket)在许多严格的企业网络环境下会被拦截。

    • 异步解耦:客户端通过普通的HTTP POST发送请求,服务端通过建立好的SSE单向流异步回传结果。这种“单向下行流 + 短平快上行 POST”的组合,比维护一个状态复杂的双向 WebSocket 连接更加稳健,容错性更高。

六、 架构启示:AI Agent 时代的协议设计哲学

从 MCP 的协议选型中,我们可以总结出 AI Agent 时代软件架构的三大新趋势:

1. 实用主义胜过纯粹的“性能偏执”

在微服务时代,我们追求 1 毫秒还是 0.1 毫秒的 RPC 延迟,因此二进制序列化(Protobuf / FlatBuffers)是首选。

但在大模型时代,大模型自身的推理耗时通常在 500ms 到 5000ms 之间。此时,传输层节省的 2 毫秒相对于 LLM 的延迟几乎可以忽略不计。相反,文本的可读性、调试的便捷性以及开发者生态的扩展速度(DX)成为了最高优先级的指标

2. 传输层与协议层的彻底解耦

MCP 的高明之处在于将 JSON-RPC 作为语义层,与具体的stdio/SSE传输层分离开来。这使得 MCP 可以以极轻量的方式嵌在本地命令行中,也可以无缝扩展到云端分布式服务中

3. “Local-First(本地优先)”的 AI 隐私范式

未来的 AI Agent 不仅仅存在于云端,更多会深入到用户的本地操作系统中(读写本地文件、操作本地代码库、调用本地 CLI)。不依赖网络端口、天然隔离安全的stdio架构,为本地 AI 生态的爆发奠定了最坚实的安全基石。

总结

MCP 没有选择 HTTP REST 或 gRPC,绝不是对成熟技术的标新立异,而是在深入洞察 AI Tool Calling 范式后的必然选择

  • 它放弃了 HTTP 的单向无状态,换取了本地stdio的零配置、极佳安全性与双向交互

  • 它放弃了 gRPC 的二进制高性能与 Protobuf 约束,换取了对 JSON Schema 的原生契合、极致的开发者体验与极低的可观测性门槛

理解了 MCP 的传输协议设计,就理解了 AI Agent 与外部世界交互的本质。希望本文能够帮助你在设计自己的 AI 插件、Agent 架构或上下文集成服务时,做出更加优雅的技术选型!

http://www.jsqmd.com/news/1340936/

相关文章:

  • 2026年重庆大口径顶管钢套管挑选攻略 重庆金江管业等企业实测盘点 - 小范同学a
  • Unity性能优化利器:MaterialPropertyBlock原理、实战与避坑指南
  • 2026个人个体户公司注册商标哪家好? - 新闻快传
  • 2026年8月GEO优化服务商竞争格局深度分析报告 - GrowthUME
  • 前端倒计时组件开发实战:从时间处理到性能优化
  • 体考复读踩坑率超6成!2026长沙8所正规体育生复读学校推荐:训学一体提分实测避坑全指南 - 互联网科技品牌测评
  • 扩频通信技术:从原理到实战,解析DSSS、FHSS与CSS
  • 从零构建AI智能体:基于LangChain的规划、工具与记忆系统实战
  • C++图形编程实战:从零构建Painted Deck项目完整指南
  • TiDB与CockroachDB深度对比:NewSQL分布式数据库选型与实战指南
  • Spark大数据处理实战:从核心原理到生产避坑指南
  • 零基础备考 26 税务师,网课怎么选? - 优学考证上岸
  • 2026Certum一站式本地化服务全解析|**指定服务商河南聚妍SSLDUN - damaigeo
  • 淮阳聚氨酯喷涂保温/高层建筑喷涂施工厂家联系方式-建源聚氨酯喷涂施工 - 行业严选官
  • 电容屏与电阻屏技术解析:原理、选型及触觉反馈设计
  • 2026年Q3欧盟EUDR法案实施在即:苏州验厂宝企业策划有限公司助力制造企业构筑合规护城河 - 卓企推荐
  • RAG 瑕疵知识库:服装品控的智能助手
  • 豆瓣宕机事件解析:高可用架构设计与故障处理实战
  • Nginx多域名与多证书配置实战指南
  • 跨平台 DNS 查询方法整理:从 dig 到 DoH
  • 2026苏州审计报告服务甄选指南,口碑优质机构汇总推荐 - 产品评测官
  • LVDT解调电路:从二极管整流到同步解调的原理、仿真与工程实践
  • 2026信阳别墅装修哪家靠谱 本土家装品牌实用参考 - 谁都没有我好看
  • 上海静安区空气净化器租赁公司怎么选?综合对比优选筠郡(上海)环境科技有限公司 - 专注室内空气检测治理
  • XSwitch:3分钟搞定Chrome浏览器请求转发难题
  • 2026口碑好的高清视频会议系统推荐!看看itc保伦股份获奖智能超高清视讯系统 - 品牌速递
  • DDS直接数字频率合成技术:从核心原理到工程选型与调试实战
  • MyBatis流式查询实战:千万级数据导出与性能优化指南
  • 高管离任、业绩下滑!机构正在撤离山西汾酒
  • 福州豪宅装修公司高端家装服务商综合实力深度测评含专家点评 - 全域品牌推荐