Skip to content

Chapter 7: MCP — 让 Claude 连接万物 ​

附录链接:A06 MCP 协议深入解析 涵盖了线协议、能力协商、传输层以及构建生产级 MCP 服务器的方法。

你将构建什么 ​

三个真实的 MCP 集成,让 Claude 突破文件系统的限制:

  1. GitHub MCP — 分析你自己的仓库、分流 issue、审查 PR,全程不离开 Claude
  2. Context7 MCP — 查询任何库的实时文档,始终最新,永不过时
  3. Playwright MCP — 自动化浏览器测试、截图、验证已部署的应用是否正常

这些是 Everything Claude Code 的 .mcp.json 配置中实际使用的 MCP 服务器。不是理论性的 -- 这就是生产团队将 Claude 接入工具链的方式。

MCP 工作原理 ​

MCP(Model Context Protocol,模型上下文协议)是 Claude 与外部工具之间的标准化接口。把它想象成 AI 的 USB 接口 -- 任何实现 MCP 协议的工具都能插入 Claude 成为原生工具。

Claude Code
  |
  |-- 内置: Read, Write, Edit, Bash, Glob, Grep
  |
  +-- MCP 层
       |-- GitHub Server     --> PR、issue、分支、代码搜索
       |-- Context7 Server   --> 任何库的实时文档
       |-- Playwright Server --> 浏览器自动化、截图
       |-- Exa Server        --> 带引用的网络搜索
       |-- Memory Server     --> 跨会话知识图谱
       |-- 你的自定义服务器   --> 任何你需要的能力

为什么用 MCP 而不是 Bash? ​

没有 MCP,Claude 仍然可以通过 Bash 调用 gh issue list。MCP 更好因为:

  • 类型安全:MCP 工具有 JSON Schema 定义。Claude 精确知道哪些参数有效。
  • 进程隔离:每个 MCP 服务器运行在独立进程中。有问题的工具不会让 Claude 崩溃。
  • 语义理解:Claude 对 mcp__github__list_issues 的理解深度远超解析 gh CLI 输出。
  • 权限控制:你可以允许 GitHub MCP 工具,同时拦截原始的 gh 命令。

工具命名 ​

所有 MCP 工具遵循 mcp__<server>__<tool> 模式:

mcp__github__list_issues       -- GitHub 服务器的 list_issues 工具
mcp__context7__query-docs      -- Context7 服务器的 query-docs 工具
mcp__playwright__navigate      -- Playwright 服务器的 navigate 工具

这种命名使它们很容易在 hook 中作为目标:

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "mcp__github__.*",
      "hooks": [{ "type": "command", "command": "echo 'GitHub API call'" }]
    }]
  }
}

配置方式 ​

两种添加 MCP 服务器的方式:

CLI(推荐):

bash
claude mcp add github -e GITHUB_PERSONAL_ACCESS_TOKEN -- npx -y @modelcontextprotocol/server-github

手动 .mcp.json:

json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx"
      }
    }
  }
}

作用域 ​

作用域文件适合
user~/.claude/.mcp.json到处使用的工具(GitHub、Memory)
project项目根目录 .mcp.json项目特定工具(提交到 Git)

安全规则:不要硬编码 token。使用环境变量:

bash
# 在 .bashrc 或 .zshrc 中
export GITHUB_PERSONAL_ACCESS_TOKEN=ghp_xxx

# 然后引用它
claude mcp add github -e GITHUB_PERSONAL_ACCESS_TOKEN -- npx -y @modelcontextprotocol/server-github

ECC 的 .mcp.json 参考 ​

这是生产环境的 .mcp.json 配置(基于 ECC):

json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "" }
    },
    "context7": {
      "command": "npx",
      "args": ["-y", "@anthropic-ai/context7-mcp"]
    },
    "playwright": {
      "command": "npx",
      "args": ["-y", "@anthropic-ai/claude-code-playwright"]
    },
    "memory": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-memory"]
    },
    "exa": {
      "command": "npx",
      "args": ["-y", "exa-mcp-server"],
      "env": { "EXA_API_KEY": "" }
    }
  }
}

不需要全部配置。从 GitHub 和 Context7 开始 -- 它们覆盖 80% 的真实使用场景。


Demo 18: GitHub MCP — 在 Claude 中管理你的仓库 ​

18
GitHub MCP Integration
Intermediate~15 min

问题 ​

