- Published on
Claude Code Remote Control 源码深度解析
- Authors
- Name
- 大聪明
- @wooluoo
引言
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) 这是传统的桥接方式,流程为:
- 向 Environments API 注册 worker,获取
environment_id - 轮询
/work端点等待任务分发 - 收到
WorkSecret(base64url 编码),解码后获得session_ingress_token、api_base_url、Git 源信息等 - 通过 HybridTransport(WebSocket 读 + HTTP POST 写)或 SSETransport + CCRClient(v2 协议)建立双向通信
Env-less 路径(remoteBridgeCore.ts) 跳过 Environments API,直接操作 Session:
POST /v1/code/sessions创建会话 → 获得session.idPOST /v1/code/sessions/{id}/bridge获取 worker JWT → 直接建立通信- 通过
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: ... }
消息过滤遵循严格规则——只有 user、assistant 类型和 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 实现了一个精巧的代码传送方案,核心流程:
git stash create→ 将未提交的更改保存为 stash 对象update-ref refs/seed/stash→ 使 stash 引用可达(git bundle 只打包可达对象)git bundle create→ 打包所有引用(包括 stash)及其对象- 上传到
/v1/files→ 获得文件 ID - 清理
refs/seed/stash→ 不污染用户仓库 - 调用方将
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 发送
- 权限流转:维护
pendingPermissionRequestsMap,协调工具执行的权限审批
WebSocket 连接协议:
- 连接到
wss://api.anthropic.com/v1/sessions/ws/{sessionId}/subscribe?organization_uuid=... - 发送认证消息:
{ type: 'auth', credential: { type: 'oauth', token: '...' } } - 接收 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 多层认证体系
系统采用多层认证:
- OAuth 认证:所有 API 调用携带 Bearer Token,Header 包含
anthropic-version: 2023-06-01 - 组织级隔离:每个请求携带
x-organization-uuidHeader - Worker JWT:Bridge 注册后获得短期 worker JWT,通过
createTokenRefreshScheduler主动刷新 - Trusted Device Token:额外的设备信任令牌层
- Session Ingress Token:
WorkSecret中的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_v2、tengu_ccr_bridge_multi_session) - Policy Limits:
isPolicyAllowed('allow_remote_sessions')组织级策略控制 - Beta Headers:部分 API 需要特定的 beta header(如
ccr-byoc-2025-07-29、ccr-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 部分实现跨版本兼容。
七、设计亮点总结
- 渐进式架构演进:Env-based → Env-less 的路径共存,通过 Feature Gate 平滑过渡,而非一次性重写
- 传输协议抽象:
ReplBridgeTransport统一了 WebSocket 和 SSE 两种底层传输,上层代码无感知 - Git Bundle 三级降级:全量 → HEAD → Squashed,在代码传送的完整性和大小之间取得平衡
- 权限模型的一致性抽象:通过合成消息和工具存根,让本地 UI 无需区分本地和远程工具
- 防御性编程:
RedactedGithubToken的私有字段设计、WorkSecret 的严格解码校验、重试次数限制等
Claude Code 的 Remote Control 系统展示了如何将一个终端工具安全地延伸到云端,同时保持本地开发体验的完整性。其架构上的渐进演进策略和多层安全设计,对构建类似的远程 AI Agent 系统具有很强的参考价值。