AI 工具 | | 约 22 分钟 | 8,475 字

MCP 协议详解:理解 Client-Server 架构

深入理解 MCP 协议规范、消息格式、工具定义和资源管理

什么是 MCP

Model Context Protocol(MCP)是 Anthropic 推出的开放协议,定义了 AI 模型与外部工具之间的通信标准。你可以把它理解为 AI 世界的 USB 接口——只要遵循这个协议,任何工具都能被 AI 使用。

在 MCP 出现之前,每个 AI 工具都需要自己实现与外部服务的集成,导致大量重复工作。MCP 统一了这个接口,让工具开发者只需要实现一次,就能被所有支持 MCP 的 AI 客户端使用。

核心概念

┌─────────────────┐     MCP 协议      ┌─────────────────┐
│   MCP Client    │ ←──────────────→  │   MCP Server    │
│  (Claude Code)  │    JSON-RPC       │  (你开发的工具)  │
└─────────────────┘                   └─────────────────┘
        │                                      │
        ↓                                      ↓
   AI 模型交互                           外部服务/数据
  • MCP Client:AI 应用端,如 Claude Code、Claude Desktop
  • MCP Server:工具提供端,连接外部服务
  • Transport:通信层,支持 stdio 和 HTTP SSE

协议架构

传输层

MCP 支持两种传输方式:

1. stdio(标准输入输出)

最常用的方式,Client 启动 Server 进程,通过 stdin/stdout 通信:

Client 进程                    Server 进程
    │                              │
    │──── stdin (请求) ──────→     │
    │                              │
    │     ←──── stdout (响应) ─────│
    │                              │

配置示例:

{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["server.js"],
      "env": {
        "API_KEY": "xxx"
      }
    }
  }
}

2. HTTP SSE(Server-Sent Events)

适合远程部署的 Server:

Client                         Server (HTTP)
    │                              │
    │──── POST /message ─────→     │
    │                              │
    │     ←──── SSE stream ────────│
    │                              │

配置示例:

{
  "mcpServers": {
    "remote-server": {
      "url": "https://my-server.example.com/mcp"
    }
  }
}

消息格式

MCP 基于 JSON-RPC 2.0 协议,所有消息都是 JSON 格式。

请求消息

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "query_database",
    "arguments": {
      "sql": "SELECT * FROM users LIMIT 10"
    }
  }
}

响应消息

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "查询返回 10 条记录..."
      }
    ]
  }
}

错误消息

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "Invalid SQL query",
    "data": {
      "detail": "Table 'users' does not exist"
    }
  }
}

通知消息(无需响应)

{
  "jsonrpc": "2.0",
  "method": "notifications/progress",
  "params": {
    "progressToken": "task-1",
    "progress": 50,
    "total": 100
  }
}

连接生命周期

握手流程

Client 和 Server 建立连接时,会经历以下步骤:

Client                              Server
  │                                    │
  │──── initialize ──────────────→     │
  │     (客户端能力声明)                │
  │                                    │
  │     ←──── initialize result ───────│
  │           (服务端能力声明)          │
  │                                    │
  │──── initialized ─────────────→     │
  │     (确认初始化完成)                │
  │                                    │
  │     正常通信开始...                 │

initialize 请求

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "roots": {
        "listChanged": true
      }
    },
    "clientInfo": {
      "name": "claude-code",
      "version": "1.0.0"
    }
  }
}

initialize 响应

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": {},
      "resources": {},
      "prompts": {}
    },
    "serverInfo": {
      "name": "my-database-server",
      "version": "1.0.0"
    }
  }
}

三大核心能力

1. Tools(工具)

Tools 是 MCP 最常用的能力,让 AI 能够执行操作。

工具定义

{
  "name": "query_database",
  "description": "执行 SQL 查询并返回结果",
  "inputSchema": {
    "type": "object",
    "properties": {
      "sql": {
        "type": "string",
        "description": "要执行的 SQL 查询语句"
      },
      "limit": {
        "type": "number",
        "description": "返回结果的最大行数",
        "default": 100
      }
    },
    "required": ["sql"]
  }
}

工具定义包含三个关键部分:

  • name:工具的唯一标识
  • description:工具的功能描述,AI 根据这个决定何时使用
  • inputSchema:参数的 JSON Schema 定义

工具调用流程

AI 模型决定使用工具

Client 发送 tools/call 请求

Server 执行操作

Server 返回结果

AI 模型处理结果并继续对话

列出可用工具

// 请求
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list"
}

