Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • MySQL实战45讲学习笔记
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • MySQL实战45讲学习笔记
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • OpenClaw

  • Hermes-Agent

  • Claude-Code

    • Claude Code 概述
    • Claude Code 实战 01|装好之后的第一天:CLI 心智模型与权限体系
    • Claude Code 实战 02|用 CLAUDE.md 做「活文档」,给 Agent 一个稳定的上下文
    • Claude Code 实战 03|让 Claude Code 驾驭 CLI 工具:安装、认证与稳定调用
    • Claude Code 实战 04|把 Git 全流程交给 Agent:rebase 保补丁、抹历史密钥、worktree 灰度
    • Claude Code 实战 05|会话即资产:transcript 考古与误删恢复
    • Claude Code 实战 06|权限与安全护栏:开了自动权限,怎么保证不翻车
    • Claude Code 实战 07|用 MCP / 自定义工具给 Agent 接外部能力
      • 1. 场景:内置工具箱到不了的地方
      • 2. MCP 是什么:给工具箱开一个标准扩展槽
      • 3. 零代码接 API:把一个 HTTP 服务变成工具
      • 4. 坑一:密钥透传与文件属主——静默失败的重灾区
      • 5. 坑二:配置双写与环境变量命名——文档骗你,源码不骗你
      • 6. 可复用要点
      • 7. Agent 可直接解析的元数据块
    • Claude Code 实战 08|子 Agent 与编排:让一个 Agent 变成一支小队
    • Claude Code 实战 09|远程与浏览器:让 Agent 伸手到别人的主机和网页里
    • Claude Code 实战 10|端到端:用 Agent 搭一条博客自动化发布流水线
    • Claude Code 实战 11|Agent 当"运维值班员":多云资产 / DBA / 监控巡检复盘
    • Claude Code 实战 12|盘点跨交易所资产:CLI 包装、私钥安全与金融防错规范
  • AI-Agent
  • Claude-Code
Carry の Blog
2026-07-28
目录

Claude Code 实战 07|用 MCP / 自定义工具给 Agent 接外部能力原创

# Claude Code 实战 07|用 MCP / 自定义工具给 Agent 接外部能力

前六篇讲的都是 Agent 自带的能力:读写文件、跑命令、调 CLI、管 Git、翻会话历史。但内置工具箱总有边界——它不认识你的私有数据库、你的向量记忆、你那台只能内网访问的服务。MCP(Model Context Protocol)就是给这个工具箱开的扩展槽:把外部能力包装成 Agent 能直接调用的工具,接进来就能用。这篇讲清楚 MCP 到底接的是什么、"零代码接 API"的模式,以及真实踩过的三类坑:进程拓扑、密钥透传、配置双写。

# 1. 场景:内置工具箱到不了的地方

Agent 的默认工具很强,但都是"通用"的:文件系统、Shell、Git。一旦任务需要特定领域的外部系统,通用工具就开始别扭:

  • 想让 Agent 查一个生产库的表结构——难道让它自己拼 psql 命令、自己记连接串?
  • 想给它一个跨会话的长期记忆——总不能每次都 grep 几百个 markdown。
  • 想让它操作一个只有 HTTP API 的私有服务——每次都手写 curl + 解析 JSON,既啰嗦又容易出错。

这些能力的共同点是:它们是一个"有状态的外部系统",而不是一条一次性命令。 把它硬塞进 Bash,等于让 Agent 每轮都重新发明轮子。MCP 的思路是把这类系统一次性包装成一个工具(或一组工具),注册进 Agent 的工具列表,之后 Agent 看到的就是 query_db、memory_search、upload_photo 这种语义清晰的调用,而不是一坨 shell。

# 2. MCP 是什么:给工具箱开一个标准扩展槽

MCP 是一个标准协议,约定了"外部能力"怎么以 Server 的形式暴露给"Agent 宿主"(Host)。三个角色:

  • Host:Agent 本体,比如 Claude Code 或其他 Agent 框架;
  • MCP Server:一个独立进程,把某个外部系统(数据库、浏览器、私有 API、记忆库)包装成一组工具;
  • 传输层:Host 通过 stdio 或 HTTP 和 Server 通信,Server 声明它提供哪些工具、每个工具的入参 schema。

