前言
上文[【MCP-01】JSON-RPC2.0協議]闡述了MCP服務端和客戶端交互的基本數據結構,這里簡單說明下MCP不同的傳輸方式的技術細節,側重關注RemoteMCP場景下的HTTP+SSE(社區已經廢棄)和StreamableHttp兩種方式,Stdio主要是進程通信,這里不再說明,具體可以參考官方文檔。
為什么不直接HTTP?
1)HTTP為單向請求,無法實現服務端主動推送消息,比如LLM任務完成事件,如果是HTTP請求則需要客戶端不斷輪詢。
2)短連接和無狀態性,無法應對對話式會話的需求,客戶端和LLM大模型交互需要在多次對話中保持連接,已確保LLM大模型能讀取交互的上下文信息。
3)HTTP無法滿足實時性需求,LLM大模型通常是一個一個字符的流式返回結果。
4)同步阻塞模式,LLM大模型在處理耗時的任務下,HTTP會長時間阻塞。
綜上所述:在AI的場景下,純Http傳輸方式無法滿足異步、實時性、流式返回、服務器消息推送、會話上下文保?持等痛點,因此MCP依次提供了HTTP+SSE和StreamableHttp方式。
HTTP+SSE
SSE解決了那些問題?
MCP選擇HTTP+[SSE]作為初版的傳輸方式解決了那些問題?
1)?提高實時性?,可以避免客戶端使用http協議做頻繁的輪詢,SSE允許服務器在數據生成時逐步傳輸,客戶端可逐步處理。
2)?實現服務器主動推送?,HTTP 是無狀態的請求 - 響應模式,服務器不能主動向客戶端發送數據,SSE 則通過建立 HTTP 長連接,支持服務器主動向客戶端推送事件,比如MCPServer往MCPClient推送tools、prompt、resources變更,LLM任務完成等信息。
3)減少連接開銷,如果使用http需要頻繁創建和釋放連接,SSE基于HTTP長連接,一次連接可多次傳輸數據,避免了頻繁建立連接的開銷,節省了系統資源,提高了通信效率。
4)簡化實現,SSE也是基于HTTP協議,客戶端只要EventSource API則可以接收SSE事件,服務端只要支持長鏈接建立也非常方便。
5)?流式傳輸支持?,在LLM大模型返回大量數據結構返回響應的時候,不需要等待整個數據集傳輸完畢,提高用戶體驗。
交互流程

一些說明:
HTTP+SSE傳輸方式MCPServer和MCPClient交互流程。
1)連接建立:客戶端首先請求建立SSE連接,服務端“同意”,然后生成并推送唯一的Session ID。
2)請求發送:客戶端通過HTTP POST發送JSON-RPC2.0請求(請求中會帶有Session ID和Request ID信息)。
3)請求接收確認:服務端接收請求后立即返回202 (Accepted)狀態碼,表示已接受請求。
4)異步處理:服務端應用框架會自動處理請求,根據請求中的參數,決定調用某個工具或資源。
5)結果推送:處理完成后,服務端通過SSE通道推送JSON-RPC2.0 響應,其中帶有對應的Request ID。
6)結果匹配:客戶端的SSE連接偵聽接收到數據流后,會根據RequestID將接收到的響應與之前的請求匹配。
7)重復處理:循環2-6這個過程。這里面包含一個MCP的初始化過程。
8)連接斷開:在客戶端完成所有請求后,可以選擇斷開SSE連接,會話結束。
綜上所述,為解決純HTTP請求方式下的痛點,?核心在于在HTTP的方式上加上了SSE?,解決思路主要是。
1)?建立SSE通道?:連接建立后保持長連接;
2)?請求響應異步?:通過RequestID實現客戶端異步請求/響應匹配;
3)?異步非阻塞交互?:服務端返回202后立即釋放請求線程;
4)?偽雙向通信?:HTTP POST用于請求 + SSE通道用于推送,HTTP Post(客戶端->服務端) + HTTP SSE(服務端->客戶端)的偽雙工通信模式,一個HTTP Post通道,用于客戶端發送請求。比如調用MCP Server中的Tools并傳遞參數,一個HTTP SSE通道,用于服務端推送數據,比如返回調用結果或更新進度,兩個通道通過session_id來關聯,而請求與響應則通過消息中的id來對應;
需要注意的是,通過上圖和上文可以了解到,存在兩個endpoint,/sse是用于會話的開始建立SSE連接,創建連接后響應結果會返回一個新的連接/messages?sessionId=xxx,/messages?sessionId=xxx則用于后續的客戶端Post請求處理。
那官方為何廢棄SSE?
既然SSE協議已經能解決純http傳輸方式下單向請求,短連接和無狀態性,低實時性,同步阻塞等痛點,那為什么近期還要廢棄掉SSE協議呢?

具體看這個PR:[[RFC] Replace HTTP+SSE with new "Streamable HTTP" transport][github.com/modelcontextprotocol/modelcontextprotocol/pull/206]
SSE存在的一些問題
PR中總結的一些問題
1)Does not support resumability。(不支持恢復功能,客戶端和服務器之間的SSE連接中斷后,只能重新創建新的連接,之前的上下文可能會丟失。)
2)Requires the server to maintain a long-lived connection with high availability。(要求服務器維持具有高可用性的長期連接,服務器必須一直保持一個穩定、不中斷的SSE長連接,否則通信就中斷。)
3)Can only deliver server messages over SSE。(只能通過服務器發送事件SSE來傳遞服務器消息,無法在已有的請求之外,主動地發送消息給客戶端,除了通過專門的/sse通道)
業內大佬補充的一些問題
4)大多數現代瀏覽器每個域總共允許最多六個SSE連接。
5)企業網絡安全限制,由于SSE因是GET方法且無請求體,本身不需要 Content-Length,一些代理和防火墻不會允許遠程連接SSE,企業級交付有安全挑戰。
6)高并發下,長鏈接比較消耗資源(這點個人感覺也不一定,頻繁創建短連接更加消耗性能)。
7)?不支持長期的serverless和stateless架構部署?,serverless和stateless架構通常自動擴縮容,不適合長時間連接,而 SSE 需要維持持久連接。
8)其他等等。
上文說到SSE在解決了純HTTP傳輸模型下異步、實時性、流式返回、服務器消息推送、會話上下文保持等痛點,但是也是估計當前MCP沒想到會這么火起來嘛,所以HTTP+SSE的解決方案看起來比較粗糙,也出現了上文說到的一些問題。因此[[RFC] Replace HTTP+SSE with new "Streamable HTTP" transport]這個PR提出了StreamableHTTP的概念,以方便解決上文說到的HTTP+SSE的那幾個痛點。才開始看到以為和HTTP+SSE同樣的思路,只是加了Streamable這個能力,以解決AI場景下流式輸出的要求。不過仔細來看,?StreamableHTTP更像是對HTTP+SSE做了一個智能化的降級(細化對的AI不同場景處理能力,服務器按場景選擇是否要做SSE返回,避免了一股腦的全部走SSE長鏈接),統一端點endpoint和優化會話管理?。
那StreamableHTTP相對HTTP+SSE有什么優勢?
PR中總結的一些優勢
1)Stateless servers are now possible—eliminating the requirement for high availability long-lived connections。(實現無狀態服務器,從而消除了對高可用性長連接的需求。)
2)Plain HTTP implementation—MCP can be implemented in a plain HTTP server without requiring SSE。(純HTTP實現方式 ——MCP可以在純HTTP服務器中實現,SSE服務器發送事件非必須。)
3)Infrastructure compatibility—it's "just HTTP," ensuring compatibility with middleware and infrastructure。(基礎架構兼容性 —— 因為“只是HTTP”,所以能確保與中間件和基礎架構的兼容性。)
4)Backwards compatibility—this is an incremental evolution of our current transport。(向后兼容性 —— 這是我們當前傳輸方式的漸進式演變。)
5)Flexible upgrade path—servers can choose to use SSE for streaming responses when needed。(靈活的升級路徑 —— 服務器可以根據需要選擇使用SSE進行流式響應。)
業內大佬補充
6)支持Last-Event-ID機制,支持將JSON-PRC的message存儲到第三方庫中,斷開連接后通過Last-Event-ID恢復和消息重傳,用戶體驗較好。
7)會話管理更加標準化和清晰。
8)只要維護一個endpoint端點,默認為/mcp。
9)智能降級,在網絡條件不佳時,自動降級到標準的HTTP模式(這個有點吹水,沒在源碼中找到相應的降級流程,不過是可以手動通過stateless_http控制是否創建sse流)。
交互流程

一些說明:
上圖來源于官網Streamable HTTP->Sequence Diagram。StreamableHTTP可以看到核心還是走HTTP+SSE,只是在調用流程上做了一些優化以及場景細化。大體流程如下:
1)初始化(含連接建立):客戶端發初始化請求,服務端響應并生成返回唯一SessionID,客戶端再發初始化完成通知,服務端以202確認,完成類似SSE連接建立與會話初始化。
2)請求發送:客戶端通過POST發送帶SessionID的請求(如業務請求等 )。
3)請求接收確認:服務端收請求后立即返202狀態碼,確認已接受。
4)異步處理:服務端框架自動處理請求,按需調用工具/資源。
5)結果推送:處理完,服務端通過SSE通道(若開啟)推送帶對應標識(如關聯請求信息 )的響應。
6)結果匹配:客戶端監聽SSE事件,依據標識(如類似RequestID )匹配響應與請求。
7)循環處理:重復“請求發送-接收確認-異步處理-結果推送-結果匹配” 流程,覆蓋客戶端請求、通知/響應及服務端請求等交互。
8)連接斷開:客戶端完成所有交互后,可斷開連接,會話結束。
綜上所述這不是和HTTP+SSE沒多大區別嗎?實際上通過參考源碼Python-SDK。確實是按PR定的新的協議規劃有做對應的優化,只是官方給的這個時序圖沒有將所有情況描述出來。除了統一端點(默認為/mcp)和Last-Event-ID機制,最重要的是StreamableHTTP MCPServer添加了兩個參數。

?**stateless_http和json_response,兩個參數默認都為False,最重要的是stateless_http這個參數,控制是否開啟SSE通道和是否對對客戶端會話進行管理。json_response主要是為了控制Post請求響應結果數據結構是否用JSON還是SSE事件數據流(不是走SSE通道,只是用SSE事件數據格式)**?。因此這兩個參數相互組合可以達到上文中說的細化對待不同的AI業務場景。
stateless_http和json_response組合
四種組合關系以及適合的場景可以參考[claudemcp文檔][claudemcp.com/blog/mcp-streamable-http]。

綜上所述,StreamableHTTP傳輸模式,除了統一端點(默認為/mcp)和Last-Event-ID機制,還提供了適應不同AI場景下的參數配置,尤其是stateless_http=True, json_response=True**非常適合之前OpenAPI的微服務(stateless),可以復用微服務的可用性和可維護性建設。不需要像HTTP+SSE那樣一股腦全部走異步、實時流推送的長鏈接SSE方式,當然業內也說明在性能上能做到大大的提升,不過這個個人認為按場景考慮。
Demo
這里簡單使用官方的[FastMCP][github.com/modelcontextprotocol/python-sdk]編寫一個MCPServer的demo。
mcpserver.py
from mcp.server.fastmcp import FastMCP
import logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
MCP_SERVER_NAME = "ShMcpServer1"
logger = logging.getLogger(MCP_SERVER_NAME)
# 初始化FastMCP服務器
mcp = FastMCP(MCP_SERVER_NAME)
@mcp.tool(name="add", description="對兩個數字進行加法")
def add(a: float, b: float) -> float:
"""
Add two numbers.
Parameters:
- a (float): First number (required)
- b (float): Second number (required)
Returns:
- float: The result of a + b
"""
return a + b
@mcp.tool(name="subtract", description="對兩個數字進行減法")
def subtract(a: float, b: float) -> float:
"""
Subtract two numbers.
Parameters:
- a (float): The number to subtract from (required)
- b (float): The number to subtract (required)
Returns:
- float: The result of a - b
"""
return a - b
@mcp.tool(name="multiply", description="對兩個數字進行乘法")
def multiply(a: float, b: float) -> float:
"""
Multiply two numbers.
Parameters:
- a (float): First number (required)
- b (float): Second number (required)
Returns:
- float: The result of a * b
"""
return a * b
@mcp.tool(name="divide", description="對兩個數字進行除法")
def divide(a: float, b: float) -> float:
"""
Divide two numbers.
Parameters:
- a (float): Numerator (required)
- b (float): Denominator (required, must not be zero)
Returns:
- float: The result of a / b
"""
if b == 0:
raise ValueError("Division by zero is not allowed")
return a / b
if __name__ == "__main__":
mcp.settings.host = "0.0.0.0"
mcp.settings.port = 8000
mcp.settings.log_level = "INFO"
# stateless_http和json_response,兩個參數默認都為False
# stateless_http
# 控制是否開啟SSE通道和是否對對客戶端會話進行管理
# json_response
# 控制Post請求響應結果數據結構是否用JSON還是SSE事件數據流(不是走SSE通道,只是用SSE事件數據格式)
# mcp.settings.json_response = True
# mcp.settings.stateless_http = True
# 初始化并運行服務器
print("Starting MCPServer...")
# transport改成sse則mcp使用HTTP+SSE傳輸模式,不過因為官方已經廢棄HTTP+SSE方式,這里不在贅述
# mcp.run(transport='sse')
mcp.run(transport="streamable-http")
mcpclient.py
"""
github.com/modelcontextprotocol/python-sdk
Run from the repository root:
uv run examples/snippets/clients/streamable_basic.py
"""
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
"""
程序入口,設置配置并啟動 MCP 客戶端。
"""
mcpUrl="127.0.0.1:8000/mcp"
# Connect to a streamable HTTP server
async with streamablehttp_client(mcpUrl) as (
read_stream,
write_stream,
_,
):
# Create a session using the client streams
async with ClientSession(read_stream, write_stream) as session:
# Initialize the connection
await session.initialize()
# List available tools
tools = await session.list_tools()
print(f"Available tools: {[(tool.name,tool.description) for tool in tools.tools]}")
if __name__ == "__main__":
asyncio.run(main())



總結
1,MCP官方初步HTTP+SSE方案確實解決了在AI的場景下異步、實時性、流式返回、服務器消息推送、會話上下文保持等痛點。核心在于在HTTP的方式上加上了SSE,實現了偽雙向通信,達到了異步,服務器流式輸出的基本效果。
2,而在MCP協議在業內被接受的情況下,大范圍的使用也出現了一些問題,因此StreamableHTTP對HTTP+SSE做了智能化的降級(細化對的AI不同場景處理能力,服務器按場景選擇是否要做SSE返回,避免了一股腦的全部走SSE長鏈接),統一端點endpoint和優化會話管理,Last-Event-ID機制等改進策略。
3,在StreamableHTTP傳輸模式下,提供了stateless_http和json_response兩個重要參數,尤其是stateless_http=True, json_response=True非常適合之前OpenAPI的微服務(stateless),可以復用微服務的可用性和可維護性建設。
4,MCP在成為業內標準后StreamableHTTP將是后續的主要傳輸協議,HTTP+SSE傳輸協議將廢棄,后續重點將在StreamableHTTP上。