主题
Streamable HTTP
INFO
Streamable HTTP 在协议版本 2025-03-26 中引入,用于替代协议版本 2024-11-05 中的 HTTP+SSE 传输。
INFO
修订版 2026-07-28 改变了 Streamable HTTP 的行为。客户端必须确保正确处理向后兼容性。变更包括:
- 移除了 GET 流端点。
- 移除了协议级会话。
在 Streamable HTTP 传输中,服务端作为独立进程运行,可以处理多个客户端连接。概览如下:
- 服务端暴露单个 HTTP 端点(即 MCP 端点),接受 POST。
- 客户端将每个 JSON-RPC 请求或通知作为独立的 HTTP POST 发送。
- 服务端对每个请求以单个 JSON 对象或一个作用域限定于该请求的 Server-Sent Events (SSE) 流进行响应,该流携带与请求相关的通知,随后是最终响应。
- 服务端到客户端的交互(采样、征询、根目录)按照多轮往返请求 (MRTR)(SEP-2322)作为输入请求嵌入在结果中。
- 长期存在的变更通知(例如列表变更和资源更新)通过
subscriptions/listen请求的响应流传递。
这些交互的时序图参见消息流。
服务端 MUST(必须)提供单个支持 POST 的 HTTP 端点路径(以下称为 MCP 端点)。例如,这可以是一个类似 https://example.com/mcp 的 URL。
安全与端点
在实现 Streamable HTTP 传输时:
- 服务端 MUST(必须)验证所有传入连接的
Origin头,以防止 DNS 重绑定攻击。- 如果
Origin头存在且无效,服务端 MUST(必须)以 HTTP 403 Forbidden 响应。HTTP 响应体 MAY(可以)包含一个没有id的 JSON-RPC 错误响应。
- 如果
- 在本地运行时,服务端 SHOULD(应该)仅绑定到 localhost (127.0.0.1),而不是所有网络接口 (0.0.0.0)。
- 服务端 SHOULD(应该)为所有连接实现适当的身份验证。
如果没有这些保护,攻击者可能利用 DNS 重绑定从远程网站与本地 MCP 服务端交互。
发送消息
客户端发送的每条 JSON-RPC 消息 MUST(必须)是发往 MCP 端点的新 HTTP POST 请求。
- 客户端 MUST(必须)使用 HTTP POST 发送 JSON-RPC 消息。
- 客户端 MUST(必须)包含一个
Accept头,列出application/json和text/event-stream两者作为支持的内容类型。 - 客户端 MUST(必须)在每个 POST 请求中包含请求元数据头。
- HTTP POST 的正文 MUST(必须)是单个 JSON-RPC 请求或通知。客户端 MUST NOT(不得)发送 JSON-RPC 响应。
- 如果正文是 JSON-RPC 通知:
- 如果服务端接受它,服务端 MUST(必须)返回 HTTP 状态码
202 Accepted,且无正文。 - 如果服务端无法接受它,它 MUST(必须)返回 HTTP 错误状态码(例如
400 Bad Request)。HTTP 响应体 MAY(可以)包含一个没有id的 JSON-RPC 错误响应。
- 如果服务端接受它,服务端 MUST(必须)返回 HTTP 状态码
- 如果正文是 JSON-RPC 请求,服务端 MUST(必须)返回
Content-Type: application/json(单个 JSON 对象)或Content-Type: text/event-stream(SSE 响应流)。客户端 MUST(必须)同时支持两者。
NOTE
本修订版的核心协议未定义通过 Streamable HTTP 的客户端到服务端通知。核心协议中唯一由客户端发送的通知 notifications/cancelled 仅用于 stdio 传输;在 Streamable HTTP 上,关闭 SSE 响应流本身就是取消信号,不期望出现 notifications/cancelled 消息(参见取消)。上述通知规则描述了通知 POST 的传输机制;本修订版未定义通知 POST 的头要求。
接收消息
当服务端返回 SSE 响应流(Content-Type: text/event-stream)时:
- 服务端 MAY(可以)在最终响应之前发送 JSON-RPC 通知——例如
notifications/progress或notifications/message。这些通知 MUST(必须)与发起它们的客户端请求相关。 - 服务端 MUST NOT(不得)在此流上发送独立的 JSON-RPC 请求。服务端到客户端的交互(采样、征询、list-roots)按照 MRTR(SEP-2322)作为输入请求嵌入在
InputRequiredResult中,而不是作为单独请求在此流或任何其他流上传递。这是相对于协议版本2025-03-26至2025-11-25中 Streamable HTTP 的变更,在那些版本中服务端可以在 SSE 流上发送此类请求。 - 最终的 JSON-RPC 响应 SHOULD(应该)终止该流。
长期存在的通知流通过发送 subscriptions/listen 请求获得。服务端的响应本身就是一个保持打开的 SSE 流,传递客户端选择订阅的变更通知(例如 notifications/tools/list_changed 或 notifications/resources/updated)。像 notifications/progress 和 notifications/message 这样的请求作用域通知不会在 listen 流上传递——它们仅在与它们相关的请求的响应流上流动。 在发起 SSE 流时,服务端 SHOULD(应该)在 HTTP 响应中包含 X-Accel-Buffering: no 头。这会指示反向代理(例如 nginx)禁用响应缓冲,确保 SSE 事件立即传递给客户端,而不是被保留在缓冲区中。如果没有此头,代理可能会在将消息发送给客户端之前累积消息,引入不必要的延迟,并可能破坏 SSE 通信的实时性。
NOTE
对于长期存在的流——特别是 subscriptions/listen 响应流——鼓励服务端定期发出 SSE 注释行(以冒号开头的行,例如 :\r\n)作为保活。这可以防止连接在没有通知流动的静默期间被中间设备或客户端空闲超时关闭。根据 SSE 规范,任何以冒号开头的行都是不携带事件数据的注释;客户端必须忽略此类行,且不得将其视为格式错误的输入。
不支持通过 Last-Event-ID 实现可断流恢复的 SSE 流。
消息流
以下图示说明了单个 MCP 端点上的消息流。
请求与响应。 每个请求都是独立的 POST;服务端按请求选择以单个 JSON 对象或 SSE 流进行响应:
sequenceDiagram
participant Client
participant Server
note over Client,Server: Simple response
Client->>Server: POST tools/call (JSON-RPC request)
Server-->>Client: 200 OK, application/json<br/>JSON-RPC response
note over Client,Server: Streaming response
Client->>Server: POST tools/call (JSON-RPC request)
note over Server: Opens SSE stream<br/>scoped to this request
Server-->>Client: SSE: notifications/progress
Server-->>Client: SSE: notifications/progress
Server-->>Client: SSE: JSON-RPC response
note over Client,Server: Stream closes
note over Client,Server: Notification
Client->>Server: POST (JSON-RPC notification)
Server-->>Client: 202 Accepted
服务端到客户端的交互 (MRTR)。 当服务端需要来自客户端的输入——采样、征询或根目录——它不会发送自己的 JSON-RPC 请求。它返回一个包含 inputRequests 的 InputRequiredResult,客户端使用匹配的 inputResponses 重试原始请求(参见多轮往返请求):
sequenceDiagram
participant Client
participant Server
Client->>Server: POST tools/call (id: 1)
note over Server: Needs user input or<br/>an LLM completion
Server-->>Client: InputRequiredResult<br/>(inputRequests: elicitation/create)
note over Client: Gathers the requested input
Client->>Server: POST tools/call (id: 2)<br/>(original params + inputResponses)
Server-->>Client: Final result
变更通知。 希望获得服务端发起的变更通知的客户端通过 subscriptions/listen 打开一个长期存在的流;响应流保持打开,仅携带客户端选择订阅的通知类型:
sequenceDiagram
participant Client
participant Server
Client->>Server: POST subscriptions/listen<br/>(notification filter)
Server-->>Client: SSE: notifications/subscriptions/acknowledged
note over Client,Server: Stream stays open
Server-->>Client: SSE: notifications/tools/list_changed
Server-->>Client: SSE: notifications/resources/updated
note over Client,Server: Until the client or server closes the stream
取消
关闭 SSE 响应流 MUST(必须)被服务端视为对该请求的取消。由于每个请求都有自己的响应流,传输层断开是明确的。服务端 SHOULD(应该)尽快停止被取消请求的工作,并且 MUST NOT(不得)为其发送任何进一步的消息。完整规则参见取消。
请求元数据
Streamable HTTP 传输将选定的 JSON-RPC 正文字段镜像到 HTTP 头中,以便中间设备(负载均衡器、网关、可观测性工具)无需解析正文即可路由和检查请求。
协议版本头
发往 MCP 端点的每个 POST 请求 MUST(必须)包含 MCP-Protocol-Version 头。
例如:MCP-Protocol-Version: 2026-07-28
头值 MUST(必须)与请求正文 _meta 中携带的 io.modelcontextprotocol/protocolVersion 字段匹配。如果值不匹配,服务端 MUST(必须)以 400 Bad Request 和 HeaderMismatch JSON-RPC 错误拒绝该请求(参见服务端验证)。
如果服务端未实现所请求的协议版本(无论该版本对服务端未知,还是服务端选择不支持的已知版本),它 MUST(必须)以 400 Bad Request 和列出其支持版本的 UnsupportedProtocolVersionError 响应。协商流程参见版本管理:协议版本协商。
如果服务端未实现所请求的 RPC 方法,它 MUST(必须)以 404 Not Found 和代码为 -32601(Method not found)的 JSON-RPC 错误响应。JSON-RPC 错误正文将此情况与不承载现代 MCP 端点的传统 HTTP+SSE 服务端返回的 404 区分开来(参见向后兼容性)。 支持实现早于 2025-06-18 协议版本(该版本未定义 MCP-Protocol-Version 头)的客户端的服务端 MAY(可以)将省略该头的请求视为协议版本 2025-03-26。不支持此类客户端的服务端 MUST(必须)按照服务端验证拒绝没有该头的请求。
标准请求头
| Header Name | Source Field | Required For |
|---|---|---|
Mcp-Method | method | All requests |
Mcp-Name | params.name or params.uri | tools/call, resources/read, prompts/get requests |
这些头是合规所 REQUIRED(必需)的。
如果 Mcp-Name 源值无法安全地表示为纯 ASCII 头值,客户端 MUST(必须)使用值编码中描述的 Base64 哨兵格式对其进行编码。
tools/call 请求:
http
POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_weather
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {
"location": "Seattle, WA"
},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "ExampleClient",
"version": "1.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}resources/read 请求:
http
POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: resources/read
Mcp-Name: file:///projects/myapp/config.json
{
"jsonrpc": "2.0",
"id": 2,
"method": "resources/read",
"params": {
"uri": "file:///projects/myapp/config.json",
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "ExampleClient",
"version": "1.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}来自工具参数的自定义头
MCP 服务端 MAY(可以)使用工具 inputSchema 中参数 schema 内的 x-mcp-header 扩展属性,指定将特定工具参数镜像到 HTTP 头中。有关如何标注工具参数的详细信息,参见工具定义。
虽然 x-mcp-header 的使用对服务端是可选的,但客户端 MUST(必须)支持此功能。当服务端的工具定义包含 x-mcp-header 标注时,符合规范的客户端 MUST(必须)将指定的参数值镜像到 HTTP 头中。
Schema 扩展
x-mcp-header 属性指定用于构造头名称 Mcp-Param-{name} 的名称部分。
对 x-mcp-header 值的约束:
- MUST NOT(不得)为空
- MUST(必须)匹配 HTTP 字段名 token 语法(
1*tchar,RFC 9110 第 5.1 节) - MUST NOT(不得)包含控制字符,包括回车 (CR,
\r) 或换行 (LF,\n) - MUST(必须)在
inputSchema中的所有x-mcp-header值中大小写不敏感地唯一 - MUST(必须)仅应用于具有原始类型(integer、string、boolean)的参数。类型为
number的参数不允许。整数值 MUST(必须)在 JavaScript 的安全范围内(−253+1 到 253−1) - MUST(必须)仅应用于从 schema 根静态可达的属性:通过仅由
properties键组成的链可达。该链 MUST NOT(不得)经过items(或任何其他数组关键字)、组合关键字(oneOf、anyOf、allOf、not)、条件关键字(if/then/else)或$ref。只要链中的每一步都是properties键,就允许嵌套对象属性。任何其他位置的x-mcp-header标注都会使该标注——进而使该工具定义——无效。
头提取定义为读取被标注属性确切属性路径(通向它的 properties 键链)处的实例值。如果调用参数中该路径处不存在值,则省略该头。
使用 Streamable HTTP 传输的客户端 MUST(必须)拒绝任何 x-mcp-header 值违反这些约束的工具定义。拒绝意味着客户端 MUST(必须)将无效工具从 tools/list 的结果中排除。客户端 SHOULD(应该)在拒绝工具定义时记录警告,包括工具名称和拒绝原因。这确保单个格式错误的工具定义不会阻止其他有效工具被使用。使用其他传输(例如 stdio)的客户端 MAY(可以)完全忽略 x-mcp-header 标注。
示例工具定义:
json
{
"name": "execute_sql",
"description": "Execute SQL on Google Cloud Spanner",
"inputSchema": {
"type": "object",
"properties": {
"region": {
"type": "string",
"description": "The region to execute the query in",
"x-mcp-header": "Region"
},
"query": {
"type": "string",
"description": "The SQL query to execute"
}
},
"required": ["region", "query"]
}
}生成的 HTTP 请求:
http
POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: execute_sql
Mcp-Param-Region: us-west1
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "ExampleClient",
"version": "1.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
},
"name": "execute_sql",
"arguments": {
"region": "us-west1",
"query": "SELECT * FROM users"
}
}
}值编码
客户端 MUST(必须)在将参数值包含到 HTTP 头之前对其进行编码,以确保安全传输并防止注入攻击。
类型转换:将参数值转换为其字符串表示:
string:按原样使用该值integer:转换为十进制字符串表示(例如42、-7)boolean:转换为小写"true"或"false"
根据 RFC 9110,HTTP 头字段值必须由可见 ASCII 字符 (0x21-0x7E)、空格 (0x20) 和水平制表符 (0x09) 组成。当值无法安全地表示为纯 ASCII 头值(例如它包含非 ASCII 字符、控制字符,或具有前导/尾随空白)时,客户端 MUST(必须)使用 UTF-8 表示的 Base64 编码,格式如下:
text
Mcp-Param-{Name}: =?base64?{Base64EncodedValue}?=同样的编码规则适用于 Mcp-Name 头值。工具和提示模板名称仅 SHOULD(应该)受限于头安全字符,因此安全集合之外的名称(或资源 URI)按如下方式携带:
text
Mcp-Name: =?base64?{Base64EncodedValue}?=前缀 =?base64? 和后缀 ?= 表示该值是 Base64 编码的。这些标记区分大小写,且 MUST(必须)完全如所示出现(小写)。需要检查这些值的服务端和中间设备 MUST(必须)相应地解码它们。特别是,服务端 MUST(必须)在服务端验证期间,将编码的 Mcp-Name 或 Mcp-Param-{Name} 值与相应的请求正文值比较之前先解码。
为避免歧义,客户端 MUST(必须)也对任何匹配哨兵模式(即以 =?base64? 开头并以 ?= 结尾)的纯 ASCII 值进行 Base64 编码。
编码示例:
| Original Value | Reason | Encoded Header Value |
|---|---|---|
"us-west1" | Plain ASCII | Mcp-Param-Region: us-west1 |
"Hello, 世界" | Contains non-ASCII | Mcp-Param-Greeting: =?base64?SGVsbG8sIOS4lueVjA==?= |
" padded " | Leading/trailing spaces | Mcp-Param-Text: =?base64?IHBhZGRlZCA=?= |
"line1\nline2" | Contains newline | Mcp-Param-Text: =?base64?bGluZTEKbGluZTI=?= |
"=?base64?literal?=" | Matches sentinel pattern | Mcp-Param-Val: =?base64?PT9iYXNlNjQ/bGl0ZXJhbD89?= |
客户端行为
通过 HTTP 传输构造 tools/call 请求时,客户端 MUST(必须):
- 从请求正文中提取任何标准头的值(例如
method、params.name、params.uri)。 - 将
Mcp-Method头以及(如适用)Mcp-Name头追加到请求中。 - 检查工具
inputSchema中标记有x-mcp-header的属性,并在每个被标注属性的确切属性路径处提取值,当不存在值时省略该头(参见 Schema 扩展)。 - 根据值编码规则对值进行编码。
- 将
Mcp-Param-{Name}: {Value}头追加到请求中。
如果服务端因缺少必需的 Mcp-Param-* 头或这些头与正文不匹配而以 HeaderMismatch 错误拒绝请求,客户端 SHOULD(应该)调用 tools/list 检查工具 inputSchema 的变更,然后使用适当的头重试原始请求。
自定义头的服务端行为
不识别 Mcp-Param-{Name} 头的中间服务端 MUST(必须)转发它,否则忽略它,如 HTTP 语义 RFC 所要求。
服务端 MUST(必须)拒绝包含无效字符的已识别 Mcp-Param-{Name} 头的请求(参见值编码)。
任何处理消息正文的服务端 MUST(必须)验证编码的头值(如果是 Base64 编码的,在解码后)与请求正文中的相应值匹配。如果任何验证失败,服务端 MUST(必须)以 400 Bad Request HTTP 状态和 JSON-RPC 错误代码 -32020(HeaderMismatch)拒绝请求。
| Scenario | Client Behavior | Server Behavior |
|---|---|---|
| Parameter value provided | Client MUST include the header | Server MUST validate header matches body |
Parameter value is null | Client MUST omit the header | Server MUST NOT expect the header |
| Parameter not in arguments | Client MUST omit the header | Server MUST NOT expect the header |
| Client omits header but value is in body | Non-conforming client | Server MUST reject the request |
大小写敏感性
头名称(在 RFC 9110 中称为 "field names")是大小写不敏感的。客户端和服务端 MUST(必须)对头名称使用大小写不敏感的比较。头值(例如方法名)是大小写敏感的。
服务端验证
处理请求正文的服务端 MUST(必须)拒绝头中指定的值与请求正文中相应值不匹配的请求。这可以防止当网络中的不同组件依赖不同的事实来源时(例如负载均衡器根据头值路由,而 MCP 服务端根据正文值执行)可能存在的安全漏洞。
NOTE
验证整数参数值时,服务端 SHOULD(应该)以数值方式而非字符串方式比较头值和正文值(例如 42.0 和 42 被视为相等)。
当因头验证失败而拒绝请求时,服务端 MUST(必须)返回 HTTP 状态 400 Bad Request,并且 MUST(必须)包含使用以下错误代码的 JSON-RPC 错误响应:
| Code | Name | Description |
|---|---|---|
-32020 | HeaderMismatch | The HTTP headers do not match the corresponding values in the request body, or required headers are missing/malformed. |
此错误代码从 MCP 规范为协议定义的错误保留的子范围中分配。参见错误代码。
示例错误响应:
json
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32020,
"message": "Header mismatch: Mcp-Name header value 'foo' does not match body value 'bar'"
}
}验证失败条件包括:
- 缺少必需的标准头(
MCP-Protocol-Version、Mcp-Method、Mcp-Name)。 - 头值与相应的请求正文值不匹配。对于允许 Base64 哨兵编码的头(
Mcp-Name和Mcp-Param-{Name}),服务端 MUST(必须)在将其与正文值比较之前解码编码值(参见值编码)。 - 头值包含无效字符。
NOTE
中间设备 MUST(必须)为验证失败返回适当的 HTTP 错误状态(例如 400 Bad Request),但不要求返回 JSON-RPC 错误响应。
NOTE
基于镜像头强制执行策略(例如按租户路由或限流)的中间设备 SHOULD(应该)验证 MCP-Protocol-Version 头指示的版本是否要求头–正文验证。如果版本较旧或头缺失,中间设备 SHOULD(应该)拒绝请求,而不是信任未验证的头值。
向后兼容性
同时支持现代(逐请求元数据)MCP 版本和需要 initialize 握手的传统版本的客户端 MAY(可以)通过先尝试现代请求来检测服务端实现的是哪个时代。在收到 400 Bad Request 时,客户端 SHOULD(应该)在回退之前检查响应正文:现代服务端也会对 UnsupportedProtocolVersionError、MissingRequiredClientCapabilityError 和头验证失败使用 400。
- 如果正文包含已识别的现代 JSON-RPC 错误,则服务端使用现代版本的 MCP——使用通告的
supported版本重试或更正请求,而不是回退。 - 如果正文为空或不是已识别的现代 JSON-RPC 错误,则回退到
initialize,并在后续请求中继续使用传统版本。
时代模型和面向实现者的兼容性矩阵参见[版本管理:向后兼容性][lifecycle-compat]。
早期 Streamable HTTP 修订版
协议版本 2025-03-26 至 2025-11-25 也使用 Streamable HTTP 传输,但形态不同:服务端可以通过 Mcp-Session-Id 头分配会话(以 HTTP DELETE 终止),客户端可以使用 HTTP GET 打开独立 SSE 流以接收服务端发起的消息,服务端可以在 SSE 流上发送 JSON-RPC 请求,并且流可以通过 Last-Event-ID 断流恢复。这些机制均不属于本修订版。
仅支持本修订版的服务端如果收到来自较旧客户端的此类流量,SHOULD(应该)按如下方式响应:
- 对 MCP 端点的 HTTP GET 或 DELETE:以
405 Method Not Allowed响应。 - 请求上的
Mcp-Session-Id头:忽略它,不生成或回显会话 ID。 Last-Event-ID头:忽略它;流不可断流恢复。
需要与使用这些协议版本的对端互操作的服务端和客户端,除上述版本协商回退外,还应实现相应修订版中描述的行为(例如 2025-11-25:Streamable HTTP)。
HTTP+SSE 传输 (2024-11-05)
WARNING
已弃用:协议版本 2024-11-05 中的 HTTP+SSE 传输 自协议版本 2025-03-26 起已被弃用,并根据功能生命周期策略(SEP-2596)归类为已弃用。新实现 SHOULD NOT(不应)采用它;现有实现 SHOULD(应该)迁移到 Streamable HTTP。它有可能在未来的修订版中被移除;参见已弃用功能注册表。
客户端和服务端可以按如下方式保持与已弃用的 HTTP+SSE 传输(来自协议版本 2024-11-05)的向后兼容性:
希望支持较旧客户端的服务端应该:
- 继续托管旧传输的 SSE 和 POST 端点,与为 Streamable HTTP 传输定义的新 "MCP 端点" 并存。
- 也可以将旧的 POST 端点与新的 MCP 端点合并,但这可能引入不必要的复杂性。
希望支持较旧服务端的客户端应该:
- 接受用户提供的 MCP 服务端 URL,该 URL 可能指向使用旧传输或新传输的服务端。
- 尝试向服务端 URL POST 一个请求,带有如上定义的
Accept头:- 如果成功,客户端可以假定这是支持新 Streamable HTTP 传输的服务端。
- 如果失败并返回 HTTP 状态码
400 Bad Request、404 Not Found或405 Method Not Allowed,且响应正文不是已识别的现代 JSON-RPC 错误(现代服务端会为不支持的版本、未知方法或头验证失败返回一个):- 向服务端 URL 发出 GET 请求,期望这会打开一个 SSE 流并作为第一个事件返回
endpoint事件。 - 当
endpoint事件到达时,客户端可以假定这是运行旧 HTTP+SSE 传输的服务端,并应使用该传输进行所有后续通信。 [lifecycle-compat]: https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning#backward-compatibility-with-initialization-based-versions
- 向服务端 URL 发出 GET 请求,期望这会打开一个 SSE 流并作为第一个事件返回