这是什么
Remote Control 让本地的 qsdashi 会话不再局限于当前终端:CLI 会把自己注册成一个
bridge 环境,持续长轮询等待任务;你可以从浏览器(甚至手机)打开 Web UI,选中该环境后
创建会话、发指令、审批工具权限。本地终端成为「执行者」,控制面在浏览器里。
中间层是 Remote Control Server (RCS)——一个纯内存的中间服务,负责环境注册、工作轮询、 消息双向传输与会话管理。它有两种部署形态:
| 形态 | 认证方式 | 门控 | 数据流经 |
|---|---|---|---|
| 自托管 RCS | API Key(RCS_API_KEYS) |
设置 CLAUDE_BRIDGE_BASE_URL 后自动跳过 GrowthBook / 订阅检查 |
你自己的服务器 |
| 云端(Anthropic CCR) | claude.ai OAuth 订阅 | 需要 tengu_ccr_bridge 通过 |
Anthropic 基础设施 |
两种形态都要求构建时启用 BRIDGE_MODE feature flag。自托管模式的核心优势是:
只要设置了 CLAUDE_BRIDGE_BASE_URL,代码里的 isSelfHostedBridge()
即返回 true,无需 claude.ai 账户即可使用。
RCS 的职责:
- 接收 CLI 的环境注册与工作轮询(长轮询 + 心跳保活)
- 接收
acp-link的 ACP agent 注册,支持 WebSocket relay 桥接 - 提供 Web UI 供操作者远程监控与审批
- 通过 WebSocket / SSE 双向传输消息,管理会话、环境与权限请求
前置条件
- 服务器:一台能被 CLI 与浏览器同时访问的机器(物理机 / VM / 容器均可)。
-
Docker:容器化部署 RCS 时需要;若用
bun run rcs本地启动,则只需 Bun。 -
启用 BRIDGE_MODE 的构建:dev 模式默认启用;build 模式的默认 feature 列表也包含
BRIDGE_MODE。运行时可用FEATURE_BRIDGE_MODE=1显式开启。 -
自托管模式不需要 claude.ai 账户,只需要一组与服务器端
RCS_API_KEYS匹配的令牌。
RCS 用内存 Map 存储会话与环境,重启后数据全部丢失,且不支持水平扩展(单实例部署)。
/app/data 卷已预留但当前未使用。
安装与启动
任选一种方式部署 RCS,然后按「实战示例」用 CLI 连接。
在项目根目录构建镜像,再以环境变量启动容器。
# 构建镜像
docker build -t rcs:latest -f packages/remote-control-server/Dockerfile .
# 启动容器
docker run -d \
--name rcs \
-p 3000:3000 \
-e RCS_API_KEYS=sk-rcs-your-secret-key-here \
-e RCS_BASE_URL=https://rcs.example.com \
-v rcs-data:/app/data \
--restart unless-stopped \
rcs:latest
也可直接用预构建镜像
ghcr.io/qianshou-dashi/remote-control-server:latest 启动。
services:
rcs:
build:
context: .
dockerfile: packages/remote-control-server/Dockerfile
args:
VERSION: "0.1.0"
ports:
- "3000:3000"
environment:
- RCS_API_KEYS=sk-rcs-your-secret-key-here
- RCS_BASE_URL=https://rcs.example.com
volumes:
- rcs-data:/app/data
restart: unless-stopped
volumes:
rcs-data:
docker compose up -d
仓库根 package.json 提供 rcs 脚本,执行
scripts/rcs.ts,读取 RCS 配置后用 Bun.serve 起服务。
# 默认监听 3000 端口
bun run rcs
# 覆盖端口与密钥
RCS_API_KEYS=key1,key2 RCS_PORT=4000 bun run rcs
curl https://rcs.example.com/health
# 预期: {"status":"ok","version":"0.1.0"}
配置
服务器端环境变量(由 packages/remote-control-server/src/config.ts 读取):
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
RCS_API_KEYS |
是 | (空) | API 密钥列表,逗号分隔。用于客户端认证与 JWT 签名,务必设置强密钥 |
RCS_PORT |
否 | 3000 |
服务监听端口 |
RCS_HOST |
否 | 0.0.0.0 |
服务监听地址 |
RCS_BASE_URL |
否 | http://localhost:<port> |
外部访问 URL,用于生成 WebSocket 连接地址,须与客户端实际访问地址一致 |
RCS_VERSION |
否 | 0.1.0 |
版本号,显示在 /health 响应中 |
RCS_POLL_TIMEOUT |
否 | 8 |
V1 工作轮询超时(秒) |
RCS_HEARTBEAT_INTERVAL |
否 | 20 |
心跳间隔(秒) |
RCS_JWT_EXPIRES_IN |
否 | 3600 |
JWT 令牌有效期(秒) |
RCS_DISCONNECT_TIMEOUT |
否 | 300 |
断线判定超时(秒) |
RCS_WS_IDLE_TIMEOUT |
否 | 30 |
WebSocket 空闲超时(秒),Bun 发送协议级 ping |
RCS_WS_KEEPALIVE_INTERVAL |
否 | 20 |
服务端到客户端 keep_alive 帧间隔(秒),防止反向代理关闭空闲连接 |
RCS_WEB_CORS_ORIGINS |
否 | (空) | Web UI 跨域允许来源列表,逗号分隔 |
客户端(qsdashi CLI)环境变量:
| 变量 | 必填 | 说明 |
|---|---|---|
CLAUDE_BRIDGE_BASE_URL |
是 | RCS 服务器地址,如 https://rcs.example.com。设置此变量即启用自托管模式,跳过 GrowthBook 门控 |
CLAUDE_BRIDGE_OAUTH_TOKEN |
是 | 认证令牌,必须与服务器端 RCS_API_KEYS 中的某个值匹配 |
CLAUDE_BRIDGE_SESSION_INGRESS_URL |
否 | WebSocket 入口地址,默认与 CLAUDE_BRIDGE_BASE_URL 相同 |
QS_REMOTE |
否 | 设为 1 时标记为远程执行模式 |
客户端与 Worker 连接用 API Key 校验,并由 RCS_API_KEYS 派生
JWT;浏览器 Web UI 则使用 UUID 绑定会话(无用户账户、无登录),适合受信任网络环境。
常用命令与参数
CLI 子命令(cli.tsx 快速路径,均需 BRIDGE_MODE 启用):
| 命令 | 说明 |
|---|---|
qsdashi remote-control |
把本机作为 bridge 环境启动,接受远程会话 |
qsdashi rc |
同上,简写 |
qsdashi remote |
旧别名,行为一致 |
qsdashi sync |
旧别名,行为一致 |
qsdashi bridge |
旧别名,行为一致 |
其他相关入口:
| 入口 | 行为 |
|---|---|
qsdashi --remote-control [name] |
启动交互式会话并启用 Remote Control,可附带会话名 |
qsdashi --rc [name] |
--remote-control 的别名 |
/remote-control(别名 /rc) |
会话内命令,连接当前终端以进行远程控制,可带 [name] |
bun run rcs |
在仓库内启动 RCS 服务(scripts/rcs.ts) |
已连接后再次执行 /remote-control 会弹出对话框,包含
Disconnect this session(断开远程连接)、Show QR code(显示 / 隐藏二维码)、
Continue(保持连接继续使用)三个选项。
实战示例
1. 在 CLI 所在机器设置连接变量:
export CLAUDE_BRIDGE_BASE_URL="https://rcs.example.com"
export CLAUDE_BRIDGE_OAUTH_TOKEN="sk-rcs-your-secret-key-here"
2. 启动并注册环境:在 REPL 中执行 /remote-control,
或直接用子命令启动。环境型 Remote Control 注册成功后会打印连接 URL:
# 发布版默认包含 BRIDGE_MODE
CLAUDE_BRIDGE_BASE_URL=https://rcs.example.com \
CLAUDE_BRIDGE_OAUTH_TOKEN=sk-rcs-your-secret-key-here \
qsdashi
# REPL 内执行
/remote-control
# 终端会显示环境 URL:
# https://rcs.example.com/code?bridge=<environmentId>
# 某些桥接模式下给出会话 URL:https://rcs.example.com/code/session_<id>
3. 在浏览器打开 URL 操控。两种 URL 都能直接打开;只有 environment 模式会出现在
Web UI 的环境列表中。Web UI 位于 /code/* 路径,基于 React + Vite + Radix UI,
可查看运行环境、创建会话、实时查看对话与工具调用、审批权限、选择权限模式与模型、
查看 Plan 可视化,并支持 QR 码扫描跳转 ACP 直连视图。
4.(可选)把 ACP agent 接入 RCS:
ACP_RCS_URL=http://localhost:3000 \
ACP_RCS_TOKEN=sk-rcs-your-key \
acp-link qsdashi -- --acp
注册后 ACP session 会在 Web UI 中显示品牌色标签,与普通 qsdashi session 区分。 详见 ACP 页面。
Nginx 需设置 proxy_http_version 1.1、Upgrade 与
Connection "upgrade" 头,并把 proxy_read_timeout 调大
(建议 86400 秒);Caddy 的 reverse_proxy 会自动处理。
常见问题排错
原因是 BRIDGE_MODE feature flag 未启用。使用 dev 模式(默认启用)
或确保构建时包含该 flag,也可用 FEATURE_BRIDGE_MODE=1 显式开启。
检查 CLAUDE_BRIDGE_OAUTH_TOKEN 是否与 RCS_API_KEYS 中某个值
完全一致,确认 key 没有多余空格或换行,并确认两个环境变量都已设置。
若经反向代理,确认已正确配置 WebSocket 升级(Upgrade /
Connection 头),proxy_read_timeout 足够大,且防火墙放行
WebSocket 流量。RCS 会以 RCS_WS_IDLE_TIMEOUT 与
RCS_WS_KEEPALIVE_INTERVAL 保活。
standby 表示 proactive 已开启、正等待下一个 tick;sleeping
表示模型正在 SleepTool 等待窗口。两者通过 worker 的
external_metadata.automation_state 上报。若只显示普通 working spinner,
优先检查 CLI 与 RCS 之间的 worker metadata PUT 是否成功。
RCS 是纯内存存储,服务器重启后所有会话与环境数据丢失;也不支持水平扩展, 仅适合单实例的中小规模使用。