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

相关推荐
黎燃30 分钟前
技术前沿:MCP如何重塑大模型性能架构
mcp
Lorin洛林2 小时前
MCP 协议系列序言篇:开启 AI 应用融合新时代的钥匙
ai编程·mcp
程序员海军8 小时前
从0到1开发一个MCP Server:让AI助手拥有数据库操作能力
aigc·openai·mcp
coder_pig21 小时前
【Trae + 掘金MCP】不写代码,靠嘴遁花0.5h定制公号排版工具
aigc·mcp·trae
穿过生命散发芬芳1 天前
基于MCP实现实时北京旅游信息智能体的方案
mcp
阿里云云原生1 天前
通义灵码带你玩转 MCP 最佳实践(合辑,持续更新中)
mcp
柒崽1 天前
Cursor只支持MCP的tools功能,来用Claude演示下完整的MCP服务是如何被调用的
mcp
Captaincc1 天前
MCP 很好,但它不是万灵药!真正的技术进步,往往始于祛魅之后的清醒认知
ai编程·mcp
仙人掌_lz1 天前
如何打造一款金融推理工具Financial Reasoning Workflow:WebUI+Ollama+Fin-R1+MCP/RAG
人工智能·搜索引擎·ai·金融·llm·rag·mcp