你在一个项目上工作,需要查看 open issue、找过期的 PR、或审查多个仓库的最近变更。现在意味着切到浏览器、在 GitHub 上点来点去、丢失上下文。有了 GitHub MCP,Claude 内联完成所有操作。

配置 ​

1. 创建 GitHub Token ​

前往 github.com/settings/tokens?type=beta 创建 fine-grained token:

  • Repository access: 选择你的仓库(或全部)
  • Permissions: Issues (R/W), Pull Requests (R/W), Contents (R/W)

保存:

bash
# 添加到 shell 配置文件
echo 'export GITHUB_PERSONAL_ACCESS_TOKEN=ghp_your_token_here' >> ~/.bashrc
source ~/.bashrc

2. 添加服务器 ​

bash
claude mcp add github -e GITHUB_PERSONAL_ACCESS_TOKEN -- npx -y @modelcontextprotocol/server-github

验证:

bash
claude mcp list
# 预期: github: npx -y @modelcontextprotocol/server-github (stdio)

3. 在你的真实仓库上使用 ​

bash
mkdir -p ~/claude-demos/demo-18 && cd ~/claude-demos/demo-18
git init
claude

用你 真实的 仓库来体验真正的价值:

分流 open issue:

List all open issues in <your-username>/<your-repo>, sorted by most recent.
For each one, summarize the problem in one sentence.
terminal
> List all open issues in myuser/web-app, sorted by most recent.
  For each one, summarize the problem in one sentence.

  ● mcp__github__list_issues
    owner: "myuser"
    repo: "web-app"
    state: "open"
    sort: "created"
    direction: "desc"

  Allow? [y/n/a]: y

  ✔ 4 open issues found:

  #23 (May 25) — Dashboard chart fails to render when date range
       spans a DST transition
  #21 (May 22) — Login page shows blank screen on Safari 17.4
  #18 (May 15) — CSV export truncates rows after 10,000 entries
  #12 (Apr 30) — Dark mode toggle does not persist across sessions

找过期 PR:

Find all open PRs in <your-username>/<your-repo> that haven't been updated
in the last 14 days. List them with the author and last activity date.

审查特定 PR:

Get the files changed in PR #42 of <your-username>/<your-repo>.
Summarize what the PR does and flag any concerns.

从发现创建 issue:

I found a SQL injection vulnerability in src/api/users.js:10. Create a
GitHub issue for it with appropriate labels, referencing the exact code location.

刚才发生了什么? ​

1
mcp__github__list_issues
myuser/web-app
↓
2
Claude formatting
Issue list

要点:

  • MCP 服务器使用你的环境变量自动处理认证
  • Claude 收到的是结构化 JSON,不是原始 CLI 输出,解析更可靠
  • 你像审批任何内置工具(Read、Bash 等)一样审批工具调用
  • MCP 服务器作为子进程运行 -- Claude 启动时启动,退出时停止

底层运行机制 ​

你说:"列出 myuser/myrepo 的 open issue"
  |
  v
Claude 选择: mcp__github__list_issues
  |
  v
Claude Code ---(stdio)---> GitHub MCP Server ---(HTTPS)---> GitHub API
  |
  v
GitHub 返回 issue 的 JSON 数组
  |
  v
Claude 格式化并呈现结果

MCP 服务器作为 Claude Code 的子进程运行。会话开始时自动启动,退出时停止。

真实使用模式 ​

晨会上下文:配合 SessionStart hook 自动展示分配给你的 issue 和待审查的 PR。

Issue 驱动开发:让 Claude 读取一个 issue,实现修复,然后创建关联 issue 的 PR -- 全程不离开终端。

跨仓库搜索:使用 mcp__github__search_code 在多个仓库中搜索代码模式。


Demo 19: Context7 MCP — 始终最新的文档 ​

19
Context7 MCP for Live Docs
Intermediate~10 min

问题 ​

你在使用一个库,需要查看某个函数的 API。Claude 的训练数据可能已经过时几个月。文档可能已经变了。你可以开浏览器搜索,或者让 Claude 实时查询。

Context7 是一个文档服务器,为数千个库提供实时文档。它列在 ECC 推荐的 MCP 配置中。

配置 ​

bash
claude mcp add context7 -- npx -y @anthropic-ai/context7-mcp

验证:

bash
claude mcp list
# 应显示: context7: npx -y @anthropic-ai/context7-mcp (stdio)

使用 ​

bash
cd ~/claude-demos/demo-18
claude

