LLM—— 基于 MCP 协议(Streamable HTTP 模式)的工具调用实践

发布于:2025-08-03 ⋅ 阅读:(13) ⋅ 点赞:(0)

在上一篇博客中,我们介绍了 LLM—— 基于 MCP 协议(SSE 模式)的工具调用实践 。本文我们将聚焦于MCP协议(Streamable HTTP 模式)的工具调用实践,了解Streamable HTTP 模式下,客户端与服务端的交互方式,并通过实际的案例加深对该模式下交互的体验,那就让我们开始吧!

一、什么是 MCP Streamable HTTP 模式?

MCP 的 Streamable HTTP 模式是对早期 HTTP+SSE 模式的标准化升级,具备以下关键特性:

能力 描述
单一 /mcp 接口 所有消息统一通过一个 HTTP 路由处理
支持 POST 客户端可发送 JSON-RPC 请求/通知
支持 GET 客户端可监听 SSE 流接收服务器消息
支持流式响应 响应可拆分为 token 流或异步事件推送
支持 Session 管理 可状态化地追踪上下文并做权限控制
支持连接恢复 SSE 流支持基于 Last-Event-ID 的断点续传

二、 示例程序

服务端:注册工具并启动 HTTP 服务

from mcp.server.fastmcp import FastMCP

# 创建 MCP 服务端(无状态 HTTP 模式)
mcp = FastMCP("MyServer", host="127.0.0.1", port=8050, stateless_http=True)

# 注册工具 say_hello
@mcp.tool()
def say_hello(name: str) -> str:
    return f"Hello, {name}! Nice to meet you!"

# 注册工具 add
@mcp.tool()
def add(a: int, b: int) -> int:
    return a + b

# 启动服务,使用 Streamable HTTP 模式
if __name__ == "__main__":
    mcp.run(transport="streamable-http")

🔎 说明:

  • MCP 服务器将监听 /mcp 路径,处理所有 POST/GET 请求
  • 所有函数通过 @mcp.tool() 注册,自动暴露为 JSON-RPC 工具接口
  • 使用 stateless_http=True 代表服务器为无状态模型,适合横向扩展

客户端:调用远程工具并输出结果

import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    # 与 MCP 服务建立连接(使用流式 HTTP)
    async with streamablehttp_client("http://localhost:8050/mcp") as (read_stream, write_stream, get_session_id):
        async with ClientSession(read_stream, write_stream) as session:
            await session.initialize()  # 初始化连接

            tools_result = await session.list_tools()  # 列出所有工具
            print("Available tools:")
            for tool in tools_result.tools:
                print(f"- {tool.name}: {tool.description}")

            result = await session.call_tool("add", arguments={"a": 1, "b": 2})  # 远程调用 add 函数
            print(f"1 + 2 = {result.content[0].text}")

if __name__ == "__main__":
    asyncio.run(main())

🧩 说明:

  1. MCP 客户端远程调用Server端的工具 add(a=1, b=2)
  2. MCP 客户端(通过 ClientSession.call_tool)将此请求封装为 JSON-RPC 格式,并发送给服务端
  3. 服务端运行了 add() 函数,并把结果返回给客户端
  4. 返回的内容不是一个简单的数字,而是被封装在一个 JSON-RPC 响应对象中
  5. 程序最终从返回结果中提取了 content[0].text 字段进行打印

程序运行结果:
在这里插入图片描述


如果我们把server端的程序中,stateless_http=True去掉,让它走默认值False,会发生什么呢?

mcp = FastMCP("MyServer", host="127.0.0.1", port=8050)

我们再来运行下程序
在这里插入图片描述
我们发现,stateless_http=False的情况下,在输出的日志中明显多了下面两条

Created new transport with session ID: 82a3519c341d4088a9c4c0856b991480
...
Terminating session: 82a3519c341d4088a9c4c0856b991480

说明:

  • 默认 stateless_http=False(有状态)时,MCP Server 会为每个客户端维护会话(Session)。每个会话对应一个 Session ID,用于所有后续请求识别。
  • 当stateless_http=True(无状态)时,MCP Server 不会创建或追踪会话,每次请求作为完全独立的一次性操作处理,不返回 Mcp-Session-Id,也不要求客户端持有。

三、总结

MCP 的 Streamable HTTP 模式 结合 HTTP 标准化、SSE 流能力、Session 状态管理与 JSON-RPC 结构表达,为开发者提供了:

  • 高效的工具注册与调用方式
  • 可扩展的服务架构
  • 可靠的多端通信保障
  • 平滑的旧版本兼容策略

对于希望打造智能体工具平台的开发者而言,这种方式既现代、又实用。


网站公告

今日签到

点亮在社区的每一天
去签到