深入解析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

相关推荐
五更琉璃018 小时前
十分钟完全理解MCP
mcp
围巾哥萧尘19 小时前
「MCP系列」轻松上手:三步快速完成 MCP 运行环境搭建指南🧣
mcp
AI大模型1 天前
COZE实战部署(一)—— 扣子任务空间调配和实现
agent·coze·mcp
堆栈future1 天前
揭秘 Google A2A 协议:赋能智能体协作的未来
llm·agent·mcp
小雷FansUnion3 天前
深入理解MCP架构:智能服务编排、上下文管理与动态路由实战
人工智能·架构·大模型·mcp
CoderLiu3 天前
用这个MCP,只给大模型一个figma链接就能直接导出图片,还能自动压缩上传?
前端·llm·mcp
吴佳浩4 天前
Python入门指南-AI番外-MCP完整教程:从零开始学会Model Context Protocol
人工智能·python·mcp
聚客AI4 天前
🚀拒绝试错成本!企业接入MCP协议的避坑清单
人工智能·掘金·日新计划·mcp
ZNineSun4 天前
MCP+Cursor入门
ai·cursor·mcp
大模型真好玩4 天前
准确率飙升!Graph RAG如何利用知识图谱提升RAG答案质量(四)——微软GraphRAG代码实战
人工智能·python·mcp