查询当前 API 文档:

I'm using Drizzle ORM with PostgreSQL. Look up the current documentation for
defining a schema with relations. Show me the exact API for one-to-many relationships.
terminal
> Look up the current Drizzle ORM docs for one-to-many relationships.

  ● mcp__context7__resolve-library-id
    libraryName: "drizzle-orm"
    → Resolved: /drizzle-team/drizzle-orm (confidence: 0.97)

  ● mcp__context7__query-docs
    libraryId: "/drizzle-team/drizzle-orm"
    query: "one-to-many relations schema definition"

  ✔ Documentation retrieved (2,847 tokens):

  ## Relations in Drizzle ORM

  To define a one-to-many relation, use the `relations()` helper:

  ```typescript
  import { relations } from 'drizzle-orm';
  import { pgTable, serial, text, integer } from 'drizzle-orm/pg-core';

  export const users = pgTable('users', {
    id: serial('id').primaryKey(),
    name: text('name'),
  });

  export const posts = pgTable('posts', {
    id: serial('id').primaryKey(),
    authorId: integer('author_id').references(() => users.id),
    title: text('title'),
  });

  export const usersRelations = relations(users, ({ many }) => ({
    posts: many(posts),
  }));
  ...

Claude 调用 mcp__context7__resolve-library-id 找到 Drizzle 文档,然后调用 mcp__context7__query-docs 获取相关章节。

检查破坏性变更:

Look up the Tailwind CSS v4 docs. What changed in the configuration format
compared to v3? I need to know if my tailwind.config.js needs updating.

获取正在使用的函数的最新 API:

Look up the current Next.js docs for the App Router's generateMetadata function.
I need the TypeScript types and all available fields.

刚才发生了什么? ​

1
mcp__context7__resolve-library-id
drizzle-orm
↓
2
mcp__context7__query-docs
/drizzle-team/drizzle-orm

要点:

  • 两步解析流程:先找到库,再查询文档
  • 返回的文档是实时且最新的,不是来自 Claude 的训练数据
  • Context7 返回聚焦的章节,不是整个文档站,节省上下文 token

为什么这比训练数据好 ​

Claude 的训练数据有截止日期。库持续发新版本。Context7 获取 当前 文档,所以你得到:

  • 准确的 API 签名(不是过时的)
  • 当前的配置格式
  • 最新的迁移指南
  • 最近新增的功能

进阶技巧:配合 /review 使用 ​

在你的 /review skill 指令中加入:

markdown
When reviewing code that uses third-party libraries, use Context7 to verify
that the API usage is current and follows recommended patterns.

这样你的代码审查就能自动发现过时的 API 用法。


Demo 20: Playwright MCP — 浏览器自动化 ​

20
Playwright MCP for Browser Testing
Intermediate~15 min

问题 ​

你部署了应用。它真的在工作吗?登录流程能走通吗?有没有控制台错误?你可以手动开浏览器点一遍,或者让 Claude 做并带截图回来。

配置 ​

bash
# 安装 MCP 服务器
claude mcp add playwright -- npx -y @anthropic-ai/claude-code-playwright

# 安装浏览器引擎(仅首次需要)
npx playwright install chromium

构建测试页面 ​

bash
mkdir -p ~/claude-demos/demo-20 && cd ~/claude-demos/demo-20

cat > index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
  <title>Task Manager</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: system-ui, sans-serif; max-width: 600px; margin: 40px auto; padding: 0 20px; }
    h1 { margin-bottom: 20px; }
    .add-form { display: flex; gap: 8px; margin-bottom: 20px; }
    .add-form input { flex: 1; padding: 8px 12px; border: 1px solid #ddd; border-radius: 6px; }
    .add-form button { padding: 8px 16px; background: #2563eb; color: white; border: none; border-radius: 6px; cursor: pointer; }
    .task { display: flex; align-items: center; gap: 8px; padding: 12px; border-bottom: 1px solid #eee; }
    .task.done span { text-decoration: line-through; color: #999; }
    .task input[type=checkbox] { width: 18px; height: 18px; }
    .task span { flex: 1; }
    .task button { background: none; border: none; color: #ef4444; cursor: pointer; font-size: 18px; }
    #count { color: #666; margin-top: 12px; }
    #error { color: #ef4444; margin-top: 8px; display: none; }
  </style>
</head>
<body>
  <h1>Task Manager</h1>
  <div class="add-form">
    <input type="text" id="taskInput" placeholder="Add a task..." />
    <button onclick="addTask()">Add</button>
  </div>
  <div id="tasks"></div>
  <div id="count"></div>
  <div id="error"></div>

  <script>
    let tasks = [];
    function addTask() {
      const input = document.getElementById('taskInput');
      const text = input.value.trim();
      if (!text) {
        document.getElementById('error').style.display = 'block';
        document.getElementById('error').textContent = 'Task cannot be empty';
        return;
      }
      document.getElementById('error').style.display = 'none';
      tasks.push({ text, done: false });
      input.value = '';
      render();
    }
    function toggleTask(i) { tasks[i].done = !tasks[i].done; render(); }
    function deleteTask(i) { tasks.splice(i, 1); render(); }
    function render() {
      const container = document.getElementById('tasks');
      container.innerHTML = tasks.map((t, i) =>
        `<div class="task ${t.done ? 'done' : ''}">
          <input type="checkbox" ${t.done ? 'checked' : ''} onchange="toggleTask(${i})" />
          <span>${t.text}</span>
          <button onclick="deleteTask(${i})">x</button>
        </div>`
      ).join('');
      const remaining = tasks.filter(t => !t.done).length;
      document.getElementById('count').textContent = `${remaining} task${remaining !== 1 ? 's' : ''} remaining`;
    }
    document.getElementById('taskInput').addEventListener('keypress', e => { if (e.key === 'Enter') addTask(); });
    render();
  </script>
</body>
</html>
EOF

启动服务器:

bash
python -m http.server 8765 &

使用 ​

bash
claude

视觉冒烟测试:

Navigate to http://localhost:8765/ and take a screenshot. Tell me if the page
renders correctly and what UI elements you see.
terminal
> Navigate to http://localhost:8765/ and take a screenshot.

  ● mcp__playwright__navigate
    url: "http://localhost:8765/"
    → Page loaded (200 OK, 1.2s)

  ● mcp__playwright__screenshot
    → Screenshot captured (1280x720)

  The page renders correctly. I can see:
  - A heading: "Task Manager"
  - An input field with placeholder "Add a task..."
  - An "Add" button (blue, rounded)
  - A counter showing "0 tasks remaining"
  - No console errors detected

功能测试:

On http://localhost:8765/, test the full task workflow:
1. Add a task called "Deploy to staging"
2. Add a task called "Write unit tests"
3. Check off "Deploy to staging"
4. Take a screenshot showing the current state
5. Tell me if the remaining count is correct
terminal
> Test the full task workflow...

  ● mcp__playwright__fill
    selector: "#taskInput"
    value: "Deploy to staging"

  ● mcp__playwright__click
    selector: ".add-form button"
    → Task added

  ● mcp__playwright__fill
    selector: "#taskInput"
    value: "Write unit tests"

  ● mcp__playwright__click
    selector: ".add-form button"
    → Task added

  ● mcp__playwright__click
    selector: ".task:first-child input[type=checkbox]"
    → Checkbox toggled

  ● mcp__playwright__screenshot
    → Screenshot captured (1280x720)

  ✔ Results:
  - "Deploy to staging" shows with strikethrough (checked off)
  - "Write unit tests" is unchecked
  - Counter reads "1 task remaining" — correct
  - All UI interactions worked as expected

错误处理测试:

Try to add an empty task (click Add without typing anything).
Take a screenshot — does it show an error message?

完整 QA 报告:

Give me a QA report for http://localhost:8765/ covering:
- Does the page load correctly?
- Can you add tasks?
- Does checking/unchecking work?
- Does the counter update?
- Does error handling work for empty input?
Include screenshots for each test.

刚才发生了什么? ​

1
mcp__playwright__navigate
http://localhost:8765/
↓
2
mcp__playwright__fill
#taskInput
↓
3
mcp__playwright__click
.add-form button
↓
4
mcp__playwright__screenshot
Full page

要点:

  • Claude 控制的是真实浏览器,不是模拟 -- 这些是实际的 DOM 交互
  • 截图给 Claude 提供视觉确认,不只是 DOM 状态
  • 每个 Playwright 操作在交互前等待元素就绪
  • 完整的工作流(导航、填充、点击、截图)和 QA 工程师手动操作如出一辙

清理 ​

bash
kill %1 2>/dev/null  # 停止 HTTP 服务器

真实应用场景 ​

  • 部署后验证:git push 后让 Claude 检查 staging URL 是否正常
  • 视觉回归:CSS 修改前后截图对比,让 Claude 比较差异
  • E2E 冒烟测试:在已部署的应用上跑完整用户流程(登录、创建、验证)
  • 竞品分析:访问竞品页面并记录 UX 模式

ECC 的 /e2e-testing skill 使用 Playwright MCP 配合 Page Object Model 模式进行结构化、可重复的浏览器测试。


常见问题排查 ​

MCP 服务器崩溃 ​

服务器进程在会话中意外退出:

terminal
> List open issues in myuser/web-app

  ● mcp__github__list_issues
    ⚠ Error: MCP server 'github' is not connected.
    The server process exited with code 1.

诊断和修复:

bash
# 1. 检查服务器是否能正常启动
npx -y @modelcontextprotocol/server-github 2>&1
# 如果看到 "Error: GITHUB_PERSONAL_ACCESS_TOKEN is not set",说明环境变量缺失

# 2. 验证环境变量已导出
echo $GITHUB_PERSONAL_ACCESS_TOKEN
# 应该打印你的 token。如果为空,重新导出:
export GITHUB_PERSONAL_ACCESS_TOKEN=ghp_your_token_here

# 3. 重启 Claude 以重新连接所有 MCP 服务器
# 用 Ctrl+C 退出,然后:
claude

MCP 服务器在你启动新的 Claude 会话时自动重启。如果在会话中崩溃,退出并重新进入即可。

Token 过期或已撤销 ​

GitHub 通过 MCP 服务器返回 401 错误:

terminal
> Create an issue in myuser/web-app

  ● mcp__github__create_issue
    ⚠ Error: GitHub API returned 401 Unauthorized
    {"message":"Bad credentials","documentation_url":"https://docs.github.com/rest"}

修复:

  1. 前往 github.com/settings/tokens
  2. 检查 token 是否过期或已撤销
  3. 生成新 token 并赋予所需权限
  4. 更新 shell 配置并重新导出:
    bash
    export GITHUB_PERSONAL_ACCESS_TOKEN=ghp_new_token_here
  5. 重启 Claude(MCP 服务器在启动时读取环境变量)

服务器超时 ​

慢网络或过载的 API 导致 MCP 调用挂起:

terminal
> Look up the Drizzle ORM docs for relations

  ● mcp__context7__resolve-library-id
    libraryName: "drizzle-orm"
    ... (waiting)
    ⚠ Error: MCP call timed out after 30s

常见原因:

  • 企业代理或 VPN 阻止了 npx 子进程的出站连接
  • 上游 API(GitHub、Context7)正在经历停机
  • 受限网络环境中的 DNS 解析失败

修复:

bash
# 直接测试连通性
curl -s https://api.github.com/rate_limit | head -5

# 如果在代理后面,确保 npx 继承代理设置
export HTTPS_PROXY=http://your-proxy:8080

Context7 找不到某个库的文档 ​

不是所有库都被索引了。当 Context7 找不到文档时:

terminal
> Look up the docs for my-obscure-library

  ● mcp__context7__resolve-library-id
    libraryName: "my-obscure-library"
    → No matching library found (confidence: 0.0)

  I could not find documentation for "my-obscure-library" in Context7.
  This library may not be indexed yet. I can try alternative approaches:
  - Check the npm/PyPI registry for a README
  - Read the source code directly if it is installed locally
  - Search GitHub for the repository

变通方案: 当 Context7 没有文档时,Claude 会回退到训练数据或使用 Bash 查询包注册表。你也可以提交请求将该库添加到 Context7 的索引中。


构建自定义 MCP 服务器 ​

现成的服务器不够用时,自己构建。

TypeScript(使用官方 SDK) ​

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

const server = new McpServer({ name: "internal-api", version: "1.0.0" });

server.tool(
  "query_deployments",
  "Get deployment status for a service",
  {
    service: z.string().describe("Service name, e.g. auth-api, web-app"),
    environment: z.enum(["staging", "production"]).default("staging"),
  },
  async ({ service, environment }) => {
    const res = await fetch(
      `https://deploy.internal.co/api/status/${service}?env=${environment}`,
      { headers: { Authorization: `Bearer ${process.env.DEPLOY_TOKEN}` } }
    );
    const data = await res.json();
    return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);

