大模型应用技术之 详解 MCP 原理

1. MCP 概述

1.1 什么是 MCP

Model Context Protocol (MCP) 是由 Anthropic 推动的一项开放标准协议,旨在为大型语言模型(LLM)应用提供标准化的接口,使其能够连接并交互外部数据源和工具。

1.2 MCP 的核心价值

  • 标准化接口:统一的协议规范,简化集成复杂度
  • 扩展能力:让 AI 应用能够访问文件系统、数据库、API 等外部资源
  • 工具调用:支持 AI 调用外部工具执行特定任务
  • 资源管理:提供资源发现、访问和管理能力

1.3 MCP 的核心组件

复制代码
┌─────────────┐
│  MCP Host   │  ← 用户直接交互的应用(如 Claude Desktop、Cursor)
└──────┬──────┘
       │
       ▼
┌─────────────┐
│ MCP Client  │  ← 协议客户端,负责与服务器通信
└──────┬──────┘
       │
       │ Transport Layer (传输层)
       │ ├─ STDIO
       │ ├─ SSE
       │ └─ Streamable HTTP
       │
       ▼
┌─────────────┐
│ MCP Server  │  ← 提供服务(资源、工具、提示词)
└─────────────┘

2. MCP 架构基础

2.1 通信流程

MCP 采用基于 JSON-RPC 2.0 的通信协议,支持以下核心操作:

  • 初始化(Initialize):建立连接,交换能力信息
  • 资源(Resources):访问文件、数据等资源
  • 工具(Tools):调用外部工具执行任务
  • 提示词(Prompts):获取预定义的提示词模板
  • 采样(Sampling):服务器请求 AI 进行推理

2.2 消息格式

所有消息都遵循 JSON-RPC 2.0 规范:

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search",
    "arguments": {
      "query": "MCP protocol"
    }
  }
}

3. Transport Type 详解

Transport Type 决定了 MCP 客户端和服务器之间的通信方式。MCP 支持三种主要的传输类型,每种都有其独特的原理和适用场景。


3.1 STDIO 传输

3.1.1 工作原理

STDIO(Standard Input/Output) 是最简单的传输方式,通过进程的标准输入输出流进行通信。MCP 客户端将服务器作为子进程启动,通过 stdin 发送请求,从 stdout 接收响应。

3.1.2 数据流向图

MCP Host (AI应用) MCP Client 子进程管理器 MCP Server (子进程) STDIO 传输流程 1. 启动请求 2. 创建子进程 3. 启动服务器进程 (stdin/stdout/stderr) 初始化阶段 4. 发送初始化请求 (通过 stdin) 5. 返回初始化响应 (通过 stdout) 正常通信阶段 6. 用户请求 7. JSON-RPC 请求 (stdin) 8. 处理请求 9. JSON-RPC 响应 (stdout) 10. 返回结果 loop [持续通信] 11. 关闭连接 12. 终止子进程 13. 进程退出 MCP Host (AI应用) MCP Client 子进程管理器 MCP Server (子进程)

3.1.3 逐步原理解读

步骤 1-3:进程启动阶段

  1. MCP Host 发起连接:当 AI 应用需要连接 MCP 服务器时,向 MCP Client 发送启动请求
  2. 创建子进程:MCP Client 根据配置(command、args)创建新的子进程
  3. 进程管道建立 :操作系统为子进程创建三个标准流:
    • stdin:标准输入(客户端 → 服务器)
    • stdout:标准输出(服务器 → 客户端)
    • stderr:标准错误(用于日志输出)

步骤 4-5:初始化阶段

  1. 发送初始化消息 :客户端通过 stdin 发送 JSON-RPC 初始化请求

    json 复制代码
    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "initialize",
      "params": {
        "protocolVersion": "2024-11-05",
        "capabilities": {...},
        "clientInfo": {...}
      }
    }
  2. 服务器响应 :服务器通过 stdout 返回能力信息和服务器信息

    json 复制代码
    {
      "jsonrpc": "2.0",
      "id": 1,
      "result": {
        "protocolVersion": "2024-11-05",
        "capabilities": {...},
        "serverInfo": {...}
      }
    }

