MCP协议、熔断器与OAuth——Agent接入外部世界的工程方案

《Claude Code 架构解密》精读笔记 · 第15篇
覆盖章节:第9章后半(9.6-9.12, p.237-251)
主题:8种MCP传输适配、分级熔断连接缓存、OAuth/XAA认证状态机、分区批处理编排、插件模块化组合


导语:从"内部拦截"到"外部集成"

第14篇解析了 Hook 事件系统——Claude Code 的"内部扩展骨架"。但 Agent 的真正威力不仅来自"能拦截什么",更来自"能连接什么"。

当 Agent 需要查询公司内部的知识库、调用云服务 API、读取设计稿里的组件定义、甚至控制智能家居设备时,它需要一个统一的外部集成通道。这个通道就是 MCP(Model Context Protocol)

但"统一接入"说起来容易,做起来难。MCP 服务器可能跑在本地子进程里,也可能部署在远程 HTTP 服务上,还可能嵌在 IDE 的 WebSocket 连接里——8 种传输协议,每种都有不同的连接方式、错误处理和安全约束。更麻烦的是,这些连接会断开、会超时、会认证过期——Agent 不能每次都傻傻地报错,而要有智能的故障恢复机制。

本篇将深入 Claude Code 的 MCP 协议栈、连接管理体系、认证状态机,以及把这一切打包分发的插件系统。这是 Agent 从"产品"走向"平台"的另一半故事。


一、架构图解:MCP 协议栈与插件全景

┌─────────────────────────────────────────────────────────────────┐
│                  MCP 协议栈 + 插件系统全景                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │               插件系统(Plugin System)                      │  │
│  │  Skills(.md) + Commands(.md/.ts) + Agents(.md)         │  │
│  │  + Hooks(hooks.json) + MCP(.mcp.json)                   │  │
│  │  → 注册到各自子系统,优先级999(最低)                    │  │
│  └───────────────────────────────────────────────────────────┘  │
│                            ▲                                  │
│                            │ 插件安装时自动注册                  │
│                            ▼                                  │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │          工具编排层(Tool Orchestration)                    │  │
│  │  分区-批处理:isConcurrencySafe → 并发/串行决策           │  │
│  │  + 触发 PreToolUse/PostToolUse Hook                      │  │
│  └───────────────────────────────────────────────────────────┘  │
│                            ▲                                  │
│                            │                                   │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │        MCP 客户端层(connectToServer + 连接缓存)            │  │
│  │                                                          │  │
│  │  8种传输适配器                                            │  │
│  │  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐                │  │
│  │  │stdio │ │ http │ │ sse  │ │ ws   │                │  │
│  │  └──────┘ └──────┘ └──────┘ └──────┘                │  │
│  │  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────────┐            │  │
│  │  │sse-ide││ws-ide││ sdk  ││claudeai- │            │  │
│  │  └──────┘ └──────┘ └──────┘ │proxy     │            │  │
│  │                                        └──────────┘            │  │
│  │                                                          │  │
│  │  连接缓存(memoize)+ 本地/远程分组并发                      │  │
│  │  四层熔断:指数退避 → 认证熔断 → 终端错误 → 会话过期      │  │
│  └───────────────────────────────────────────────────────────┘  │
│                            ▲                                  │
│                            │                                   │
│  ┌───────────────────────────────────────────────────────────┐  │
│  │         认证层(OAuth State Machine)                        │  │
│  │  pending → connected → failed / needs-auth                │  │
│  │  + 标准OAuth流程 + XAA跨应用访问                          │  │
│  └───────────────────────────────────────────────────────────┘  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

二、核心点拆解

2.1 8 种 MCP 传输协议统一适配

问题:8 种协议,1 个接口

MCP 工具服务器可能运行在各种环境中——本地子进程通过标准输入输出通信,远程服务通过 HTTP/SSE 连接,IDE 通过 WebSocket 内嵌,SDK 通过控制通道桥接。如何用统一的客户端接口屏蔽这些传输差异?

Claude Code 的 connectToServer 函数实现了 8 种传输适配器,统一收敛到 MCP SDK 的 client 接口:

传输类型 适配器类 连接方式 特殊处
stdio StdioClientTransport 子进程 spawn 本地最低开销
sse SSEClientTransport Server-Sent Events + OAuth 远程流式
http StreamableHTTPClientTransport 可流式 HTTP 支持 POST 双向
ws WebSocketTransport Bun/Node 双运行时 IDE 内嵌
sse-ide SSEClientTransport SSE + IDE Auth Token Token 注入
ws-ide WebSocketTransport WebSocket + IDE Auth Token Token 注入
sdk SdkControlClientTransport 控制消息桥 SDK 集成
claudeai-proxy StreamableHTTPClientTransport HTTP + Claude.ai OAuth 组织级认证

这种设计的核心模式是**适配器模式(Adapter Pattern)**的极端版本——不是"一个接口多种实现",而是"8种完全不同的通信协议,统一到一个 Client 接口"。每种适配器处理协议特有的连接建立、消息编解码、错误处理和断开重连。

连接缓存与分组并发

连接管理有两个关键优化:

连接缓存:使用 memoize 确保同一配置只建立一次连接,缓存键为 ${name}-${JSON.stringify(config)}。这避免了重复连接同一服务器的开销。

本地/远程分组启动

启动时按传输类型分组:
  本地传输(stdio)→ 低并发(默认3),避免子进程爆炸
  远程传输(http/ws)→ 高并发(默认20),充分利用网络

这种分组策略源于一个实际问题:如果同时 spawn 20 个本地 MCP 服务器子进程,在资源受限的机器上可能导致 OOM。但远程连接只是 TCP 握手,20 个并发完全可以承受。

InProcessTransport:避免进程开销

对于 Chrome MCP 和 Computer Use MCP 这样的"重量级"工具,Claude Code 提供了 InProcessTransport——直接在主进程内启动 MCP 服务器,避免 325MB 的子进程开销。这是**“性能热路径特殊处理”**的典型实践。

缓存失效:onclose 的全面清理

连接缓存最棘手的问题是失效。Claude Code 在 onclose 回调中执行全面清理:

// 连接关闭时清除所有相关缓存
client.onclose = () => {
  memoizedConnect.cache.delete(cacheKey);   // 连接缓存
  toolsCache.delete(name);                   // 工具列表缓存
  resourcesCache.delete(name);               // 资源缓存
  commandsCache.delete(name);               // 命令缓存
  // 确保下次调用重建连接
};

这种**“一次断开,全面清理”**的策略确保了不会出现"连接已断但缓存仍在"导致的幽灵调用。

2.2 四层渐进式故障恢复:分级熔断

MCP 连接可能因网络抖动、认证过期、服务器崩溃等原因断开。Claude Code 实现了四层故障恢复机制,从轻到重逐层升级:

第一层:指数退避重连
  检测断开 → 检查是否禁用 → 更新为 pending → 等待退避时间 → 重连
  1s → 2s → 4s → 8s → 16s (上限 30s)
  最多5次,失败后标记 failed

第二层:认证缓存熔断
  对返回401的服务器,进行15分钟的"短路缓存":
  const MCP_AUTH_CACHE_TTL_MS = 15 * 60 * 1000;
  // 缓存命中时跳过连接,注入 McpAuthTool 供用户手动认证

第三层:终端错误计数
  连续3次终端错误(ECONNRESET/ETIMEDOUT/EPIPE/SSEdisconnected)
  → 强制关闭 → 触发重连流程

第四层:会话过期检测
  HTTP 404 + JSON-RPC -32001 ("Session not found")
  → 清除连接缓存 → 重试一次 → 仍失败则报错

这四层防御体现的核心模式是分级熔断(Tiered Circuit Breaking)

故障级别 触发条件 恢复路径 用户感知
轻故障 网络抖动 自动重连,最多5次 无感
中故障 认证过期(401) 熔断15分钟 + 注入 McpAuthTool 手动触发重新认证
重故障 终端错误连续3次 标记 failed,停止重试 明确报错
会话级 HTTP 404 + -32001 清除缓存重试一次 短暂延迟后恢复或报错

每一级都有明确的触发条件和恢复路径,避免了"一刀切"的粗暴策略。

子进程的渐进式退出

对于 stdio 类型的 MCP 服务器(本地子进程),Claude Code 实现了 SIGINT → SIGTERM → SIGKILL 的渐进式退出策略:先礼貌请求退出,再强制终止,最后无条件杀死。每个阶段都有超时窗口,确保子进程有机会做清理工作。

2.3 OAuth 认证状态机:Token 的完整生命周期

连接状态的显式建模

MCP 服务器的连接状态不是简单的"连接/断开"二值,而是一个包含认证维度的复杂状态空间。Claude Code 将其建模为显式的状态机

pending ─────→ connected
  │                │
  │                ├── [onerror] ──→ pending(重连)
  │                │
  ├── [401] ──→ needs-auth
  │                │
  ├── [失败超限] → failed
  │
  └── [用户主动] → disabled

McpServerConnection 使用**判别联合类型(Discriminated Union)**表达这些状态——每个状态携带不同的数据(如 needs-auth 携带认证 URL,failed 携带错误原因)。这比"一个状态字段 + 若干可选字段"的类型设计更安全——编译器会强制处理每个状态分支。

标准 OAuth 流程

当 MCP 服务器返回 401 需要认证时,Claude Code 启动标准 OAuth 流程:

  1. RFC 8414/9728 发现授权服务器元数据
  2. 启动本地回调服务器(随机端口,避免端口冲突)
  3. 打开浏览器 → 用户授权 → 回调获取 authorization_code
  4. code + PKCE (Proof Key for Code Exchange) → Access Token
  5. Token 安全存储:macOS Keychain / Windows Credential Manager

PKCE 是 OAuth 2.1 的必要安全机制,防止授权码被中间人截获后使用。

XAA 跨应用访问流程

对于企业内部的跨应用场景,Claude Code 还支持 **XAA(Cross-Application Access)**流程:

OIDC 登录 → 获取 id_token(缓存复用,避免重复登录)
  → RFC 8693 Token Exchange: id_token → ID-TAG
  → RFC 7523 JWT Bearer Grant: ID-TAG → access_token

这是一个三步令牌变换链,每一步都遵循标准 RFC 规范。XAA 的核心价值是:用户只需登录一次(OIDC),就能访问多个内部系统,无需每个系统都单独认证。

Token 管理的细节

Token 生命周期管理中有几个值得注意的实现细节:

  • Step-up 认证wrapFetchWithStepUpDetection 处理"权限不够,需要更高级别认证"的场景
  • 强制刷新重试createClaudeAiProxyFetch 支持收到 401 后的一次性强制 Token 刷新重试——只重试一次,避免死循环
  • 安全存储:Token 不存放在文件中,而是使用操作系统级的凭证管理器,防止明文泄露

2.4 分区批处理工具编排:并发与正确性的精确平衡

问题:多工具调用的执行顺序

LLM 可能在一次响应中返回多个工具调用。这带来一个关键问题:哪些工具可以并发执行,哪些必须串行?

直觉上,文件读取是"安全的"——并发读 10 个文件不会相互影响。但文件编辑就不行——如果两个编辑操作修改同一个文件,并发执行会导致冲突。Shell 命令更加复杂——git add . && git commit -m "fix" 这样的命令序列显然不能乱序执行。

分区-批处理策略

Claude Code 的 toolOrchestration.ts 实现了一种**"分区-批处理"编排模式**:

LLM 返回 tool_use[] → partitionToolCalls → Batch[]
                            ├── 按 isConcurrencySafe 分区
                            ├── 连续安全工具 → 合并为一个并发批次
                            └── 不安全工具 → 单独作为串行批次

并发批次

  • Promise.all(runToolUseN)
  • 上限:10 并发
  • 上下文修改:延迟收集,批次完成后按序应用

串行批次

  • 逐个 runToolUse
  • 上下文修改:立即应用

注意"上下文修改"的处理方式:并发批次中的工具可能都会修改对话上下文,但并发执行时无法确定顺序。Claude Code 的策略是延迟收集、按序应用——先并发执行所有工具,收集各自的上上下文修改,批次完成后按工具在原始数组中的顺序依次应用。

Hook 集成

工具编排与 Hook 系统紧密集成。每个工具执行前后都会触发 PreToolUse/PostToolUse Hook,Hook 可以:

  • 修改工具输入参数
  • 做出权限决策(allow/deny
  • 修改 MCP 工具的输出结果

但权限决策遵循**“安全优先"原则**:Hook 返回的 allow 不能绕过 settings.json 中的 deny/ask 规则。这确保了 Hook 不能被用来"越权”——一个恶意插件无法通过 Hook 给自己开放被系统禁止的工具。

2.5 插件系统:Skills、Commands 与 Agents 的模块化组合

为什么 Hook 和 MCP 还不够

Hook 是行为级扩展——在生命周期节点注入逻辑片段。MCP 是能力级扩展——接入外部工具和资源。但还有一类需求它们无法优雅满足:工作流级扩展

考虑这样的场景:团队需要一套标准化的代码审查流程——包含一个特定的 Agent 定义(带专用 system prompt 和工具白名单)、几个配套的斜杠命令(如 /review/approve)、一组 Hook(提交前自动运行 lint)、甚至自定义的输出样式。这些组件分属 Hook、MCP、Agent、Command 四个不同的子系统,单独配置既繁琐又容易遗漏。

这就是插件系统要解决的问题:将分散在多个子系统中的组件打包为一个可分发、可安装、可管理的模块

插件的整体架构

Claude Code 的插件系统由三种核心组件构成,每种对应不同的扩展粒度:

组件 定义格式 运行时行为 典型场景
Skills Markdown + Frontmatter 注入 System Prompt,不执行代码 工作流模板(如"提交前必须跑测试")
Commands .md 文件 / TypeScript 模块 响应斜杠命令,本地即时执行 /review/deploy 等自定义命令
Agents Markdown Frontmatter 启动子 Agent,拥有独立工具白名单 代码审查 Agent、测试 Agent

三种组件的设计哲学截然不同:

  • Skills提示级扩展。本质上是结构化的 System Prompt 片段,通过 skillTool 动态注入到对话上下文中。Skill 不执行任何代码,它只改变 Agent 的"思维方式"。

  • Commands行为级扩展。分为三种类型:

    • PromptCommand:最轻量,.md 文件即命令,支持 $ARGUMENTS 占位符
    • LocalCommand:用于 /compact/clear 等无 UI 操作
    • LocalJSXCommand:用于 /config/help 等需要全屏界面的场景

    所有命令都采用懒加载load: () => Promise<>),确保未使用的命令不消耗启动时间。

  • Agents编排级扩展。通过 Markdown Frontmatter 定义 Agent 类型——正文作为 system prompt,YAML header 声明工具白名单、模型配置等元数据。

插件的目录结构与清单

Claude Code 通过约定优于配置的目录结构定义插件:

my-plugin/
├── .claude-plugin/
│   ├── plugin.json        # 插件清单(PluginManifest)
│   └── marketplace.json  # Marketplace 入口
├── commands/             # 斜杠命令(.md 文件或 TypeScript 模块)
├── agents/               # Agent 定义(.md 文件 + Frontmatter)
├── skills/               # Skills(子目录 + SKILL.md)
├── hooks/                # 生命周期钩子(hooks.json)
├── output-styles/        # 输出样式定制
├── .mcp.json             # 内嵌 MCP 服务器配置
└── .lsp.json             # LSP 服务器配置

plugin.json 是插件的清单文件,声明插件的名称、版本、依赖关系和能力矩阵。关键字段包括:

  • 依赖声明:指定插件依赖的其他插件,支持版本约束
  • 能力声明:列出插件提供的 Commands、Agents、Skills、Hooks 和 Output Styles
  • Marketplace 归属:标明插件来源的 Marketplace,用于安全策略评估

注意目录结构中包含了 .mcp.json——这意味着插件可以内嵌 MCP 服务器配置。这是一个精巧的设计:插件安装时自动注册其依赖的 MCP 服务器,卸载时自动清理,避免了手动管理 MCP 配置的麻烦。

发现、加载与注册

插件的生命周期包含三个阶段:发现 → 加载 → 注册

发现阶段pluginLoader.ts 扫描预定义的插件目录,查找包含 .claude-plugin/plugin.json 的子目录。发现过程是递归的,支持嵌套插件结构。

加载阶段:解析 plugin.json 清单,验证格式和版本兼容性。这个阶段的关键是依赖解析——dependencyResolver.ts 使用 **DFS(深度优先搜索)**遍历依赖闭包,具有三个安全规则:

  • 循环检测:使用栈检测循环依赖 → 发现即报错
  • 跨 Marketplace 阻断:默认阻止跨 Marketplace 依赖,除非在 allowCrossMarketplaceDependenciesOn 中显式允许
  • 裸名解析:无 @marketplace 后缀的依赖继承声明插件的 Marketplace

跨 Marketplace 阻断是一个重要的安全决策。想象一个场景:企业内部 Marketplace 的插件 A 依赖了公共 Marketplace 的插件 B——如果 B 被恶意替换,A 也会受到影响。默认阻断这种跨域依赖,从源头切断供应链攻击。

注册阶段:加载完成的插件组件被注册到各自的子系统中:

插件加载完成 → 分发注册
  ├── Commands  → 合并到全局命令注册表(loadPluginCommands)
  ├── Agents     → 合并到 Agent Type Registry(loadPluginAgents)
  ├── Skills     → 注册到 skill 发现目录(子目录扫描 SKILL.md)
  ├── Hooks      → 合并到 Hook 配置(优先级999)
  ├── MCP        → 注入 dynamicMcpConfig(复用现有连接管理)
  └── Output Styles → 注册到输出样式表

注意 Hook 的注册优先级是 999(最低)。这确保了用户设置(优先级0)、项目设置(优先级1)和企业策略(优先级3)都能覆盖插件提供的 Hook。插件永远是最低优先级的配置来源。

插件安全模型

插件加载到主进程地址空间,比 MCP 的进程级隔离风险更大。Claude Code 通过三层安全机制进行防护:

第一层:企业策略过滤pluginPolicy.ts

企业管理员可以通过策略文件精确控制哪些插件允许安装:

策略评估链(按优先级):
  1. blocklist — 明确阻止的插件(黑名单优先)
  2. strictKnownMarketplaces — 仅允许已知来源的 Marketplace
  3. hostPattern — 正则匹配允许的插件仓库域名
  4. pathPattern — 正则匹配允许的插件路径

这四层策略构成了一个先否后允的裁决链:blocklist 一票否决,strictKnownMarketplaces 限制来源,hostPattern 和 pathPattern 提供细粒度的正则匹配。

第二层:信任边界隔离

信任级别 机制 隔离方式 适用场景
低(不可信) MCP 进程级隔离 第三方工具服务
中(可信生态) Plugin 主进程 + 策略过滤 社区贡献的扩展包
高(内部信任) Skill 纯 Prompt,无代码执行 团队工作流模板

Skill 内容即使被恶意注入,其影响范围也仅限于 Agent 的"思考",不会直接操作文件系统或网络。当然,Agent 可能因为恶意 Prompt 而执行危险操作,但这会被第5章的权限模型和第八章的安全纵深防御拦截。

第三层:Hook 命名空间隔离

每个插件的 Hook 使用独立的命名空间,通过 \0(空字符)分隔符的复合键实现隔离。这确保了不同插件的 Hook 不会产生命名冲突,也使得管理员可以精确地禁用或覆盖特定插件的特定 Hook。

2.6 跨模式协作全景

让我们退一步,看看第9章解析的九个设计模式如何协同工作:

                    Agent 核心循环(QueryEngine)
                            │
          ┌─────────────────┼─────────────────┐
          │                 │                 │
    工具编排(模式8)    Hook事件总线(模式1)   MCP工具(模式5/6/7)
          │                 │                 │
          ├── 触发 Pre/PostToolUse Hook      │
          ├── 发起 MCP 工具调用               │
          │                 │                 │
          ▼                 ▼                 ▼
    分区批处理      多态执行器        传输适配器
    (模式9)        (模式2)         (模式6)
          │                 │                 │
          └─────────────────┼─────────────────┘
                            │
                    分级配置合并(模式4)
                    (Hook 和 MCP 统一仲裁)
  • 左侧是 MCP 外部集成线(模式5/6/7):从传输适配到连接管理到认证处理,层层深入。
  • 右侧是 Hook 内部扩展线(模式1/2/3):从事件总线到执行器到会话隔离,逐层细化。
  • **模式4(分级配置合并)**横跨两侧,为 Hook 和 MCP 提供统一的配置解析。
  • **模式8(工具编排)**位于顶层,既触发 Hook 事件,又发起 MCP 工具调用,是两条线的汇聚点。

插件系统(模式9:模块化组合容器)则横跨两条线,扮演"组合容器"的角色。插件将 Hook 定义、MCP 配置、Agent 类型、Skill 模板、Commands 打包成一个可分发的模块。插件不引入新的运行时机制——它的每个组件最终都注册到已有的子系统中运行。


三、横向对比:MCP 协议栈 vs 其他集成方案

维度 Claude Code MCP LSP(语言服务器协议) VS Code Extension API OpenAI Function Calling
协议类型 JSON-RPC 2.0 over 8种传输 JSON-RPC 2.0 over stdio/WebSocket 直接 TypeScript API 调用 JSON Schema 声明
传输灵活性 8种适配器,统一接口 2种(stdio/WebSocket) 无(进程内调用) 无(HTTP API)
连接管理 四层熔断 + memoize 缓存 简单的断开重连 无(扩展生命周期管理) 无(每次请求独立)
认证 OAuth 2.1 + XAA 双流程 无(进程级隔离) 扩展自行处理 API Key(明文)
安全隔离 进程级(MCP)/ 主进程(Plugin) 进程级 主进程 无(服务端验证)
扩展性 插件系统打包分发 无(单个服务器) Extension Pack 无(手动集成)

Claude Code 的 MCP 协议栈在传输灵活性连接管理健壮性两个维度上显著超越其他方案。8 种传输适配器的设计虽然增加了复杂度,但换来了"同一个 MCP 服务器可以在任何环境下运行"的灵活性——这是 Agent 系统需要支持多样化部署场景的必然选择。

OpenAI Function Calling 最简单但也最脆弱——没有连接管理,没有认证状态机,每次请求都是独立的。这对于"一次性工具调用"足够,但对于"需要持久连接的 Agent 工作流"则力不从心。


四、实战启示

启示一:适配器模式的极端版本——协议无关性

当你需要支持多种通信协议时,不要试图"统一协议"(这通常需要所有实现方同时升级),而是"适配协议"——在客户端做协议转换,让上层逻辑看到统一的接口。

Claude Code 的 connectToServer 函数就是一个典范:8 种传输协议,统一收敛到一个 Client 接口。新增传输协议时,只需添加一个适配器类,不需要修改上层逻辑。

启示二:分级熔断比"重试 N 次"更智能

简单的"重试 N 次"策略对待所有错误一视同仁——网络抖动重试5次,认证失败也重试5次,服务器崩溃还是重试5次。这是不对的。

正确的设计是分级熔断

  • 轻故障(网络抖动)→ 自动重连,用户无感
  • 中故障(认证过期)→ 熔断 + 提示用户操作
  • 重故障(服务器崩溃)→ 标记 failed,停止重试

每一级都有明确的触发条件和恢复路径。这比"一刀切"的粗暴策略更智能,也比"为每个错误类型写特殊逻辑"更可维护。

启示三:判别联合类型比"状态字段 + 可选字段"更安全

OAuth 状态机的类型定义如果用"一个 status 字段 + 若干可选字段",会出现"忘记了处理某种状态"的 bug,而且编译器不会报错。

判别联合类型(Discriminated Union),编译器会强制处理每个状态分支。这是 TypeScript 中最强大的类型安全工具之一,特别适合建模"有多种可能状态,每种状态携带不同数据"的场景。

启示四:插件系统 = 约定目录结构 + 清单文件

Claude Code 的插件系统没有用复杂的注册 API 或依赖注入框架,而是用了最简单的文件系统约定——特定的目录结构就是注册表,plugin.json 就是清单。

这种设计的好处是:插件可以纯手工创建(写一个目录 + 一个 JSON 文件),也可以由工具生成;插件的版本控制就是目录的版本控制;插件的调试就是看目录结构对不对。

VS Code 的 Extension 用了类似的思路,但 Claude Code 更极致——连 Skill 都是一个 .md 文件,开发者甚至不需要懂 TypeScript 就能创建 AI 命令。


五、本篇小结

概念 一句话总结
8种传输适配器 stdio/sse/http/ws/sse-ide/ws-ide/sdk/claudeai-proxy,统一收敛到 Client 接口
连接缓存 memoize + 本地/远程分组并发 + InProcessTransport 性能优化
四层熔断 指数退避 → 认证熔断(15min) → 终端错误计数(3次) → 会话过期检测
OAuth状态机 判别联合类型建模,标准OAuth + XAA跨应用访问,Token操作系统级安全存储
分区批处理 isConcurrencySafe 分区 + 并发/串行混合 + 延迟收集按序应用上下文修改
插件三组件 Skills(Prompt级) + Commands(行为级) + Agents(编排级),约定目录结构打包
插件安全三层 企业策略过滤(4层裁决链) + 信任边界隔离 + Hook命名空间隔离
配置优先级 插件Hook固定999(最低),确保用户/企业策略可覆盖

下期预告

第16篇将深入第10章,解析 极简命令式 Store 与分层持久化——Agent 的"记忆宫殿"是如何构建的。30 行代码的 Store 实现、选择器驱动的细粒度订阅、单一 Diff 点的副作用闸门——这些设计体现了"不要为你不需要的能力付出复杂度税"的工程哲学。从"扩展架构"走向"状态管理",挑战从"连接外部"转向"组织内部"。


本篇思考题:插件系统将 Hook 优先级固定为999(最低)——这意味着用户和企业策略总能覆盖插件的 Hook 定义。你认为这个设计是否合理?在什么场景下,插件可能需要更高的优先级?

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