MCP 协议详解

目录

[一、协议本质:JSON-RPC 2.0 + 约定](#一、协议本质:JSON-RPC 2.0 + 约定)

核心组成

[1. JSON-RPC 2.0 基础](#1. JSON-RPC 2.0 基础)

二、协议消息全集(核心内容)

[1. 初始化消息(初始化握手)](#1. 初始化消息(初始化握手))

[2. 工具相关消息](#2. 工具相关消息)

[3. 资源相关消息](#3. 资源相关消息)

[4. 通知消息(服务器主动推送)](#4. 通知消息(服务器主动推送))

三、协议传输层

支持两种传输方式

[STDIO 通信示例](#STDIO 通信示例)

四、协议中的核心概念

[1. 工具(Tools)规范](#1. 工具(Tools)规范)

[2. 资源(Resources)规范](#2. 资源(Resources)规范)

[3. 内容(Content)类型](#3. 内容(Content)类型)

五、完整通信流程示例

完整会话示例

六、协议的错误处理

错误响应格式

常见错误码

七、协议扩展性

扩展字段

能力协商

八、实际实现示例

[Python 实现片段](#Python 实现片段)

完整通信追踪

九、协议设计哲学

为什么这样设计?

与其他协议对比

[十、总结:MCP 协议是什么](#十、总结:MCP 协议是什么)


MCP 协议是 Model Context Protocol​ 的规范,定义了 LLM 与工具之间的标准通信方式。

一、协议本质:JSON-RPC 2.0 + 约定

核心组成

复制代码
MCP 协议 = JSON-RPC 2.0 基础协议 + 特定消息约定 + 传输约定

1. JSON-RPC 2.0 基础

每个消息都是这样的 JSON:

复制代码
{
  "jsonrpc": "2.0",     // 必填,版本标识
  "id": 1,              // 请求ID,用于匹配响应
  "method": "tools/list", // 方法名
  "params": {...}       // 参数
}

响应格式:

复制代码
{
  "jsonrpc": "2.0",
  "id": 1,              // 与请求的 id 对应
  "result": {...}       // 成功结果
  // 或
  "error": {...}        // 错误信息
}

二、协议消息全集(核心内容)

1. 初始化消息(初始化握手)

客户端 → 服务器

复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "roots": { "listChanged": true },
      "tools": {},
      "resources": {}
    },
    "clientInfo": {
      "name": "claude",
      "version": "1.0.0"
    }
  }
}

服务器响应

复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": {},
      "resources": {}
    },
    "serverInfo": {
      "name": "weather-server",
      "version": "1.0.0"
    }
  }
}

2. 工具相关消息

列出工具

复制代码
// 请求
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list"
}

// 响应
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "get_weather",
        "description": "获取天气信息",
        "inputSchema": {
          "type": "object",
          "properties": {
            "city": {"type": "string"},
            "unit": {"enum": ["celsius", "fahrenheit"]}
          },
          "required": ["city"]
        }
      }
    ]
  }
}

调用工具

复制代码
// 请求
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "city": "北京",
      "unit": "celsius"
    }
  }
}

// 响应
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "北京天气:晴,25°C,湿度 60%"
      },
      {
        "type": "image",
        "data": "base64...",
        "mimeType": "image/png"
      }
    ],
    "isError": false
  }
}

3. 资源相关消息

列出资源

复制代码
// 请求
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "resources/list"
}

// 响应
{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "resources": [
      {
        "uri": "file:///reports/q4.md",
        "name": "Q4 报告",
        "description": "第四季度财务报告",
        "mimeType": "text/markdown"
      }
    ]
  }
}

读取资源

复制代码
// 请求
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "resources/read",
  "params": {
    "uri": "file:///reports/q4.md"
  }
}

// 响应
{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "contents": [
      {
        "uri": "file:///reports/q4.md",
        "mimeType": "text/markdown",
        "text": "# Q4 财务报告\n\n收入:...\n利润:..."
      }
    ]
  }
}

4. 通知消息(服务器主动推送)

资源变更通知