步骤 6-10:正常通信阶段

  1. 用户请求:用户在 AI 应用中发起操作(如读取文件、调用工具)
  2. 客户端编码 :MCP Client 将请求编码为 JSON-RPC 格式,写入 stdin
  3. 服务器处理 :MCP Server 从 stdin 读取请求,解析并执行相应操作
  4. 服务器响应 :处理完成后,服务器将结果编码为 JSON-RPC 响应,写入 stdout
  5. 客户端解码 :MCP Client 从 stdout 读取响应,解析后返回给 Host

步骤 11-13:关闭阶段

  1. 关闭请求:Host 请求关闭连接
  2. 终止进程:Client 向子进程发送终止信号
  3. 进程退出:服务器进程清理资源后退出
3.1.4 技术特点
  • 进程隔离:服务器运行在独立进程中,崩溃不会影响客户端
  • 无网络依赖:完全本地通信,无需网络配置
  • 简单直接:实现简单,调试方便
  • 生命周期绑定:服务器随客户端启动和关闭
3.1.5 配置示例
json 复制代码
{
  "mcpServers": {
    "filesystem": {
      "command": "python",
      "args": ["-m", "mcp_server_filesystem"],
      "env": {
        "ALLOWED_DIRECTORIES": "/home/user/documents"
      }
    }
  }
}

3.2 SSE 传输

3.2.1 工作原理

SSE(Server-Sent Events) 基于 HTTP 长连接,允许服务器主动向客户端推送事件。MCP 使用 SSE 实现服务器到客户端的单向事件流,客户端请求则通过独立的 HTTP POST 请求发送。

3.2.2 数据流向图

MCP Host MCP Client HTTP 连接 MCP Server SSE 传输流程 1. 连接请求 2. HTTP GET /sse (建立 SSE 连接) 3. HTTP 200 OK Content-Type: text/event-stream 连接保持打开状态 初始化阶段 4. HTTP POST /request (初始化请求) 5. 处理初始化 6. 初始化响应 7. SSE Event: initialized 正常通信阶段 8. 用户请求 9. HTTP POST /request (JSON-RPC 请求) 10. 处理请求 11. HTTP 响应 (JSON-RPC 响应) 12. SSE Event: progress (可选:进度更新) loop [持续通信] 服务器主动推送 13. 检测到事件 14. SSE Event: notification (服务器主动推送) 15. 关闭连接 16. 关闭 SSE 连接 17. 连接关闭 MCP Host MCP Client HTTP 连接 MCP Server

3.2.3 逐步原理解读

步骤 1-3:建立 SSE 连接

  1. 连接请求:Host 请求连接到远程 MCP 服务器

  2. 发起 SSE 连接:客户端向服务器发送 HTTP GET 请求,请求头包含:

    复制代码
    GET /sse HTTP/1.1
    Host: example.com
    Accept: text/event-stream
    Cache-Control: no-cache
  3. 服务器响应:服务器返回 HTTP 200,并设置响应头:

    复制代码
    HTTP/1.1 200 OK
    Content-Type: text/event-stream
    Cache-Control: no-cache
    Connection: keep-alive

    连接保持打开状态,用于服务器推送事件

步骤 4-7:初始化阶段

  1. 发送初始化请求:客户端通过独立的 HTTP POST 请求发送初始化消息

    复制代码
    POST /request HTTP/1.1
    Content-Type: application/json
    
    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "initialize",
      "params": {...}
    }
  2. 服务器处理:服务器处理初始化请求

  3. 返回初始化响应:通过 HTTP POST 响应返回初始化结果

  4. 推送初始化事件:服务器通过 SSE 连接推送初始化完成事件

    复制代码
    event: initialized
    data: {"status": "ready"}

步骤 8-12:正常通信阶段

  1. 用户请求:用户在 AI 应用中发起操作

  2. 发送请求:客户端通过 HTTP POST 发送 JSON-RPC 请求

  3. 服务器处理:服务器处理请求(可能涉及长时间操作)

  4. 返回响应:通过 HTTP POST 响应返回结果

  5. 推送进度事件(可选):如果操作耗时较长,服务器可以通过 SSE 推送进度更新

    复制代码
    event: progress
    data: {"progress": 50, "message": "Processing..."}

