Skip to content

MCP 协议

MCP(Model Context Protocol)是由 Anthropic 提出的开放标准协议,用于连接 AI 模型与外部工具和数据源。MateClaw 实现了完整的 MCP 客户端,支持动态发现和调用外部 MCP 服务器暴露的工具,使 Agent 能够像使用内置工具一样使用第三方能力,无需编写额外代码。

什么是 MCP

MCP 采用客户端-服务器架构,基于 JSON-RPC 2.0 进行通信:

┌───────────────────────┐              ┌───────────────────────┐
│     MateClaw           │              │     MCP Server        │
│     (MCP Client)       │              │     (工具提供方)       │
│                       │   JSON-RPC   │                       │
│  Agent Engine  ───────┼──────────────┼──► Tool A             │
│                       │              │    Tool B             │
│  Tool Registry ◄──────┼──────────────┼─── Tool Discovery     │
│                       │              │    (tools/list)       │
└───────────────────────┘              └───────────────────────┘

核心概念:

  • MCP Client:MateClaw 作为客户端,负责连接 MCP 服务器、发现工具、转发工具调用请求
  • MCP Server:第三方工具服务器,声明自身提供的工具列表,接收并执行工具调用
  • Tool Discovery:客户端通过 tools/list 请求获取服务器暴露的所有工具及其参数 schema
  • Tool Invocation:Agent 推理过程中决定调用某工具时,客户端将请求转发给对应 MCP 服务器执行

通过 MCP,MateClaw 可以在不修改代码、不重启服务的情况下,动态接入新的工具能力。

传输类型

MateClaw 支持三种 MCP 传输方式,适用于不同的部署场景:

stdio(标准输入输出)

通过子进程的 stdin/stdout 管道通信。MateClaw 会启动一个本地子进程作为 MCP 服务器,通过标准输入输出交换 JSON-RPC 消息。

MateClaw  ── stdin ──►  MCP Server 子进程
          ◄─ stdout ──

