0%

MCP streamable-http 通信过程

最近因为工作需要研究了一下MCP的streamable-http的通信流程, 具体来说整个连接过程涉及了两次POST和一次GET

  1. 建立mcp session,这步主要作用是从response的header中获得session-id
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
curl --location --request POST 'http://localhost:8000/mcp' \
--header 'accept: application/json, text/event-stream' \
--header 'content-type: application/json' \
--data-raw '{
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {
"sampling": {},
"roots": {
"listChanged": true
}
},
"clientInfo": {
"name": "mcp-inspector",
"version": "0.12.0"
}
},
"jsonrpc": "2.0",
"id": 0
}'

response body 是sse格式的

1
2
event: message
data: {"jsonrpc":"2.0","id":0,"result":{"protocolVersion":"2025-03-26","capabilities":{"experimental":{},"prompts":{"listChanged":false},"resources":{"subscribe":false,"listChanged":false},"tools":{"listChanged":false}},"serverInfo":{"name":"Creative Hub MCP Server","version":"1.9.0"}}}

response header 中 mcp-session-id 是重点

1
2
3
4
5
6
7
8
9
10
< HTTP/1.1 200 OK
< date: Wed, 21 May 2025 16:58:40 GMT
< server: uvicorn
< cache-control: no-cache, no-transform
< connection: keep-alive
< content-type: text/event-stream
< mcp-session-id: 008aad264bd34776bb48e26b20d65eb4
< x-accel-buffering: no
< transfer-encoding: chunked
<
  1. 使用session初始化sse, 这一步会立刻返回
1
2
3
4
5
6
7
8
curl --location --request POST 'http://localhost:8000/mcp?transportType=streamable-http' \
--header 'Accept: application/json, text/event-stream' \
--header 'mcp-session-id: 008aad264bd34776bb48e26b20d65eb4' \
--header 'Content-Type: application/json' \
--data-raw '{
"method": "notifications/initialized",
"jsonrpc": "2.0"
}'
  1. 建立sse连接监听notification, 这里是一个GET请求,会变成SSE连接一直保持
1
2
3
curl --location --request GET 'http://localhost:8000/mcp' \
--header 'Accept: application/json, text/event-stream' \
--header 'mcp-session-id: 008aad264bd34776bb48e26b20d65eb4'
  1. 开始后续的请求,如tool-list等,tool-call中涉及的sse notification 如log或progress都会通过第三步中建立的sse连接发送到client, 最终结果则会返回到本次请求的response中
1
2
3
4
5
curl --location --request POST 'http://localhost:8000/mcp?transportType=streamable-http' \
--header 'accept: application/json, text/event-stream' \
--header 'content-type: application/json' \
--header 'mcp-session-id: 008aad264bd34776bb48e26b20d65eb4' \
--data-raw '{"method":"tools/call","params":{"name":"text_to_image","arguments":{"prompt":"asd","negitive_prompt":"asd","height":1024,"width":1024},"_meta":{"progressToken":2}},"jsonrpc":"2.0","id":2}'