MCP 协议解读:STDIO 高效通信与 JSON-RPC 实战

cover mcp stdio
本文深度解析 MCP 协议的传输机制与消息格式,涵盖 stdio、SSE 及自定义传输方式,剖析 JSON-RPC 2.0 的请求、响应与通知设计。
结合 RooCode 开源实现与天气查询案例,揭秘如何通过 MCP 实现跨进程通信与高效服务集成,为开发者提供从协议原理到落地实践的完整指南。

MCP 协议解读:STDIO 高效通信与 JSON-RPC 实战

Standard Input/Output (stdio)

stdio 传输允许通过标准输入和输出流进行通信。这对于本地集成和命令行工具特别有用。

使用 stdio 的情况:

  • 构建命令行工具
  • 实现本地集成
  • 需要简单的进程通信
  • 使用 shell 脚本

server 示例

app = Server("example-server")

async with stdio_server() as streams:
    await app.run(
        streams[0],
        streams[1],
        app.create_initialization_options()
    )

client 示例

params = StdioServerParameters(
    command="./server",
    args=["--option", "value"]
)

async with stdio_client(params) as streams:
    async with ClientSession(streams[0], streams[1]) as session:
        await session.initialize()

Server-Sent Events (SSE)

SSE 传输通过 HTTP POST 请求实现服务器到客户端的流式传输,并支持客户端到服务器的通信。
目前非本地程序开发,都可使用 SSE 实现,已有的 HTTP 接口都可方便的改下 Controller 层对外提供服务。
不过 MCP 目前官方还没有标准的鉴权方式(roadmap 已规划),只能每个 mcp-server 通过参数自定义实现

支持使用 SSE 的情况:

  • 仅需要服务器到客户端的流式传输
  • 在受限网络中工作
  • 实现简单更新

server 示例

from mcp.server.sse import SseServerTransport
from starlette.applications import Starlette
from starlette.routing import Route

app = Server("example-server")
sse = SseServerTransport("/messages")

# Define handler functions
async def handle_sse(scope, receive, send):
    async with sse.connect_sse(scope, receive, send) as streams:
        await app.run(streams[0], streams[1], app.create_initialization_options())

async def handle_messages(scope, receive, send):
    await sse.handle_post_message(scope, receive, send)
    
# Create and run Starlette app
starlette_app = Starlette(
    routes=[
        Route("/sse", endpoint=handle_sse),
        Route("/messages", endpoint=handle_messages, methods=["POST"]),
    ]
)

client 示例

async with sse_client("http://localhost:8000/sse") as streams:
    async with ClientSession(streams[0], streams[1]) as session:
        await session.initialize()

自定义传输协议

MCP 使得实现针对特定需求的自定义传输变得简单。任何传输实现只需符合传输接口:
您可以实现自定义传输,用于:

  • 自定义网络协议
  • 专用通信通道
  • 与现有系统集成
  • 性能优化

示例

@contextmanager
async def create_transport(
    read_stream: MemoryObjectReceiveStream[JSONRPCMessage | Exception],
    write_stream: MemoryObjectSendStream[JSONRPCMessage]
):
    """
    Transport interface for MCP.

    Args:
        read_stream: Stream to read incoming messages from
        write_stream: Stream to write outgoing messages to
    """
    async with anyio.create_task_group() as tg:
        try:
            # Start processing messages
            tg.start_soon(lambda: process_messages(read_stream))

            # Send messages
            async with write_stream:
                yield write_stream

        except Exception as exc:
            # Handle errors
            raise exc
        finally:
            # Clean up
            tg.cancel_scope.cancel()
            await write_stream.aclose()
            await read_stream.aclose()

消息格式 JSON-RPC

MCP 使用 JSON-RPC 2.0 作为其传输格式。

JSON-RPC

目前存在两种 JSON-RPC 规范,分别是 JSON-RPC 1.0 和 JSON-RPC2.0。

  • JSON-RPC 1.0 在多个方面缺乏实用性,特别是缺少名称参数和错误消息解释,引起的麻烦超出了预期。使得它更像是一种点对点的交流方式。
  • JSON RPC 2.0 规范则解决了 1.0 版本的缺陷,表现得更加先进。使用客户机 - 服务器模式,同时增加了多种传输方式的支持。