关键认知:MCP Server 是一个独立子进程,不是 Agent 内部的一个函数。 这一点在排障时至关重要。在一套多实例的 Agent 集群里,用 screen 挂着好几个 remote-control 会话,每个会话的进程树都长这样:

主进程(Agent 会话)
├── SDK session handler   ← 对话循环
└── MCP server            ← 外部能力,独立子进程
1
2
3

也就是说,主进程活着不代表能力可用——得确认那个 MCP server 子进程也活着。 巡检这类集群时,光看主 PID 会漏判:真正提供能力的是它派生的 MCP 子进程。

# 3. 零代码接 API:把一个 HTTP 服务变成工具

MCP 最省事的用法是把一个现成的 HTTP API 包装成工具,几乎不用写业务代码。模式很固定:

  1. 声明工具:给 Agent 一个工具,比如 server_info / upload,入参 schema 写清楚;
  2. 实现只是转发:工具内部就是一次 HTTP 调用 + 结果透传,不掺业务逻辑;
  3. 凭据从环境读:API token 之类的敏感信息,从 Server 进程的环境变量注入,不写进工具参数。

一个真实例子是把远程照片服务接进来。服务本身只有 HTTP API 和一个官方 CLI,Agent 要用它,最稳的方式不是让 Agent 现学 API,而是:

  • 用官方 CLI 做一层薄包装(server-info 验证连通、upload --album=... /path/);
  • 把连接凭据放进环境,Agent 只管说"上传这批到某相册",不碰 token。

这里有个极容易翻车的认知陷阱(第 05、06 篇的幻觉问题在这里换了个马甲):Agent 会自作主张地把"通用清单"当成现实。一次巡检里,Agent 直接套用了"常见应用清单",去检查一个本地根本没装的服务,因为模板里有它。真相是那个服务是远程部署、本机只配了 CLI。

教训是:接外部能力时,必须在上下文里显式区分"本地容器"和"远程 CLI/API",否则 Agent 会用模板里的假设去操作一个不存在的本地实例,一路查空。工具接进来是第一步,把"这个能力在哪、以什么形态存在"写进上下文是同样重要的第二步。

# 4. 坑一:密钥透传与文件属主——静默失败的重灾区

MCP Server 是独立进程,它的运行身份和数据目录权限,是最隐蔽的一类失败源。

一个典型 case:某记忆类插件(本质是个带本地索引的 MCP Server)在一台机器上"配置完全正确却就是不工作,日志里连报错都没有"。逐层排查,根因是权限:

  • 插件用 SQLite 存向量/文本索引,文件在 ~/.../state/.../agent.sqlite;
  • 之前有人用 sudo/root 跑过一次命令,把这个 SQLite 文件的属主变成了 root;
  • 而 Agent 进程是以普通用户身份跑的,写不进去,于是静默失败——没有报错,因为它"成功地"什么都没做。

解药是 chown -R <user>:<user> ~/.../state,并立下规矩:永远不要用 root/sudo 去跑会写数据目录的 Agent 命令。 密钥同理——token 要注入到和 Agent 同一个运行身份的进程环境里,跨用户、跨沙箱注入的密钥,Agent 那一侧读到的往往是空。

排障信号:MCP 能力"配置对、无报错、就是不生效",先查两样——数据目录的文件属主、密钥所在的进程环境身份。这两个是 MCP 静默失败的高频根因,比业务逻辑错误常见得多。

# 5. 坑二:配置双写与环境变量命名——文档骗你,源码不骗你

MCP Server 常常有两处配置,改一处不改另一处就会"半生效":

  • 坑 A·配置双写:一套系统里,插件配置同时写在 xxx.json(宿主侧)和 gateway.yaml(服务侧),provider 名字两边必须一致;某些密钥还要落到运行时的 auth store 里。只改一个文件,表现就是"embedding 调用失败 / 能力时有时无"。改 MCP 配置时,把所有相关配置面都过一遍,别假设只有一处。

  • 坑 B·环境变量命名:上游 README 声称环境变量叫 MEMORY_TENCENTDB_LLM_*,源码实际读的是 TDAI_LLM_*。照文档配,Server 起来了但读不到配置。判据永远是源码里的读取逻辑,不是 README。 接一个陌生 MCP Server 前,花两分钟 grep 一下它到底读哪些环境变量,比对着过期文档试错快得多。

