MCP协议 进阶 MCP JSON-RPC 消息格式 协议规范

MCP消息格式定义:JSON-RPC 2.0协议深度解析

AIEng Hub
阅读约 18 分钟

引言

MCP协议基于 JSON-RPC 2.0 规范构建消息通信层。理解消息格式是掌握MCP协议的基础,也是开发MCP Server和Client的第一步。

本文将详细解析:

  • JSON-RPC 2.0核心规范
  • MCP请求/响应的消息结构
  • 错误编码与处理约定
  • 数据类型定义与序列化
  • 消息校验与版本兼容

JSON-RPC 2.0 基础

什么是JSON-RPC?

JSON-RPC是一种轻量级的远程过程调用(RPC)协议。它使用JSON作为数据格式,支持请求-响应和通知两种通信模式。

┌─────────────────────────────────────────────────────────────┐
│                   JSON-RPC 2.0 通信模型                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   Client                      Server                        │
│     │                          │                            │
│     │──── 请求 (Request) ────► │                            │
│     │                          │                            │
│     │◄─── 响应 (Response) ──── │                            │
│     │                          │                            │
│     │──── 通知 (Notification) ►│  (无响应)                  │
│     │                          │                            │
└─────────────────────────────────────────────────────────────┘

核心规范

特性说明
传输与传输层无关(stdio、SSE、WebSocket均可)
格式始终为JSON对象,非数组
版本必须包含 jsonrpc: "2.0" 字段
ID请求必须包含唯一ID,响应必须匹配对应ID
通知不包含ID的请求,Server无需响应

MCP消息结构

请求消息

MCP请求遵循JSON-RPC 2.0规范,增加MCP特定的方法命名空间:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_docs",
    "arguments": {
      "query": "MCP协议"
    }
  }
}
字段类型必填说明
jsonrpcstring固定为 "2.0"
idnumber/string请求唯一标识,响应通过此ID匹配
methodstringMCP方法名,格式为 namespace/action
paramsobject方法参数,可为null

响应消息

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "搜索结果..."
      }
    ],
    "isError": false
  }
}
字段类型必填说明
jsonrpcstring固定为 "2.0"
idnumber/string与请求ID一致
resultobject与error二选一成功响应数据
errorobject与result二选一错误信息

错误响应

当请求处理失败时,Server返回错误响应:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32603,
    "message": "Internal error",
    "data": {
      "details": "数据库连接超时",
      "retryAfter": 5
    }
  }
}

MCP方法命名空间

MCP的方法按功能域组织,使用 域/操作 格式:

命名空间方法用途
initializeinitialize连接初始化与能力协商
pingping心跳检测
notificationsnotifications/initialized初始化完成通知
resourcesresources/list列出可用资源
resourcesresources/read读取资源内容
resourcesresources/subscribe订阅资源变更
toolstools/list列出可用工具
toolstools/call调用工具
promptsprompts/list列出可用提示模板
promptsprompts/get获取提示模板内容
logginglogging/setLevel设置日志级别

方法分类

分类方法用途
生命周期initialize, notifications/initialized, ping连接建立与保活
工具管理tools/list, tools/call工具的发现与调用
资源管理resources/list, resources/read, resources/subscribe资源访问与订阅
提示管理prompts/list, prompts/get提示模板的管理
日志管理logging/setLevel运行时日志控制

错误编码规范

标准JSON-RPC错误码

错误码名称描述
-32700Parse ErrorJSON解析失败
-32600Invalid Request无效的JSON-RPC请求
-32601Method Not Found请求的方法不存在
-32602Invalid Params参数验证失败
-32603Internal Error服务器内部错误
-32000 ~ -32099Server Error服务器自定义错误

MCP扩展错误码

MCP在标准错误码基础上增加协议级错误:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32002,
    "message": "Tool execution failed",
    "data": {
      "toolName": "search_docs",
      "errorType": "timeout",
      "duration": 30000
    }
  }
}
MCP错误码含义典型场景
-32000工具未找到请求的工具不存在
-32001资源未找到请求的资源URI无效
-32002执行超时工具执行超过时限
-32003权限不足无权访问指定资源
-32004限流触发请求频率过高

数据类型定义

基础类型

MCP使用JSON原生类型,并定义了内容类型:

// TypeScript类型定义
type RequestId = string | number;

interface TextContent {
  type: "text";
  text: string;
}

interface ImageContent {
  type: "image";
  data: string;
  mimeType: string;
}

interface AudioContent {
  type: "audio";
  data: string;
  mimeType: string;
}

type Content = TextContent | ImageContent | AudioContent;

工具参数Schema

工具参数使用JSON Schema定义输入验证规则:

{
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "搜索关键词"
      },
      "limit": {
        "type": "integer",
        "description": "返回数量上限",
        "minimum": 1,
        "maximum": 100,
        "default": 10
      }
    },
    "required": ["query"]
  }
}

消息校验

TypeScript实现

function validateMessage(raw: string): JSONRPCMessage {
  let parsed: any;
  try {
    parsed = JSON.parse(raw);
  } catch {
    throw new Error("Parse Error: 无效的JSON格式");
  }

  if (parsed.jsonrpc !== "2.0") {
    throw new Error("Invalid Request: JSON-RPC版本必须为2.0");
  }

  if (!parsed.method && !parsed.result && !parsed.error) {
    throw new Error("Invalid Request: 必须包含method、result或error之一");
  }

  return parsed as JSONRPCMessage;
}

Python实现

import json
from typing import Any, Dict

def validate_mcp_message(raw: str) -> Dict[str, Any]:
    """验证并解析MCP消息"""
    try:
        data = json.loads(raw.strip())
    except json.JSONDecodeError as e:
        raise ValueError(f"Parse Error: {e}")

    if data.get("jsonrpc") != "2.0":
        raise ValueError("Invalid Request: jsonrpc版本不匹配")

    has_method = "method" in data
    has_result = "result" in data
    has_error = "error" in data

    if not (has_method or has_result or has_error):
        raise ValueError("Invalid Request: 缺少method/result/error字段")

    return data

调试与工具

# 使用MCP Inspector验证消息
npx @modelcontextprotocol/inspector

# 快速验证JSON-RPC格式
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
  python3 -c "import json,sys; obj=json.load(sys.stdin); assert obj['jsonrpc']=='2.0'; print('Valid')"

总结

MCP的消息格式基于JSON-RPC 2.0提供了以下核心能力:

特性优势
标准化成熟稳定的RPC协议基础
可扩展自描述的方法命名空间机制
类型安全完整的JSON Schema验证支持
版本兼容协商机制确保平滑演进

下一步学习建议:


本文最后更新于 2024-06-30。