复制代码
{
  "jsonrpc": "2.0",
  "method": "notifications/resources/updated",
  "params": {
    "resources": [
      {
        "uri": "file:///reports/q4.md",
        "changed": true
      }
    ]
  }
}

进度通知

复制代码
{
  "jsonrpc": "2.0",
  "method": "notifications/progress",
  "params": {
    "progressToken": "abc123",
    "progress": 0.5,
    "total": 100
  }
}

三、协议传输层

支持两种传输方式

1. 标准输入输出(STDIO)

复制代码
客户端进程
    │
    ├─STDIN───┐
    │         ▼
    │     服务器进程
    │         ▲
    └─STDOUT──┘
  • 通过管道通信

  • 一行一个 JSON 消息

  • 用换行符分隔

2. HTTP + Server-Sent Events(SSE)

复制代码
客户端 ──HTTP POST──▶ 服务器
    │                    │
    │◀──SSE 流───────────│
    │                    │
    └──HTTP POST───▶     │
         (调用工具)       │

STDIO 通信示例

复制代码
# 服务器读取消息
import sys
import json

def read_message():
    line = sys.stdin.readline()
    if not line:
        return None
    return json.loads(line)

def send_message(msg):
    json.dump(msg, sys.stdout)
    sys.stdout.write('\n')
    sys.stdout.flush()

# 客户端发送
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}' | python server.py

四、协议中的核心概念

1. 工具(Tools)规范

复制代码
{
  "name": "tool_name",          // 工具标识,全局唯一
  "description": "...",         // 给 LLM 看的描述
  "inputSchema": {              // JSON Schema
    "type": "object",
    "properties": {
      "param1": {"type": "string"}
    },
    "required": ["param1"]
  }
}

2. 资源(Resources)规范

复制代码
{
  "uri": "scheme://path",       // 统一资源标识符
  "name": "显示名称",
  "description": "...",         // 资源描述
  "mimeType": "text/plain"      // 内容类型
}

3. 内容(Content)类型

复制代码
{
  "content": [
    {
      "type": "text",           // 文本内容
      "text": "Hello World"
    },
    {
      "type": "image",          // 图片
      "data": "base64...",
      "mimeType": "image/png"
    },
    {
      "type": "resource",       // 引用其他资源
      "resource": {
        "uri": "file:///doc.md",
        "mimeType": "text/markdown"
      }
    }
  ]
}

五、完整通信流程示例

完整会话示例

复制代码
// 1. 初始化
客户端 → {"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}
服务器 ← {"jsonrpc":"2.0","id":1,"result":{...}}

// 2. 列出工具
客户端 → {"jsonrpc":"2.0","id":2,"method":"tools/list"}
服务器 ← {"jsonrpc":"2.0","id":2,"result":{...}}

// 3. 调用工具
客户端 → {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{...}}
服务器 ← {"jsonrpc":"2.0","id":3,"result":{...}}

// 4. 资源变更通知(服务器主动)
服务器 ← {"jsonrpc":"2.0","method":"notifications/resources/updated","params":{...}}

// 5. 列出资源
客户端 → {"jsonrpc":"2.0","id":4,"method":"resources/list"}
服务器 ← {"jsonrpc":"2.0","id":4,"result":{...}}

六、协议的错误处理

错误响应格式

复制代码
{
  "jsonrpc": "2.0",
  "id": 123,
  "error": {
    "code": -32601,            // JSON-RPC 标准错误码
    "message": "Method not found",
    "data": {                  // MCP 扩展信息
      "type": "INVALID_TOOL",
      "details": "Tool 'xyz' not found"
    }
  }
}

常见错误码

错误码 含义 场景
-32600 无效请求 JSON 格式错误
-32601 方法不存在 调用未定义的方法
-32602 无效参数 参数不符合 schema
-32700 解析错误 JSON 解析失败
-32000 服务器错误 工具执行异常

七、协议扩展性

扩展字段

复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {...},
  "annotations": {          // 扩展字段
    "auth": {"token": "..."},
    "trace": {"id": "abc123"}
  }
}

能力协商