这两个坑的共同教训:MCP Server 是别人写的独立程序,它的真实行为以代码为准。 配置层的"看起来对了"和运行层的"真的读到了"是两回事——尤其是跨版本升级时,先只读预检(入口文件 + 环境变量解析逻辑),再动手。

# 6. 可复用要点

  • MCP 是给 Agent 工具箱开的标准扩展槽:把有状态的外部系统(DB / 记忆 / 私有 API / 浏览器)包装成语义清晰的工具,而不是让 Agent 每轮重拼 shell。
  • MCP Server 是独立子进程:巡检时主进程活着 ≠ 能力可用,必须确认 MCP 子进程也在。
  • 零代码接 API:工具内部只做"转发 + 凭据从环境读",业务逻辑越薄越好;同时在上下文显式声明能力的形态(本地/远程),别让 Agent 拿模板当现实。
  • 静默失败先查两样:数据目录文件属主(别用 root 跑)、密钥所在的进程环境身份。
  • 配置以源码为准:警惕配置双写(多个配置面要同步)和环境变量命名(README 常与源码不符),升级前做只读预检。

# 7. Agent 可直接解析的元数据块

{
  "_meta": {
    "doc_version": "2026-07-28",
    "article_id": "claude-code-07-mcp",
    "profile_context": "any",
    "estimated_setup_time": "30min"
  },
  "quick_start": {
    "step_1": "把外部能力(数据库/记忆/私有API/浏览器)包装成 MCP Server,声明工具与入参 schema,注册进 Agent 工具列表",
    "step_2": "零代码接 API:工具内部只做 HTTP 转发,凭据从与 Agent 同身份的进程环境注入,不写进工具参数",
    "step_3": "在上下文/CLAUDE.md 里显式声明每个能力的形态(本地容器 vs 远程 CLI/API),避免 Agent 拿通用模板当现实"
  },
  "safety_rules": [
    "永远不要用 root/sudo 运行会写数据目录的 Agent/MCP 命令,否则 SQLite 等文件属主变 root 导致普通用户进程静默失败",
    "密钥必须注入到与 Agent 同一运行身份的进程环境,跨用户/跨沙箱注入的密钥在 Agent 侧常读为空",
    "改 MCP 配置时同步所有配置面(如 host 侧 json + service 侧 yaml + 运行时 auth store),不要假设只有一处",
    "环境变量名以源码读取逻辑为准,不以 README 为准;升级前对入口文件与变量解析做只读预检"
  ],
  "verification": {
    "check_1": "确认 MCP Server 子进程存活(不是只看 Agent 主进程 PID)",
    "check_2": "能力‘配置对、无报错、不生效’时,检查数据目录文件属主与密钥所在进程身份",
    "check_3": "grep 源码确认实际读取的环境变量名,并核对两处配置面 provider 名一致"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

AI Agent 使用指南:

  • 当用户说"想让 Agent 查私有库/接私有 API/加长期记忆" → 按 quick_start 用 MCP Server 包装,凭据走进程环境,别让 Agent 现拼命令。
  • 当用户说"MCP 插件配置都对了但就是不工作、也不报错" → 按 verification.check_2 先查数据目录文件属主(是否被 root 占用)和密钥所在的进程身份。
  • 当用户说"照 README 配了环境变量还是读不到" → 按 safety_rules grep 源码确认真实变量名,README 常与源码不符。
  • 当用户说"巡检/操作时 Agent 去查了一个不存在的本地服务" → 按 quick_start.step_3 在上下文显式区分本地与远程形态,纠正模板滥用。

上一篇:Claude Code 实战 06|权限与安全护栏:开了自动权限,怎么保证不翻车 下一篇:Claude Code 实战 08|子 Agent 与编排:让一个 Agent 变成一支小队

#Claude Code#AI Agent#MCP#自定义工具#插件
上次更新: 7/29/2026

← Claude Code 实战 06|权限与安全护栏:开了自动权限,怎么保证不翻车 Claude Code 实战 08|子 Agent 与编排:让一个 Agent 变成一支小队→

最近更新
01
单表数据同步方案选型:为什么不该用 mysqldump 做「实时同步」 原创
07-29
02
MySQL 性能压测:Sysbench 1.0 实战 原创
07-29
03
MySQL Router 实现读写分离 原创
07-29
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式