使用 Claude Code 进行 Agentic 编码——通过 MCP 服务器与插件扩展 Claude Code

0 阅读47分钟

Model Context Protocol(MCP) 提供了一种标准化方式,让 AI 应用能够通过统一接口连接到工具、数据源和服务。开发者不再需要为每一个宿主应用单独构建一套集成逻辑,而是只需要在一个 MCP server 中实现一次功能,就可以在任何兼容 MCP 的客户端中复用。MCP 正是为了解决这一类集成难题而诞生的。这个抽象层带来了互操作性、可移植性以及生态系统增长。在 Claude Code 的语境下,MCP 尤其重要,因为它让开发者能够以结构化、可复用的方式,为这个编码智能体扩展更多工具、能力与集成。

在本章中,你将学习 MCP 是什么、它为什么会被创造出来,以及它在实践中是如何工作的。你会了解 MCP 所解决的集成问题,并考察它的核心架构组件:host、client 和 server。通过实际演示,你会把 MCP server 连接到 Claude 和 Cursor 这样的 AI 应用上,配置本地与远程 MCP server,并理解工具是如何通过这个协议暴露出来并被调用的。

你还会看到一些重要的运行层面考量。MCP 很强大,但它也会带来与上下文管理、性能和执行效率相关的挑战。本章会介绍一些上下文工程策略,用于减少上下文污染、正确限定 MCP 配置范围,并在一个会话中动态管理 server。此外,你还会学习 Claude Code plugin 如何把 MCP server 以及相关组件打包成可复用、可分享的单元,从而实现团队范围内的标准化。

本章的整体目标,是帮助你在 MCP 上建立一个扎实的概念基础与实践基础。到最后,你不仅会理解 MCP 如何实现跨平台工具集成,还会知道如何在真实 AI 系统中,以负责任的方式去配置和管理它。

这项知识之所以重要,是因为 MCP 正在迅速成为 agent-based architecture(基于智能体的架构)中的基础层。随着 AI 开发转向工具增强型系统与自主系统,理解 MCP 的架构、优势和取舍,将让你能够设计出可扩展、高效率、可互操作的 AI 应用。

本章将涵盖以下主题:

  • 为什么需要 MCP
  • MCP 核心架构
  • MCP 的实际运行方式
  • 将 Claude Code 连接到 MCP server
  • MCP scope 速查表
  • MCP 生态中的上下文工程
  • 项目级 MCP 配置
  • MCP 当前的局限
  • 使用 Claude Code plugin 管理配置

虽然本书以 Claude Code 为中心,但 MCP 是一个跨平台协议,已经被多个 AI 开发工具支持。为了演示方便,本章在某些例子中会使用 Cursor。不过底层概念是一样的,在 Claude Code 中同样适用。

为什么需要 MCP?

MCP 在短时间内获得了快速普及,如今围绕它的讨论非常广泛,也已经出现了大量 MCP server 的实现。很多 AI 应用,包括 Claude Code 和 Cursor 这样的工具,都已经把 MCP 集成进自己的系统中。

在正式定义 MCP 之前,先理解它所解决的需求,会更重要。

集成问题

设想这样一个 AI agent:它需要执行发送 Slack 消息、读取和发送邮件,或者查询数据库这类操作。为了让它具备这些能力,你就必须亲自实现对应功能。这意味着你需要对接 Slack 或 Gmail 这类 API,并编写自定义代码,把这些集成封装成 agent 可调用的 tools。

image.png

图 4.1 —— Agent 通过 API 与 Slack、Gmail 和数据库集成

在很多场景中,自定义实现是必要的。比如,某个邮件集成可能会故意不暴露 Gmail API 的 delete endpoint,以防止意外删数据。于是,这套集成逻辑就会根据具体需求被手工定制实现。

某些框架会提供内置 tools。比如,一个框架可能已经内建了 Gmail 集成,并覆盖了整个 API 能力面。这种现成工具对于通用需求是可以开箱即用的。但无论你用的是内置工具还是自定义工具,这些功能最终都必须被集成到某个特定的 agent 环境里。

一旦这些能力被实现,这个 agent 就能够发邮件、发 Slack 消息、执行数据库查询。问题是:这套集成只在那个特定 agent 环境中有效。

可移植性挑战

假设这个 agent 变得很受欢迎,其他团队也希望在不同环境里复用它的功能。

比如,最初这个 agent 是为了跑在 Cursor 环境中而构建的。在这个设定下,它通过各自的 API 与 Slack、Gmail 和数据库集成。下图展示了这种架构。

image.png

图 4.2 —— 与 Cursor 环境及其 API 集成强耦合的 Agent

在这种情况下,这个 agent 与 Cursor 环境是强耦合的。它对 Slack、Gmail 和数据库的集成,都是专门为这套环境实现的。

现在假设我们希望把同样的 agent 能力接入 Claude Code。虽然从概念上看,功能并没有变化,但原有集成并不能直接复用。因为那套实现是专门写给原来的 agent 环境的,所以要接入 Claude Code,就必须重新做一遍集成。

结果就是,类似“发送 Slack 消息”“操作 Gmail”“执行数据库查询”这种能力,都要为新环境重新实现。再往后想一层:如果还想把这套能力接到别的环境,比如 Cursor、Bolt、GitHub Copilot 或其他 AI 编码助手中,你就得一次次重复这个过程。

image.png

图 4.3 —— 为 Claude Code 环境重新实现 Agent 集成

每增加一个新环境,都会新增一轮实现工作。同样一套功能,必须为每一个目标系统单独适配。

MCP 作为抽象层

这个可移植性问题,本质上会不断重复出现:每当同样的功能要在另一个环境里复用时,开发者都必须从头重做集成。

MCP 通过引入一个额外的抽象层来解决这个问题。软件工程中有一句很著名的话:

“我们可以通过再加一层间接层,解决任何问题。”
—— Andrew Koenig

这个思想和软件工程基本定理是相通的:很多复杂系统问题,都可以通过加一层抽象来简化。MCP server 就扮演了这样一个角色。

与其把功能分别集成进每个 agent,不如把这套功能实现一次,并放进一个 MCP server 里。随后,所有支持 MCP 的 agent 都可以直接连接到这个 MCP server。

image.png

图 4.4 —— 作为统一集成层的 MCP server,连接外部服务

这样一来,兼容性只需要实现一次。只要某项能力通过一个 MCP server 暴露出来,它就能被所有支持该协议的平台使用。原本只为 Cursor 实现的能力,也就自然变得可以被 Claude Code 和其他 MCP 环境调用,而不需要再写额外的集成逻辑。

开发者不再需要为每个平台重写或复制集成代码。任何支持 MCP 的系统,都可以无缝接入并使用这些能力。

网络效应与生态增长

MCP 的增长呈现出一种类似社交平台的网络效应。一个用户很少的社交产品,本身价值有限;但随着用户增多、内容变丰富,整个系统就会越来越有价值,从而进一步强化增长循环。