适用场景

  • 本地 Node.js/Python MCP 工具包(如 @anthropic/mcp-filesystem
  • 命令行工具封装
  • 开发调试阶段

优点:无需网络配置,启动即用,进程隔离 限制:仅支持本地部署,MateClaw 必须能直接执行指定命令

streamable_http(Streamable HTTP)

MCP 协议最新推荐的 HTTP 传输方式。使用标准 HTTP POST 请求发送 JSON-RPC,响应通过 HTTP 流式返回。

MateClaw  ── HTTP POST ──►  远程 MCP Server
          ◄─ HTTP Stream ──

适用场景

  • 云端部署的 MCP 服务器
  • 需要负载均衡或反向代理的场景
  • 生产环境推荐使用

优点:标准 HTTP 协议,兼容各类网络基础设施(CDN、负载均衡、防火墙),支持认证头 限制:需要服务器支持 Streamable HTTP 传输

sse(Server-Sent Events)

早期 MCP HTTP 传输方式,使用 SSE 进行服务器到客户端的推送。

MateClaw  ── HTTP POST ──►  远程 MCP Server
          ◄─── SSE ────────

适用场景

  • 兼容仅支持 SSE 传输的旧版 MCP 服务器
  • 当远端服务器尚未升级到 Streamable HTTP 时使用

优点:兼容性好,许多现有 MCP 服务器仍使用此传输方式 限制:已被 Streamable HTTP 逐步替代,新项目建议优先使用 streamable_http

传输类型对比

特性stdiostreamable_httpsse
部署位置仅本地本地或远程本地或远程
网络要求HTTP 可达HTTP 可达
认证支持环境变量传递HTTP HeadersHTTP Headers
进程管理MateClaw 管理子进程外部管理外部管理
推荐程度本地工具首选远程服务首选兼容旧版

通过管理界面配置

添加 MCP 服务器

  1. 登录 MateClaw 管理界面
  2. 进入「工具管理」页面
  3. 切换到「MCP 服务器」标签页
  4. 点击「添加 MCP 服务器」按钮
  5. 填写配置表单:
    • 名称:服务器唯一标识(仅允许字母、数字、下划线、连字符、点和空格,1-128 字符)
    • 描述:可选,说明该服务器的用途
    • 传输类型:选择 stdiostreamable_httpsse
    • 命令(stdio):启动 MCP 服务器的命令,如 npxnodepython
    • 参数(stdio):JSON 数组格式的命令行参数,如 ["-y", "@anthropic/mcp-filesystem", "/path"]
    • 工作目录(stdio):可选,命令执行的工作目录
    • 环境变量(stdio):JSON 对象格式,如 {"API_KEY": "xxx"},支持 ${ENV_VAR} 引用系统环境变量
    • URL(streamable_http/sse):MCP 服务器端点地址
    • HTTP 请求头(streamable_http/sse):JSON 对象格式,如 {"Authorization": "Bearer token"}
    • 连接超时:连接建立超时时间,默认 30 秒
    • 读取超时:请求响应超时时间,默认 30 秒
  6. 点击「保存」

保存后,如果服务器处于启用状态,MateClaw 会自动尝试连接并发现工具。

测试连接

在 MCP 服务器列表中,点击某个服务器的「测试连接」按钮。测试连接会:

  • 尝试建立到 MCP 服务器的连接
  • 发送 tools/list 请求发现可用工具
  • 返回连接结果(成功/失败)、延迟时间、发现的工具列表
  • 测试连接不会影响当前活跃的连接

启用与禁用

每个 MCP 服务器都有独立的启用/禁用开关:

  • 启用:MateClaw 会建立连接,发现的工具可被 Agent 调用
  • 禁用:断开连接,该服务器的工具不再可用,但配置保留

查看连接状态

MCP 服务器列表显示每个服务器的实时状态:

  • connected:已连接,工具可用
  • disconnected:已断开(手动禁用或尚未连接)
  • error:连接失败,可查看错误信息

通过 REST API 配置

MCP 服务器的完整 CRUD 操作通过 /api/v1/mcp/servers 接口提供。所有接口需要 JWT 认证。

查询所有 MCP 服务器

bash
curl -s http://localhost:18088/api/v1/mcp/servers \
  -H "Authorization: Bearer <token>" | jq

返回示例:

json
{
  "code": 200,
  "data": [
    {
      "id": "1",
      "name": "filesystem",
      "transport": "stdio",
      "command": "npx",
      "argsJson": "[\"-y\", \"@anthropic/mcp-filesystem\", \"/home/user\"]",
      "enabled": true,
      "lastStatus": "connected",
      "toolCount": 5,
      "lastConnectedTime": "2026-04-01T10:30:00"
    }
  ]
}

注意:返回的 headersJsonenvJson 字段中的值会被脱敏处理(如 sk-****abcd),以保护敏感信息。

查询单个 MCP 服务器

bash
curl -s http://localhost:18088/api/v1/mcp/servers/{id} \
  -H "Authorization: Bearer <token>"

创建 MCP 服务器(stdio 类型)

bash
curl -X POST http://localhost:18088/api/v1/mcp/servers \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name": "filesystem",
    "description": "文件系统读写工具",
    "transport": "stdio",
    "command": "npx",
    "argsJson": "[\"-y\", \"@anthropic/mcp-filesystem\", \"/home/user/workspace\"]",
    "enabled": true
  }'

创建 MCP 服务器(streamable_http 类型)

bash
curl -X POST http://localhost:18088/api/v1/mcp/servers \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name": "remote-tools",
    "description": "远程工具服务",
    "transport": "streamable_http",
    "url": "https://mcp.example.com/mcp",
    "headersJson": "{\"Authorization\": \"Bearer your-api-key\"}",
    "connectTimeoutSeconds": 15,
    "readTimeoutSeconds": 60,
    "enabled": true
  }'

更新 MCP 服务器

使用 PATCH 语义 -- 仅传入需要修改的字段,未传入的字段保持不变:

bash
curl -X PUT http://localhost:18088/api/v1/mcp/servers/{id} \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "description": "更新后的描述",
    "readTimeoutSeconds": 60
  }'

更新后,如果服务器处于启用状态,会自动重新连接。

删除 MCP 服务器

bash
curl -X DELETE http://localhost:18088/api/v1/mcp/servers/{id} \
  -H "Authorization: Bearer <token>"

删除前会自动断开连接。注意:标记为 builtin 的内置服务器不允许删除。

启用/禁用 MCP 服务器