步骤 13-14:服务器主动推送

  1. 事件检测:服务器检测到需要通知客户端的事件(如文件变更、任务完成等)

  2. 推送通知:通过 SSE 连接主动推送事件

    复制代码
    event: notification
    data: {"type": "file_changed", "path": "/path/to/file"}

步骤 15-17:关闭连接

  1. 关闭请求:Host 请求关闭连接
  2. 关闭 SSE 连接:客户端关闭 SSE 连接
  3. 连接关闭:服务器检测到连接关闭,清理资源
3.2.4 SSE 事件格式

SSE 事件遵循标准格式:

复制代码
event: <event_type>
data: <json_data>

示例:

复制代码
event: message
data: {"type": "notification", "content": "Task completed"}

event: progress
data: {"progress": 75, "status": "almost done"}
3.2.5 技术特点
  • 单向推送:服务器可以主动向客户端推送事件
  • HTTP 长连接:保持一个持久的 HTTP 连接用于事件推送
  • 独立请求通道:客户端请求通过独立的 HTTP POST 发送
  • 实时性:适合需要实时通知的场景
  • 自动重连:浏览器环境支持自动重连机制
3.2.6 配置示例
json 复制代码
{
  "mcpServers": {
    "remote-server": {
      "url": "https://api.example.com/mcp/sse",
      "headers": {
        "Authorization": "Bearer token"
      }
    }
  }
}

3.3 Streamable HTTP 传输

3.3.1 工作原理

Streamable HTTP 是完全基于标准 HTTP 协议的传输方式。在连接层面,它支持 HTTP Keep-Alive (HTTP/1.1 默认)或 HTTP/2 多路复用,可以在同一个 TCP 连接上复用多个请求-响应。但在 HTTP 请求语义上,每个请求-响应都是独立的、无状态的,支持流式响应(Streaming Response)。

关键特性:

  • TCP 连接层面:支持长连接复用(Keep-Alive 或 HTTP/2)
  • HTTP 请求层面:每次请求-响应独立,无状态
  • 与 SSE 的区别:不像 SSE 那样保持一个专门的长连接用于服务器推送,而是每个请求都是独立的
3.3.2 数据流向图

MCP Host MCP Client HTTP 连接 MCP Server 负载均衡器 (可选) Streamable HTTP 传输流程 1. 连接请求 2. HTTP POST /mcp (初始化请求) 3. 转发请求 4. 处理初始化 5. 初始化响应 6. HTTP 200 OK (初始化完成) 7. 连接就绪 正常通信阶段 8. 用户请求 9. HTTP POST /mcp (JSON-RPC 请求) 新连接或复用连接 10. 路由到服务器实例 11. 处理请求 12. 开始流式响应 (Transfer-Encoding: chunked) 13. 流式数据块 1 14. 部分结果 15. 流式数据块 2 16. 流式数据块 2 17. 部分结果 18. 流式数据块 N (结束) 19. 流式数据块 N 12. 完整响应 13. HTTP 200 OK (完整响应) alt [流式响应] [普通响应] 20. 返回结果 连接可能关闭或保持 loop [持续通信] 21. 关闭连接 无需显式关闭 (无状态连接) MCP Host MCP Client HTTP 连接 MCP Server 负载均衡器 (可选)

3.3.3 逐步原理解读

步骤 1-7:初始化阶段

  1. 连接请求:Host 请求连接到 MCP 服务器

  2. 发送初始化请求:客户端向服务器发送 HTTP POST 请求

    复制代码
    POST /mcp HTTP/1.1
    Host: api.example.com
    Content-Type: application/json
    Connection: keep-alive
    
    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "initialize",
      "params": {...}
    }

    注意Connection: keep-alive 头(HTTP/1.1 默认)表示客户端希望复用连接

  3. 请求路由:如果使用负载均衡器,请求会被路由到合适的服务器实例

  4. 处理初始化:服务器处理初始化请求,建立会话(如果需要)

  5. 返回响应:服务器返回初始化结果,并保持连接打开(如果支持 Keep-Alive)

    复制代码
    HTTP/1.1 200 OK
    Content-Type: application/json
    Connection: keep-alive
    
    {
      "jsonrpc": "2.0",
      "id": 1,
      "result": {...}
    }
  6. 响应返回 :响应通过负载均衡器返回客户端,TCP 连接保持打开状态(如果双方都支持 Keep-Alive)

  7. 连接就绪:客户端通知 Host 连接已建立,后续请求可以复用这个 TCP 连接

步骤 8-20:正常通信阶段

  1. 用户请求:用户在 AI 应用中发起操作
  2. 发送请求 :客户端发送新的 HTTP POST 请求
    • 连接复用:如果使用 HTTP/1.1 Keep-Alive 或 HTTP/2,客户端会复用现有的 TCP 连接
    • 新连接:如果没有可用连接或连接已关闭,则建立新的 TCP 连接
    • 连接协商 :通过 Connection: keep-alive 头(HTTP/1.1)或自动(HTTP/2)协商连接复用
  3. 请求路由:负载均衡器将请求路由到服务器实例(支持横向扩展)
  4. 处理请求:服务器处理请求

流式响应场景(步骤 12-19)

  1. 开始流式响应:服务器设置响应头,开始流式传输

    复制代码
    HTTP/1.1 200 OK
    Content-Type: application/json
    Transfer-Encoding: chunked

    13-19. 流式数据传输

    • 服务器分块发送数据
    • 每个数据块格式:长度\r\n数据\r\n
    • 客户端接收每个数据块后立即处理
    • 适合大文件传输、长时间操作等场景

普通响应场景(步骤 12-13)

  1. 返回完整响应:服务器处理完成后返回完整响应

  2. 响应返回:客户端接收完整响应

  3. 返回结果:客户端将结果返回给 Host

步骤 21:关闭阶段

  1. 关闭连接:Host 请求关闭,但 HTTP 连接本身是无状态的,无需显式关闭
3.3.4 流式响应详解

Streamable HTTP 支持两种流式响应模式:

模式 1:JSON-RPC 流式响应

http 复制代码
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked

5\r\n
{"id"\r\n
:1,\r\n
"resu\r\n
lt":{\r\n
"data":\r\n
"chunk1"}}\r\n
0\r\n
\r\n

模式 2:Server-Sent Events 格式

http 复制代码
HTTP/1.1 200 OK
Content-Type: text/event-stream
Transfer-Encoding: chunked

data: {"progress": 25}\n\n
data: {"progress": 50}\n\n
data: {"progress": 75}\n\n
data: {"progress": 100, "result": "complete"}\n\n
3.3.5 技术特点
  • 连接复用:支持 HTTP Keep-Alive(HTTP/1.1)或 HTTP/2 多路复用,底层 TCP 连接可以复用
  • 无状态通信:每个 HTTP 请求-响应都是独立的,无需维护会话状态
  • 标准 HTTP:完全基于标准 HTTP 协议,兼容性好
  • 支持流式:支持流式响应(Transfer-Encoding: chunked),适合大文件和长时间操作
  • 易于扩展:支持负载均衡、CDN、API 网关等
  • 横向扩展:可以轻松扩展到多个服务器实例
  • 灵活连接:连接可以复用(长连接)或每次新建(短连接),由客户端和服务器协商决定
3.3.6 Streamable HTTP 的深层原理

两层配合机制:

Streamable HTTP 的高效性来自于两个层面的巧妙配合:

  1. 第一层:流式响应(Streaming Response)

    • 目的:在单个请求的响应过程中,实现"边生产边消费"
    • 实现 :使用 Transfer-Encoding: chunked,服务器可以分块发送数据
    • 特点 :块大小没有固定限制 ,完全由服务器端数据产生速度决定
      • 可以是 1 字节(AI 刚生成一个字)
      • 可以是 10KB(服务器缓冲区满了)
    • 生命周期 :从请求开始到发送 0\r\n\r\n(结束块)为止
  2. 第二层:连接复用(Keep-Alive)

    • 目的:在多个请求之间,复用 TCP 连接以减少开销
    • 实现:HTTP/1.1 Keep-Alive 或 HTTP/2 多路复用
    • 特点 :一次响应结束后,TCP 连接可以保持一段时间(由超时配置决定)

