Published on

Claude Code Remote Control 源码深度解析

Authors

引言

Claude Code 是 Anthropic 推出的终端 AI 编程助手,其 Remote Control 系统允许用户通过 claude.ai 网页端远程操控本地或云端终端中运行的 Claude Code 实例。这一机制打破了终端工具的物理限制,使得 AI 编程能力可以跨设备、跨网络无缝衔接。

本文基于 Claude Code 源码,从架构设计、核心模块、安全机制三个维度,全面解析 Remote Control 系统的技术实现。

一、整体架构

Remote Control 系统由三个核心层构成:

1. Bridge 桥接层(src/bridge/

  • 本地 Claude Code 实例与 claude.ai 后端之间的通信桥梁
  • 负责会话注册、消息路由、权限流转、心跳维持
  • 两种运行模式:Env-based(通过 Environments API 轮询调度)和 Env-less(直接连接 Session Ingress,跳过环境调度层)

2. Remote 会话管理层(src/remote/

  • 管理远程 CCR(Claude Code Remote)会话的生命周期
  • WebSocket 实时消息推送 + HTTP POST 用户消息写入
  • 权限请求/响应的协调

3. Teleport 会话传送层(src/utils/teleport/

  • 封装 Sessions API、Environments API 的调用逻辑
  • Git Bundle 创建与上传,将本地代码上下文"传送"到云端环境
  • 环境选择与会话创建

三者关系如下:

┌─────────────┐     WebSocket/SSE     ┌──────────────────┐
│  claude.ai   │ ◄──────────────────► │  Claude Code     │
│  Web Client  │                       │  (Local/Bridge)  │
└──────┬───────┘                       └────────┬─────────┘
       │                                        │
       │         CCR Backend (Sessions API)      │
       └────────────────┬───────────────────────┘
              ┌─────────▼──────────┐
              │  Environment Layer  │
              │  (Cloud/BYOC/Bridge)│
              └────────────────────┘

二、Bridge 桥接机制

2.1 双模式架构

Bridge 系统存在两条核心路径:

Env-based 路径(replBridge.ts 这是传统的桥接方式,流程为:

  1. 向 Environments API 注册 worker,获取 environment_id
  2. 轮询 /work 端点等待任务分发
  3. 收到 WorkSecret(base64url 编码),解码后获得 session_ingress_tokenapi_base_url、Git 源信息等
  4. 通过 HybridTransport(WebSocket 读 + HTTP POST 写)或 SSETransport + CCRClient(v2 协议)建立双向通信

Env-less 路径(remoteBridgeCore.ts 跳过 Environments API,直接操作 Session:

  1. POST /v1/code/sessions 创建会话 → 获得 session.id
  2. POST /v1/code/sessions/{id}/bridge 获取 worker JWT → 直接建立通信
  3. 通过 createTokenRefreshScheduler 主动刷新 JWT,每次 /bridge 调用都会递增 worker_epoch

这种设计是架构演进的产物——Env-less 路径由 GrowthBook 特性开关 tengu_bridge_repl_v2 控制,代表了更简化的通信模型。

2.2 消息协议

Bridge 的消息处理集中在 bridgeMessaging.ts,核心类型包括:

type SDKMessage = { type: string; ... }  // 判别联合类型
type SDKControlRequest = { type: 'control_request'; request_id: string; request: ... }
type SDKControlResponse = { type: 'control_response'; response: ... }

消息过滤遵循严格规则——只有 userassistant 类型和 subtype === 'local_command' 的系统消息会转发到桥接层,虚拟消息(REPL 内部调用)和工具结果等内部消息被过滤。

2.3 传输抽象

ReplBridgeTransport 接口统一了 v1 和 v2 两种传输协议的差异:

type ReplBridgeTransport = {
  write(message: StdoutMessage): Promise<void>
  writeBatch(messages: StdoutMessage[]): Promise<void>
  connect(): void
  setOnData(callback: (data: string) => void): void
  getLastSequenceNum(): number
  reportState(state: SessionState): void
  reportMetadata(metadata: Record<string, unknown>): void
  reportDelivery(eventId: string, status: 'processing' | 'processed'): void
  flush(): Promise<void>
}
  • v1: HybridTransport — WebSocket 读取 + POST 写入 Session Ingress
  • v2: SSETransport(读取)+ CCRClient(写入 CCR v2 /worker/* 端点)

v2 的写入路径通过 SerialBatchEventUploader 批量上传事件,并支持 reportState(如 requires_action 权限等待状态)和 reportDelivery(事件投递追踪)。

2.4 会话生成与会话隔离

Bridge 支持三种会话生成模式(SpawnMode):

  • single-session: 工作目录中只运行一个会话,会话结束后 Bridge 拆除
  • worktree: 持久化服务,每个会话获得独立的 git worktree,完全隔离
  • same-dir: 持久化服务,所有会话共享工作目录(可能互相干扰)

sessionRunner.ts 通过子进程方式生成 Claude Code 实例,支持权限请求转发(PermissionRequest)和活动状态追踪(SessionActivity)。

三、Teleport 会话传送

3.1 Git Bundle 传送机制

gitBundle.ts 实现了一个精巧的代码传送方案,核心流程:

  1. git stash create → 将未提交的更改保存为 stash 对象
  2. update-ref refs/seed/stash → 使 stash 引用可达(git bundle 只打包可达对象)
  3. git bundle create → 打包所有引用(包括 stash)及其对象
  4. 上传到 /v1/files → 获得文件 ID
  5. 清理 refs/seed/stash → 不污染用户仓库
  6. 调用方将 seed_bundle_file_id 设置在 SessionContext

Bundle 大小有三级降级策略:

  • --all(全量,包含所有分支和标签)→ 超限则
  • HEAD(仅当前分支)→ 超限则
  • squashed-root(单次提交,无历史,仅保留文件快照)

默认大小限制 100MB,可通过 GrowthBook 开关 tengu_ccr_bundle_max_bytes 调整。

3.2 会话上下文

SessionContext 定义了会话的完整上下文:

type SessionContext = {
  sources: Array<GitSource | KnowledgeBaseSource>
  cwd: string
  outcomes: Outcome[] | null
  custom_system_prompt: string | null
  model: string | null
  seed_bundle_file_id?: string
  github_pr?: { owner: string; repo: string; number: number }
}

支持三种来源类型:Git 仓库、知识库,以及 GitHub PR 上下文。

3.3 API 重试策略

Teleport API 采用指数退避重试:[2000, 4000, 8000, 16000]ms,共 4 次重试。仅对瞬态错误(网络错误和 5xx)重试,4xx 客户端错误直接抛出。

四、远程 Agent 任务(RemoteAgentTask)

4.1 RemoteTriggerTool

RemoteTriggerTool 是一个特殊的工具,允许 Claude Code 自身管理远程定时任务触发器:

inputSchema: z.strictObject({
  action: z.enum(['list', 'get', 'create', 'update', 'run']),
  trigger_id: z
    .string()
    .regex(/^[\w-]+$/)
    .optional(),
  body: z.record(z.string(), z.unknown()).optional(),
})

这意味着 Claude Code 可以创建、更新、执行定时远程任务,形成"Agent 调度 Agent"的递归能力。该工具由 GrowthBook 开关 tengu_surreal_dali 控制。

4.2 RemoteSessionManager

RemoteSessionManager 是远程会话的核心协调器:

  • WebSocket 订阅:通过 SessionsWebSocket 连接 /v1/sessions/ws/{id}/subscribe,实时接收消息
  • HTTP POST 写入:用户消息通过 HTTP API 发送
  • 权限流转:维护 pendingPermissionRequests Map,协调工具执行的权限审批

WebSocket 连接协议:

  1. 连接到 wss://api.anthropic.com/v1/sessions/ws/{sessionId}/subscribe?organization_uuid=...
  2. 发送认证消息:{ type: 'auth', credential: { type: 'oauth', token: '...' } }
  3. 接收 SDKMessage 流

重连机制:初始延迟 2s,最多 5 次重连尝试,30s 心跳间隔。对于 4001(session not found)错误,允许 3 次额外重试(compaction 期间服务端可能短暂认为会话过期)。

4.3 远程权限桥接

remotePermissionBridge.ts 解决了一个有趣的问题:远程 CCR 容器中运行的 Claude Code 可能有本地 CLI 不知道的工具(如 MCP 工具)。为此:

  • createSyntheticAssistantMessage:为远程权限请求构造合成的 AssistantMessage,因为本地的权限确认 UI 需要它
  • createToolStub:为未知工具创建最小化的 Tool 存根,路由到 FallbackPermissionRequest

五、远程环境设置

5.1 环境类型

系统支持三种环境类型(EnvironmentKind):

  • anthropic_cloud: Anthropic 托管的云环境
  • byoc: Bring Your Own Container,用户自托管
  • bridge: 桥接模式,连接到本地终端

5.2 GitHub Token 导入

remote-setup/api.ts 中的 importGithubToken 实现了 GitHub Token 的安全导入:

class RedactedGithubToken {
  readonly #value: string // 私有字段,外部无法访问
  reveal(): string {
    return this.#value
  }
  toString(): string {
    return '[REDACTED:gh-token]'
  }
}

Token 发送到 CCR 后端后,由后端验证 GitHub /user 端点,然后以 Fernet 加密存储在 sync_user_tokens 中。这种设计确保了 Token 在日志和错误信息中不会被泄露。

5.3 Web Setup

/web-setup 命令(由 tengu_cobalt_lantern 开关控制)引导用户在 claude.ai 网页端配置 Claude Code,需要连接 GitHub 账号。

六、安全与认证

6.1 多层认证体系

系统采用多层认证:

  1. OAuth 认证:所有 API 调用携带 Bearer Token,Header 包含 anthropic-version: 2023-06-01
  2. 组织级隔离:每个请求携带 x-organization-uuid Header
  3. Worker JWT:Bridge 注册后获得短期 worker JWT,通过 createTokenRefreshScheduler 主动刷新
  4. Trusted Device Token:额外的设备信任令牌层
  5. Session Ingress TokenWorkSecret 中的 session_ingress_token 用于 WebSocket 认证

6.2 WorkSecret 机制

WorkSecret 是 Bridge 认证的核心数据结构:

type WorkSecret = {
  version: number                    // 协议版本,当前为 1
  session_ingress_token: string      // WebSocket 认证令牌
  api_base_url: string               // API 基础 URL
  sources: Array<{ type: string; git_info?: {...} }>  // 代码源信息
  auth: Array<{ type: string; token: string }>        // 认证信息
  claude_code_args?: Record<string, string>           // CLI 参数
  mcp_config?: unknown                                   // MCP 配置
  environment_variables?: Record<string, string>       // 环境变量
}

以 base64url 编码传输,解码时严格验证版本号和必需字段。

6.3 Worker Epoch 防护

v2 协议引入了 worker_epoch 机制——每次 /bridge 调用递增 epoch,子进程的 CCRClient 在每次心跳/状态/事件请求中携带 epoch。这防止了过期 worker 继续发送消息(类似乐观锁)。

6.4 权限控制

  • Feature Gates:核心功能通过 GrowthBook 特性开关控制(如 tengu_bridge_repl_v2tengu_ccr_bridge_multi_session
  • Policy LimitsisPolicyAllowed('allow_remote_sessions') 组织级策略控制
  • Beta Headers:部分 API 需要特定的 beta header(如 ccr-byoc-2025-07-29ccr-triggers-2026-01-30
  • Tool 权限委托:远程工具执行需要本地用户确认,权限请求通过 control_request/control_response 消息对流转

6.5 Session ID 兼容性

sessionIdCompat.ts 处理 CCR v1 和 v2 之间 Session ID 格式差异(v1 使用 session_* 前缀,v2 使用 cse_* 前缀,但底层 UUID 相同)。sameSessionId() 通过比较最后一个下划线后的 UUID 部分实现跨版本兼容。

七、设计亮点总结

  1. 渐进式架构演进:Env-based → Env-less 的路径共存,通过 Feature Gate 平滑过渡,而非一次性重写
  2. 传输协议抽象ReplBridgeTransport 统一了 WebSocket 和 SSE 两种底层传输,上层代码无感知
  3. Git Bundle 三级降级:全量 → HEAD → Squashed,在代码传送的完整性和大小之间取得平衡
  4. 权限模型的一致性抽象:通过合成消息和工具存根,让本地 UI 无需区分本地和远程工具
  5. 防御性编程RedactedGithubToken 的私有字段设计、WorkSecret 的严格解码校验、重试次数限制等

Claude Code 的 Remote Control 系统展示了如何将一个终端工具安全地延伸到云端,同时保持本地开发体验的完整性。其架构上的渐进演进策略和多层安全设计,对构建类似的远程 AI Agent 系统具有很强的参考价值。