具体区别:

  • 结构变化:2.0 版本引入了强制性的 jsonrpc:“2.0” 字段,将 id 字段变为可选,并规范了响应结构(成功必须有 result,错误必须有 error)。
  • 功能增强:2.0 版本新增了 批处理功能,改进了 通知机制,并支持两种参数传递方式(按位置的数组和按名称的对象)。
  • 错误处理优化:2.0 版本标准化了 错误对象格式(code, message, data)并定义了预设错误代码范围,使错误处理更规范和一致。

MCP 的传输层负责将 MCP 协议消息转换为 JSON-RPC 格式进行传输,并将接收到的 JSON-RPC 消息转换回 MCP 协议消息。
MCP 的 RPC 消息有请求,响应,通知 3 种类型。

请求 Requests

{
  jsonrpc: "2.0",
  id: number | string,
  method: string,
  params?: object
}

客户端请求类型

class ClientRequest(
    RootModel[
        PingRequest
        | InitializeRequest
        | CompleteRequest
        | SetLevelRequest
        | GetPromptRequest
        | ListPromptsRequest
        | ListResourcesRequest
        | ListResourceTemplatesRequest
        | ReadResourceRequest
        | SubscribeRequest
        | UnsubscribeRequest
        | CallToolRequest
        | ListToolsRequest
    ]
):
    pass

响应 Responses

{
  jsonrpc: "2.0",
  id: number | string,
  result?: object,
  error?: {
    code: number,
    message: string,
    data?: unknown
  }
}

服务端响应类型

class ServerResult(
    RootModel[
        EmptyResult
        | InitializeResult
        | CompleteResult
        | GetPromptResult
        | ListPromptsResult
        | ListResourcesResult
        | ListResourceTemplatesResult
        | ReadResourceResult
        | CallToolResult
        | ListToolsResult
    ]
):
    pass

通知 Notifications

{
  jsonrpc: "2.0",
  method: string,
  params?: object
}

通知类型

# 客户端通知
class ClientNotification(
    RootModel[
        CancelledNotification
        | ProgressNotification
        | InitializedNotification
        | RootsListChangedNotification
    ]
):
    pass

# 服务端通知
class ServerNotification(
    RootModel[
        CancelledNotification
        | ProgressNotification
        | LoggingMessageNotification
        | ResourceUpdatedNotification
        | ResourceListChangedNotification
        | ToolListChangedNotification
        | PromptListChangedNotification
    ]
):
    pass

MCP 开源实现分析 -Cline/RooCode

  1. 每个 vscode 实例启动时,插件 RooCode 都会自动启动 2 个进程。
  2. RooCode 支持配置全局的 MCP-Server,也支持在 Projet 级别配置 MCP-Server,从而实现按项目隔隔离参数配置;

MCP 客户端配置

{
  "MCPServers": {
    "weather": {
      "command": "uv",
      "args": [
        "--directory",
        "/mnt/github/MCP/weather",
        "run",
        "weather.py"
      ],
      "alwaysAllow": [
        "get_forecast",
        "get_alerts"
      ],
      "disabled": false
    }
  }
}

客户端进程分析

  1. uv 作为父进程,负责运行和管理 mcp-server
  2. MCP.run(transport='stdio') 使用 python 虚拟环境运行 weather.py,对外使用 stdio 通信
    py
# ps -ef --forest | grep weather.py
## `uv` 是一个进程管理工具,它负责启动和管理子进程(在这里是 weather.py)。它本身会作为一个父进程存在。
\_ uv --directory /mnt/github/MCP/weather run weather.py
## 初始化了 `FastMCP` 服务,并通过 `MCP.run(transport='stdio')` 开启了一个基于标准输入/输出的通信服务。
    \_ /mnt/github/MCP/weather/.venv/bin/python3 weather.py

结语

看完这篇解析,是不是对 MCP 协议的设计思路更清晰了?无论是本地命令行工具还是分布式服务,MCP 都能用灵活的传输方式和标准的 JSON-RPC 帮你 " 搭桥 "。
如果你正头疼进程通信或服务集成,不妨试试 MCP 框架——毕竟,好的协议就像隐形的桥梁,默默支撑着每一次高效交互。😃
今天分享的主要是传输层的实现细节,宏观的 MCP 工作原理见昨天分享的 模型无关的AI集成革命:MCP协议解读