MCP 身上也在发生类似的事情。随着采用率上升、越来越多的 MCP server 被开发出来,整个生态也在不断扩展。实现数量越多,可用的集成和能力就越丰富,协议本身的总体价值也随之提升。

在理解了这一点之后,接下来就该进入 MCP 的核心架构,看看它在实践中究竟是如何运作的。

MCP 核心架构

MCP 标准化了应用向大语言模型(LLM)提供上下文的方式。上下文可以有多种形式。它可能是附加到 Prompt 后面的额外信息,也可能是一个要调用的工具定义,甚至 Prompt 本身也可以被视为上下文。

image.png

图 4.5 —— 连接 host、client 与 MCP server 的 MCP 核心架构

从这个角度看,所谓上下文,不仅包括辅助性数据,还包括会影响 LLM 响应方式的操作性指令。

一旦这样的标准被广泛采用,它就能在 AI 应用之间催生出强大而可扩展的集成能力。

MCP 的优势

MCP 官方文档(https://modelcontextprotocol.io/)强调了若干采用 MCP 的优势:

第一,MCP 支持一个广泛的集成生态,涵盖工具、数据源和各种服务,这些都可以用模块化方式接入 LLM 驱动的应用。举例来说,Claude Code 作为一个 AI 编码智能体,就利用 MCP 通过结构化的工具集成来扩展自己的能力。

第二,MCP 降低了系统对特定 LLM 厂商或 AI 应用提供方的耦合。开发者可以把核心能力实现成 tools,并通过 MCP server 暴露出来。随后,这些工具就能跨不同厂商和 host 应用复用,而不需要改动。

像 LangChain 这样的开源框架,也在解决 AI 工程中某些相邻的问题。不过,MCP 和 LangChain 看待这些问题的方式并不相同,它们的解决方案也不直接重叠。比如,它们都可能支持扩展性,但具体机制和架构含义是不同的。

MCP 的核心组件

MCP 的架构由三个主要组件构成:MCP host、MCP server 和 MCP client

MCP hosts

MCP host 是指支持 MCP 的 AI 应用。典型例子包括 Claude Desktop、Claude Code 或 Cursor 这样的开发环境,以及各种专门化 AI agents。通过连接额外的工具、数据源或产品,这些应用能够被 MCP 增强,从而获得原生不具备的能力。

image.png

图 4.6 —— MCP host 通过 MCP client 连接到 MCP server

MCP servers

MCP server 用来向 MCP host 暴露功能。这些功能可能包括:

  • 调用外部工具,例如通过 API 获取天气信息
  • 数据库搜索能力
  • 知识资源,例如 PDF 或大段文本内容

image.png

图 4.7 —— MCP server 向 MCP host 暴露工具、数据库和外部 API

MCP server 本质上是一个 gateway 或 proxy,它按照 MCP 规范,把这些 tools、resources 和 prompts 暴露出去。

image.png

图 4.8 —— 作为网关的 MCP server,为外部资源提供标准化访问方式

为了符合协议,一个 MCP server 需要实现特定方法,例如:

  • listPrompts
  • getPrompt
  • listTools
  • callTool
  • listResourceTemplates
  • 进度通知机制

一旦这些方法被实现,这个 MCP server 就可以连接到任何支持该协议的 MCP host。也就是说,一次实现,多端复用。这种复用性正是 MCP 的核心架构优势之一。

MCP clients

MCP client 位于 MCP host 内部。它负责让 host 和 MCP server 通过 MCP 进行通信。

image.png

图 4.9 —— 位于 host 内部、负责与 MCP server 通信的 MCP client

例如,如果要把一个 weather MCP server 接入 Claude Desktop,那么 Claude Desktop 内部就会有一个 MCP client 来管理与该 server 的交互。client 和 server 之间的通信完全遵循协议本身。

这里有一个重要细节:一个 MCP client 与一个 MCP server 是一对一关系。一个 MCP client 不能同时与多个 MCP server 通信。因此,如果一个 MCP host 需要连接多个 MCP server,它就必须为每个 server 各自实例化一个 MCP client。

image.png

图 4.10 —— 多个 MCP client 将一个 host 连接到不同的 MCP server

至此,MCP 的核心架构就完整了,也为构建可互操作、可扩展的 AI 应用打下了基础。

MCP 的实际运行方式

接下来我们通过一个实际例子,走一遍添加和配置 MCP server 的过程。这个演示展示了 MCP 带来的能力,以及这些能力在实践中是如何表现的。例子中,我们将一个实现天气查询功能的 MCP server,接入到两个不同客户端:Claude Desktop 和 Cursor。

这两个场景用的是同一个 MCP server。配置细节会分别处理,这里更关注的是:server 接入之后,系统会表现出什么行为。任何支持 MCP 协议的客户端都可以使用这项能力,包括 Claude Code、Claude Desktop、Cursor、Lovable 以及其他兼容客户端。

没有 MCP server 时的行为

在 Claude Desktop 中,起初并没有在 Developer 设置里配置任何 MCP server。比如,如果你问旧金山的天气,而系统还没接入 MCP server,那么语言模型通常会回答:它无法访问实时天气信息。有时它可能会尝试调用一个 search 工具去获取摘要化信息。

没有 MCP 时,模型只能依赖训练数据,无法直接获取实时数据;最多只能借助一些通用内置工具,例如搜索。

连接 MCP server

当 weather MCP server 被配置好之后,它就会出现在 Claude 的 Developer 设置中,并显示运行时细节。

image.png

图 4.11 —— 在 Claude Developer 设置中配置好的 Weather MCP server

这时你再问一次旧金山天气,系统就会弹出权限请求,询问是否允许在本地执行 weather tool。之所以需要批准,是因为工具调用可能涉及本地代码执行。相关安全问题我们后面单独讨论。

安全警告:MCP server 可以在你的机器上运行代码

MCP server 会在本地运行,并继承与你当前用户账户相同的权限。这意味着它可以访问你的文件、环境变量和网络资源。

在添加 MCP server 之前,你需要意识到这些风险:

  • MCP server 可以在你的机器上执行命令,包括读取、修改甚至删除文件
  • 恶意 server 可能把敏感信息(例如源码、环境变量或 API Key)发送到外部服务
  • 来自 MCP server 的 tool response 里,可能携带隐藏指令,从而影响模型行为

因此,MCP server 应该被视为一种第三方依赖。尽量审查源码,只安装来自可信维护者的 server,并避免使用高权限运行它们。

一旦你允许 Claude Code 调用 MCP 工具,执行序列就会是这样:

  • MCP server 内部包含获取天气数据的逻辑
  • 它暴露了一个名为 getForecast 的函数
  • getForecast 接收两个参数:纬度和经度
  • 语言模型(这里是 Claude Sonnet 3.7)先判断出旧金山对应的经纬度
  • 然后模型发起一次对 getForecast 的 MCP 调用
  • MCP server 执行该函数并返回响应
  • 最后,语言模型处理响应并生成最终答案

image.png

图 4.12 —— Claude 调用 Weather MCP 工具并返回天气预报

得到的结果,就是基于 MCP server 实时拉取数据生成的天气报告。

虽然天气查询只是一个简单示例,但底层机制支持的是任意逻辑。任何功能都可以被实现成一个 MCP server。只要实现了 MCP 协议,兼容客户端就能通过工具调用来执行这些功能。这样,AI agent 的能力就不再局限于静态模型本身,而能够真正运行外部逻辑。

在多个客户端之间复用同一个 MCP server

同样的 weather MCP server 也可以接入 Cursor。配置完成后,它会出现在 Cursor 设置中的 MCP 标签页里。

image.png

图 4.13 —— 同一个 Weather MCP server 在 Cursor 中可用

连接后的 server 会显示它暴露的工具:

  • GetAlerts
  • GetForecast

配置中还会展示启动这个 server 的命令。在这个例子里,它是一个 Node.js server。在 Cursor Chat 中,MCP 功能可以在 agent mode 下使用。

image.png

图 4.14 —— 在 Cursor 的 Agent Mode 中调用 Weather MCP 工具

这时再问旧金山天气,agent 会带上正确参数调用 GetForecast。在这里,Cursor 运行在 YOLO mode 下,也就是说工具会自动执行,而不再需要手工批准。虽然这样更方便,但也确实有安全代价。

整个过程中,agent 会:

  • 用纬度与经度参数调用 GetForecast
  • 从 MCP server 获取天气数据
  • 判断天气预警信息也可能相关
  • 再调用 GetAlerts 查询旧金山是否存在天气告警
  • 最后把两个响应组合成一个最终答案,既包含天气情况,也包含告警信息

在这个例子里,一个 Prompt 之下调用了两个工具。agent 自主判断该调用哪些工具,并决定如何把它们的结果组织成一份连贯回答。

天气示例展示的是一个普遍模式:MCP 让 AI agent 能够执行定义在 MCP server 中的外部逻辑。 任何支持 MCP 的客户端,都能连接这些 server 并调用其中的工具。

只要开发者在 server 中实现 MCP 协议,它的功能就会自动对所有兼容客户端开放。这样,系统就摆脱了静态模型知识的限制,agent 得以执行动态、实时、定制化的操作。

将 Claude Code 连接到 MCP server

我们从一个空项目开始,并使用本书 GitHub 仓库中的一个空分支 project/MCP。仓库链接可通过前言中 Download the example code files 一节获取。接着,我们使用 /mcp 这个斜杠命令查看当前可用的 MCP server。此时列表中还没有任何 MCP server。

image.png

图 4.15 —— 在 Claude Code 中使用 /mcp 查看可用 MCP server

这里会提供一个链接,带你进入 MCP 文档,说明如何添加 MCP server。添加方式有多种:

  • 通过文件添加 MCP server
  • 通过 CLI 添加 MCP server

虽然可以通过文件配置,但更推荐使用 CLI。因为 CLI 通常是最新的;如果格式变化或者 API 发生变化,CLI 往往能更好地保证兼容性。

通过 CLI 添加 Context7 MCP Server

Context7(https://context7.com/)提供大量包的最新文档。尤其是在 AI 生态里,很多包(例如 LangGraph)变化很快,而拥有最新文档,意味着生成出来的代码能和最新 API 保持一致。

Context7 索引了将近 30,000 个包(https://github.com/upstash/context7),在写作本书时,该仓库大约有 49,200 个 stars。

要在 Claude Code 中使用 Context7,需要做 Claude Code integration。命令如下:

claude mcp add --transport http context7 https://mcp.context7.com/mcp

这条命令做了以下几件事:

  • 使用 claude mcp add
  • 指定传输协议为 HTTP
  • 指定 MCP 名称为 context7
  • 提供 MCP server 的 URL

这是一个远程 MCP server,也就是说 server 并不运行在本地,而是运行在 Context7 的服务器上。

每一次调用,都会向远端 server 发起请求。这种方式有几个优点:

  • 服务端更容易扩展
  • 同一个 MCP 可以被多个客户端复用

关于 HTTP transport 和 remote MCP server,更深入的说明可以参考 Udemy 上的 MCP 课程:
https://www.udemy.com/course/model-context-protocol/

你可以把这条命令复制粘贴到终端里。执行前,可以先加上 --help 看看可用参数。

MCP server 的 scope 与配置

帮助输出会显示:MCP server 可以配置在不同 scope 下。可选 scope 包括:

  • User scope
  • Project scope
  • Session scope

你也可以额外提供环境变量或 HTTP headers。

image.png

图 4.16 —— 使用 mcp add 命令向项目添加 MCP server

在这个例子中,我们选择 project scope 来添加 MCP server。

执行后,会生成一个新文件,其中包含 Context7 MCP 的配置。配置内容大致如下:

{
  "mcpServers": {
    "context7": {
      "type": "http",
      "url": "https://mcp.context7.com/mcp"
    }
  }
}

如果希望本地运行这个 MCP server,而不是用远程方式,也可以使用如下替代命令:

claude mcp add context7 -- npx -y @upstash/context7-mcp

这条命令会用 npx 下载对应仓库并在本地执行。

重启 Claude Code 并启用 MCP server

安装完 MCP server 后,需要重启 Claude Code。退出当前会话,清空终端,然后重新启动 Claude。

image.png

图 4.17 —— Claude Code 启动后检测并启用配置好的 MCP server

启动时,Claude 会检测到 mcp.json 文件,并询问你是否允许连接其中配置的 MCP server。这里选择第一个选项,允许连接。

随后,Claude 会为当前用户会话创建一个 settings.local.json 文件。打开这个文件,就能看到 Context7 MCP server 已经被启用,Claude 后续就可以在需要时调用它。

列出并检查已安装的 MCP server

现在就可以列出 MCP server 了。我们能看到 Context7 已经接入。

image.png

图 4.18 —— 列出已安装的 MCP server,并查看已连接的 Context7

点进去之后,可以看到它暴露了两个工具:

  • resolve-library-id
  • get-library-docs

这些工具的描述会成为 agent 上下文的一部分,使得 agent 能够在运行时按需调用它们。比如,当你让系统获取最新版 LangGraph 文档时,它会先调用 resolve-library-id 获取合适的上下文 ID,然后再调用 get-library-docs 把最新文档拉回来。

通过 Context7 MCP server 查询 LangGraph

我们可以问这样一个问题,并明确指定希望使用 Context7 MCP server:

What is the latest version of LangGraph?

Claude Code 会请求权限调用 Context7 MCP 工具。批准后,这个权限会被写入 settings.local.json

image.png

图 4.19 —— 调用 Context7 MCP 工具获取最新的 LangGraph 版本

MCP server 会先解析 library ID,然后再发出一次请求以获取文档。

根据 Context7 返回的文档,当时 LangGraph 的最新版本是 1.2

LangGraph 是一个快速演进中的框架。你在实际使用时看到的版本,可能会比书里的示例更新;不过,这里讨论的架构概念和设计模式仍然成立。

将 MCP server 的使用习惯持久化到项目 Memory 中

我们可以进一步配置:以后每次问到 LangGraph 时,都自动使用 Context7。为此,我们把这条指令写入项目 memory,让它在跨会话场景下持续生效。

这条指令会被记录下来,并写入一个 Claude.md 文件,内容类似:

When discussing LangGraph, always use context7 MCP

验证持久化后的 MCP 行为

接着我们可以重启 Claude,清空会话,再问:

What is a LangGraph interrupt?

Claude Code 会自动选择 Context7 MCP server。它会解析 LangGraph 对应的库、获取相关文档和代码片段,然后返回关于 LangGraph interrupt 的解释。

image.png

图 4.20 —— Claude 自动使用 Context7 MCP server 解释 LangGraph interrupt

由于 Context7 提供的是最新文档与 API,生成出来的代码也会更贴近当前真实用法。

将 MCP 产物提交到版本控制中

我们可以把这些生成出的文件加入 GitHub 仓库。使用如下 commit message 提交:

git commit -m "context7 mcp"

然后再 push 到远端仓库。这个 commit 可以在本书 GitHub 仓库中找到。获取仓库链接的方式同样请参考前言中的 Download the example code files

MCP Scope 速查表

正确选择 scope,有助于保持环境整洁,并避免无关配置泄漏到不相关项目中。下表总结了每种 MCP scope 的适用场景:

维度Project-scopeUser-scopeSession-scope
配置位置项目根目录下的 .mcp.json~/.claude/settings.json使用 --mcp-config 启动,或在会话中途添加
可见范围项目内所有人只有你自己,跨所有项目仅当前会话
是否提交到 Git
是否跨会话持久化
是否与团队共享

表 4.1 —— MCP scope 对比:project、user 与 session

每种 MCP Scope 适合在什么时候使用?

Project-scope(.mcp.json

当某个 MCP server 属于项目共享开发环境的一部分时,就用 project scope:

  • 只服务于这个项目的数据库工具(例如项目自己的 Postgres MCP)
  • 项目特定 API,例如内部服务或 staging 环境
  • 整个团队都需要的定制工具,例如部署脚本或测试执行器
  • 与项目技术栈绑定的文档 server

User-scope(~/.claude/settings.json

当某个工具是个人性质的,或者绑定的是你自己的凭证时,用 user scope:

  • 个人效率工具(Slack、Linear、Notion)
  • 与你个人凭证绑定的工具,例如带你自己 PAT 的 GitHub,或者邮箱访问
  • 你希望跨所有项目都可用的通用型 server(例如 Tavily 搜索或 Context7 文档)
  • 那些依赖 secrets、且你不希望把它们提交到仓库里的 server

Session-scope(--mcp-config / 临时配置)

当配置是临时性的、实验性的,或者不该持久化时,用 session scope:

  • 一次性调试用的 server,例如临时 proxy 或 mock API
  • 你正在评估的实验性或不可信 server
  • 依赖短时 token 的 server(OAuth 会话或临时凭证)
  • 在 CI/CD 环境中动态启动的 server

MCP 生态中的上下文工程

这一节讨论的是 MCP 生态中的上下文工程。虽然示例基于 Claude Code,但这些概念适用于任何支持 MCP 的 agentic system。

image.png

图 4.21 —— 在有限 LLM context window 中,好的上下文使用与坏的上下文使用

在 agentic system,尤其是 agentic coding workflow 中,上下文是最昂贵、也最有限的资源。上下文会直接影响 agent 的表现。上下文质量差,agent 的性能就差。这里我们只讨论性能层面的影响,故意不涉及价格和延迟。

image.png

图 4.22 —— 上下文工程:只加载必要上下文,从而减少 token 消耗

一个很隐蔽、但影响极大的上下文低效来源,就是 MCP 配置方式。MCP 很强,但如果使用不当,它会严重拖垮上下文效率。核心问题在于:MCP 可能会把大量当前任务根本不需要的工具定义塞进 context window,从而浪费大量 token。

问题所在:过于泛化的 MCP 配置

上下文低效的根本原因,是 过于宽泛的 MCP 配置。当 MCP server 被配置得太泛时,agent 会在处理任何请求之前,就把所有可用工具全部加载进上下文窗口。

这会在推理开始之前,先消耗掉大量宝贵 token,让真正任务可用的空间被压缩。

image.png

图 4.23 —— 过宽 MCP 配置导致的 context window 浪费

在 Claude Code 中,MCP server 常常会通过项目级 mcp.json 文件进行配置。这个文件会同时加载多个 MCP server,以及它们关联的全部工具。

image.png

图 4.24 —— 启动时一次性加载所有工具的通用 MCP 配置

绝大多数人都会这样配置:用一个通用型 MCP 配置,去加载所有 MCP server 和所有 tools。出发点通常是“先把所有可能会用到的能力都给 agent 备齐”。

问题在于:这样一来,每次会话都会加载所有 MCP server 和全部工具,即便它们和当前任务毫不相关。在你还没写下第一个 Prompt 之前,这种配置就可能已经吃掉几万 token。

这一节的目标,就是把这个问题拆开讲清楚,并通过上下文工程技术展示如何修复它。

示例仓库与 MCP server

这一节使用的代码可以在本书 GitHub 仓库中的 context-engineering-mcp 分支找到。我们从第一个 commit 开始,以便准确复现整个 setup。

仓库中包含了一个用 verbose_mcp_server.py 实现的简单 MCP server。它使用 FastMCP 编写,并暴露了大量 MCP tools,例如:

  • add_two_numbers
  • subtract_two_numbers
  • multiply_two_numbers

这个 server 故意包含了很多根本用不到的 MCP tools。每个 tool 还都带有很详细的描述。如下图所示:

image.png

图 4.25 —— 详细冗长的 MCP tool 定义如何推高上下文体积

这些描述确实有助于 MCP client 判断是否要调用某个 tool,但它们也会直接增加上下文体积。

运行这个 MCP server

这个 MCP server 使用 UV 包管理器运行。仓库中已经包含 uv.lock 文件,其中定义了 FastMCP 依赖(https://github.com/PrefectHQ/fastmcp)。操作步骤如下:

运行 uv sync,然后激活虚拟环境:

source .venv/bin/activate

环境激活后,就可以使用 FastMCP CLI(https://github.com/jlowin/fastmcp)。我们通过以下命令启动 MCP server:

fastmcp run verbose_mcp_server.py --transport http

这个 verbose mathematical operations MCP server 现在会通过 streamable HTTP transport 运行,并在 http://127.0.0.1:8000/mcp 暴露出来。

将这个正在运行的 MCP server 接入 Claude Code

接下来,我们需要观察:一旦 MCP server 和它的 tools 被加载进会话之后,它们究竟会如何影响上下文。

在本地 MCP server 已经运行的前提下,我们打开 Claude Code,并把这个 MCP server 添加进去。

为此,我们创建一个项目级 MCP 配置文件 .mcp.json

如果回到仓库查看这个分支,你会发现有一个名为 Add project-based MCP configuration 的 commit,其中已经给出了完整配置。你可以直接复制,并根据实际情况填入 API Key。书中示例里的 API Key 都做了脱敏处理。

项目级 MCP 配置

这个项目级 MCP 配置一共定义了 4 个 MCP server:

  • 一个本地运行的 verbose MCP server
  • Context7(前面已经讲过,https://context7.com/
  • Tavily(https://tavily.com/),用于联网搜索、网站抓取与网页提取
  • Playwright MCP,用于浏览器自动化

image.png

图 4.26 —— 在 mcp.json 中定义多个 server 的项目级 MCP 配置

因为这是项目级配置,所以每次从该项目目录启动 Claude Code 时,这 4 个 MCP server 都会自动加载。

示例中的 API Key 同样做了脱敏。

为了确认配置已经正确应用,可以这样验证:

  1. 打开终端
  2. 切换到项目目录
  3. 确认当前位于 context-engineering-mcp 分支
  4. 启动 Claude Code
  5. 运行 /mcp,确认 4 个 MCP server 都已连接

image.png

图 4.27 —— Claude Code 中已连接多个 MCP server

检查上下文使用情况

然后运行 /context,查看当前会话的上下文占用情况。

这个时候,即便你一个 Prompt 都还没写,context window 已经差不多被吃掉了一半。/context 输出会显示可用 token 是如何被分配的。

image.png

图 4.28 —— MCP tools 占据 context window 大量空间

占用情况大致如下:

  • 约 2,000 tokens 用于 Claude Code 的 system prompt
  • Claude Code 自带 system tools 大约消耗了 12,000 tokens
  • MCP tool descriptions 消耗了接近整个上下文窗口的 20%
  • 此时还没有任何消息、没有 memory file、也没有配置 sub-agent

如果此时还配了 sub-agents,它们的说明也会进入上下文,包括“什么时候该用它们、如何使用它们”的指令。

也就是说,在你真正开始工作之前,差不多已经有 50% 的 context window 被吃掉了。

而根据具体任务来看,其中很多 MCP server,尤其是那些 verbose mathematical MCP tools,其实是完全没必要存在的。

通过收窄 MCP 配置来减少上下文占用

要减少上下文占用,就必须把 MCP 配置范围收窄。

操作步骤如下:

  1. 删除项目级 .mcp.json 文件
  2. 创建一个新文件,命名为 .mcp.json.tavily
  3. 从仓库中复制 Tavily MCP 配置
  4. 粘贴到 .mcp.json.tavily

image.png

图 4.29 —— 使用 mcp.json.tavily 进行范围收窄的 MCP 配置

这样,这个配置里就只剩下 Tavily MCP server。

接下来,用这个收窄后的配置启动 Claude Code:

claude --mcp-config .mcp.json.tavily

这里的 --mcp-config 参数支持传入多个空格分隔的 MCP 配置文件路径。

Claude 启动后,再次运行 /mcp 检查 MCP server。

image.png

图 4.30 —— 使用 scoped config 后仍处于活跃状态的 MCP server

此时你会看到 Tavily MCP——这是预期内的。但你也可能仍会看到 verbose MCP 和 Context7,而 Playwright 已经不见了。

原因在于:Claude Code 仍然会从用户级 MCP 配置中加载 server,而用户级配置里还包含 Context7、Tavily 和 verbose MCP。

强制启用严格 MCP 配置

如果想确保只加载你指定的那份 MCP 配置,就必须启用严格模式

运行以下命令:

claude --mcp-config .mcp.json.tavily --strict-mcp-config

--strict-mcp-config 的含义是:让 Claude Code 忽略默认 MCP 层级体系,只加载你在指定配置文件中显式写出来的 MCP server。

验证方式如下:

  • 运行 /mcp,确认只剩 Tavily MCP
  • 再运行 /context,确认 MCP 工具带来的上下文占用显著下降,因为此时只有 Tavily MCP 处于活跃状态

image.png

图 4.31 —— 开启 strict MCP 配置后的上下文使用情况

MCP 相关上下文占用会从接近 20%,下降到大约 2.4%

这样,agent 就能更专注于当前任务,而不会背着一堆与当前目标无关的工具上下文前进。在这个例子里,当前任务是研究,因此只保留 Tavily 就足够了。

在会话中动态管理 MCP

除了通过配置文件收窄范围,还可以在一个会话内部动态启用或禁用 MCP server

做法如下:

  1. 恢复原来那个通用项目级 .mcp.json 配置
  2. 重启 Claude Code
  3. 禁用 verbose MCP server
  4. 禁用 Playwright MCP server
  5. 运行 /mcp,确认这两个 server 已被禁用
  6. 再运行 /context

image.png

图 4.32 —— 禁用部分 MCP server 后的上下文占用

这时,MCP 相关的上下文占用大约会下降到 3.2%

这种方式的好处是:你可以直接在一个会话中通过 CLI 启用或禁用某些 MCP server,而不必去改 MCP 配置文件本身。

MCP 当前的局限

MCP 的设计初衷,是标准化 agent 与数据、工具之间的连接方式。但它当前的实现方式,也引入了一些明显缺点。它们主要来自两个方面:LLM 上下文管理agent 任务执行方式

image.png

图 4.33 —— LLM 与外部 API 之间的 MCP 抽象层

结果就是,agent 可能会比预期更慢、更贵,也更不稳定。不存在完美协议,MCP 也不例外。

上下文污染(Context Pollution)

MCP 最严重的问题,就是上下文污染。因为 MCP 要求在使用前,先把 tool definition 预加载进模型上下文。这些定义——包括所需参数和预期输出——都会被放进 system prompt 中。

image.png

图 4.34 —— 预加载 MCP 工具定义引发的上下文污染

因为所有工具定义都必须事先加载,这本身就会带来非常可观的 token 开销。要使用某个 MCP server,agent 就必须先拿到它全部可用工具的定义。

比如,一个配置中如果包含 GitHub MCP、Slack MCP 和 Central MCP 等 58 个工具,仅仅这些 tool definitions 本身,就可能在对话开始之前占掉 55,000 tokens。某些情况下,这个数字甚至可能膨胀到几十万 tokens。

在 LLM 应用和 agent 系统中,上下文是最应该被优化的首要资源。一旦上下文被大量工具定义塞满,agent 就会一直背着大堆无关信息工作。

例如,一个 agent 明明只是在改前端页面,但它却同时携带着数千行和数据库工具、PDF 阅读器等完全不相关的上下文。这些无关数据会在对话的每一步、每一次迭代中持续存在。

image.png

图 4.35 —— 过多 MCP 工具导致的“大海捞针”问题

随着上下文被越来越多无关定义填满,模型性能会下降。模型不得不在大量无关内容中寻找所需信息,从而更容易出现幻觉、指令跟随失败,或错误选工具。上下文污染越严重,模型就越难在其中找到真正相关的信息。

Agent 执行效率低下

除了上下文问题,MCP 还会引入执行层面的低效。

image.png

图 4.36 —— 多次 MCP tool 调用导致的低效 agent 执行

传统 MCP 用法依赖一种“乒乓球式”的交互模式。每个动作都需要完整往返一轮:

  1. 模型先请求一个工具
  2. 工具执行
  3. 执行结果被追加到对话历史中
  4. 更新后的完整历史再次发回模型,由模型决定下一步

一旦任务需要多个工具调用,这个过程就会迅速膨胀。大量中间结果会不断堆进 context window,即便它们对最终答案并不总是必要。虽然按理说某些中间结果后面是可以被移除的,但当前 MCP 实现通常会把它们一直保留下来,从而继续污染上下文。

image.png

图 4.37 —— 模型、client 与 server 之间的 MCP 工具往返调用

每一次往返,都需要多做一次 LLM inference。推理次数越多,延迟和成本就越高。随着工具调用次数增长,模型调用次数也同步增长,最终表现为更慢执行和更高开销。

“母语问题”:JSON vs Code

MCP 还有一个更底层的问题:它迫使 LLM 以一种并不贴近其训练分布的方式工作。

image.png

图 4.38 —— LLM 训练分布 vs 工具调用格式

MCP 协议高度依赖结构化 tool-call token 和 JSON schema。但 LLM 的主要训练材料其实是自然语言和代码,而不是这种专门化的工具调用 token。

虽然各家模型厂商已经显著提升了 tool calling 的可靠性,但这种格式终究不是模型最自然的工作方式。对 LLM 来说,文本和代码才是更“原生”的表达形式。尤其是代码,比 JSON 式工具调用机制更接近它的训练数据和能力边界。

这就造成了一种摩擦:模型的训练分布,与 MCP 所要求的结构化交互方式之间并不完全对齐。

工具定义与 Schema 的局限

MCP 中的 tool definition 和 JSON schema,只能描述一个工具“长什么样”:它有哪些参数、输入与输出。

image.png

图 4.39 —— JSON schema 在描述工具使用方式上的局限

但它们无法表达“怎么用、什么时候用、什么时候不该用”这类使用模式

即便你可以额外写指令去约束工具使用方式,schema 本身也无法编码这种行为约束。换句话说,协议定义了工具的结构,却没有定义意图和正确应用方式。

Cloudflare 的 CodeMode

Cloudflare 在一篇博客中首次提出了 CodeModehttps://blog.cloudflare.com/code-mode/)。这是一个试图改变 agent 与 MCP tools 交互方式的执行模型。

它的出发点,就是前面提到的 MCP 问题,尤其是上下文膨胀,以及多次 LLM 调用造成的额外延迟。

与传统 MCP 用法不同,Cloudflare 的思路是:把 MCP 中所有的 tool definitions、tool interfaces 和 tool implementations,都转换成一个 TypeScript API。然后,不是让 LLM 去“选工具并调用”,而是让 LLM 直接写代码,并通过这套 TypeScript API 使用这些工具。

image.png

图 4.40 —— Cloudflare Code Mode:用代码执行取代直接工具调用

在这种模型里,LLM 会一次性生成完整可执行代码。代码里包含多个工具调用,以函数调用形式表达。随后,这段代码会在沙箱中执行一次。

这种方式可以显著减少工具调用中的往返轮数。传统模式下,模型要调一个工具、拿结果,再调下一个工具,如此反复;而在 CodeMode 下,模型直接把整套调用流程写成代码,在内部完成。Cloudflare 给出的核心理由是:LLM 非常擅长写代码。 写代码是它训练里极其常见的任务,数据量远超工具调用样例。由于代码只生成一次、执行一次,因此 tool definitions 也不用反复发送,从而减少 token 占用。

核心观察

Cloudflare 认为,MCP 过去往往是“直接把工具暴露给 LLM 来调用”。而在 CodeMode 中,MCP tools 会先被转成 TypeScript API,再由 LLM 写代码来调用它。

他们声称,这样 agent 能处理更多工具,也能处理更复杂的工具。传统 MCP 的一个问题是:工具一多,上下文就变大,成本和延迟上升,性能也会下降。而如果工具是以 TypeScript API 的形式呈现,而不是直接暴露为工具定义,那么性能就会更好。理由是:LLM 训练中见过大量真实 TypeScript 代码,却只见过极少量刻意构造的 tool-call 样例。

这种方法尤其适合多工具链式调用场景。传统 MCP 里,每一个工具输出都要回送给 LLM,再决定下一步;这种重复会持续消耗时间、能量和 token。而在 CodeMode 中,LLM 直接写出完成整条调用链的代码,只把最终结果返回出来。

所以 Cloudflare 的结论是:LLM 更擅长“写代码去调用 MCP”,而不是“直接调用 MCP 工具”。

Tool Calling 及其限制

传统 MCP 用法中,LLM 会生成表示工具调用的特殊 token。系统解析这些 token,提取函数名和参数,然后执行函数并返回结果。

但这种特殊 tool-call token,并不常见于真实世界数据。它们是训练阶段人为引入的语法构造。虽然模型厂商已经大幅提升了 tool calling 的效果,但这种机制本质上仍是“人工语法”。

一旦工具太多,或者工具本身太复杂,LLM 就可能难以选中正确工具,或者使用方式出错。因此,MCP server 设计者通常会被迫去简化 API,让它更适合 LLM 调用。

相比之下,LLM 对完整编程 API 的处理能力往往更强。面对复杂 API,它们可以分析、理解并生成对应代码,而不需要人为简化。根本区别在于:LLM 见过海量真实代码,却几乎没见过真实世界中的 tool calls。

Cloudflare 还给出了一个类比:让 LLM 做 tool calling,就像“把莎士比亚送去参加一个短期中文速成班,然后要求他用中文写戏剧”。含义非常明确:tool calling 并不是模型最擅长的领域。

MCP 的角色仍然重要

即便如此,MCP 仍然有价值。因为它依然提供了一种统一方式,让 agent 能够连接到 tools。MCP tools 本质上是一个带文档的 RPC 接口,而大多数 MCP server 本身也只是对已有传统 API 的包装。

CodeMode 的思路,不是直接把 MCP tools 以“工具”暴露出去,而是把它们转成编程语言 API。虽然底层传统 API 本来也存在,但 MCP 提供的是一种统一的接入与发现机制,这一点在 agent-based system 中依然非常有意义。

集成 CodeMode

Cloudflare 已经扩展了自己的 Agent SDK,以支持 CodeMode。在一个典型的 AI SDK 配置中,通常你会设置 model、system prompt、user message 和 tools。例如:

const stream = streamText({
  model: openai("gpt-5.3"),
  system: "You are a helpful research assistant.
    Your job is to help the user…",
  messages: [
    { role: "user", content: "Research on deep agents" }
  ],
  tools: {
    research agent's tool definition
  }
})

而在 CodeMode 中,system prompt 和工具定义会先被 codemode helper 包装,再传给应用:

import { codemode } from "agents/codemode/ai";

const { system, tools } = codemode({
  system: " You are a helpful research assistant.
    Your job is to help the user…",
  tools: [
    research agent's tool definition
  ],
})

这样改完之后,应用就不再直接进行 tool calling,而是生成并执行调用这些工具(包括 MCP server)的 TypeScript 代码。

将 MCP 转成 TypeScript

当 CodeMode 连接到 MCP server 时,Agent SDK 会抓取这个 MCP server 的 schema,并将其转换成 TypeScript API。生成出的 API 会包含 TypeScript 类型定义,以及从 schema 派生出来的文档注释。

这些 TypeScript 定义会被加载进 agent 的上下文。目前,整个 API 仍然是一次性整体加载进去;未来可能会支持动态搜索或按需浏览。

虽然整套 API 加载也会增加上下文体积,但这只发生在初始化阶段。随后 LLM 读取 API,并生成代码。由于 LLM 很擅长处理代码,这种方案实际上是在利用它的优势。

在沙箱中执行

在 CodeMode 下,agent 不再直接面对一堆 MCP tools,而是只拥有一个“执行 TypeScript 代码”的工具。

生成出的代码会运行在一个安全沙箱中,与互联网隔离。这个沙箱只能通过提供给它的 TypeScript API 来访问外部系统,而这些 API 对应的正是已经连接好的 MCP servers。

当沙箱中的代码调用某个 API 函数时,这个调用会通过 RPC binding 回路由回 MCP server。沙箱通过 console.log() 返回结果;等执行完成后,这些日志再返回给 agent。

于是,传统 MCP 流程和 CodeMode 的差异就很清楚了:

传统 MCP:

  • agent 从 MCP server 获取 tool schema
  • LLM 调用中包含这些 tool definitions
  • LLM 输出特殊 token 形式的函数调用
  • agent 解析并执行这些调用
  • 这一流程不断重复

CodeMode:

  • agent 同样先从 MCP server 获取 tool schema
  • LLM 调用中包含从这些 schema 推导出的 TypeScript API
  • LLM 直接针对这个 API 写 TypeScript 代码
  • 代码在沙箱中执行
  • 沙箱通过 RPC 绑定与 MCP server 通信
  • 最终日志返回给 agent

下图展示了传统 MCP 与 CodeMode 的执行架构对比。

image.png

图 4.41 —— Traditional MCP vs CodeMode 的执行流对比

CodeMode 被呈现为一种替代执行模型:它保留 MCP 作为统一集成层,但把执行方式建立在“LLM 擅长写代码”这一能力之上。

使用 Claude Code Plugins 管理配置

这里请参考 Claude Code 官方文档:
https://code.claude.com/docs/en/plugins

Plugins 可以把 slash commands(skills)、sub-agents、MCP servers 和 hooks 打包成一个统一、可分享的原语。它们可以在团队内部共享,也可以发布到开源社区中,从而帮助不同环境实现复用与一致性。

在 plugins 出现之前,复用配置是一件非常麻烦的事。比如,如果你想使用某个开源仓库里的 slash command,就得先去那个仓库,找到对应命令,复制出来,再粘贴进本地 .claude 目录。sub-agent 和 hook 也是类似流程。虽然 MCP server 的安装方式略有不同,但整体上仍然是手工、割裂、零散的。

Claude Code plugins 的出现,就是为了改善这个问题:它把所有这些组件统一打包成一个 plugin,让安装和集成变得顺畅。Plugin 可以来自开源仓库,也可以来自企业内部仓库,适合跨团队共享。

Claude Code 为此提供了一套基于 CLI 的 plugin system,操作直观、也很容易上手。

Plugin 系统的价值

Plugin 的一个核心价值,是让整个团队拥有统一的 Claude Code setup。比如,当一个新开发者加入团队时,我们希望他一上来就能拥有和其他人一样的工具、一样的 agents / sub-agents、一样的 MCP servers。Plugin 就提供了一种标准化 Claude Code 开发环境的机制。

另外,plugin 还支持细粒度安装。你不一定非要装完整 plugin,也可以只安装其中某个具体组件,比如一个单独的 MCP server。

Claude Code 还引入了一个新的原语:marketplace。它本质上是一个 JSON 文件,用来描述当前有哪些 plugin 可以安装。

值得一提的是,Google 的 Gemini CLI 也引入了一个类似概念,叫 Gemini Extensions。Gemini Extensions 发布于 2025 年 10 月 8 日,而 Claude Code plugins 发布于 2025 年 10 月 9 日。这个仅差一天的发布时间,很难不让人猜测:要么 Claude Code 团队迭代极快,要么两个团队几乎是在同时实现同一类思路。

查看官方 Plugin Marketplace

为了理解 plugin 是如何工作的,我们从 Claude Code 课程仓库开始看。

在 Claude Code 的开源仓库里,有一个 .claude-plugin 目录。这个目录里有一个 marketplace.json 文件。

它定义了官方 plugin marketplace,列出了所有可用 plugin,并包含对应元数据和 source 路径。

例如,marketplace 中列出的 plugin 包括:

  • pr-review-toolkit
  • commit-commands
  • agent-sdk-dev
  • feature-dev
  • Security guidelines

这个 marketplace 本质上就是一个 registry,Claude Code 读取它之后,就知道有哪些 plugin 可供发现与安装。

将 Marketplace 添加到 Claude Code 中

在安装 plugin 之前,必须先把一个 marketplace 加到 Claude Code 里。

步骤如下:

  1. 打开 Claude Code,运行命令:
/plugin

2. 选择 Browse and install plugins

  1. 因为起初还没有配置 marketplace,所以选择 Add Marketplace

  2. 输入以下任意一种:

    • 一个 GitHub 仓库 URL
    • 或一个直接指向 marketplace.json 的链接

在这个例子里,我们提供的是官方 Claude Code 仓库的 base URL。Claude Code 会自动检测 marketplace 文件,并加载所有可用 plugin。

加载完成后,就能看到 plugin 列表及其描述。

image.png

图 4.42 —— Claude Code plugin marketplace 中展示的可用 plugins

查看 Plugin 源码与安全考量

在这个阶段,你看到的仍然只是 plugin 描述。想真正知道某个 plugin 安装了什么,就必须去检查它的源码。

marketplace.json 中每个 plugin 条目都有一个 source 字段。这个字段指向 plugin 实现所在的位置。

在安装前审查这个 source 非常重要。从安全角度看,这和安装 MCP server、使用别人写的 system prompt 或 agent 没有本质区别。不看源码就安装 plugin,是有风险的。

查看 plugin source 的步骤如下:

  1. 打开 marketplace.json
  2. 找到目标 plugin 条目
  3. 查看 source 字段
  4. 跳转到仓库中的对应路径

例如,agent-sdk-dev 这个 plugin 指向仓库中的某个目录。要检查它:

  1. 打开仓库
  2. 进入 plugins/ 目录
  3. 再进入 agent-sdk-dev/
  4. 再进入 .claude-plugin/
  5. 查看其中的 plugin.json 文件

plugin.json 会包含这个 plugin 的元数据,并定义它要安装的 agent 和 slash commands(skills)。

另一个例子是 feature-dev。这个 plugin 包含多个 agent,例如:

  • code reviewer
  • code explorer
  • code architect

它还包含一个定义在 feature-dev.md 中的 slash command,用于描述待实现 feature,并引导整个工作流。

安装与管理 Plugins

一旦 marketplace 被添加,plugin 就可以被安装和管理了。

安装一个 Plugin

步骤如下:

  1. /plugin 打开 plugin 界面
  2. 选择 Browse and install plugins
  3. 找到 commit-commands 这个 plugin
  4. 打开 plugin 详情页
  5. 选择 Install
  6. 等待安装完成

安装完成后,这个 plugin 会出现在已安装列表里。

验证安装

为了确认 plugin 已成功安装并启用,可以:

  1. 打开已安装 plugin 列表
  2. 找到 commit-commands
  3. 确认它显示为 installed
  4. 同时确认它处于 enabled 状态

更新 Plugin

Plugin 背后绑定的是仓库,因此它们可以随着时间持续更新。更新方式如下:

  1. 选择一个已安装 plugin
  2. 找到 Update 选项
  3. 应用更新

从概念上看,更新 plugin 很像对着插件仓库的最新版本做一次 rebase。

尝试卸载 Plugin

插件界面里也有 uninstall 选项。操作步骤如下:

  1. 选中一个已安装 plugin
  2. 找到 Uninstall
  3. 尝试卸载它

目前,这个卸载功能并不能如预期那样工作。执行卸载之后,plugin 并不会真正消失。这看起来像是当前版本的一个限制,或者一个 bug。

image.png

图 4.43 —— 尝试卸载 Claude Code plugin

使用 feature-dev Plugin

接下来,我们用 feature-dev plugin 演示一个完整工作流。

开始之前,请先确认这个 plugin 已经安装并启用。

image.png

图 4.44 —— Claude Code 中 feature-dev plugin 的详情

启动工作流

步骤如下:

  1. 打开 Claude Code,运行命令:
/feature-dev

2. 等待 plugin 初始化

命令执行后,Claude 会进入一个discovery phase(探索阶段) 。这时它会开始提问,以弄清楚你到底想实现什么 feature。

feature-dev 工作流中的 Git 状态处理

在切分支之前,Claude Code 会先检查当前仓库的 Git 状态。

在这个阶段,仓库很可能存在尚未提交的本地改动。如果不处理这些改动就直接切分支,可能会引发冲突,甚至丢失工作内容。

检查 Git 状态

在这个流程中,Claude 会自动完成:

  • 检查当前 working tree 状态
  • 发现存在本地未提交改动
  • 判断此时直接切分支是不安全的
暂存本地改动

为了安全推进流程,Claude 会使用 git stash 保存当前工作状态。

在这一步中,Claude 会:

  • stash 当前工作目录中的改动
  • 确认 working tree 已经干净
  • 然后继续执行 branch 切换

这样就能确保本地改动不会丢失。

切回原分支并恢复状态

在检查完 feature branch 之后,Claude 会回到原分支,并恢复之前的 Git 状态:

  • 切回 main branch
  • 重新应用刚才 stash 的改动
  • 确认 working directory 已恢复原状

这时,仓库就回到了最初状态,本地改动也都还在。

提供 Feature 细节

在这个示例里,要完成的任务是:更新仓库的 README 文件

README 里有一张课程章节表格。现在 GitHub 上已经有一个新分支 context-engineering-mcp,因此需要把这个新分支对应的课程条目补进表格。仓库链接同样可从前言的 Download the example code files 一节获得。

在 Claude 提问时,你需要:

  • 描述要做的改动
  • 提供 context-engineering-mcp 分支的 URL

在 feature branch 中检查 README

Claude 会进入 feature branch,检查 README 文件。它会:

  • 切换到 context-engineering-mcp 分支
  • 打开 README
  • 识别表格结构

image.png

图 4.45 —— 在 feature branch 中检查 README

切回主分支

完成检查后,Claude 会:

  • 切回 main branch
  • 准备应用变更
  • 提出一条新的表格条目

审查并微调拟议变更

Claude 会先生成一个 README 新条目的初稿描述。这时你需要:

  • 检查描述
  • 找出不准确之处
  • 微调措辞

image.png

图 4.46 —— 审查并微调拟议的 README 变更

这个例子里,Claude 的描述已经接近正确,只需要稍作调整即可继续。

提交、推送并验证变更

一旦变更被批准,接下来会发生:

  • Claude 创建 commit
  • Claude 把 commit push 到远程仓库
  • 你刷新仓库
  • 打开 README
  • 检查新课程条目是否已经出现在表格里

image.png

图 4.47 —— commit 后验证 README 更新

这就说明整个工作流已经顺利跑完。

Plugin Marketplace 与企业使用

Claude Code 支持第三方 plugin marketplace。

例如,一个 DevOps automation marketplace 可以提供一组与基础设施工作流相关的 plugins,其中包含 slash commands、agents 和 MCP servers。组织也可以构建自己的私有 marketplace,专门服务于内部工具和团队。

很有可能像 Supabase 这样的基础平台公司,将来也会发布自己的 marketplace 和 plugins,以提升与 Claude Code 的集成体验。

Plugins 还支持细粒度安装。你可以只安装一个单独组件,比如一个 slash command 或一个 MCP server,而不需要把整个 plugin 整体装进来。这个 plugin 生态预计会持续增长,并在企业级 Claude Code 采用中扮演重要角色。

总结

在本章中,你学习了 MCP 为什么会被创造出来,以及它是如何解决 AI 系统中的集成问题的。你考察了它的核心架构:host、client 和 server,并看到了 MCP 如何实现可复用、跨平台的工具集成。通过实战例子,你配置并使用了 Context7 MCP,把 server 接入 Claude,并通过 CLI 管理 MCP 设置。

你还学习了:糟糕的 MCP 配置如何污染上下文窗口、拖垮性能,以及如何通过上下文工程与 scoped configuration 优化使用方式。最后,你还考察了 Claude Code plugins,理解了 MCP 的局限,并了解了 CodeMode 这种替代执行模型。

理解 MCP 之所以重要,是因为它正在成为 agent-based AI 开发中的一个基础集成层。知道如何高效使用它,以及在什么情况下应该反过来质疑它,都会帮助你构建出更可扩展、更有效的 AI 系统。

在下一章中,我们将讨论 GitHub 仓库配置、Pull Request 与 Issue 自动化,以及如何借助 GitHub Actions 执行工作流。