跳转至

MySQL MCP 原理与链路

本文介绍 Model Context Protocol (MCP) 的基本原理,以及 MySQL MCP 在 QwenPaw 中的完整工作链路。


什么是 MCP

MCP (Model Context Protocol) 是 Anthropic 提出的一种开放协议,用于标准化 AI 模型与外部数据源和工具之间的通信方式。

核心思想:

让 AI 模型能够通过统一的协议访问各种外部资源,而不需要为每个工具编写特定的集成代码。

MCP 架构

graph LR
    A[AI Agent] -->|MCP 协议| B[MCP Client]
    B -->|JSON-RPC| C[MCP Server]
    C -->|API/SDK| D[外部资源]

    style A fill:#e1f5fe
    style B fill:#f3e5f5
    style C fill:#e8f5e8
    style D fill:#fff3e0
组件 职责 示例
AI Agent 发起请求的大语言模型 QwenPaw Agent
MCP Client 管理与 MCP Server 的连接 QwenPaw 内置 Client
MCP Server 提供具体工具能力的进程 MySQL MCP Server
外部资源 被操作的目标系统 MySQL 数据库

通信协议

MCP 使用 JSON-RPC 2.0 作为底层通信协议:

// Agent 发送请求
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "mysql_query",
    "arguments": {
      "sql": "SELECT * FROM todos LIMIT 10"
    }
  }
}

// MCP Server 返回结果
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "[{\"id\": 1, \"title\": \"示例任务\"}]"
      }
    ]
  }
}

MySQL MCP 工作链路

完整调用链

sequenceDiagram
    participant U as 用户
    participant A as QwenPaw Agent
    participant C as MCP Client
    participant S as MySQL MCP Server
    participant D as MySQL 数据库

    U->>A: "查看我的待办"
    A->>A: 解析意图,加载 todo skill
    A->>C: 调用 mysql_query 工具
    C->>S: JSON-RPC: tools/call
    S->>D: 执行 SQL 查询
    D-->>S: 返回查询结果
    S-->>C: JSON-RPC 响应
    C-->>A: 工具调用结果
    A-->>U: 格式化展示结果

各层详解

1. Agent 层(意图理解)

Agent 接收用户自然语言,通过 skill 路由找到对应的 todo skill,然后按照 SKILL.md 中的指令构造 SQL:

用户: "查看我的待办"
  ↓
Agent: 加载 todo skill
  ↓
Agent: 执行 SELECT 查询
  ↓
调用 mysql_query 工具

2. MCP Client 层(协议转换)

QwenPaw 内置的 MCP Client 负责:

  • 维护与 MCP Server 的连接池
  • 将工具调用转换为 JSON-RPC 请求
  • 处理响应和错误
# QwenPaw 内部的 MCP Client 调用示例
result = await client.call_tool(
    name="mysql_query",
    arguments={"sql": "SELECT * FROM todos"}
)

3. MCP Server 层(工具执行)

MySQL MCP Server 是一个独立进程,负责:

  • 接收 JSON-RPC 请求
  • 解析 SQL 语句
  • 连接 MySQL 数据库执行查询
  • 返回格式化结果
# MySQL MCP Server 的工具定义
@server.tool()
async def mysql_query(sql: str) -> str:
    """执行 SQL 查询"""
    async with connection_pool.acquire() as conn:
        async with conn.cursor() as cursor:
            await cursor.execute(sql)
            result = await cursor.fetchall()
            return json.dumps(result, ensure_ascii=False)

4. 数据库层(存储)

MySQL 数据库执行实际的数据操作:

-- 创建待办表
CREATE TABLE IF NOT EXISTS todos (
    id               BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    title            VARCHAR(500) NOT NULL,
    description      TEXT,
    status           ENUM('pending', 'in_progress', 'done', 'archived') NOT NULL DEFAULT 'pending',
    priority         ENUM('low', 'medium', 'high', 'urgent') NOT NULL DEFAULT 'medium',
    created_at       DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at       DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    last_accessed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    access_count     INT UNSIGNED NOT NULL DEFAULT 1
);

QwenPaw 中的 MCP 集成

配置方式

在 QwenPaw 的配置文件中注册 MCP Server:

# ~/.qwenpaw/config.yaml
mcp_servers:
  mysql:
    command: "uvx"
    args:
      - "mysql-mcp-server"
    env:
      MYSQL_HOST: "localhost"
      MYSQL_PORT: "3306"
      MYSQL_USER: "root"
      MYSQL_PASSWORD: "your_password"
      MYSQL_DATABASE: "todo_db"

工具发现

Agent 启动时,MCP Client 会:

  1. 连接到配置的 MCP Server
  2. 调用 tools/list 获取可用工具列表
  3. 将工具信息注册到 Agent 的工具池
// tools/list 返回的工具定义
{
  "tools": [
    {
      "name": "mysql_query",
      "description": "执行 SQL 查询",
      "inputSchema": {
        "type": "object",
        "properties": {
          "sql": {
            "type": "string",
            "description": "要执行的 SQL 语句"
          }
        },
        "required": ["sql"]
      }
    }
  ]
}

安全机制

MySQL MCP Server 通常提供以下安全机制:

机制 说明
只读模式 只允许 SELECT 查询,禁止修改操作
SQL 白名单 只允许特定表的查询
连接池限制 限制并发连接数
超时控制 防止长时间阻塞

常见问题排查

连接失败

# 检查 MCP Server 是否运行
ps aux | grep mysql-mcp

# 检查端口监听
netstat -tlnp | grep 3306

# 测试数据库连接
mysql -h localhost -u root -p

工具调用超时

# 在配置中增加超时时间
mcp_servers:
  mysql:
    timeout: 30  # 秒

权限问题

确保 MySQL 用户有相应的权限:

-- 授予查询权限
GRANT SELECT ON todo_db.* TO 'your_user'@'localhost';

-- 授予完整权限(开发环境)
GRANT ALL PRIVILEGES ON todo_db.* TO 'your_user'@'localhost';

扩展阅读


实践建议

在生产环境中,建议使用只读权限的数据库账号,并限制可查询的表范围,避免 Agent 误操作导致数据丢失。