// 响应
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "query_database",
        "description": "执行 SQL 查询",
        "inputSchema": { ... }
      },
      {
        "name": "list_tables",
        "description": "列出所有数据库表",
        "inputSchema": { ... }
      }
    ]
  }
}

2. Resources(资源)

Resources 让 AI 能够读取数据,类似于文件系统的概念。

资源定义

{
  "uri": "db://schema/users",
  "name": "users 表结构",
  "description": "users 表的列定义和约束",
  "mimeType": "application/json"
}

读取资源

// 请求
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "resources/read",
  "params": {
    "uri": "db://schema/users"
  }
}

// 响应
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "contents": [
      {
        "uri": "db://schema/users",
        "mimeType": "application/json",
        "text": "{\"columns\": [{\"name\": \"id\", \"type\": \"INTEGER\"}, ...]}"
      }
    ]
  }
}

资源模板

支持动态 URI 模式:

{
  "uriTemplate": "db://schema/{table_name}",
  "name": "数据库表结构",
  "description": "获取指定表的结构信息"
}

3. Prompts(提示模板)

Prompts 提供预定义的交互模板,帮助用户更好地使用 Server。

提示定义

{
  "name": "analyze_table",
  "description": "分析数据库表的数据质量",
  "arguments": [
    {
      "name": "table_name",
      "description": "要分析的表名",
      "required": true
    }
  ]
}

获取提示内容

// 请求
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "prompts/get",
  "params": {
    "name": "analyze_table",
    "arguments": {
      "table_name": "users"
    }
  }
}

// 响应
{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "description": "分析 users 表的数据质量",
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "请分析 users 表的数据质量,检查空值、重复值和异常值..."
        }
      }
    ]
  }
}

Server 能力声明

Server 在初始化时声明自己支持哪些能力:

{
  "capabilities": {
    "tools": {},
    "resources": {
      "subscribe": true,
      "listChanged": true
    },
    "prompts": {
      "listChanged": true
    },
    "logging": {}
  }
}
能力说明
tools支持工具调用
resources支持资源读取
resources.subscribe支持资源变更订阅
prompts支持提示模板
logging支持日志输出

协议版本

MCP 协议有版本号,Client 和 Server 在握手时协商版本:

{
  "protocolVersion": "2024-11-05"
}

版本兼容规则:

  • Client 和 Server 必须支持相同的协议版本
  • 如果版本不匹配,连接会被拒绝
  • 建议始终使用最新的稳定版本

用 TypeScript SDK 实现

理解了协议之后,我们来看看如何用 SDK 快速实现一个 MCP Server:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// 创建 Server 实例
const server = new McpServer({
  name: "demo-server",
  version: "1.0.0",
});

// 注册工具
server.tool(
  "greet",
  "向用户打招呼",
  {
    name: z.string().describe("用户名"),
    language: z.enum(["zh", "en"]).default("zh").describe("语言"),
  },
  async ({ name, language }) => {
    const greeting = language === "zh" ? `你好,${name}!` : `Hello, ${name}!`;
    return {
      content: [{ type: "text", text: greeting }],
    };
  }
);

// 注册资源
server.resource(
  "config",
  "config://app",
  async (uri) => ({
    contents: [
      {
        uri: uri.href,
        mimeType: "application/json",
        text: JSON.stringify({ version: "1.0.0", debug: false }),
      },
    ],
  })
);

// 启动 Server
const transport = new StdioServerTransport();
await server.connect(transport);

SDK 封装了底层的 JSON-RPC 通信细节,我们只需要关注业务逻辑。


调试技巧

使用 MCP Inspector

MCP Inspector 是官方提供的调试工具:

npx @modelcontextprotocol/inspector node server.js

它会启动一个 Web 界面,可以:

  • 查看 Server 提供的所有工具和资源
  • 手动调用工具并查看结果
  • 查看通信日志

日志输出

在 Server 中添加日志:

server.server.sendLoggingMessage({
  level: "info",
  data: "Server started successfully",
});

总结

MCP 协议的设计简洁而强大:

  • JSON-RPC 2.0 作为通信基础,成熟可靠
  • 三大能力(Tools、Resources、Prompts)覆盖了大部分集成需求
  • stdio 和 HTTP SSE 两种传输方式,适应不同部署场景
  • 能力协商 机制让 Client 和 Server 灵活配合

理解了协议本身,后续开发 MCP Server 就会轻松很多。接下来的文章,我们会动手实现几个实用的 MCP Server。

协议是桥梁,连接 AI 的智能和工具的能力。理解 MCP,就是理解 AI 如何与世界交互。

评论

加载中...

相关文章

分享:

评论

加载中...