深入解析MCP的三种传输方式实现

引言

在Model Context Protocol (MCP) 定义了多种传输方式以适应不同场景需求。本文将详细解析MCP的三种主要传输方式:标准输入输出(stdio)、服务器发送事件(SSE)和可流式HTTP(Streamable HTTP),帮助开发者根据实际需求选择最佳实现方案

1. 标准输入输出(stdio)模式

标准输入输出模式是最基础的传输方式,特别适合命令行工具和简单的交互场景。

实现逻辑

python 复制代码
# 初始化服务器
app = Server("mcpServer")

async def run_stdio():
    """运行标准输入输出模式的服务器
    
    使用标准输入输出流(stdio)运行服务器,主要用于命令行交互模式
    
    Raises:
        Exception: 当服务器运行出错时抛出异常
    """
    from mcp.server.stdio import stdio_server

    async with stdio_server() as (read_stream, write_stream):
        try:
            await app.run(
                read_stream,
                write_stream,
                app.create_initialization_options()
            )
        except Exception as e:
            print(f"服务器错误: {str(e)}")
            raise

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

核心特点:

  • 使用标准输入(stdin)和标准输出(stdout)进行通信
  • 实现简单,无需额外网络配置
  • 适合本地调试和CLI工具开发
  • 通过stdio_server()上下文管理器管理流资源

适用场景:

  • 本地开发调试
  • 命令行工具集成
  • 简单的进程间通信

2. 服务器发送事件(SSE)模式

SSE模式利用HTTP长连接实现服务器向客户端的单向实时通信。

该传输方式在 2024-11-05 协议版本开始替换为了 HTTP+SSE 传输,及第三中streamableHttp方式

实现逻辑

python 复制代码
# 初始化服务器
app = Server("mcpServer")

def run_sse():
    """运行SSE(Server-Sent Events)模式的服务器
    
    启动一个支持SSE的Web服务器,允许客户端通过HTTP长连接接收服务器推送的消息
    服务器默认监听0.0.0.0:9000
    """
    sse = SseServerTransport("/messages/")

    async def handle_sse(request):
        """处理SSE连接请求
        
        Args:
            request: HTTP请求对象
        """
        async with sse.connect_sse(
                request.scope, request.receive, request._send
        ) as streams:
            await app.run(streams[0], streams[1], app.create_initialization_options())

    starlette_app = Starlette(
        debug=True,
        routes=[
            Route("/sse", endpoint=handle_sse),
            Mount("/messages/", app=sse.handle_post_message)
        ],
    )
    uvicorn.run(starlette_app, host="0.0.0.0", port=9000)
    
if __name__ == "__main__":
	run_sse()

核心特点:

  • 基于HTTP/1.1的长连接技术
  • 服务器可主动向客户端推送消息
  • 使用SseServerTransport处理SSE连接
  • 提供/sse端点建立连接,/messages/端点接收消息

适用场景:

  • 需要服务器主动推送但不需要双向通信的场景

3. 可流式HTTP(Streamable HTTP)模式

可流式HTTP模式提供了更灵活的HTTP双向通信能力。

实现逻辑

有状态的实现方式

python 复制代码
# 初始化服务器
app = Server("mcpServer")

def run_streamable_http(json_response: bool):
    event_store = InMemoryEventStore()

		# 使用我们的应用和事件存储创建会话管理器
    session_manager = StreamableHTTPSessionManager(
        app=app,
        event_store=event_store,
        json_response=json_response,
    )

		# 用于可流式HTTP连接的ASGI处理器
    async def handle_streamable_http(
            scope: Scope, receive: Receive, send: Send
    ) -> None:
        await session_manager.handle_request(scope, receive, send)

    @contextlib.asynccontextmanager
    async def lifespan(app: Starlette) -> AsyncIterator[None]:
     """用于管理会话管理器生命周期的上下文管理器。"""
        async with session_manager.run():
            yield

		# 使用传输创建ASGI应用程序
    starlette = Starlette(
        debug=True,
        routes=[
            Mount("/mcp", app=handle_streamable_http)
        ],
        lifespan=lifespan,
    )
    uvicorn.run(starlette, host="0.0.0.0", port=3000)

if __name__ == "__main__":
	run_streamable_http(False)

无状态的实现方式

python 复制代码
# 初始化服务器
app = Server("mcpServer")

