Skip to content

第 20 章 · MCP 客户端集成实战

本章目标:把写好的 MCP Server 接入真实客户端——掌握 Claude Desktop 的 mcpServers 配置、Claude Code 的 mcp add 命令、stdio 与远程服务器的配置差异,并能用 Python 写出程序化调用的客户端。

14.1 在 Claude Desktop 中配置本地服务器

Claude Desktop 通过一个 JSON 配置文件管理 MCP 服务器。打开 claude_desktop_config.json(菜单 File → Settings → Developer → Edit Config),添加 mcpServers 字段:

json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/yourname/Documents",
        "/Users/yourname/Desktop"
      ]
    }
  }
}

逐个字段解读:

字段含义注意点
键名 filesystem你给这个服务器起的显示名会出现在工具名前缀里
command启动服务器的可执行程序npxpythonuv 或编译好的二进制
args命令行参数数组上例限定了只允许访问两个目录
env注入子进程的环境变量放 API Key 等密钥(见 14.3)

保存后完全退出并重启 Claude Desktop(不是关窗口)。配置正确的话,输入框右下角会出现工具图标,点开能列出该服务器暴露的所有工具。

最小权限

上例中 args 里列出的目录就是 filesystem server 的全部可见范围。永远不要配置成整个用户根目录或 /——这是 MCP 安全的第一道闸门。

14.2 stdio 与远程服务器的配置差异

本地服务器走 stdio 传输:客户端把它作为子进程拉起,通过标准输入输出通信,所以需要 command + args。远程服务器走 Streamable HTTP:它已经在别处运行,只需要一个 URL。

json
{
  "mcpServers": {
    "local-notes": {
      "command": "python",
      "args": ["/path/to/server.py"]
    },
    "remote-docs": {
      "url": "https://mcp.example.com/mcp",
      "headers": {
        "Authorization": "Bearer <token>"
      }
    }
  }
}

选择建议:个人工具、访问本机文件用 stdio;团队共享能力(内部知识库查询、CI 状态等)部署成 HTTP 服务,一处维护多方使用。

14.3 环境变量与密钥传递

服务器经常需要 API Key。正确做法是写在配置的 env 字段里,由客户端注入子进程环境:

json
{
  "mcpServers": {
    "brave-search": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-brave-search"],
      "env": {
        "BRAVE_API_KEY": "你的密钥"
      }
    }
  }
}

官方文档特别提醒过一个 Windows 坑:如果日志报错中出现 ${APPDATA} 字样,说明服务器没有拿到展开后的路径变量,需要在 env 里手动补上展开值。

安全红线:

  1. 配置文件含明文密钥,不要提交到 Git 仓库
  2. 密钥只经环境变量进入服务器进程,不要写死在 server.py 源码里;
  3. 团队分发时提供 config.example.json 模板,真实配置各自本地填写。

14.4 在 Claude Code 中用命令行管理

Claude Code 把同样的配置做成了 CLI 命令,不用手动编辑 JSON:

bash
# 添加一个 stdio 本地服务器
claude mcp add notes -- python /path/to/server.py

# 添加带环境变量的服务器
claude mcp add brave-search -e BRAVE_API_KEY=sk-xxx -- npx -y @modelcontextprotocol/server-brave-search

# 添加远程 HTTP 服务器
claude mcp add --transport http docs https://mcp.example.com/mcp

# 查看 / 删除
claude mcp list
claude mcp remove notes

-- 之后的部分就是启动命令本身,语义与 JSON 配置一一对应。

14.5 工具不出现?排查清单

配置后客户端里看不到工具,按命中率从高到低排查:

bash
# ① 手工运行服务器命令,确认它能正常启动不报错
npx -y @modelcontextprotocol/server-filesystem ~/Documents

# ② 查看 Claude Desktop 的 MCP 日志(macOS)
tail -f ~/Library/Logs/Claude/mcp*.log
  • JSON 语法错误:多逗号、少引号是最常见原因,用任意 JSON 校验器过一遍;
  • 重启不彻底:Claude Desktop 必须从托盘完全退出再启动才会重读配置;
  • 依赖缺失npx 需要 Node.js;Python 服务器注意是否装在了正确的虚拟环境里;
  • 路径错误server.py 用相对路径时,工作目录取决于客户端,一律写绝对路径;
  • 服务器启动即崩溃:看 ② 的日志输出,通常是缺依赖或密钥未设置。

14.6 用 Python 编写程序化客户端

除了现成客户端,你也可以在自己的应用里直接调用 MCP 服务器。官方 SDK 同时是一个完整的 MCP 客户端库:

python
import asyncio

from mcp import Client


async def main() -> None:
    # URL 形式连接 Streamable HTTP 传输的服务器
    async with Client("http://localhost:8000/mcp") as client:
        # 列出服务器提供的所有工具
        tools = await client.list_tools()
        for t in tools:
            print("工具:", t.name, "-", t.description)

        # 调用第 13 章写的 add 工具
        result = await client.call_tool("add", {"a": 1, "b": 2})
        print(result.structured_content)  # {'result': 3}


asyncio.run(main())

先以 HTTP 方式启动上一章的服务器,再运行客户端:

bash
mcp run server.py --transport streamable-http   # 终端 1
python my_client.py                             # 终端 2

几个关键点:

  • async with Client(...) 负责完整生命周期——建立连接、initialize 握手、能力协商、退出清理都在这一步完成;
  • URL 连接的是 HTTP 传输;Client 同样支持把本地脚本作为 stdio 子进程拉起,参数形式与 Claude Desktop 配置一致;
  • 需要精细控制请求/通知收发等底层行为时,SDK 还提供 Low-Level 的会话 API(位于 mcp.client.session 模块),日常场景用上面的高层接口即可。

这就是把 MCP 能力嵌入自己产品的最小路径——你的应用此时就是一个 MCP Host。

本章小结

  • Claude Desktop 在 claude_desktop_config.jsonmcpServers 下配置服务器,改完必须彻底重启;
  • 本地服务器配 command+args(stdio),远程服务器配 url(Streamable HTTP);
  • 密钥放 env 字段,配置文件不入库;Windows 注意 ${APPDATA} 展开问题;
  • Claude Code 提供 claude mcp add/list/remove 命令化等效操作;
  • 排查顺序:手工起服务器 → 看 mcp 日志 → 查 JSON 语法 → 查依赖与绝对路径;
  • from mcp import Client 十几行代码即可让任何 Python 应用成为 MCP 宿主。

🛠️ 动手实践

  1. 把第 13 章的笔记服务器接入 Claude Desktop,验证工具列表出现,并故意删掉配置文件里的一个逗号观察报错现象。
  2. claude mcp add 把同一个服务器添加进 Claude Code,对比两种方式生成的最终配置结构是否一致。
  3. 扩展本章的 Python 客户端:列出工具后自动调用其中每一个的"无参调用"或跳过必填参数的工具,并打印每个工具的结构化返回。

完成练习后,进入,学习把服务器安全地跑在生产环境。

完成后进入下一章:MCP 安全与生产实践