两层如何配合:
Client TCP Connection Server 请求 A - 流式响应阶段 POST /mcp (Request A) 转发请求 Chunk 1 (流式输出) 实时接收 Chunk 2 实时接收 0-chunk (结束) 响应完成 连接保持阶段 (Keep-Alive) TCP 连接保持打开 等待下一个请求 请求 B - 复用连接 POST /mcp (Request B) 复用同一 TCP 连接 转发请求 响应 返回结果 Client TCP Connection Server

关键理解:

  • HTTP 语义层 :每次 POST /mcp 都是新的 HTTP 请求,与上一次请求完全独立
  • TCP 连接层:可能复用同一条 TCP 连接(如果 Keep-Alive 生效),也可能新建连接
  • "可以关闭也可以不用关闭":一次响应结束后,TCP 连接可以立即关闭(短连接),也可以保持一段时间用于复用(Keep-Alive)
3.3.7 流式块的格式与大小

块格式(Chunked Transfer Encoding):

每个块遵循以下格式:

复制代码
<长度(16进制)>\r\n
<数据内容>\r\n

示例:

复制代码
5\r\n        ← 表示接下来有 5 个字节
Hello\r\n    ← 数据内容 "Hello"
7\r\n        ← 表示接下来有 7 个字节
World!\r\n   ← 数据内容 "World!"
0\r\n        ← 0 表示结束
\r\n

块大小特点:

  • 没有固定大小:完全由服务器端数据产生速度和缓冲区策略决定
  • 动态调整
    • AI 刚生成一个字 → 可能发送 1 字节的块(实时性优先)
    • 缓冲区积累了大量数据 → 可能发送 10KB 的块(效率优先)
  • 为什么不定长?
    • 实时性:固定大小会导致等待,影响用户体验(打字机效果)
    • 效率:大数据量时,大块传输网络利用率更高
3.3.8 断开时机详解

Streamable HTTP 的"断开"分为两个层面:

1. 逻辑结束(请求处理完成)

  • 触发条件 :服务器发送 0\r\n\r\n(大小为 0 的块)
  • 含义:本次 AI 回复(或文件传输)彻底完成
  • 客户端表现response.read() 返回,进度条走满,代码继续执行

2. 物理断开(TCP 连接断开)

取决于是否启用 Keep-Alive:

情况 A:没有 Keep-Alive(短连接)

  • 时机:紧接着逻辑结束后立即断开
  • 过程 :服务器发送 TCP FIN 包,连接关闭

情况 B:有 Keep-Alive(常见情况)

  • 时机:逻辑结束后,再过一段"空闲时间"(Keep-Alive Timeout)
  • 过程
    1. 服务器发送 0\r\n\r\n(逻辑结束)
    2. 连接保持通畅(State: ESTABLISHED),但无数据传输
    3. 计时开始
      • 如果客户端在超时时间内发新请求 → 计时清零,连接继续用
      • 如果客户端超时无动作 → 服务器/网关发送 TCP FIN,物理断开

典型超时配置:

  • Nginx 默认:keepalive_timeout 65s
  • Spring Boot 默认:server.tomcat.keep-alive-timeout: 60s
  • 自定义:根据业务需求设置

异常断开:

  • 客户端崩溃 → 服务器写数据报错(Broken Pipe),服务器端断开
  • 服务器崩溃 → 客户端读超时(Read Timeout),客户端断开
3.3.9 客户端多次请求的机制

能否发多次请求?

可以。 Streamable HTTP 的客户端可以连续发多次请求(一次 POST /mcp 完成后,再发下一次)。

为什么可以继续发?

因为 Streamable HTTP 遵循标准的 HTTP 请求-响应模型:

  • 一次请求对应一次响应(响应可以流式)
  • 本次响应结束后,这次交互就结束了
  • 客户端当然可以再发下一次请求(新的 HTTP request)

还是"之前那条连接"吗?

不一定,但可能是。

  • HTTP 语义层:下一次请求一定是"新的请求"(新的 request),不是接着上一次 response
  • TCP 连接层 :可能复用同一条 TCP 连接,也可能新建一条
    • 复用:如果启用 HTTP/1.1 Keep-Alive 或 HTTP/2,客户端通常会复用已有连接
    • 新建:如果连接空闲超时被关闭,或客户端策略不复用,就会新建连接

第一次响应没完成,能否发第二次请求?

