引言
在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工具/调试 | 服务器推送通知 | 复杂双向通信 |
最佳实践建议
-
开发阶段:建议从stdio模式开始,便于调试和快速验证逻辑
-
简单推送场景:选择SSE模式,实现简单且资源消耗低
-
复杂交互应用:采用可流式HTTP模式,提供完整的双向通信能力
-
性能考量:
- stdio模式性能最高但适用场景有限
- SSE适合大量客户端连接但只需服务器推送的场景
- 可流式HTTP提供最灵活的功能但资源消耗相对较高
结语
MCP提供的三种传输方式各具特色,能够满足不同场景下的通信需求。目前小编已经编写好三种方式的demo,大家可以开箱即用啦!觉得不错的话,也帮小编点个star支持一下~
- 纯净的简易框架
- 具体实现的案例
mysql的增删改查功能; 还包含了数据库异常分析能力;且便于开发者们进行个性化的工具扩展https://github.com/wenb1n-dev/mysql_mcp_server_pro.git