复制代码
{
  "capabilities": {
    "tools": {
      "listChanged": true,     // 支持工具变更通知
      "callParallel": true     // 支持并行调用
    },
    "resources": {
      "subscribe": true,       // 支持资源订阅
      "listChanged": true
    },
    "prompts": {}              // 提示词能力
  }
}

八、实际实现示例

Python 实现片段

复制代码
import json
import sys
import asyncio
from typing import Dict, Any

class MCPServer:
    def __init__(self, name: str):
        self.name = name
        self.tools = {}
        self.resources = {}
    
    async def handle_message(self, msg: Dict[str, Any]) -> Dict[str, Any]:
        method = msg.get("method")
        
        if method == "initialize":
            return {
                "jsonrpc": "2.0",
                "id": msg["id"],
                "result": {
                    "protocolVersion": "2024-11-05",
                    "serverInfo": {"name": self.name}
                }
            }
        
        elif method == "tools/list":
            return {
                "jsonrpc": "2.0",
                "id": msg["id"],
                "result": {
                    "tools": [
                        {
                            "name": "echo",
                            "description": "Echo input",
                            "inputSchema": {
                                "type": "object",
                                "properties": {
                                    "text": {"type": "string"}
                                }
                            }
                        }
                    ]
                }
            }
        
        elif method == "tools/call":
            tool_name = msg["params"]["name"]
            arguments = msg["params"]["arguments"]
            
            if tool_name == "echo":
                return {
                    "jsonrpc": "2.0",
                    "id": msg["id"],
                    "result": {
                        "content": [{
                            "type": "text",
                            "text": arguments.get("text", "")
                        }]
                    }
                }

完整通信追踪

复制代码
# 启动服务器
$ python simple_server.py

# 通信过程(STDIO)
发送: {"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}
接收: {"jsonrpc":"2.0","id":1,"result":{...}}

发送: {"jsonrpc":"2.0","id":2,"method":"tools/list"}
接收: {"jsonrpc":"2.0","id":2,"result":{"tools":[...]}}

发送: {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{...}}
接收: {"jsonrpc":"2.0","id":3,"result":{"content":[...]}}

九、协议设计哲学

为什么这样设计?

  1. 基于 JSON-RPC 2.0

    • 成熟标准,广泛支持

    • 请求-响应模型简单

    • 良好的错误处理

  2. STDIO 传输

    • 语言无关性

    • 简单可靠

    • 无需网络配置

  3. 声明式工具定义

    • LLM 可理解工具用途

    • 运行时发现能力

    • 类型安全输入

  4. 资源概念

    • 统一数据访问

    • 变更通知机制

    • 内容协商能力

与其他协议对比

协议 特点 与 MCP 的区别
OpenAI Function Calling 函数调用,供应商绑定 MCP 是开放协议
gRPC 高性能 RPC,复杂 MCP 更简单,JSON 友好
REST API HTTP 资源操作 MCP 是 LLM 专用协议
LSP 编辑器语言服务 类似理念,不同领域

十、总结:MCP 协议是什么

MCP 协议是

  1. 一套规范:定义了 LLM 如何与外部工具通信

  2. 基于 JSON-RPC 2.0:使用成熟的 RPC 标准

  3. 传输无关:支持 STDIO 和 HTTP/SSE

  4. 声明式:工具和资源有明确的 schema

  5. 双向通信:客户端调用工具,服务器主动通知

  6. 扩展性强:支持多种内容类型和扩展字段

简单说

复制代码
MCP 协议 = JSON 消息格式 + 通信约定 + 工具定义规范

核心价值

  • 标准化 LLM 工具调用

  • 实现工具的动态发现

  • 提供安全的执行环境

  • 支持丰富的返回类型

这就是为什么说 MCP Server 是"遵循 MCP 协议的进程"------它必须按照这个规范接收和发送 JSON 消息,才能与 Claude 等 LLM 应用正常通信。

相关推荐
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner12 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner13 天前
DicomViewer (目录调整) 2
qt
xcyxiner13 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00615 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术15 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript