# 外交网络：MCP、Hooks、插件与 Skills

Claude Code 的扩展生态由四个互补机制组成——MCP 协议（标准化工具接入）、Hooks（生命周期事件拦截）、插件系统（第三方功能包）、Skills（AI 自主触发的能力）。本章从架构层面解析这四个机制的设计边界、安全模型和协作方式，并分析扩展性与安全性之间的核心张力。

> **源码位置**：`src/services/mcp/`（23 个文件）、`src/utils/hooks.ts` + `src/utils/hooks/`（事件系统）、`src/utils/plugins/`（44 个文件）、`src/skills/`（技能加载）

---

## 🌍 行业背景：扩展生态是 AI Agent 最激烈的战场

扩展生态——让 AI Agent 连接外部工具、响应生命周期事件、加载第三方能力——是当前 AI 编程工具竞争最白热化的领域。理解 Claude Code 的扩展设计，必须先看清行业全貌：

**MCP 不是 Claude Code 独创，而是 Anthropic 推出的开放标准。** Anthropic 于 2024 年 11 月发布 MCP（Model Context Protocol），目标是成为 AI Agent 连接外部工具的"USB 标准"。关键事实：MCP 不只 Claude Code 在用——Cursor、Windsurf、Zed、Cline、Continue 等主流 AI 编程工具都已宣布支持 MCP。这意味着 MCP 生态的工具可以跨产品复用，一个 MCP Server 写一次，所有支持 MCP 的客户端都能用。

**VS Code Extension API vs Claude Code Hooks：两种截然不同的扩展哲学。** VS Code 的 Extension API 是"图形界面优先"——扩展可以添加面板、菜单、装饰器、语言服务。Claude Code 的 Hooks 系统是"AI 管线优先"——扩展拦截的是工具调用前/后、权限检查、上下文压缩等 AI Agent 内部事件。这种面向 Agent 生命周期的 Hook 设计，在行业中几乎是 Claude Code 独有的。

**LangChain Tool 抽象 vs MCP 标准化方案。** LangChain 很早就提出了 Tool 抽象（函数签名 + 描述），但它是框架级方案——绑定 LangChain 运行时。MCP 的野心更大：它是协议级方案——定义的是进程间通信标准（JSON-RPC over stdio/HTTP），不绑定任何框架或语言。这是"库 vs 协议"的根本差异。

**在本文调研范围内，Claude Code 领先的扩展能力：**
- **27 个 Hook 事件 + 退出码 2 阻塞语义**——在调研的 AI 编程工具中，没有同等细粒度的 Agent 生命周期拦截机制
- **Skill 的 `whenToUse` 自主调度**——AI 自己判断何时触发能力，而非用户显式调用
- **四机制组合架构**（MCP + Hooks + 插件 + Skills）——多数竞品只实现了其中一两个
- **Channel Permission Relay 远程审批**——跨设备的权限确认流程

### MCP 生态竞品对比

| 产品 | 支持 MCP | 自有扩展机制 | 生命周期 Hook | AI 自主触发能力 | 远程审批 |
|------|---------|------------|-------------|--------------|---------|
| **Claude Code** | ✅ 首发支持，多传输协议 | Hooks + Plugins + Skills | ✅ 27 个事件 | ✅ Skills (whenToUse) | ✅ Channel Relay |
| **Cursor** | ✅ 深度支持 | .cursor/rules/（.mdc 条件规则引擎） | ❌ | ❌ | ❌ |
| **Windsurf** | ✅ 深度支持 | Cascade Engine（级联式持续观测） | ❌ | 部分（Flows 内） | ❌ |
| **Zed** | ✅ 支持 MCP | Extension API（WASM） | ❌ | ❌ | ❌ |
| **Cline** | ✅ 深度支持 | 自定义指令 + 原生子智能体（v3.58+） | ❌ | ❌ | ❌ |
| **Continue** | ✅ 深度支持 | 合规审批工作流 + CI/CD 卡点强制验证 | 部分 | ❌ | ❌ |
| **GitHub Copilot** | ✅ 原生 GitHub 注册表 | VS Code Extension API + Agent Mode GA | 通过 VS Code 事件 | Explore/Plan/Task 智能体 | ❌ |
| **Codex（OpenAI）** | ✅ 深度（SSE/Stdio） | 开源技能库（Figma/Linear 原生集成） | ❌ | ❌ | ❌ |
| **OpenCode** | ✅ 声明式扩展 | YAML 深度定制 + 75+ 模型提供商 | ❌ | ❌ | ❌ |
| **GLM（Z.ai）** | 开放平台 API | Z Code 平台（本地化知识库引擎） | ❌ | ❌ | ❌ |

> **读表关键**：MCP 已成事实标准（大多数产品都支持），但 Claude Code 在 MCP 之上的三层叠加（Hooks + Plugins + Skills）是独到的。特别是 Hook 系统的退出码 2 阻塞语义和 Skill 的 AI 自主调度，在竞品中尚无对等设计。

---

## 引子：大使馆、海关和自贸区

一个国家想和外部世界交流，需要三样东西：**大使馆**（标准外交通道）、**海关**（进出口管控）、和**自贸区**（让特定外部实体在境内活动）。

Claude Code 的扩展生态也是这三样：
- **MCP**（Model Context Protocol）= 大使馆——标准化的外部工具接入协议
- **Hooks** = 海关——在关键节点检查和控制进出的数据
- **插件 + Skills** = 自贸区——第三方功能在系统内运行

> **🔑 OS 类比：** MCP = 手机的蓝牙/USB 接口（标准方式连接外部设备），Hooks = 手机的"自动化快捷指令"（在特定时刻自动触发操作），插件 = App Store 里下载的应用（别人开发的功能包），Skills = 你自己录制的操作宏（自定义的自动化脚本）。
>
> 💡 **通俗理解**：扩展生态就像给你的手机装 App——MCP 是**USB 转接口**（让 Claude 连接各种外部设备和服务）；Hooks 是**快递柜的短信通知**（系统在关键时刻自动触发你预设的动作）；插件是**App Store 里的应用包**（一键安装一整套功能）；Skills 是**手机上的快捷指令**（AI 自己判断什么时候该用哪个）。

---

## 1. MCP：标准化的外部工具协议

### 1.1 什么是 MCP

MCP（Model Context Protocol）是 Anthropic 于 2024 年 11 月发布的**开放协议标准**（不是 Claude Code 独有功能），让任何外部服务器都可以向支持 MCP 的客户端注册工具。Claude Code 是 MCP 的首发客户端实现之一，但 Cursor、Windsurf、Zed 等产品同样支持。就像 USB 协议让任何厂商的设备都能连接到任何电脑一样——MCP 的目标是成为 AI Agent 世界的 USB 标准。

> 📚 **课程桥接**：MCP = **操作系统的设备驱动接口 / USB 标准**。操作系统通过标准驱动接口（如 USB）让打印机、键盘、摄像头等外设即插即用；MCP 通过标准协议让数据库、API、文件系统等外部服务即插即用到 AI Agent 中。写一次驱动（MCP Server），所有操作系统（MCP 客户端）都能用。

### 1.2 规模

`src/services/mcp/`：23 个文件。源码 `TransportSchema`（`types.ts:23`）是一个 **6 值 Zod 枚举**：`['stdio', 'sse', 'sse-ide', 'http', 'ws', 'sdk']`。用户可通过 `.mcp.json` 直接配置其中 4 种；另外 2 种由 IDE 插件 / SDK 内部自动装配，用户不直接写配置。此外还有 2 种**配置类型**（不在 TransportSchema 里）来自 `McpServerConfigSchema`：

**用户可直接配置的传输协议（TransportSchema 中的 4 项）：**

| 传输协议 | 说明 |
|---------|------|
| `stdio` | 本地子进程通信（最常见）📚 = Unix 管道 (pipe) |
| `sse` | HTTP Server-Sent Events，服务器推送事件 |
| `http` | HTTP Streamable 流式传输 |
| `ws` | WebSocket 双向实时通信 |

**TransportSchema 中的 2 种内部类型（用户不直接写配置）：**

| 类型 | 说明 |
|------|------|
| `sse-ide` | IDE 扩展专用的 SSE 连接（VS Code / JetBrains 注入） |
| `sdk` | SDK 内部通信 |

**不在 TransportSchema 中、但存在于 McpServerConfigSchema 的类型：**

| 类型 | 说明 |
|------|------|
| `ws-ide` | IDE 扩展专用的 WebSocket 连接 |
| `claudeai-proxy` | Claude.ai 代理服务器（仅在状态响应中出现）|

> **常见混淆**：`npx`、`uvx`、`docker` 不是传输协议——它们是 MCP Server 的**启动方式**，底层都走 `stdio` 传输。例如 `"command": "npx", "args": ["-y", "@some/mcp-server"]` 只是指定用 npx 启动服务器进程，通信仍然是 stdio 管道。

### 1.3 MCP 工具在系统中的地位

MCP 工具以 `mcp__服务器名__工具名` 格式出现在工具列表中。从 queryLoop 的视角看，它和内置工具走完全相同的管线——输入验证、权限检查、执行、结果序列化。

**但有一个关键差异**：MCP 工具的执行发生在外部进程/服务器上。这意味着：
- 执行时间不可预测（网络延迟）
- 结果内容不可控（可能包含恶意内容）
- 服务器可能随时断开

### 1.4 Channel Permission Relay

这是 MCP 系统中最有趣的安全机制。当 Claude Code 在远程运行时（通过 Bridge），权限确认需要传回到用户那里。Channel Permission Relay 通过 Telegram/iMessage 发送审批请求，用户在手机上批准或拒绝。

审批码使用 **5 字母 ID**（25 字母表 + 脏话过滤）——确保 ID 不会拼出不雅词汇。

---

## 2. Hooks：27 个关键节点的自定义逻辑

### 2.1 什么是 Hook

Hook 是在系统生命周期的特定时刻执行用户自定义逻辑的机制。Hook 不只是 Shell 命令——还可以是 LLM 提示词、HTTP 请求或独立的 Agent 验证器（详见 2.4 节）。和工具不同——**AI 不调用 Hook，系统自动触发**。

> 📚 **课程桥接**：Hooks = **操作系统的中断处理程序（ISR, Interrupt Service Routine）**。CPU 在执行主程序时，硬件中断（键盘按下、磁盘读完）会打断当前流程，跳到预注册的中断处理程序执行完毕后返回。Claude Code 的 Hook 机制完全相同：AI Agent 在执行主流程（工具调用、权限检查）时，系统在 27 个预定义中断点自动跳到用户注册的处理逻辑（Shell 命令、LLM 提示词、HTTP 请求或 Agent 验证器）执行，完毕后返回主流程。退出码 2 相当于中断处理程序返回"拒绝服务"——直接阻止主流程继续。

### 2.2 27 个事件

源码 `HOOK_EVENTS` 数组（`src/entrypoints/sdk/coreSchemas.ts`）定义了全部 27 个事件，按生命周期分类如下：

| 生命周期 | 事件 | 时机 |
|---------|------|------|
| 工具调用 | `PreToolUse` | 工具调用前 |
| | `PostToolUse` | 工具调用后（成功）|
| | `PostToolUseFailure` | 工具调用后（失败）|
| 对话流程 | `Stop` | AI 完成本轮回答 |
| | `StopFailure` | AI 回答异常终止 |
| | `UserPromptSubmit` | 用户提交提示词时 |
| | `Notification` | 系统通知 |
| 权限 | `PermissionRequest` | 权限请求时 |
| | `PermissionDenied` | 权限被拒绝时 |
| 上下文 | `PreCompact` | 上下文压缩前 |
| | `PostCompact` | 上下文压缩后 |
| 会话生命周期 | `SessionStart` | 会话启动 |
| | `SessionEnd` | 会话结束 |
| | `Setup` | 初始化设置 |
| 子 Agent | `SubagentStart` | 子 Agent 启动 |
| | `SubagentStop` | 子 Agent 停止 |
| 任务 | `TaskCreated` | 任务创建 |
| | `TaskCompleted` | 任务完成 |
| | `TeammateIdle` | 队友空闲 |
| 配置与环境 | `ConfigChange` | 配置变更 |
| | `CwdChanged` | 工作目录切换 |
| | `FileChanged` | 文件变更 |
| | `InstructionsLoaded` | 指令加载完成 |
| Worktree | `WorktreeCreate` | 工作树创建 |
| | `WorktreeRemove` | 工作树删除 |
| 交互 | `Elicitation` | 信息收集请求 |
| | `ElicitationResult` | 信息收集结果 |

### 2.3 退出码双轨制

Hook 的退出码有特殊语义：

| 退出码 | 含义 |
|--------|------|
| 0 | 成功，继续 |
| 2 | **阻塞**——停止当前操作 |
| 其他非零 | 失败，但不阻塞（只记录错误）|

退出码 2 的特殊含义是关键设计——它让 Hook 可以**拦截**操作而不仅仅是观察。例如，一个 `PreToolUse` Hook 可以检查 Bash 命令是否包含危险操作，返回 2 来阻止执行。

### 2.4 四种 Hook 类型

Hook 不只是 Shell 命令。源码通过 `type` 字段区分了四种 Hook 类型（`src/schemas/hooks.ts` 中的 `HookCommandSchema`），这是一个真正的创新设计：

| 类型 | `type` 值 | 行为 | 关键字段 |
|------|----------|------|---------|
| **Shell 命令** | `command` | 执行 Shell 命令（最常用） | `command`（命令字符串）|
| **LLM 提示词** | `prompt` | 调用 LLM 评估一段 prompt，用 AI 做判断 | `prompt`（提示词）、`model`（可选模型）|
| **HTTP 请求** | `http` | 向指定 URL 发 POST 请求 | `url`、`headers`、`allowedEnvVars` |
| **Agent 验证器** | `agent` | 启动一个子 Agent 执行验证任务 | `prompt`（验证目标描述）、`model` |

> **为什么这很重要？** 大多数 Hook 系统只支持 Shell 命令。Claude Code 的 `prompt` 类型让 Hook 可以**调用 LLM 判断**（比如"这个修改是否符合代码规范？"），`agent` 类型更进一步——启动一个完整的验证 Agent 来审查操作。这意味着 Hook 的判断力不局限于脚本逻辑，而是可以利用 AI 推理能力。

异步控制通过 `async`（后台执行，不阻塞）和 `asyncRewake`（后台执行，但退出码 2 时唤醒模型）两个布尔字段实现，而非独立的执行类型。

---

## 3. 插件系统：第三方功能包

### 3.1 插件能做什么

一个插件可以包含：
- 新的工具
- 新的 Skills
- 新的 Hooks
- 新的 MCP 服务器配置
- 新的命令

### 3.2 安全防护

插件系统有三重安全：
1. **白名单**：只有经过审批的插件可以安装
2. **正则验证**：插件名和源地址需要匹配安全模式
3. **同形字防护**：防止用看起来相似的 Unicode 字符伪造插件名（如 `а`（西里尔字母）伪装成 `a`（拉丁字母））

> 📚 **课程桥接**：插件信任链 = **PKI 证书链（Public Key Infrastructure）**。浏览器信任一个 HTTPS 网站，靠的是一条证书链：根 CA → 中间 CA → 网站证书。Claude Code 信任一个插件，靠的也是一条信任链：Anthropic 官方白名单 → 插件名正则验证 → 同形字检测。任何一环断裂（未审批、名称不匹配、检测到仿冒字符），信任链中断，插件被拒绝。和 PKI 一样，这是"默认不信任，逐级验证"的零信任模型。

### 3.3 `strictPluginOnlyCustomization`

企业管理员可以启用此设置：只允许企业策略指定的插件。用户不能自行安装或配置插件。

---

## 4. Skills：AI 可以自主触发的能力

### 4.1 Skill vs Command