这儿的文章都会同步发送到:极客工具 XTool

🌟 极客工具:共享开源力量,成就超级个体

<think>好的,我现在需要处理用户关于Model Context Protocol(MCP)的查询。用户希望了解使用说明或协议文档,但根据提供的引用内容,信息似乎比较有限,主要涉及架构和理论。首先,我需要整理现有的资料,确保准确传达已知的信息,同时指出文档的不足或可能的获取途径。 首先,确认用户提供的引用内容。引用[1]提到MCP协议规范架构,引用[2]详细说明了MCP的分层结构,包括协议层和传输层,使用JSON-RPC 2.0格式,支持Stdio和HTTP with SSE传输方式。这些是核心点,需要重点呈现。 接下来,用户可能需要具体的步骤或示例来理解如何实际使用MCP。但由于现有资料有限,需要基于已知信息进行合理推断。例如,协议层处理消息封装,传输层负责通信机制,可以举例说明如何配置传输层,或者如何封装JSON-RPC消息。 同时,用户可能遇到文档获取的问题,需要建议他们查阅官方资源或联系维护者。此外,生成相关问题时要考虑用户可能进一步的需求,比如协议的安全性、调试工具、扩展性等。 在组织回答时,要保持结构清晰,分点说明协议结构、传输方式、消息格式,并补充实施建议和文档获取方法。同时,确保使用正确的中文表达,避免技术术语错误。 最后,检查是否符合系统级指令:行内公式正确使用$...$,独立公式用$$...$$(虽然当前问题可能不涉及数学公式,但需注意),LaTeX语法正确,使用中文,生成相关问题,并在引用处添加标识。确认没有遗漏引用标记,比如[^2]在适当的位置。 总结步骤: 1. 概述MCP的基本架构和组成部分。 2. 分协议层和传输层详细说明。 3. 解释消息格式标准。 4. 提供实施建议和文档获取途径。 5. 生成相关问题,覆盖潜在的用户疑问点。</think>### Model Context Protocol (MCP) 使用说明 根据现有资料,Model Context Protocol (MCP) 是一种基于分层架构设计的通信协议,主要用于规范模型上下文之间的交互。以下是其核心功能和使用逻辑的整理: --- #### 1. **协议分层结构** MCP 分为 **协议层** 和 **传输层**,两者分工明确: - **协议层** 负责消息的封装、路由和高级通信模式(如请求-响应、发布-订阅)。 - 消息格式遵循 **JSON-RPC 2.0** 标准,例如: ```json { "jsonrpc": "2.0", "method": "model.predict", "params": {"input_data": [1,2,3]}, "id": 1 } ``` - 支持自定义扩展字段,如超时控制、身份验证等。 - **传输层** 负责实际通信机制,支持多种传输方式: - **Stdio**:通过标准输入/输出流传输,适合本地进程间通信- **HTTP with Server-Sent Events (SSE)**:适用于远程服务调用,支持实时数据推送[^2]。 --- #### 2. **典型使用流程** 以 HTTP with SSE 为例: 1. **建立连接** 客户端通过 HTTP 请求初始化 SSE 连接: ```http GET /mcp-endpoint HTTP/1.1 Accept: text/event-stream ``` 2. **发送请求** 封装 JSON-RPC 消息并通过 SSE 发送: ```json {"jsonrpc": "2.0", "method": "model.train", "params": {"dataset": "data.csv"}, "id": 100} ``` 3. **处理响应** 服务端返回流式响应: ```json {"jsonrpc": "2.0", "result": "training_started", "id": 100} ``` --- #### 3. **实施建议** - **调试工具** 可使用 `curl` 或 Postman 测试 HTTP with SSE 接口: ```bash curl -N -H "Accept: text/event-stream" http://localhost:8080/mcp-endpoint ``` - **安全性** 若需加密通信,建议在传输层启用 HTTPS 或 TLS。 - **扩展性** 协议层可通过添加自定义 `method` 和 `params` 字段扩展功能。 --- #### 4. **文档获取途径** 目前公开的详细文档较为有限,建议通过以下方式获取更多信息: 1. 联系 MCP 维护团队或查看开源仓库(如 GitHub)的文档目录。 2. 参考 **JSON-RPC 2.0 官方规范**([jsonrpc.org](https://www.jsonrpc.org/specification))补充协议细节。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值