深度剖析 MCP SDK 最新版:Streamable HTTP 模式

好記憶不如爛筆頭,能記下點東西,就記下點,有時間拿出來看看,也會發覺不一樣的感受.

目錄

一、概述

二、快速上手:開啟 Streamable HTTP

服務端開啟

客戶端連接

三、深入兩個核心參數

stateless_http

json_response

參數組合效果

四、認識 session-id

生成與獲取

作用與使用

失效機制

五、樣例實測與驗證

服務端工具實現

客戶端測試

六、完整的通信流程

七、Low - Level API 開發服務端

八、解讀多應用實例模式

九、思考與總結


一、概述

本文主要對 MCP SDK 最新版(v1.9.0)中的 Streamable HTTP 模式進行全面剖析與實測。Streamable HTTP 是 MCP SDK 新增的傳輸模式,具有更復雜的實現和更靈活的配置。它為開發者提供了更多選擇,以滿足不同場景下的需求。

二、快速上手:開啟 Streamable HTTP

服務端開啟

從 MCP SDK 1.8.0 開始,支持三種傳輸模式:stdio、sse 與 streamable-http。服務端開啟 Streamable HTTP 模式推薦使用 FastMCP 高層 API:

# 創建 FastMCP 實例
app = FastMCP(name="SimpleServer",port=5050,stateless_http=False,json_response=False,streamable_http_path="/mcp"
)....if __name__ == '__main__':app.run(transport='streamable-http')

關鍵參數變化:

  • transport 參數新增 streamable-http 選項。

  • stateless_httpjson_response 控制工作模式,默認都為 False。

客戶端連接

客戶端代碼需做以下修改:

try:async with streamablehttp_client(url=server_url) as (read, write, get_session_id):async with ClientSession(read, write) as session:print(f"連接成功!")# 初始化會話await session.initialize()print("會話初始化完成")# 獲取會話 IDsession_id = get_session_id()print(f"會話 ID: {session_id}")......    

主要變化:

  • 使用 streamablehttp_client 客戶端傳輸模塊。

  • 新增可回調的 get_session_id 方法獲取 session-id。

三、深入兩個核心參數

stateless_http

  • 控制是否建立長連接的 SSE 通道,為 False 時開啟 SSE 通道。

  • 控制是否管理客戶端會話,為 False 時管理客戶端會話。

json_response

  • 控制 Post 請求響應形式是否為 JSON,默認 False,使用 SSE 流式響應。

  • 客戶端 Post 請求頭需聲明可接收兩種形式響應:"Accept": "application/json, text/event-stream"。

參數組合效果

不同參數組合產生不同效果,具體如下:

四、認識 session-id

session-id 是服務端跟蹤與管理客戶端會話的關鍵標識。

生成與獲取

  • 當 stateless_http=False 時,發起初始化請求,服務端生成 session-id 并在 HTTP 頭中返回。

  • 客戶端使用 get_session_id 回調方法獲取 session-id。

作用與使用

  • 客戶端后續請求自動攜帶 session-id,也可用于關聯多次交互。

  • 服務端從會話池查詢對應會話模塊處理請求,無需每次都建立新連接與會話。

失效機制

客戶端退出 streamablehttp_client 上下文區域時,觸發 HTTP Delete 請求,服務端刪除會話,session-id 失效。

五、樣例實測與驗證

服務端工具實現

創建一個模擬長時間處理任務的工具,定期報告進度:

@app.tool(name='hello')
async def hello(ctx: Context, name: str) -> str:steps = 10await ctx.report_progress(0.0, steps, 'MCP Server 正在處理請求...')# 模擬計算過程的多個步驟for step in range(1, steps + 1):await asyncio.sleep(1)logger.info(f"正在處理第 {step} 步,發送進度通知...")await ctx.report_progress(float(step), float(steps), f'正在處理第 {step} 步...')await ctx.report_progress(steps, steps, 'MCP Server 請求處理完成!')return f'Hello, {name}'

客戶端測試

  • 有狀態模式(stateless_http=False,json_response=False) :連接成功后獲取 session-id,可接收服務端發送的進度通知,通過 SSE 通道以流形式發送。

  • 無狀態模式(stateless_http=True,json_response=False) :無法接收到進度通知,服務端不會建立 SSE 通道。

六、完整的通信流程

  1. 連接 :客戶端無需事先創建 SSE 連接,直接發起初始化請求。

  2. 初始化請求 :客戶端發起 Initialize 請求,有狀態模式下服務端返回帶 session-id 的 HTTP 頭。

  3. 初始化確認 :客戶端發起 Initialized 確認,有狀態模式下客戶端發起 HTTP Get 請求建立獨立 SSE 通道。

  4. 正常交互 :普通交互通過 Post 通道進行,只有服務端發起的通知與請求、會話恢復事件發送使用 SSE 通道。

七、Low - Level API 開發服務端

使用 Low - Level API 開發服務端更簡潔,借助 SessionManager 模塊管理客戶端會話:
?

...mcp_server = Server(name="example")... call_tool 等實現 ...try:# 創建會話管理器session_manager = StreamableHTTPSessionManager(app=mcp_server,json_response=True,stateless=False)starlette_app = Starlette(debug=True,routes=[Mount("/mcp", app=session_manager.handle_request),],lifespan=lambda app: session_manager.run(),)config = uvicorn.Config(starlette_app, host="127.0.0.1", port=5050)server = uvicorn.Server(config)await server.serve()logger.info("MCP server is running on http://127.0.0.1:5050")
......

八、解讀多應用實例模式

MCP 服務端支持多應用實例模式,可創建多個 FastMCP 應用實例,不同實例采用不同參數,靈活滿足不同場景需求:

......
app = FastMCP(name="SimpleServer",...stateless_http=True,json_response=False
)app2 = FastMCP(name="SimpleServer2",...stateless_http=False,json_response=False
)if __name__ == '__main__':
......@asynccontextmanagerasync def lifespan(server):async with contextlib.AsyncExitStack() as stack:await stack.enter_async_context(app.session_manager.run())await stack.enter_async_context(app2.session_manager.run())yieldserver = FastAPI(lifespan=lifespan)server.mount("/server1", app.streamable_http_app())server.mount("/server2", app2.streamable_http_app())print("Starting FastAPI server on http://localhost:5050")print("- App1 available at: http://localhost:5050/server1")print("- App2 available at: http://localhost:5050/server2")uvicorn.run(server, host="0.0.0.0", port=5050)

注意:

  • 每個 FastMCP 應用實例內的 session_manager 必須在啟動時初始化。

  • mount 映射將應用實例掛載到指定路徑,客戶端連接的 URL 要相應變化。

九、思考與總結

Streamable HTTP 模式相比之前的傳輸模式,提供了更高的靈活性和更多的配置選項。開發者可以根據實際需求,選擇有狀態或無狀態模式,決定是否使用長連接的 SSE 通道,以及控制響應的形式。這種靈活性使得 MCP SDK 能夠更好地適應各種復雜的應用場景。

然而,在實際使用過程中,我們也發現了一些問題,如會話恢復功能的完善性有待驗證。希望在后續的版本更新中,這些問題能夠得到解決,進一步提升 Streamable HTTP 模式的穩定性和可靠性。

對于開發者來說,深入理解 Streamable HTTP 模式的原理和配置,熟練掌握其開發方法,將有助于更好地利用 MCP SDK 構建高效、可靠的通信系統,滿足不斷增長的業務需求。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/82083.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82083.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/82083.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

樹莓派開箱上手教程(無需顯示器版)

樹莓派開箱上手教程(無需顯示器版) 硬件準備 名稱參數電源適配器5V電源適配器,至少需要3A的額定電流,配備USB Type-C輸出接頭microSD卡用來將樹莓派的操作系統安裝到上邊,至少需要8GB容量,一般建議16GB及以…

MySQL強化關鍵_015_存儲過程