| | Command（命令）| Skill（技能）|
|--|--------|------|
| **触发方式** | 用户输入 `/xxx` | AI 自主决定调用 |
| **触发者** | 只能是用户 | 可以是 AI |
| **关键字段** | — | `whenToUse`：描述什么时候应该使用这个 Skill |
| **来源** | 系统内置 | 内置 + 用户自定义 + 插件提供 |

### 4.2 `whenToUse` 字段

这是 Skill 和 Command 最本质的区别。Skill 有一个 `whenToUse` 描述，放在 system prompt 里：

```
Skill: commit
whenToUse: "When the user asks you to create a git commit"
```

AI 在生成回答时看到这个描述，如果当前场景匹配，就主动调用。**AI 成为了 Skill 的调度器**——不需要用户显式触发。

---

## 5. 四个扩展机制的协作

这四个机制不是孤立的——它们协作形成完整的扩展生态：

```
用户场景："我想让 Claude Code 在每次提交前自动运行 lint"

解决方案组合：
  1. MCP 服务器 → 提供 lint 工具
  2. Hook（PreToolUse on Bash(git commit *)）→ 在 commit 前触发
  3. Skill（lint）→ AI 可以自主决定何时运行 lint
  4. Plugin → 把以上打包成一个可安装的包
```

```
用户场景："企业要求所有代码修改都经过安全扫描"

解决方案组合：
  1. 企业策略 → 强制安装安全扫描插件
  2. Hook（PostToolUse on Edit/Write）→ 修改后自动扫描
  3. MCP 服务器 → 连接企业安全扫描服务
  4. strictPluginOnlyCustomization → 用户不能禁用这些
```

---

## 6. 设计取舍

### 优秀

1. **积极拥抱 MCP 开放标准**（而非发明私有协议）使 Claude Code 能直接复用整个 MCP 生态的工具——Anthropic 推动标准，Claude Code 率先受益，但生态红利也惠及所有 MCP 客户端
2. **Hook 的退出码 2 阻塞语义**让用户自定义的安全检查可以拦截操作——不仅仅是日志
3. **Skill 的 `whenToUse` 让 AI 成为调度器**——从"用户告诉 AI 做什么"变成"AI 知道什么时候该做什么"
4. **同形字防护**说明团队认真考虑了供应链攻击——不是理论威胁，Unicode 同形字攻击已在 npm 生态中被真实利用
5. **四个机制可以组合使用**——不是彼此替代，而是互补

### 代价与局限

1. **MCP 的多种传输协议和启动方式**增加了连接调试的复杂度——"为什么连不上"可能需要区分是传输层（stdio/sse/http/ws）还是启动方式（npx/docker/uvx）的问题
2. **27 个 Hook 事件**的文档维护成本高——用户需要知道在哪个事件注入才能达到想要的效果。如果注入到错误的事件可能导致意外失败
3. **Hook 执行用户自定义逻辑**（Shell 命令、LLM 提示词、HTTP 请求、Agent）有安全风险——恶意 Hook 可以读取所有对话内容，这是扩展性与安全性之间的核心权衡
4. **插件的白名单模型**限制了开放性——没有审批的插件无法使用，但这是安全边界情况下的有意选择
5. **Skill 的自主触发**可能导致意外行为——AI 可能在不恰当的时候调用 Skill，需要警惕 `whenToUse` 描述过于宽泛的问题

---

## 代码落点

- `src/services/mcp/MCPConnectionManager.tsx`：MCP 连接管理器——多种传输协议的统一抽象层
- `src/services/mcp/types.ts`：`TransportSchema` 定义——stdio、sse、http、ws 等传输协议类型
- `src/utils/hooks.ts`：Hook 事件系统核心——`executePreToolHooks()`、`executeStopHooks()` 等 27 种事件的执行入口
- `src/schemas/hooks.ts`：Hook 类型定义——`HookCommandSchema` 四种类型（command/prompt/http/agent）的 discriminated union
- `src/utils/plugins/schemas.ts`：官方 Marketplace 名称白名单和仿冒检测正则
- `src/skills/loadSkillsDir.ts`：Skill 加载器——解析 `.md` 文件中的 `whenToUse` 字段