def run_streamable_http(json_response: bool):
		# 使用我们的应用和事件存储创建会话管理器
    session_manager = StreamableHTTPSessionManager(
        app=app,
        event_store=None,
        json_response=json_response,
        stateless=True,
    )

		# 用于可流式HTTP连接的ASGI处理器
    async def handle_streamable_http(
            scope: Scope, receive: Receive, send: Send
    ) -> None:
        await session_manager.handle_request(scope, receive, send)

    @contextlib.asynccontextmanager
    async def lifespan(app: Starlette) -> AsyncIterator[None]:
     """用于管理会话管理器生命周期的上下文管理器。"""
        async with session_manager.run():
            yield

		# 使用传输创建ASGI应用程序
    starlette = Starlette(
        debug=True,
        routes=[
            Mount("/mcp", app=handle_streamable_http)
        ],
        lifespan=lifespan,
    )
    uvicorn.run(starlette, host="0.0.0.0", port=3000)

if __name__ == "__main__":
	run_streamable_http(False)

核心特点:

  • 有状态的方式使用InMemoryEventStore存储事件,另外实现的持久化方式
  • 通过StreamableHTTPSessionManager管理会话
  • 支持JSON或原始格式响应(json_response参数控制)
  • 提供生命周期管理(lifespan)确保资源正确释放
  • 所有请求通过/mcp端点处理

适用场景:

  • 需要双向通信的Web应用
  • 需要持久化会话管理的应用--使用有状态的实现方式

三种传输方式对比

特性 stdio模式 SSE模式 可流式HTTP模式
通信方向 双向 服务器→客户端 双向
协议支持 标准输入输出 HTTP/1.1 HTTP/1.1+
实时性
复杂度
适用场景 CLI工具/调试 服务器推送通知 复杂双向通信

最佳实践建议

  1. 开发阶段:建议从stdio模式开始,便于调试和快速验证逻辑

  2. 简单推送场景:选择SSE模式,实现简单且资源消耗低

  3. 复杂交互应用:采用可流式HTTP模式,提供完整的双向通信能力

  4. 性能考量

    • stdio模式性能最高但适用场景有限
    • SSE适合大量客户端连接但只需服务器推送的场景
    • 可流式HTTP提供最灵活的功能但资源消耗相对较高

结语

MCP提供的三种传输方式各具特色,能够满足不同场景下的通信需求。目前小编已经编写好三种方式的demo,大家可以开箱即用啦!觉得不错的话,也帮小编点个star支持一下~

  • 纯净的简易框架

使开发者快速的搭建一个支持mcp协议所有传输方式(STDIO、SSE、StreamableHttp)的mcp server服务框架Enable developers to quickly build an MCP server service framework that supports stdio and sse。使开发者快速的搭建一个支持stdio与sse的mcp server服务框架 - wenb1n-dev/easyMcphttps://github.com/wenb1n-dev/easyMcp

  • 具体实现的案例

mysql的增删改查功能; 还包含了数据库异常分析能力;且便于开发者们进行个性化的工具扩展https://github.com/wenb1n-dev/mysql_mcp_server_pro.git

相关推荐
带娃的IT创业者1 小时前
实战:用 Python 搭建 MCP 服务 —— 模型上下文协议(Model Context Protocol)应用指南
开发语言·python·mcp
葡萄城技术团队1 天前
低代码+MCP实战三大案例,企业如何通过MCP构建专属AI智能体?
低代码·mcp
GitLqr2 天前
AI洞察 | 新一代 Agent 框架与 3D 桌面伴侣智能体
agent·ai编程·mcp
yaocheng的ai分身2 天前
Browser MCP扩展
cursor·mcp
大模型真好玩2 天前
深入浅出LangGraph AI Agent智能体开发教程(四)—LangGraph全生态开发工具使用与智能体部署
人工智能·python·mcp
没事学点AI小知识2 天前
临时邮箱 MCP Server
aigc·mcp
key_3_feng3 天前
MCP驱动企业微信智能中枢:企业级机器人服务构建全攻略
企业微信·mcp
聚客AI4 天前
🙈AI Agent的未来:工具调用将如何重塑智能应用?
人工智能·agent·mcp
LucianaiB4 天前
【混元AIGC+腾讯云智能体+首创Coze核心流思维导图MCP】:打造一个文思通-智能写作助手Agent
aigc·腾讯云·ai写作·mcp·腾讯混元大模型aigc
组合缺一5 天前
搭建基于 Solon AI 的 Streamable MCP 服务并部署至阿里云百炼
java·人工智能·solon·mcp