服务与外部集成
services 和 utils 撑起 CLI 的外围能力:多 provider API、MCP、插件与技能、权限、长上下文、LSP/IDE/Chrome、远程桥接和托管设置。
1. services 与 utils 的分工#
src/services 更像业务服务层:API、MCP、analytics、compact、LSP、OAuth、remote managed settings、policy limits、memory sync 等都在这里。
src/utils 是最大目录,更像横切基础设施层:plugins、permissions、settings、model、bash、shell、computer use、telemetry、worktree、session storage、secure storage、hooks、teleport 等都在这里。
简单说:
services负责“一个完整业务能力如何对外工作”;utils负责“所有业务能力都要用到的基础机制”。
2. API 与模型 provider#
src/services/api/client.ts 把多种模型后端统一成 Anthropic SDK 风格客户端。支持的主要分支:
| Provider | 触发条件 | 认证/配置要点 |
|---|---|---|
| Anthropic first-party | 默认 | API key 或 Claude.ai OAuth token,自定义 headers,base URL,request id |
| Bedrock | CLAUDE_CODE_USE_BEDROCK | AWS region、小模型 region override、AWS bearer token、AWS credential refresh |
| Foundry | CLAUDE_CODE_USE_FOUNDRY | Azure Foundry API key 或 Azure AD DefaultAzureCredential |
| Vertex | CLAUDE_CODE_USE_VERTEX | GCP credential refresh、GoogleAuth、model-specific region、project id fallback |
client 统一注入 x-app、User-Agent、session id、container/remote session id、SDK client app 等 headers。对 first-party API,还会通过 fetch wrapper 添加 x-client-request-id,让 timeout 等无服务端 request id 的故障也能关联日志。
这个设计说明模型 provider 兼容是运行时能力,而不是编译时换包。
3. Analytics、GrowthBook、Telemetry#
services/analytics 不只是统计事件,也承担 feature gate 动态控制。几个关键点:
entrypoints/init.ts会延后动态导入 1P event logging / GrowthBook / OpenTelemetry 相关依赖,降低冷启动成本。initializeTelemetryAfterTrust()把遥测初始化放到 trust 之后,remote settings 用户还会先等待设置加载并重新应用环境变量。- GrowthBook gate 控制大量能力:streaming tool execution、bridge v2、context collapse、auto mode、history snip、MCP skills、workflow、assistant 等。
utils/telemetry/sessionTracing.ts、services/tools/toolExecution.ts里有 tool span、blocked-on-user span、content event 等细粒度 tracing。
也就是说,analytics 层同时是观测系统和动态配置系统。
4. MCP 子系统#
src/services/mcp/client.ts 是最复杂的服务之一,MCP 在这里已经是一条完整产品线。
支持的 transport
代码里能看到这些 server 类型:
stdio:本地子进程;sse;http/ Streamable HTTP;ws/ websocket;sse-ide/ws-ide:IDE 集成;claudeai-proxy:通过 claude.ai MCP proxy;sdk:SDK 同进程 control transport;- 特殊 in-process server:Claude in Chrome、Computer Use MCP。
MCP transport 处理了很多真实环境问题:
- HTTP POST 必须带
Accept: application/json, text/event-stream; - GET SSE stream 不加普通 request timeout;
- 每个 POST 使用新 timeout signal,避免 stale
AbortSignal.timeout(); - 401/Unauthorized 会进入 needs-auth 状态,并写 15 分钟 auth cache;
- claude.ai proxy fetch 带 OAuth bearer token,并在 401 时刷新 token 后重试一次;
- HTTP session expired 通过 404 + JSON-RPC
-32001检测,清连接缓存并重连; - SSE 最大重连耗尽时主动 close client,让 pending tool calls reject 而不是挂死;
- stdio server cleanup 会按 SIGINT → SIGTERM → SIGKILL 快速升级。
MCP tool/prompt/resource 映射
MCP server 连接成功后会并行抓取:
tools/list→ 转成内部Tool;prompts/list→ 转成 slashCommand;resources/list→ 转成ServerResource;- 可选
skill://resources → MCP skills。
MCP tool 转内部 Tool 时会处理:
- 名称:默认
mcp__server__tool,SDK no-prefix 模式可保留原名; mcpInfo:保留原始 server/tool name,用于权限;annotations.readOnlyHint/destructiveHint/openWorldHint;_meta['anthropic/searchHint']与_meta['anthropic/alwaysLoad'];- description/instructions 最大 2048 字符裁剪;
checkPermissions()默认要求 MCP 权限,并给出 addRules suggestion;- progress:started/progress/completed/failed;
- Claude in Chrome / Computer Use MCP 的工具渲染 override。
MCP prompt 会转成 type: 'prompt' 的 Command,名字形如 mcp__server__prompt,执行时调用 client.getPrompt() 并把返回 content 转成模型消息块。
MCP result 处理
MCP 结果不是直接塞上下文:
- text 直接变 text block;
- image 会 resize/downsample;
- audio/binary blob 会落盘,返回文件路径说明;
- resource text/blob/resource_link 分别处理;
structuredContent会转 JSON,并推断 compact schema;- 大结果可持久化为文件并返回读取说明;含图片的大结果不持久化为 JSON,而是回退截断,保留图片可视性。
URL elicitation 也被纳入工具调用流程:当 MCP 返回 UrlElicitationRequired (-32042) 时,会先跑 hooks,再根据 headless/SDK 或 REPL 走 structuredIO callback 或 UI queue,用户完成后重试 tool call,最多 3 次。
5. MCP 与上层产品的连接#
MCP 不是孤立 service,它贯穿多层:
services/mcp/client.ts:连接、工具/资源/prompt 转换、认证、结果处理。tools/MCPTool、ListMcpResourcesTool、ReadMcpResourceTool、ReadMcpResourceDirTool、RefreshMcpTools、SearchMcpRegistry:模型可调用面。2.1.233 没有单独的McpAuth。commands/mcp/*:用户管理面。components/mcp/*:UI 状态与面板。AppState.mcp:clients/tools/commands/resources/pluginReconnectKey。commands.ts:MCP prompt/skill 进入 slash/SkillTool 生态。utils/permissions:MCP 工具名和 server-level rule 匹配。
这就是为什么文档里说 MCP 是“完整产品线”,而不是简单第三方接口。
6. 插件与技能生态#
插件相关代码主要分布在:
utils/plugins/*:发现、安装、缓存、市场、版本、策略、校验、加载、hot reload。commands/plugin/*:插件市场、安装、启用/禁用、信任、错误展示。plugins/bundled/*、plugins/builtinPlugins.ts:内建/捆绑插件。commands.ts:插件 commands、plugin skills 进入命令系统。services/mcp:插件也可以带 MCP servers。AppState.plugins:enabled/disabled/errors/installationStatus/needsRefresh。
Skills 也有多来源:skills/bundled、用户 skill dirs、plugin skills、builtin plugin skills、dynamic skills、MCP skills。
命令系统会把它们统一成 prompt 型 Command,再由 SkillTool 暴露给模型。这说明“插件 + MCP + 技能”在产品上已经趋向统一扩展生态。
7. 权限与安全基础设施#
权限涉及多个目录:
utils/permissions/*:规则、parser、loader、classifier、auto mode、deny tracking、permission update schema。hooks/useCanUseTool.tsx与hooks/toolPermission/*:权限调用入口、队列、interactive/coordinator/swarm/bridge/channel handler。components/permissions/*:用户审批 UI。tools/*/checkPermissions():工具自己的安全规则。utils/bash/*、tools/BashTool/*:Shell AST 和命令风险控制。utils/sandbox/*:sandbox adapter。
权限规则支持多来源:settings、policy、flag、CLI arg、command、session。规则可以是整工具,也可以是内容级,例如 Bash(git status:*) 或 MCP server-level mcp__server。关键安全特征:
- deny/ask/safetyCheck 优先于 bypass;
bypassPermissions仍会受 root/sudo、sandbox、网络可达性等启动校验约束;- auto mode 不是无条件放行,而是结合 fast path、allowlist、classifier、deny tracking;
- headless/async agent 无法弹窗时,会先跑 PermissionRequest hooks,再自动 deny;
- Bash 使用 tree-sitter 与多层 validator,避免纯正则判断复杂 shell。
8. Compact、memory 与上下文治理#
长上下文治理散布在几处:
services/compact/autoCompact.ts、compact.ts:自动 compact 与 compact message 构造。services/compact/microCompact.ts、sessionMemoryCompact.ts、postCompactCleanup.ts:旧工具结果清理、session-memory compact、压缩后缓存清理。query.ts:prompt-too-long / media-size / max-output-tokens 等错误后的恢复分支,以及 history snip、context collapse feature 分支。utils/toolResultStorage.ts:大 tool result 替换/落盘。utils/attachments.ts:memory/file-change/queued command attachments。services/SessionMemory、memdir/*、services/teamMemorySync/*、services/extractMemories/*:会话/团队记忆。memory_list/memory_read/memory_write:连上的 project memory store,和本地 auto memory 目录不是一条路。
这说明项目把 token/context 当成长期运行时资源管理,而不是“超过就报错”。reactive compact / context collapse 走 query.ts 与 compact / microcompact / session-memory compact 这些路径。
9. LSP、IDE、Chrome、Computer Use#
外部开发环境集成主要包括:
services/lsp:LSP manager,与LSPTool、插件推荐、IDE 状态相关。utils/ide与 MCP IDE transport:IDE server 连接、callIdeRpc()。utils/claudeInChrome:Chrome MCP server 可 in-process 启动,避免大子进程开销。utils/computerUse:Computer Use MCP wrapper、锁、执行器、平台适配、UI 状态。- Chrome / Computer Use 走 MCP,不单独占 2.1.233 工具表里的
WebBrowser/Tungsten名。
这些能力说明 CLI 的“外部世界”不只是文件系统和 shell,还包括 IDE、浏览器、桌面应用和远程会话。
10. Remote bridge / CCR#
src/bridge 是远程控制与 session ingress 的主链路。这里有两类重要路径。
env-based bridge:bridgeMain.ts / replBridge.ts
传统路径会注册 environment、创建 session、poll work、spawn child CLI、heartbeat、stop work、cleanup。bridgeMain.ts 的 runBridgeLoop() 管理:active sessions;work id 与 session id 映射;session ingress JWT;token refresh;heartbeat 与 auth failure re-dispatch;worktree 创建/删除;timeout watchdog;capacity wake;fatal backoff 与 shutdown cleanup。
sessionRunner.ts 会真正 spawn 子进程:
claude --print --sdk-url <url> --session-id <id>
--input-format stream-json --output-format stream-json
--replay-user-messages
子进程环境会带 CLAUDE_CODE_SESSION_ACCESS_TOKEN,并可启用 CCR v2 env vars。父进程解析子进程 stdout NDJSON,提取 tool activity、assistant text、result、control_request,并通过 stdin 下发 token refresh 或控制消息。
env-less bridge:remoteBridgeCore.ts
remoteBridgeCore.ts 明确说明了“env-less Remote Control bridge core”:
POST /v1/code/sessions创建 session;POST /v1/code/sessions/{id}/bridge用 OAuth 换 worker JWT、api base URL、worker epoch;- 用
createV2ReplTransport()建 SSE + CCRClient; - token refresh 时重新调用
/bridge,因为每次会 bump epoch; - SSE 401 时重建 transport。
它去掉了 Environments API 的 register/poll/ack/stop/heartbeat/deregister 生命周期,更适合 REPL 远程控制。文件注释也强调:env-less 说的是去掉 environment/poll dispatch 层,不等同于 CCR v2 transport 本身。
11. remote / server / cli transport#
src/remote:远程会话管理、sessions websocket、viewer 类能力。src/server:直连 session 与 server 侧抽象。src/cli/transports:headless/remote IO 的 HybridTransport、SSETransport、WebSocketTransport、event uploader、worker state uploader。
这些模块共同把本地 CLI、SDK、远程 Web/Mobile、CCR worker 串起来。
12. Settings、remote managed settings、policy limits#
设置系统散布在:
utils/settings/*:读取、校验、应用、变更检测、MDM raw read。services/remoteManagedSettings/*:远端托管设置。services/policyLimits/*:策略限制。utils/managedEnv.ts:从配置应用环境变量。AppStateProvider/applySettingsChange():设置变化同步到 UI 状态。
关键设计是“trust 前后分层”:trust 前只应用 safe env;trust 后才完整应用环境与遥测。远端策略还能在会话中禁用 bypass permissions 等高风险能力。
13. vendor 目录#
recovered/vendor 只有四个包装:
audio-capture-src/index.tsimage-processor-src/index.tsmodifiers-napi-src/index.tsurl-handler-src/index.ts
数量少但意义明确:平台/原生能力被封装在 vendor 层,主仓主体仍是 TypeScript 业务与运行时代码。
14. 这一层的结论#
这一层覆盖的外围能力:
- API provider 与认证让它能运行在不同云和账号形态;
- MCP/插件/技能构成扩展生态;
- 权限、sandbox、bash AST、classifier 让工具执行有治理;
- compact/memory/tool result storage 让长会话可持续;
- bridge/remote/cli transports 让本地终端变成远程 session endpoint;
- settings/policy/telemetry 让它具备产品化运营和企业托管能力。