这取决于 HTTP 版本:

HTTP/1.1(同一条 TCP 连接):

  • 不可以 :必须等第一个响应彻底结束(收到 0-chunk
  • 原因:HTTP/1.1 在同一连接上只能串行处理请求-响应(Head-of-Line Blocking)
  • 解决方案 :如果想并发,必须新建另一个 TCP 连接

HTTP/2(同一条 TCP 连接):

  • 可以:支持多路复用(Multiplexing)
  • 原理:HTTP/2 把一个 TCP 连接拆成多个虚拟的 Stream ID
  • 表现:可以在第一个请求的流式响应还在传输时,发起第二个请求(不同的 Stream ID)
  • 数据混合传输:网线上会看到不同 Stream 的数据帧混合传输

Client TCP (HTTP/2) Server HTTP/2 多路复用示例 POST /mcp (Stream ID 1) 转发 Stream 1 Stream 1: Chunk 1 接收 Stream 1 Chunk 1 第一个响应还在进行中... POST /mcp (Stream ID 3) 并发发起! 转发 Stream 3 Stream 3: Response 接收 Stream 3 Stream 1: Chunk 2 接收 Stream 1 Chunk 2 两个请求互不干扰,并行处理 Client TCP (HTTP/2) Server

3.3.10 配置示例
json 复制代码
{
  "mcpServers": {
    "cloud-server": {
      "url": "https://api.example.com/mcp",
      "headers": {
        "Authorization": "Bearer token",
        "X-API-Version": "v1"
      }
    }
  }
}

4. Transport Type 对比分析

4.1 功能特性对比表

维度 STDIO SSE Streamable HTTP
通信方向 双向(请求-响应) 单向推送 + 双向请求 双向(请求-响应)
连接模式 进程管道 HTTP 长连接(专门用于推送) HTTP 连接(支持 Keep-Alive/HTTP/2 复用)
网络要求 不需要网络 需要网络 需要网络
部署方式 本地进程 远程服务 远程服务
扩展性 差(单进程) 中等(单连接) 优秀(无状态)
实时性 高(本地通信) 高(长连接推送) 中等(请求-响应)
流式支持 支持 支持(事件流) 支持(HTTP chunked)
负载均衡 不支持 有限支持 完全支持
实现复杂度 简单 中等 中等
调试难度 简单 中等 中等
资源消耗 中等(长连接) 低(连接可复用)
错误恢复 进程重启 连接重试 请求重试

4.2 性能对比

并发能力 吞吐量对比 延迟对比 STDIO
低并发
单进程 SSE
中等并发
每客户端一连接 Streamable HTTP
高并发
无状态设计 STDIO
中等吞吐量
单进程限制 SSE
中等吞吐量
单连接限制 Streamable HTTP
高吞吐量
可横向扩展 STDIO
最低延迟
本地进程通信 SSE
中等延迟
HTTP长连接 Streamable HTTP
中等延迟
HTTP连接可复用

4.3 适用场景对比

STDIO 适用场景

推荐使用:

  • 本地开发和测试
  • 桌面应用集成(如 Claude Desktop)
  • 需要访问本地文件系统
  • 简单的工具集成
  • 对网络延迟敏感的场景

不推荐使用:

  • 远程服务部署
  • 需要横向扩展的场景
  • 多客户端共享服务
  • 云端部署
SSE 适用场景

推荐使用:

  • 需要服务器主动推送通知
  • 实时数据更新(如股票行情、新闻推送)
  • 进度更新和状态通知
  • Web 应用集成
  • 需要实时反馈的场景

不推荐使用:

  • 简单的请求-响应模式
  • 不需要服务器推送的场景
  • 对连接数有限制的环境
  • 需要高并发处理的场景
Streamable HTTP 适用场景

推荐使用:

  • 云端生产环境部署
  • 需要横向扩展的服务
  • 通过 API 网关访问
  • 需要负载均衡的场景
  • 微服务架构
  • 需要 CDN 加速的场景
  • 大文件传输
  • 长时间操作的流式响应

不推荐使用:

  • 需要服务器主动推送(无推送能力)
  • 本地开发(过于复杂)
  • 对实时性要求极高的场景

4.4 数据流向对比图

Streamable HTTP 数据流 SSE 数据流 STDIO 数据流 请求 stdin stdout 响应 请求 HTTP POST HTTP Response SSE Push 响应 请求 HTTP POST 路由 HTTP Response
可能流式 响应 响应 Client Host Load Balancer Server Instance Client Host Server Client Host Server Process

4.5 Streamable HTTP vs SSE 深度对比

虽然两者都能"分段往外吐数据",但它们在语义和用途上有根本性区别:

4.5.1 核心区别:连接用途
维度 SSE Streamable HTTP
连接用途 专用推送通道(订阅/广播) 请求-响应通道(问答)
生命周期 无限while(true) 死等) 有限(任务完成即结束)
服务器端代码 需要维护 List<SseEmitter> 订阅者列表 不需要维护任何列表
服务器能否主动推送? (随时给所有订阅者发) 不能(必须等客户端问)
客户端能否发多次请求? ❌ 不能(SSE 连接是单向的) (响应结束后可以继续发)
HTTP 方法 GET(建立订阅) POST(发送请求)
4.5.2 生命周期对比