注册:

bash
claude mcp add internal-api -e DEPLOY_TOKEN -- npx tsx internal-mcp.ts

Python(使用 FastMCP) ​

python
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("internal-api")

@mcp.tool()
def search_logs(service: str, query: str, hours: int = 1) -> str:
    """Search application logs by service and query string."""
    # Your log search logic here
    return f"Found 42 matches for '{query}' in {service} (last {hours}h)"

if __name__ == "__main__":
    mcp.run(transport="stdio")
bash
claude mcp add internal-api -- python internal_mcp.py

调试 MCP ​

遇到问题时:

bash
# 1. 检查服务器列表
claude mcp list

# 2. 手动启动服务器查看错误
npx -y @modelcontextprotocol/server-github 2>&1

# 3. 在 Claude 会话中检查可用工具
# 输入: /tools

# 4. 强制调用测试
# 问: "Call mcp__github__list_issues for owner/repo"

常见问题:

问题原因解决
工具没出现服务器未启动检查 npx 能否运行该包
"Permission denied"缺少 token检查环境变量已设置
超时网络慢/服务器慢检查连接,增加 timeout
"Server disconnected"进程崩溃检查 ~/.claude/logs/ 中的日志

练习:多 MCP 工作流 ​

配置 GitHub + Context7 MCP 服务器,然后运行以下工作流:

  1. 用 GitHub MCP 列出你仓库的 open issue
  2. 选一个涉及你使用的库的 issue
  3. 用 Context7 查询该库的当前文档
  4. 让 Claude 基于当前文档提出修复方案
  5. 用 GitHub MCP 创建分支和 PR