bash
# 禁用
curl -X PUT "http://localhost:18088/api/v1/mcp/servers/{id}/toggle?enabled=false" \
  -H "Authorization: Bearer <token>"

# 启用
curl -X PUT "http://localhost:18088/api/v1/mcp/servers/{id}/toggle?enabled=true" \
  -H "Authorization: Bearer <token>"

测试连接

bash
curl -X POST http://localhost:18088/api/v1/mcp/servers/{id}/test \
  -H "Authorization: Bearer <token>"

返回示例:

json
{
  "code": 200,
  "data": {
    "success": true,
    "message": "Connected",
    "toolCount": 5,
    "latencyMs": 1234,
    "discoveredTools": ["read_file", "write_file", "list_directory", "search_files", "get_file_info"],
    "timestamp": "2026-04-01T10:30:00"
  }
}

刷新所有连接

断开所有现有连接,重新连接所有已启用的 MCP 服务器:

bash
curl -X POST http://localhost:18088/api/v1/mcp/servers/refresh \
  -H "Authorization: Bearer <token>"

实战示例

示例一:文件系统 MCP 服务器(stdio)

使用 Anthropic 官方提供的文件系统 MCP 服务器,让 Agent 具备读写文件、搜索目录的能力。

前置条件:服务器上已安装 Node.js(v18+)和 npm。

通过 API 创建:

bash
curl -X POST http://localhost:18088/api/v1/mcp/servers \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name": "filesystem",
    "description": "文件系统读写(限制在指定目录内)",
    "transport": "stdio",
    "command": "npx",
    "argsJson": "[\"-y\", \"@anthropic/mcp-filesystem\", \"/home/user/workspace\"]",
    "enabled": true
  }'

连接成功后将发现以下工具:

工具名说明
read_file读取文件内容
write_file写入文件
list_directory列出目录内容
search_files搜索文件
get_file_info获取文件元信息

安全提示:@anthropic/mcp-filesystem 只允许访问启动参数中指定的目录及其子目录,不会泄露系统其他文件。

示例二:远程 HTTP MCP 服务器(streamable_http + 认证)

连接一个需要 API Key 认证的远程 MCP 服务器,例如企业内部的数据查询服务。

bash
curl -X POST http://localhost:18088/api/v1/mcp/servers \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name": "internal-data-service",
    "description": "企业内部数据查询 MCP 服务",
    "transport": "streamable_http",
    "url": "https://mcp-api.internal.example.com/mcp",
    "headersJson": "{\"Authorization\": \"Bearer sk-your-api-key\", \"X-Team-Id\": \"engineering\"}",
    "connectTimeoutSeconds": 10,
    "readTimeoutSeconds": 120,
    "enabled": true
  }'

配置说明:

  • url 指向远程 MCP 服务器的 Streamable HTTP 端点
  • headersJson 传递认证信息,每次 HTTP 请求都会携带这些头
  • 头中的值支持环境变量引用:{"Authorization": "Bearer ${MCP_API_KEY}"} 会在运行时替换为系统环境变量的值
  • 较长的 readTimeoutSeconds 适用于执行时间较长的数据查询

示例三:Tavily 搜索 MCP 服务器(stdio + 环境变量)

接入 Tavily 搜索 MCP 服务器,为 Agent 提供实时网页搜索能力。

bash
curl -X POST http://localhost:18088/api/v1/mcp/servers \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name": "tavily-search",
    "description": "Tavily 实时网页搜索",
    "transport": "stdio",
    "command": "npx",
    "argsJson": "[\"-y\", \"@anthropic/mcp-tavily\"]",
    "envJson": "{\"TAVILY_API_KEY\": \"${TAVILY_API_KEY}\"}",
    "enabled": true
  }'

配置说明:

  • envJson 中的 ${TAVILY_API_KEY} 会在运行时被替换为 MateClaw 进程的同名系统环境变量
  • 也支持直接写入明文 key:{"TAVILY_API_KEY": "tvly-xxxxxx"},但建议使用环境变量引用以避免密钥泄露
  • 子进程会继承指定的环境变量

示例四:SSE 兼容的旧版 MCP 服务器

连接一个仅支持 SSE 传输的 MCP 服务器:

bash
curl -X POST http://localhost:18088/api/v1/mcp/servers \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name": "legacy-mcp-server",
    "description": "旧版 SSE 传输的 MCP 服务器",
    "transport": "sse",
    "url": "http://192.168.1.100:3001/sse",
    "enabled": true
  }'

MCP 工具注册机制

MCP 工具从发现到可被 Agent 调用,经过以下流程:

McpServerBootstrapRunner(应用启动)


McpServerService.initEnabledServers()
        │  遍历所有 enabled 的 MCP server

McpClientManager.connect(server)
        │  1. 根据 transport 类型构建 McpSyncClient
        │  2. 调用 client.initialize() 建立连接
        │  3. 调用 client.listTools() 发现工具
        │  4. 缓存到 clients 和 toolsCache

McpToolCallbackProvider.getToolCallbacks()
        │  实现 Spring AI 的 ToolCallbackProvider 接口
        │  从 McpClientManager 获取所有 active clients 的 ToolCallback

ToolRegistry(工具注册表)
        │  聚合内置工具 + MCP 工具

Agent 工具集
        │  Agent 在推理时可调用任何已注册工具

关键实现细节:

  • McpToolCallbackProvider 实现了 Spring AI 的 ToolCallbackProvider 接口。每次调用 getToolCallbacks() 都会从 McpClientManager 获取最新的活跃工具列表,因此新增或删除 MCP 服务器后无需重启应用即可生效。
  • SyncMcpToolCallbackProvider(Spring AI 内置)负责将单个 McpSyncClient 的工具转换为 ToolCallback 数组。
  • MCP 工具与内置 @Tool 注解的工具在 Agent 调用层面完全一致,Agent 无法也无需区分工具来源。
  • 每个 MCP 工具的名称、描述和参数 schema 均由 MCP 服务器在 tools/list 响应中声明。

连接管理

启动时自动连接

MateClaw 启动完成后,McpServerBootstrapRunner 会自动连接所有数据库中标记为 enabled=true 的 MCP 服务器。单个服务器连接失败不会阻塞其他服务器或应用启动。

线程安全

McpClientManager 使用 ConcurrentHashMap 存储活跃客户端,并为每个 server 维护独立的 ReentrantLock,确保同一服务器的 connect/replace/remove 操作不会并发冲突。

连接替换(Replace)

更新 MCP 服务器配置后,系统执行"先连新再断旧"的替换策略:

  1. 使用新配置创建并初始化新的 McpSyncClient
  2. 新客户端连接成功后,将其放入活跃客户端池
  3. 关闭旧客户端

如果新客户端连接失败,旧客户端不受影响(如果有的话)。

子进程清理

对于 stdio 类型的 MCP 服务器,MateClaw 会启动一个子进程。以下场景会确保子进程被正确关闭:

  • 手动禁用或删除 MCP 服务器
  • 替换 MCP 服务器配置
  • 应用关闭时(通过 @PreDestroy 钩子)
  • 连接失败时(初始化过程中已启动的子进程会被关闭)

状态监控

每次连接操作后,系统会将连接结果持久化到数据库:

  • last_statusconnected / disconnected / error
  • last_error:错误信息(连接成功时清空)
  • last_connected_time:最后一次成功连接的时间
  • tool_count:当前发现的工具数量

手动刷新

通过「刷新所有连接」操作(API: POST /api/v1/mcp/servers/refresh),可以断开所有现有连接并重新连接所有启用的服务器。适用于排查连接问题或 MCP 服务器端工具列表变更后需要重新发现的场景。

数据库存储

MCP 服务器配置存储在 mate_mcp_server 表中。完整字段如下:

字段类型默认值说明
idBIGINT-主键(雪花算法生成)
nameVARCHAR(128)-服务器名称,唯一标识。允许字母、数字、_-.、空格,1-128 字符
descriptionTEXTNULL服务器描述
transportVARCHAR(32)stdio传输类型:stdio / streamable_http / sse
urlVARCHAR(512)NULL远端 URL(streamable_http/sse 类型必填)
headers_jsonTEXTNULLHTTP 请求头,JSON 对象格式,如 {"Authorization": "Bearer xxx"}
commandVARCHAR(512)NULL启动命令(stdio 类型必填),如 npxnodepython
args_jsonTEXTNULL命令参数,JSON 数组格式,如 ["-y", "@anthropic/mcp-filesystem"]
env_jsonTEXTNULL环境变量,JSON 对象格式,支持 ${VAR} 引用系统环境变量
cwdVARCHAR(512)NULL工作目录(stdio 类型使用)
enabledBOOLEANTRUE是否启用
connect_timeout_secondsINT30连接建立超时(秒),用于 HTTP 传输类型
read_timeout_secondsINT30请求响应超时(秒),控制 initialize/listTools/callTool 的超时
last_statusVARCHAR(32)disconnected最后连接状态:connected / disconnected / error
last_errorTEXTNULL最后错误信息
last_connected_timeDATETIMENULL最后成功连接时间
tool_countINT0发现的工具数量
builtinBOOLEANFALSE是否系统内置(内置服务器不允许删除)
create_timeDATETIME-创建时间
update_timeDATETIME-更新时间
deletedINT0逻辑删除标记

敏感信息脱敏

通过 API 返回 MCP 服务器列表时,headers_jsonenv_json 字段中的值会被自动脱敏(保留前几位和后四位,中间用 * 替代)。args_json 因不涉及敏感信息而保持原样。

环境变量引用

env_jsonheaders_json 中的值支持引用系统环境变量:

  • ${VAR_NAME} -- 精确匹配并替换
  • $VAR_NAME -- 正则匹配(确保不误替换前缀相同的变量)

例如 {"TAVILY_API_KEY": "${TAVILY_API_KEY}"} 会在运行时替换为 MateClaw 进程环境中对应的值。这样可以避免在数据库中存储明文密钥。

故障排查

命令找不到(stdio 类型)

现象:连接失败,错误信息包含 "command not found" 或 "No such file or directory"。

排查步骤

  1. 确认 command 字段指定的命令在 MateClaw 运行用户的 PATH 中可用
  2. 在服务器终端手动执行该命令确认可用:which npxnpx --version
  3. 如果使用 Docker 部署,确认命令已安装在容器内
  4. 可以使用完整路径替代命令名,如 /usr/local/bin/npx

连接超时

现象:连接失败,错误信息包含 "timeout" 或 "timed out"。

排查步骤

  1. 对于 HTTP/SSE 类型,确认 URL 可达:curl -v <url>
  2. 检查防火墙规则是否允许出站连接
  3. 适当增大 connectTimeoutSecondsreadTimeoutSeconds
  4. 对于 stdio 类型,首次执行 npx -y 可能需要下载包,耗时较长,建议增大超时或预先安装

SSL/TLS 错误

现象:连接 HTTPS 端点时失败,错误信息包含 "SSL" 或 "certificate"。

排查步骤

  1. 确认远端 MCP 服务器的 SSL 证书有效且未过期
  2. 如果使用自签名证书,需要将 CA 证书添加到 JVM 信任库
  3. 确认 MateClaw 运行环境的 JDK 版本支持对应的 TLS 版本

工具未显示

现象:MCP 服务器状态为 connected,但在 Agent 工具列表中看不到对应工具。

排查步骤

  1. 检查 tool_count 字段是否大于 0
  2. 使用测试连接功能,确认 discoveredTools 列表不为空
  3. 确认 MCP 服务器正确实现了 tools/list 接口
  4. 查看 MateClaw 后端日志中的 McpToolCallbackProvider 相关输出

工具调用失败

现象:Agent 调用 MCP 工具时返回错误。

排查步骤

  1. 查看 MateClaw 后端日志中的具体错误信息
  2. 确认 MCP 服务器进程仍在运行(stdio 类型)
  3. 确认远端 MCP 服务器可用(HTTP/SSE 类型)
  4. 检查 readTimeoutSeconds 是否足够(某些工具执行时间较长)
  5. 尝试刷新连接:POST /api/v1/mcp/servers/refresh

子进程残留(stdio 类型)

现象:停止 MateClaw 后,MCP 子进程仍在运行。

排查步骤

  1. 正常情况下 @PreDestroy 钩子会清理所有子进程
  2. 如果 MateClaw 被强制终止(kill -9),子进程可能残留,需手动清理
  3. 使用 ps aux | grep mcp 查找并终止残留进程

下一步