SSE(无限生命周期):

java 复制代码
// SSE 服务器端代码示例
@GetMapping("/sse")
public SseEmitter subscribe() {
    SseEmitter emitter = new SseEmitter(0L); // 0 = 永不超时
    clients.add(emitter);
    
    // 死循环,永远不退出
    while (true) {
        emitter.send(data);
        Thread.sleep(1000);
    }
    // 永远不会执行到这里(除非断网)
}

Streamable HTTP(有限生命周期):

java 复制代码
// Streamable HTTP 服务器端代码示例
@PostMapping("/mcp")
public StreamingResponseBody chat() {
    return outputStream -> {
        // 有限循环,任务完成就结束
        for (String chunk : chunks) {
            outputStream.write(chunk);
            outputStream.flush();
        }
        // 方法结束 = 响应结束 = 这次交互结束
    };
}
4.5.3 为什么看起来像?

两者在**"一次请求的处理过程"**中确实很像:

  • 都是 HTTP
  • 都是分块传输
  • 都是像流水一样一段段来

生命周期不同:

  • SSE 的生命周期是无限的(直到断网),目的是**"监控/通知"**
  • Streamable HTTP 的生命周期是有限的(直到任务做完),目的是**"传输长结果"**
4.5.4 一句话判别法

"如果 AI 突然想起来一个小时前的话题,想主动告诉你,它能做到吗?"

  • SSE(Server 主动推送)
  • 不能 (必须等你下次问它)→ Streamable HTTP

总结:

  • SSE:你订阅了,我有消息就推给你(像收音机)
  • Streamable HTTP:你问我,我慢慢答,答完拉倒(像点歌)

5. 推荐使用场景

5.1 综合推荐矩阵

场景类型 推荐 Transport 理由
本地开发 STDIO 简单直接,无需网络配置,调试方便
桌面应用 STDIO 进程隔离,生命周期管理简单
实时通知 SSE 支持服务器主动推送,实时性好
云端生产 Streamable HTTP 易于扩展,支持负载均衡,无状态设计
微服务架构 Streamable HTTP 标准 HTTP,易于集成,支持服务发现
高并发场景 Streamable HTTP 无状态设计,可横向扩展
简单工具集成 STDIO 实现简单,资源消耗低
Web 应用 SSE 或 Streamable HTTP 根据是否需要推送选择

5.2 选择决策树

否 是 是 否 是 否 是 否 选择 Transport Type 需要网络通信? 使用 STDIO 需要服务器主动推送? 使用 SSE 需要横向扩展? 使用 Streamable HTTP 需要高并发?

5.3 最佳实践建议

开发阶段
  1. 本地开发:使用 STDIO,简单快速
  2. 功能测试:使用 STDIO,便于调试
  3. 集成测试:根据目标环境选择对应的 Transport
生产部署
  1. 单机部署:可以考虑 STDIO(如果不需要远程访问)
  2. 远程服务:优先使用 Streamable HTTP
  3. 需要推送:使用 SSE
  4. 高可用要求:必须使用 Streamable HTTP + 负载均衡
性能优化
  1. STDIO:优化进程启动时间,使用进程池
  2. SSE:合理设置连接超时,实现自动重连
  3. Streamable HTTP:使用连接池,启用 HTTP/2,配置 CDN

6. MCP Inspector 原理

6.1 什么是 MCP Inspector

MCP Inspector 是一个调试工具,本质上是一个**"带 UI 的 MCP 客户端"**,用于可视化地测试和调试 MCP 服务器。

6.2 Connected 状态的判断原理

在 MCP Inspector 中,Connected 状态不是简单的"TCP 还连着",而是指 "Inspector 已经和 MCP Server 建立了可用的 MCP 会话"

6.2.1 判断标准

Connected 状态需要满足两个条件:

  1. 传输层可用(Transport Ready)

    • STDIO:子进程启动成功,stdin/stdout 可读写
    • SSE:SSE 事件流连接成功(GET /sse 返回 200)
    • Streamable HTTP:能成功发起 HTTP 请求
  2. 协议层可用(MCP Initialized)

    • 发送 initialize(JSON-RPC)请求
    • 收到有效的初始化响应(包含 capabilitiesserverInfo
    • 这是关键门槛 :只有 initialize 成功,才会显示 Connected
6.2.2 不同 Transport 的判断方式

STDIO:
Inspector 子进程 MCP Server 启动进程 进程启动 initialize (stdin) initialize result (stdout) 状态 = Connected ✅ 状态 = Error ❌ alt [initialize 成功] [initialize 失败] Inspector 子进程 MCP Server

SSE:
Inspector MCP Server GET /sse (建立事件流) 200 OK (连接保持) POST /request (initialize) initialize result 状态 = Connected ✅ 状态 = Error ❌ alt [两条通道都成功- ] [任意一条失败] Inspector MCP Server

Streamable HTTP:
Inspector MCP Server POST /mcp (initialize) 200 OK + initialize result 状态 = Connected ✅ 状态 = Error ❌ alt [initialize 成功] [initialize 失败] Inspector MCP Server

6.2.3 状态转换
复制代码
[未连接] 
    ↓ (建立 Transport + initialize 成功)
[Connected] ✅
    ↓ (连接断开 / initialize 失败 / 超时)
[Disconnected] ❌
    ↓ (重连)
[Connecting...] ⏳
6.2.4 验证方法

在 Inspector 或浏览器开发者工具中查看:

  1. Network 面板

    • 是否有 initialize 请求
    • 是否返回 capabilities
    • 状态码是否为 200
  2. SSE 场景

    • 是否存在一条 text/event-stream 的长连接
    • 连接状态是否为 "Pending" 或 "Connected"
  3. Console 日志

    • 是否有 "initialized" 或 "handshake completed" 日志

6.3 Inspector 的工作流程

Inspector UI Inspector MCP Client Transport MCP Server 选择 server 配置并连接 建立通道 连接就绪 JSON-RPC initialize initialize result (capabilities/serverInfo) tools/list & resources/list 返回清单 点击调用 tool / 读取 resource tools/call / resources/read (JSON-RPC) result / error (可流式) 展示请求/响应与日志 Inspector UI Inspector MCP Client Transport MCP Server


相关推荐
Codebee2 小时前
#专访Ooder架构作者|A2UI时代全栈架构的四大核心之问,深度解析设计取舍
人工智能
亚马逊云开发者2 小时前
如何在亚马逊云科技部署高可用MaxKB知识库应用
人工智能
沙漠豪2 小时前
提取PDF发票信息的Python脚本
开发语言·python·pdf
亚里随笔2 小时前
突破性框架TRAPO:统一监督微调与强化学习的新范式,显著提升大语言模型推理能力
人工智能·深度学习·机器学习·语言模型·llm·rlhf
牛客企业服务3 小时前
AI面试实用性解析:不是“能不能用”,而是“怎么用好”
人工智能·面试·职场和发展
MicroTech20253 小时前
激光点云快速配准算法创新突破,MLGO微算法科技发布革命性点云配准算法技术
人工智能·科技·算法
救救孩子把3 小时前
50-机器学习与大模型开发数学教程-4-12 Bootstrap方法
人工智能·机器学习·bootstrap
趣知岛4 小时前
AI是否能代替从业者
人工智能