深度剖析 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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;满足基础通信…