再见,SSE!你好,Streamable HTTP!轻松开发 Streamable HTTP MCP Server

大家好!我是韩老师。

之前和大家分享了三篇 MCP 相关的文章:

还是那句话:也许有一天,AI 程序员不懂 MCP,就犹如前端程序员不懂 JavaScript!

相信不少童鞋已经了解了甚至参与到了 MCP 相关的开发。

从 MCP 支持的两个协议 stdio 和 SSE 来看,MCP 确实有点“快而糙”。如果我当年本科的暑假大作业,还有一天就要deadline了,我也许才会选择这两个协议,能让我快速出活。

在第一篇文章中,我就提到了 stdio 和 SSE 的的“快而糙”。

SSE 的最大缺陷之一,显而易见:SSE 需要 server 端保持一个长连接,而且,根据 MCP 的协议,在 MCP Client 与 MCP Server 建立 SEE 连接后,在整个 connection 的生命周期中,MCP Server 需要一直保持着这个 SSE 连接。

那么,对于要支持 SSE 的运行在 remote 的 MCP Server 来说,就需要保证高可靠性。在高并发的情况下,对 MCP Server 的负载更是一个挑战。

在 3 月 26 日,MCP 发布了最新的 spec,用 Streamable HTTP “取代”了 SSE。

简单来说,在新的 Streamable HTTP 协议中,MCP Server 可以根据自己实际的使用场景来决定自己是 Stateless 还是 Stateful 的,而不是像 SSE 那样,一定是 Stateful 的。

这对开发 Remote MCP Server 的开发者来说,真是一个极好的消息,因为在不少场景中,Stateless server 会对 MCP Server 的要求降低很多!

今天,我也要和大家分享个好消息,韩老师的 Code Runner MCP Server 和 Yeoman Generator for MCP Server 都已经支持 Streamable HTTP 啦!

现在,韩老师就用 Yeoman Generator for MCP Server,来带领大家快速开发一个 Streamable HTTP 的 MCP Server!

安装 Node.js

从  安装 LTS 版的 Node.js 即可。

安装 Scaffolding Tool

在命令行运行下面命令,安装 Yeoman Generator for MCP Server:

npm install -g yo generator-mcp@latest

创建 MCP Server 项目

在命令行运行下面命令,创建 MCP Server 项目:

yo mcp -n 'Weather MCP Server'

实现代码逻辑

主要的代码逻辑在 src\streamableHttp.ts 文件中,可以不做修改直接使用。

启动项目

在命令行运行下面命令,启动 MCP Server 项目:

npm run build
npm run start:streamableHttp

在 VS Code 运行

安装好最新的 VS Code Insiders 版本。

打开 .vscode\mcp.json,取消 weather-mcp-server-streamable-http 的注释,点击 “start” 按钮:

现在,就能在 VS Code Insiders 的 Agent Mode 调用你的 MCP Server 啦!

 

大功告成!

我的两个 MCP 项目完全开源,欢迎来围观或者一起共谋大业:

GitHub - formulahendry/generator-mcp: Yeoman Generator to quickly create a new MCP Server

GitHub - formulahendry/mcp-server-code-runner: Code Runner MCP Server

 

原创作者: formulahendry 转载于: https://www.cnblogs.com/formulahendry/p/18837144
<think>我们正在讨论MCP服务器(可能是某种自定义服务器)的流式HTTP处理。根据用户提供的引用,我们看到一个HTTPPOST请求示例,该请求发送到`/messages/`端点,并且服务器返回了202Accepted状态码。但是,用户现在关心的是流式处理(streamableHTTP)的配置或实现。在HTTP中,流式处理通常意味着服务器能够逐步发送响应(例如使用分块传输编码)或者客户端能够发送流式请求(例如上传大文件时边读边传)。在MCP服务器的上下文中,用户可能希望实现或配置类似的功能。根据引用中的示例,我们注意到:-请求是一个完整的POST请求,不是流式上传。-响应是202Accepted,并且响应体很小(只有8字节),这显然不是流式响应。因此,我们需要考虑如何将MCP服务器配置为支持流式处理。###可能的流式处理场景1.**流式响应(Server-SentEvents,WebSocket,或分块传输编码)**:服务器可以分块发送数据,例如实时更新。2.**流式请求**:客户端可以分块上传数据,服务器边接收边处理。###配置或实现建议####1.使用分块传输编码(ChunkedTransferEncoding)在HTTP/1.1中,分块传输编码允许服务器将响应分成多个部分(块)发送。这通常用于当响应内容长度未知时,或者需要实时生成内容时。在Python中,如果你使用像uvicorn这样的ASGI服务器(如引用中所示),并且你的应用是异步的(例如基于Starlette或FastAPI),你可以返回一个生成器来实现流式响应。示例(FastAPI):```pythonfromfastapiimportFastAPIimportasyncioapp=FastAPI()@app.post("/stream_response/")asyncdefstream_response():asyncdefgenerate():foriinrange(5):awaitasyncio.sleep(1)yieldf"Chunk{i}\n"returnStreamingResponse(generate(),media_type="text/plain")```####2.流式请求对于流式请求,客户端可以分块发送数据。服务器需要能够逐步读取请求体。在FastAPI中,你可以使用`Request`对象直接读取请求体流:```pythonfromfastapiimportFastAPI,Requestapp=FastAPI()@app.post("/stream_request/")asyncdefstream_request(request:Request):#逐块读取请求体asyncforchunkinrequest.stream():#处理每个块process_chunk(chunk)```####3.使用WebSocket如果需要双向流式通信,WebSocket可能是更好的选择。但WebSocket是完全不同的协议,不是HTTP。####4.服务器配置在引用中,服务器是uvicorn。uvicorn支持流式响应和请求,但需要应用程序支持(如上例所示)。因此,配置主要在应用程序代码中实现,而不是在服务器配置文件中。###针对MCP服务器的建议由于用户提到的MCP服务器(可能是自定义服务器)已经使用了uvicorn,因此可以按照上述方式实现流式处理。但是,具体到MCP服务器的实现,我们需要知道它的内部架构。如果MCP服务器是基于类似FastAPI的框架,那么实现流式处理是直接的。如果MCP服务器是用户自己开发的,那么需要:-对于流式响应:在生成响应时,使用分块传输编码。在ASGI中,可以通过返回一个异步生成器来实现。-对于流式请求:在读取请求体时,不要一次性读取,而是逐块读取(通过`request.stream()`)。###注意事项-在HTTP/1.1中,分块传输编码是标准的一部分,但客户端必须支持。-在HTTP/2中,流式处理更加高效,因为它支持多路复用。###引用说明引用[1]中展示的MCP服务器当前的处理方式是非流式的(一次性请求,一次性响应)。因此,要实现流式处理,需要修改端点处理逻辑。§§相关问题§§1.如何测试MCP服务器的流式HTTP端点?2.在流式处理中,如何处理错误和中断?3.MCP服务器支持HTTP/2吗?如何配置?</think>### MCP服务器流式HTTP处理分析 根据您提供的引用信息和需求,MCP服务器的流式HTTP处理涉及以下关键点: 1. **现有通信模式分析** 引用[1]显示当前MCP SSE服务器使用标准HTTP短连接POST请求: ```http POST /messages/?session_id=97a44bcff590415e99cf803350ffd542 HTTP/1.1 Host: 10.0.105.64:8080 Content-Type: application/json {"method":"tools/call","params":{...}} ``` 服务器返回`202 Accepted`状态码,表明请求已被接受但处理未完成[^1]。这种模式**不满足流式处理需求**,因为: - 使用短连接而非持久连接 - 响应为完整一次性返回 - 缺少流式数据传输机制 2. **流式HTTP实现方案** 要实现流式处理,建议采用以下技术: **a) 分块传输编码(Chunked Transfer Encoding)** 在HTTP响应头中添加: ```http HTTP/1.1 200 OK Transfer-Encoding: chunked Content-Type: application/x-ndjson ``` 服务器分段发送数据: ```http 1A // 十六进制块大小 {"event":"update","data":"..."} 0 // 结束块 ``` **b) Server-Sent Events(SSE)** 专为服务器到客户端的单向流设计: ```python # FastAPI示例 @app.get("/stream") async def message_stream(): async def event_generator(): while True: if new_data := await queue.get(): yield f"data: {json.dumps(new_data)}\n\n" return EventSourceResponse(event_generator()) ``` 客户端通过`EventSource` API接收: ```javascript const source = new EventSource('/stream'); source.onmessage = (event) => { ... }; ``` **c) WebSocket双向流** 适用于双向实时通信: ```python # uvicorn+WebSockets实现 @app.websocket("/ws") async def websocket_endpoint(websocket: WebSocket): await websocket.accept() while True: data = await websocket.receive_text() # 处理并流式返回 await websocket.send_text(process(data)) ``` 3. **MCP服务器配置建议** - **协议升级**:在现有POST端点添加`Accept: text/event-stream`支持 - **会话保持**:利用现有`session_id`参数维持流连接 - **超时设置**:配置`keepalive_timeout`保持长连接 - **缓冲区管理**:调整`uvicorn`的`max_queued_bytes`防止背压 4. **性能优化方向** - 使用异步框架(如Starlette)处理高并发流 - 实施背压控制(backpressure control) - 添加`Last-Event-ID`头支持断线重连 - 压缩流数据:`Content-Encoding: gzip` > **关键区别**:传统HTTP请求(如引用所示)是事务型交互,而流式HTTP建立持久通道持续传输数据片段[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值