尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

为什么MCP不使用HTTP或gRPC?

为什么MCP不使用HTTP或gRPC? 摘要随着 Anthropic 推出 MCPModel 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 年底开源了MCPModel Context Protocol。它定义了一套通用的客户端-服务器架构┌───────────────────────────────────────────────────────────┐ │ MCP Host (Client) │ │ (例如: Claude Desktop, Cursor, Custom Agent) │ └─────────────────────────────┬─────────────────────────────┘ │ MCP Protocol (JSON-RPC) │ ┌─────────────────────┼─────────────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Git Server │ │ Postgres Server│ │ Slack Server │ └──────────────┘ └──────────────┘ └──────────────┘然而打开 MCP 的技术规范你会发现它的底层技术选型非常“特别”消息格式采用JSON-RPC 2.0传输层Transport本地首选stdio标准输入输出远程支持SSEServer-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 架构端口冲突问题Port Collisions每一个本地运行的 MCP Server可能同时跑着十几、上百个都需要在本地监听一个 TCP 端口如http://localhost:8080。当端口被占用时需要复杂的自动重试与端口协商逻辑。本地网络安全威胁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 发起 RequestServer 被动返回 Response。但在 AI Agent 的应用场景中通信模式绝不仅仅是“客户端调工具服务端给结果”这么简单它存在大量服务端主动回调客户端的高级模式采样Sampling/ 递归推理MCP Server 在执行工具的过程中可能需要借助大模型进行二次思考。这时 Server 会向 Client 发起sampling/createMessage请求反向调用 Client 绑定的 LLM 能力。上下文变更通知Notifications当本地文件被修改、数据库表结构变更时MCP Server 需要主动推送通知给 Client刷动上下文Context。根目录与权限协商Roots/ElicitationServer 询问 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-delimitedJSON-RPC 报文没有任何多余的 HTTP 封装开销。三、 深度对比二为什么不使用高吞吐的 gRPCgRPC 拥有基于 HTTP/2 的多路复用、基于 Protocol Buffers 的极小二进制体积以及强类型定义在微服务架构中是绝对的技术王者。那么MCP 为什么没有抱紧 gRPC 的大腿呢3.1 开发者体验DX与 AI 生态的严重冲突AI 领域的开发者生态与传统微服务/后端工程存在极大的性格差异。AI 领域的工程师、数据科学家乃至自动化脚本编写者绝大多数使用Python和TypeScript / 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(transportstdio)无需任何.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] } }如果采用 gRPCMCP Server 的开发者需要先写 Protobuf 描述运行时再通过复杂的转换层将 Protobuf Schema 翻译成 LLM 能看得懂的 JSON Schema。在这个过程中许多 JSON Schema 独有的表达能力如oneOf,anyOf,pattern正则校验等会在 Protobuf 的强类型限制下丢失。如果采用 JSON-RPCMCP 中的工具定义直接透传 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 AgnosticismgRPC 强绑定于 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 规范定义了远程传输的标准模式SSEServer-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为什么不用纯 REST前文提到MCP 需要服务端具备主动推送通知Notifications和发起采样Sampling的能力。纯 REST 无法实现服务端主动推流。为什么首选 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 架构或上下文集成服务时做出更加优雅的技术选型
返回列表