这是 ECC 团队每天使用的工作流 -- Claude 作为全链路开发伙伴,从 issue 分流到 PR 创建。

成功标准 ​

  • [ ] 两个 MCP 服务器已配置且响应正常
  • [ ] GitHub MCP 能列出 issue 并创建 PR
  • [ ] Context7 返回当前文档(非过时的训练数据)
  • [ ] Claude 结合两个来源产出真实修复方案
  • [ ] Token 存储在环境变量中,未硬编码

知识检测 ​

为什么 GitHub 操作优先使用 MCP 而不是通过 Bash 调用 gh CLI?
MCP 更快因为避免了启动 shell 进程
MCP 提供类型安全的 JSON Schema 定义、进程隔离和细粒度权限控制
MCP 支持离线使用而 gh CLI 需要网络
MCP 比 gh CLI 支持更多 GitHub 功能
你添加了一个 GitHub MCP 服务器,但输入 /tools 时工具没有出现。最可能的原因是什么?
.mcp.json 文件有语法错误
MCP 服务器进程启动失败,可能是缺少环境变量或 npx 执行失败
需要重启电脑才能让 MCP 变更生效
MCP 工具只在你发起第一次 API 调用后才出现
Context7 使用两步流程:resolve-library-id 然后 query-docs。为什么不合并为一次调用?
这是 MCP 协议的限制,工具只能做一件事
分离让 Claude 在查询前验证找到了正确的库,避免在错误文档上浪费 token
两步分别在不同服务器上运行以实现负载均衡
库 ID 仅用于缓存目的
MCP 服务器的 token(如 GITHUB_PERSONAL_ACCESS_TOKEN)应该存储在哪里?
直接写在 .mcp.json 文件中让服务器读取
在提交到仓库的 .env 文件中
在 shell 配置文件(~/.bashrc 或 ~/.zshrc)中作为导出的环境变量
在 CLAUDE.md 文件中让 Claude 知道 token

总结 ​

MCP 把 Claude 从代码编辑器变成了连接的开发平台。本章的三个服务器 -- GitHub、Context7、Playwright -- 覆盖了最常见的集成需求。

要点:

  • 从 GitHub 和 Context7 开始 -- 用最少的配置提供最大价值
  • 始终使用环境变量存储 token,不要硬编码
  • user 作用域给通用工具,project 作用域给团队共享配置
  • 自定义 MCP 服务器只需约 30 行 TypeScript 或 Python
  • MCP 工具可以被 hook -- 用 mcp__github__.* matcher 审计 API 调用

深入了解:参见 A06 MCP 协议深入解析 了解线协议细节、能力协商、传输选项(stdio vs SSE)以及构建带错误处理和重试逻辑的生产级 MCP 服务器的模式。

下一章:Chapter 8: Subagent 架构 -- 构建专门的 agent 用于架构分析、安全扫描和测试生成。

基于 MIT 许可发布