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 应用正常通信。

相关推荐
sdszoe49222 小时前
IP地址规划与VLSM技术
网络·网络协议·tcp/ip·vlsm·ip地址规划
m0_569531012 小时前
《K8s 网络入门到进阶:Service 与 Ingress 原理、部署方案及核心区别对比》
网络·容器·kubernetes
广东大榕树信息科技有限公司2 小时前
当运维管理面临挑战时,如何借助动环监控系统提升响应能力?
运维·网络·物联网·国产动环监控系统·动环监控系统
cheems95272 小时前
锁策略的介绍
java·开发语言
清水白石0082 小时前
《Python × 数据库:用 SQLAlchemy 解锁高效 ORM 编程的艺术》
开发语言·python·json
风中月隐2 小时前
C语言中以坐标的方式图解“字母金字塔”的绘制
c语言·开发语言·算法·字母金子塔·坐标图解法
Arva .2 小时前
说说线程的生命周期和状态
java·开发语言
1001101_QIA2 小时前
C++中不能复制只能移动的类型
开发语言·c++
tryxr3 小时前
HashTable、HashMap、ConcurrentHashMap 之间的区别
java·开发语言·hash