載入中

MCP 伺服器中的 stateless_http 和 json_response 旗標控制著伺服器行為的基本面向。了解何時以及為何使用它們至關重要,尤其是當您計劃擴展伺服器規模或將其部署到生產環境時。

何時需要無狀態 HTTP

想像您建立了一個變得熱門的 MCP 伺服器。一開始,可能只有少數幾個客戶端連接到單一伺服器實例:

三個 MCP 客戶端,一個標示為「您」,另外兩個標示為「其他人」,全部連接到遠端機器上的一個 MCP 伺服器。

隨著伺服器成長,可能會有數千個客戶端嘗試連接。運行單一伺服器實例將無法擴展以處理所有這些流量:

三個 MCP 客戶端,您的和另外兩個,加上 99999 個其他人,全部連接到遠端機器上的一個 MCP 伺服器。

典型的解決方案是水平擴展——在負載平衡器後面運行多個伺服器實例:

三個 MCP 客戶端,您的和另外兩個,全部透過一個負載平衡器路由,該平衡器分配到三個 MCP 伺服器。

但事情在這裡變得複雜。請記住,MCP 客戶端需要兩個獨立的連接:

  • 一個用於接收伺服器到客戶端請求的 GET SSE 連接
  • 用於呼叫工具和接收回應的 POST 請求

一個「GET SSE Response」箭頭從兩個 MCP 伺服器之一指向 MCP 客戶端,負載平衡器位於它們之間。

使用負載平衡器時,這些請求可能會被路由到不同的伺服器實例。如果您的工具需要使用 Claude(透過取樣),處理 POST 請求的伺服器就需要與處理 GET SSE 連接的伺服器進行協調。這在伺服器之間造成了複雜的協調問題。

一個 MCP 客戶端,兩個伺服器:其中一個的 GET SSE Response,另一個的 POST SSE Response 帶有 Create Message Request 和 Call Tool Result。

無狀態 HTTP 如何解決這個問題

設定 stateless_http=True 可以消除這個協調問題,但會帶來顯著的取捨:

FastMCP 建構函式帶有 stateless_http=True 和 json_response=True 參數,每個都與下方列出的取捨相關聯。

啟用無狀態 HTTP 時:

  • 客戶端不會獲得 session ID —— 伺服器無法追蹤個別客戶端
  • 沒有伺服器到客戶端的請求 —— GET SSE 路徑變得不可用
  • 沒有取樣 —— 無法使用 Claude 或其他 AI 模型
  • 沒有進度報告 —— 無法在長時間操作期間傳送進度更新
  • 沒有訂閱 —— 無法通知客戶端資源更新

然而,有一個好處:不再需要客戶端初始化。客戶端可以直接發出請求,而無需初始的握手過程。

圖表顯示一個從 MCP 客戶端到伺服器的實線 POST SSE Response 箭頭,以及一個返回的虛線灰色 GET SSE Response 箭頭。

了解 JSON Response

json_response=True 旗標比較簡單——它只是停用 POST 請求回應的串流。工具執行時,您不會收到多個 SSE 訊息,而是只會以純 JSON 格式獲得最終結果。

停用串流後:

  • 沒有中間進度訊息
  • 執行期間沒有日誌陳述
  • 只有最終的工具結果

何時使用這些旗標

在以下情況使用無狀態 HTTP:

  • 您需要使用負載平衡器進行水平擴展
  • 您不需要伺服器到客戶端的通訊
  • 您的工具不需要 AI 模型取樣
  • 您想要最小化連接開銷

在以下情況使用 JSON response:

  • 您不需要串流回應
  • 您偏好更簡單、非串流的 HTTP 回應
  • 您正在與期望純 JSON 的系統整合

開發環境與生產環境

如果您在本地使用標準 I/O 傳輸進行開發,但計劃使用 HTTP 傳輸進行部署,請使用您在生產環境中將使用的相同傳輸方式進行測試。有狀態模式和無狀態模式之間的行為差異可能很顯著,最好在開發期間就發現任何問題,而不是在部署之後才發現。

這些旗標從根本上改變了您的 MCP 伺服器的運作方式,因此請根據您特定的擴展和功能需求來選擇它們。