目 錄 一、概述 1.說明 2.優點 3.缺點 二、存儲過程的操作 1.創建 2.調用 3.查看 4.刪除 三、變量 1.系統變量 (1)說明 (2)查看系統變量 (3)設置系統變量 2.用戶變量 (1&…

動態規劃dp

這里寫目錄標題 動態規劃01背包完全背包多重背包混合背包二維費用的背包分組背包有依賴的背包背包問題求方案數背包問題求具體方案數位 DP狀壓 DP常用例題 動態規劃 01背包 有 n n n 件物品和一個容量為 W W W 的背包,第 i i i 件物品的體積為 w [ i ] w[i] w…

arcgis js統計FeatureLayer的橢球面積、平面面積

1、導入依賴 import FeatureLayer from arcgis/core/layers/FeatureLayer import { geodesicArea, planarArea, simplify } from arcgis/core/geometry/geometryEngine; import { project, load as projectionLoad } from arcgis/core/geometry/projection2、初始化project o…

2.2.1 05年T2

引言 本文將從一預習、二自習、三學習、四復習等四個階段來分析2005年考研英語閱讀第二篇文章。為了便于后續閱讀,我將第四部分復習放在了首位。 四、復習 方法:錯誤思路分析總結考點文章梳理 4.1 錯題分析 題目:26(細節題&…

Java 連接并操作 Redis 萬字詳解:從 Jedis 直連到 RedisTemplate 封裝,5 種方式全解析

引言 在分布式系統和高并發場景中,Redis 作為高性能內存數據庫的地位舉足輕重。對于 Java 開發者而言,掌握 Redis 的連接與操作是進階必備技能。然而,從基礎的 Jedis 原生客戶端到 Spring 封裝的 RedisTemplate,不同連接方式的原…

談談對《加密算法》的理解

文章目錄 一、什么是加密算法?二、常見的加密算法有哪些?2.1 對稱加密2.2 非對稱加密2.3 哈希算法 三、加密算法代碼展示3.1 MD5加密3.2 秘鑰加密3.3 AES加密解密 四、加密算法的使用場景 一、什么是加密算法? 加密算法是一種通過數學方法將…

Fuzz 模糊測試篇JS 算法口令隱藏參數盲 Payload未知文件目錄

1 、 Fuzz 是一種基于黑盒的自動化軟件模糊測試技術 , 簡單的說一種懶惰且暴力的技術融合了常見 的以及精心構建的數據文本進行網站、軟件安全性測試。 2 、 Fuzz 的核心思想 : 口令 Fuzz( 弱口令 ) 目錄 Fuzz( 漏洞點 ) 參數 Fuzz( 利用參數 ) PayloadFuzz(Bypass)…

哈希表的實現(下)

目錄 前言 開散列概念 開散列實現 Insert 優化 Find Erase 前言 上一章節我們用閉散列實現了一下哈希表,但存在一些問題,比如空間浪費比較嚴重,如果連續一段空間都已經存放值,那么在此位置插入新值的時候就會一直挪動&…

再談Linux 進程:進程等待、進程替換與環境變量

目錄 1.進程等待 為什么需要進程等待? 相關系統調用:wait()和waitpid() wait(): waitpid(): 解析子進程狀態(status) 2.進程替換 為什么需要進程替換? 相關系統調用:exec函數家族 3.環境變量 ?…

基于深度學習的無線電調制識別系統

基于深度學習的無線電調制識別系統 本項目實現了一個基于深度學習的無線電調制識別系統,使用LSTM(長短期記憶網絡)模型對不同類型的 無線電信號進行自動分類識別。該系統能夠在不同信噪比(SNR)條件下,準確識別多種調制類型&#…

Python 爬蟲之requests 模塊的應用

requests 是用 python 語言編寫的一個開源的HTTP庫,可以通過 requests 庫編寫 python 代碼發送網絡請求,其簡單易用,是編寫爬蟲程序時必知必會的一個模塊。 requests 模塊的作用 發送網絡請求,獲取響應數據。 中文文檔&#xf…

隨機森林(Random Forest)學習

隨機森林是一種基于集成學習的機器學習算法,屬于Bagging(Bootstrap Aggregating)方法的一種擴展。它通過組合多個決策樹來提升模型的泛化能力和魯棒性,廣泛用于分類、回歸和特征選擇任務。 1.隨機森林核心思想 1.1少數服從多數 在…

從 0 到 1!Java 并發編程基礎全解析,零基礎入門必看!

寫在前面 博主在之前寫了很多關于并發編程深入理解的系列文章,有博友反饋說對博主的文章表示非常有收獲但是對作者文章的某些基礎描述有些模糊,所以博主再根據最能接觸到的基礎,為這類博友進行掃盲!當然,后續仍然會接…

el-input寬度自適應方法總結

使用 style 或 class 直接設置寬度 可以通過內聯樣式或 CSS 類來直接設置 el-input 的寬度為 100%&#xff0c;使其自適應父容器的寬度 <template><div style"width: 100%;"><el-input style"width: 100%;" v-model"input">…

解決 Supabase “permission denied for table XXX“ 錯誤

解決 Supabase “permission denied for table” 錯誤 問題描述 在使用 Supabase 開發應用時&#xff0c;你可能會遇到以下錯誤&#xff1a; [Nest] ERROR [ExceptionsHandler] Object(4) {code: 42501,details: null,hint: null,message: permission denied for table user…

java每日精進 5.20【MyBatis 聯表分頁查詢】

1. MyBatis XML 實現分頁查詢 1.1 實現方式 MyBatis XML 是一種傳統的 MyBatis 使用方式&#xff0c;通過在 XML 文件中編寫 SQL 語句&#xff0c;并結合 Mapper 接口和 Service 層實現分頁查詢。分頁需要手動編寫兩條 SQL 語句&#xff1a;一條查詢分頁數據列表&#xff0c;…

linux taskset 查詢或設置進程綁定CPU

1、安裝 taskset larkubuntu&#xff1a;~$ sudo apt-get install util-linux larkubuntu&#xff1a;~$ taskset --help 用法&#xff1a; taskset [選項] [mask | cpu-list] [pid|cmd [args...]] 顯示或更改進程的 CPU 關聯性。 選項&#xff1a; -a&#xff0c; --all-tasks…

Python應用字符串格式化初解

大家好!在 Python 編程中&#xff0c;字符串格式化是一項基礎且實用的技能。它能讓你更靈活地拼接字符串與變量&#xff0c;使輸出信息更符合需求。本文將為和我一樣的初學者詳細介紹 Python 字符串格式化的常用方法。 定義: 字符串格式化就是將變量或數據插入到字符串中的特定…

EasyRTC嵌入式音視頻通信SDK一對一音視頻通信,打造遠程辦公/醫療/教育等場景解決方案

一、方案概述? 數字技術發展促使在線教育、遠程醫療等行業對一對一實時音視頻通信需求激增。傳統方式存在低延遲、高畫質及多場景適配不足等問題&#xff0c;而EasyRTC憑借音視頻處理、高效信令交互與智能網絡適配技術&#xff0c;打造穩定低延遲通信&#xff0c;滿足基礎通信…