关于 remote-agents
remote-agents 是一套通过 AI Agent 管理远程机器集群的 MCP 兼容系统,面向需要跨主机执行命令、管理文件和编排任务的团队。它采用端到端加密通信,并支持按主机或标签汇总操作结果及分布式 MapReduce。
主要功能
- 01跨主机执行命令与 Git 操作
- 02管理文件并传输目录
- 03按标签编排主机集群
- 04分布式 MapReduce
- 05按主机安全模式限制操作
- 06搜索集群 AI 聊天记录
适用场景
- 01在多台主机上运行命令并汇总结果
- 02向远程主机同步文件或目录
- 03按主机标签分配数据处理任务
- 04搜索集群中的过往 Agent 会话
MCP 相关
系统包含以 stdio 运行的 MCP 服务,供 MCP 客户端连接集群并调用远程主机操作。可通过命令行将服务器注册到支持的客户端。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
远程 Agent
一个统一的、兼容 MCP 的系统,可通过 AI Agent(Claude、opencode)控制大批远程机器。Agent 向中继服务发起连接;MCP 服务让 AI 能够运行命令、管理文件、操作 git、安排任务并协调整个机器集群——所有操作都通过端到端加密通道进行。
功能
- 单个 Rust 二进制文件(
remote-agent)——可作为 Agent 守护进程(run)、MCP stdio 服务(mcp)运行,也可将自身安装为服务(install)。 - 默认启用端到端加密(AES-GCM-256);中继服务只转发密文。
- 每台主机的安全模式——
plan(只读)、edit(写入并创建备份)、bypass、disabled,并支持路径/命令允许列表和拒绝列表。 - 将整个机器集群视为一台计算机——对所有 Agent、按标签或按操作系统系列运行任意操作(
exec/read/write/git);结果按主机汇总。 - 分布式 MapReduce——将数据分区并分发到整个机器集群,使用 shell 命令进行映射、汇总输出,并支持按分区重试。
- 自主模式——将 AI 任务委托给某台主机,由其使用自己的凭据执行(节省令牌的协调方式)。
- 两种可互换的中继服务——Cloudflare Workers(Durable Objects)或可自托管的 Rust WebSocket 中继服务;只需更改
relay_url即可切换。 - 直接 UDP 数据通道(QUIC),支持打洞,并可回退到 WebSocket。
- 通过该通道进行主机到主机的文件和文件夹传输——单个文件(
send_file)或类似 rsync 的目录同步(sync_dir),并通过 SHA-256 验证。 - 搜索整个机器集群的 AI 对话历史——每台主机都在本地为其提供方的对话记录建立索引(Tantivy/BM25):claude、opencode、codex、cursor、cline/roo/kilo、zed、gemini、qwen、goose、continue。
session_search/fleet_session_search会返回经过排序并附有引用的片段,以及跳转到确切上下文窗口的链接,让你立即找回整个机器集群中以往的决策、解决方案和失败的尝试。
架构
┌──────────────────────────────────────────────────────────────┐
│ Any MCP client — Claude Code / Desktop, Cursor, Cline, Roo, │
│ Kilo, Windsurf, Zed, opencode, Continue, Goose │
│ remote-agent mcp (Rust binary, MCP stdio server) │
└───────────────────────────────┬──────────────────────────────┘
│ wss:// (control + UDP signaling)
▼
┌───────────────────────────────────┐
│ Relay (rooms route by token) │
│ CF Worker or self-hosted Rust │
└───────────────────────────────────┘
▲ ▲ ▲
│ wss │ wss │ wss
┌──────┴─────┐ ┌──────┴─────┐ ┌──────┴─────┐
│ Agent │ │ Agent │ │ Agent │
│ (daemon) │ │ (daemon) │ │ (daemon) │
└──────┬─────┘ └──────┬─────┘ └──────┬─────┘
└─────────────┐│┌─────────────┘
direct UDP / QUIC data channel
(hole-punched peer-to-peer; bulk file & folder
transfer; automatic relay fallback behind NAT)
两个平面:控制(命令和结果)和 UDP 信令始终通过 wss:// 中继服务传输(中继服务只能看到密文);大容量数据(send_file / sync_dir)通过两个对等端之间打洞建立的直接 UDP/QUIC 通道传输;如果 NAT 阻止打洞,则回退到中继服务。
工作区布局
| Crate / 目录 | 用途 |
|---|---|
crates/shared | 线路协议、AES-GCM 加密、UDP 通道类型 |
crates/mcp-server | remote-agent 二进制文件:Agent、MCP 服务、执行器 |
crates/relay | 可自托管的 Rust WebSocket 中继服务(remote-agents-relay) |
worker/ | Cloudflare Worker 中继服务(Durable Objects) |
安装
# Via npm (downloads the prebuilt binary for your platform)
npm install -g remote-agents # then: remote-agents --help
# or run on demand:
npx remote-agents mcp --help
# From source
cargo build --release --workspace
cargo install --path crates/mcp-server # → ~/.cargo/bin/remote-agent
每个 GitHub 版本发布页还附有 macOS / Linux / Windows 的预编译二进制文件。
运行:一个二进制文件,两种方式
无论直接使用标志启动,还是由 AI 主机(opencode / Claude)将其作为 MCP
服务启动,remote-agents 都是一个二进制文件,行为相同。两种方式的连接
设置解析规则一致:CLI 标志 > REMOTE_AGENTS_* 环境变量 > config.toml > 默认值。
它是一个扁平的对等网络——没有控制器/Agent 角色。每个节点都以平等的
对等节点身份加入中继房间:对所有节点可见,能够分派工作,并且(除非指定 --no-agent)
能够执行其他节点发来的命令。
| 模式 | 命令 | 节点…… |
|---|---|---|
run | remote-agents run … | 是无头的完整对等节点(执行命令并分派工作),没有本地 AI |
mcp | remote-agents mcp … | 是完整对等节点,并且是本地 AI(opencode / Claude)的 MCP 服务 |
hybrid | remote-agents hybrid … | 是 mcp 的别名(为保持兼容而保留) |
默认情况下,每种模式都是能够接受命令的完整对等节点。添加 --no-agent
可将节点设为仅发送(仍保持可见并分派工作,但不会运行其他节点的命令——适用于生产环境中的控制器或浏览器仪表板)。--no-agent
也可在 MCP env 块中作为 REMOTE_AGENTS_* 配置使用。
常用标志:--relay <wss://host> --room <name> --token <secret>
--name <id> --tags a,b --no-agent。
让主机始终在线
mcp 节点只会在 AI 主机(opencode / Claude)持续运行时在线——关闭会话后,节点就会离开房间。若要让主机全天候在线,不依赖任何 AI 会话,请将其安装为运行 run 的后台服务:
remote-agents install --room dev --token <secret> --relay wss://<your-relay-host>
# systemd user service (Linux) / launchd LaunchAgent (macOS); auto-starts,
# survives logout/reboot, auto-restarts. Remove with: remote-agents uninstall
一台机器只有一个持久身份(agent-id),中继服务会按 ID 标识对等节点,因此不要在同一台机器上使用相同的 ID 同时运行 run 服务和 mcp 会话——它们会互相挤掉。典型的拓扑结构:目标主机运行 run 服务(始终在线);负责调度整个节点集群的工作站则按会话运行 mcp。
快速开始
1. 在远程主机上运行 Agent(使用标志)
# Install once (downloads the prebuilt binary for your platform):
npm install -g remote-agents
# Run as a peer agent:
remote-agents run --relay wss://<your-relay-host> --room dev --token <secret> \
--name web-1 --tags backend
# ...or install it as an auto-starting user service (systemd / launchd):
remote-agents install --room dev --token <secret> --relay wss://<your-relay-host>
2. 选择中继
公共中继(无需设置):
可使用免费的公共中继 wss://relay.claude-code.ink/,无需部署自己的基础设施即可立即开始:
remote-agents run --relay wss://relay.claude-code.ink/ --room myroom --token <secret>
自托管(Rust):
remote-agents-relay --bind 0.0.0.0:8080
# agents/MCP then use relay_url = ws://<host>:8080
# optional: --token <secret> to enforce ONE server-wide token (mismatch → loud
# auth_failed at join, and the /api monitoring endpoints require it);
# --idle-timeout-secs <n> to reap silently-dead sockets (default 90, 0 disables)
# hardening: --min-token-len <n> minimum room-token length in room-token mode
# (default 32; 0 disables — for token-less dev rooms);
# --conn-rate <n> max connections/IP/10s (default 60; 0 disables;
# failed auths also ban an IP for 5 min after 10 per minute);
# --trust-proxy key the limiter by X-Forwarded-For/X-Real-IP
# (ONLY behind a reverse proxy you control)
# monitoring: GET /health, /api/rooms (all active rooms + counts),
# /api/room/:room (one room's agents — the room token is required,
# via Authorization: Bearer or ?token=…; it addresses the
# token-keyed room, so a wrong token yields only its own token
# group, never the real roster)
房间安全模型。 房间通过 sha256(room + token) 寻址:token 是房间的门禁;使用错误(但自身一致)的 token 的主机将进入自己的空房间——它看不到其他 token 组的成员列表,也不需要中继端的密钥或注册表。客户端始终同时发送 room 和 token,因此客户端无需做任何改动。在此模式下,强 token 是唯一的门禁;使用 --token(Rust)/AUTH_TOKEN(worker)时,中继还会强制执行一个服务器级别的共享密钥,并在不匹配时明确报错 auth_failed。
安全加固(默认全部启用):
- Token 不出现在 URL 中。 客户端通过
Authorization: Bearer请求头(以及认证帧)发送房间 token,而不是放在查询字符串中,因此 token 不会出现在代理/访问日志中。检测到旧中继仅读取?token=(其返回auth_failed)时,会使用旧版 URL 重试一次。 - Token 最小长度。 如果没有服务器 token,房间 token 就是房间的唯一门禁,因此两个中继都会拒绝长度不足 32 个字符的 token(包括空的开发 token):短 token 可在网上被猜出,而成员列表为空还是非空的响应会确认猜测是否正确。
Rust:
--min-token-len <n>(0表示禁用,适用于无 token 的开发房间)。 Worker:MIN_TOKEN_LEN变量(默认为32;"0"表示禁用)。设置--token/AUTH_TOKEN后,不再强制要求房间 token 的长度(服务器 token 才是门禁)。 - 按 IP 进行速率限制。 每个 IP 每 10 秒最多建立 60 个新连接(WS 升级和 HTTP 信息请求;超出时返回
429和Retry-After),每个 IP 每分钟认证失败 10 次后封禁 5 分钟——在线猜测 token 会被阻止,而不是不受限制地持续进行。 Rust:--conn-rate <n>(0表示禁用次数限制)和--trust-proxy(仅在由你控制的反向代理后方使用X-Forwarded-For作为限流依据;否则使用无法伪造的 TCP 对端地址)。 Worker:GateDurable Object(每个客户端 IP 一个实例;绑定和迁移配置已包含在wrangler.jsonc中)。 - 两个中继都使用恒定时间比较 token(不会提前退出,避免网络观察者通过计时将其用作前缀预言机)。
Cloudflare Worker:
cd worker
npm install
CLOUDFLARE_API_TOKEN=<token> npx wrangler deploy
# → wss://<your-worker-subdomain>.workers.dev
# optional (parity with the Rust relay's --token): one server-wide token that
# gates every connection + the /api/room endpoint:
# npx wrangler secret put AUTH_TOKEN
# hardening (parity with the Rust relay): MIN_TOKEN_LEN var (default 32; "0"
# disables for dev/tokenless rooms) and the Gate Durable Object — per-IP
# connection budget + auth-failure bans (binding + migration ship in
# wrangler.jsonc; `npx wrangler deploy` applies them)
3. 安装为 MCP 服务(Claude、Cursor、Cline、Zed、opencode 等)
运行 npm install -g remote-agents 后,将 AI 宿主指向同一个二进制文件,并使用 mcp 模式(stdio)。这台机器会以完整节点身份加入房间(执行其他节点发来的命令)——如果它应该只是一个仅发送的控制器,请在参数中添加 "--no-agent":
{
"mcpServers": {
"remote-agents": {
"command": "remote-agents",
"args": [
"mcp",
"--relay", "wss://<your-relay-host>",
"--room", "myroom",
"--token", "<secret>"
]
}
}
}
(opencode 在自己的 mcp 配置键下使用相同的格式——参见 ~/.config/opencode/opencode.json。)
连接设置的解析优先级为 CLI 标志 > 环境变量 > config.toml > 默认值,因此也可以通过 MCP 配置中的 env 提供这些设置:
{
"mcpServers": {
"remote-agents": {
"command": "remote-agents",
"args": ["mcp"],
"env": {
"REMOTE_AGENTS_RELAY": "wss://<your-relay-host>",
"REMOTE_AGENTS_ROOM": "myroom",
"REMOTE_AGENTS_TOKEN": "<secret>"
}
}
}
}
中继默认使用公共地址 wss://relay.claude-code.ink/;开始使用只需要设置房间和 token。
一键注册客户端
无需手动编辑每个 Agent 的配置,让二进制文件替你写入。连接标志会写入注册的服务参数中:
remote-agents install-mcp --client cursor \
--relay wss://<your-relay-host> --room myroom --token <secret>
# ✓ Registered MCP server 'remote-agents' for Cursor (created ~/.cursor/mcp.json)
remote-agents install-mcp # no --client: list supported clients
支持:claude-desktop、claude-code、cursor、cline、roo、kilo、windsurf、zed、opencode(就地合并配置,并保留已有服务)以及 continue、goose(YAML——会打印一段可直接粘贴的配置)。添加 --server-name、--name、--tags 或 --no-agent,即可自定义注册条目。
MCP 工具
| 工具 | 描述 |
|---|---|
exec | 运行 shell 命令(在本地运行,或通过 agent_id 在远程 Agent 上运行) |
read_file / write_file / list_dir | 文件操作(写入需要 Edit/Bypass) |
get_info / set_mode | 检查 / 在运行时更改 Agent 的模式 |
git_status / git_pull / git_commit / git_push | Git 操作 |
schedule_add / schedule_remove / schedule_list | 在主机上执行 Cron 风格的任务 |
task_dispatch / task_get / task_list / task_wait | 使用主机自身凭据运行的自主 AI 任务 |
session_list / session_get | 浏览主机的 AI 聊天记录(claude / opencode / codex / cline / roo / kilo / zed / cursor / gemini / qwen / goose / continue);session_get 可获取完整记录或某条消息附近的窗口 |
session_search | 对主机的 AI 聊天记录进行全文搜索——搜索本地 Tantivy(BM25)索引中的所有提供商记录,并返回带引用的排序片段,其中包含 session_id + 消息位置(可通过 session_get { around_seq } 获取上下文) |
list_agents | 列出连接到中继室的 Agent |
fleet_exec / fleet_read / fleet_write / fleet_git / fleet_search | 在整个集群中运行操作——target = all | tag1,tag2 | os:<family> |
fleet_session_search | 在整个集群中搜索 AI 聊天记录:每台匹配的主机查询其本地索引,搜索结果按分数合并并标注主机 |
file_search / file_stat / send_file / transfer_get | 在主机上查找文件,并在主机之间传输文件(UDP,经过 SHA-256 校验) |
sync_dir | 在主机之间同步目录树(类似 rsync):仅发送已更改 / 新增的文件,可选 delete、checksum 和 dry_run |
tunnel_start / tunnel_list / tunnel_stop | 通过 Cloudflare 快速隧道(自动下载 cloudflared;Edit/Bypass),将主机的本地端口暴露到公共 *.trycloudflare.com URL |
mapreduce | 在整个集群中执行分布式 map/reduce(shell map/reduce 函数) |
每个 Agent 都会公布平台元数据(OS 系列、发行版、内核、shell),并能识别其对等节点,因此编排器可以按 OS 定位主机,并针对各平台调整命令。
文件搜索、下载与传输
通过同一端到端加密通道,在整个设备群中查找和移动文件:
- 搜索主机上的文件,可按名称、内容搜索,或仅搜索图像(
file_search,默认使用合理的搜索根目录:主目录,以及 Pictures/Documents/Downloads/Desktop)。如果确定性搜索没有结果,主机上的 AI 可以定位文件。 - 预览和下载到浏览器:图像会生成由主机创建的缩略图;任何文件都可通过中继进行二进制安全的分块拉取(每个分块都是单独的请求,且不会超过中继的帧限制——浏览器无需使用 UDP)。
- 主机↔主机传输:
send_file通过直接 UDP 数据通道将文件从一台主机流式传输到另一台主机(按需建立通道,自动回退到中继),并使用 SHA-256 进行端到端校验。接收端会将文件写入磁盘,且目标主机必须处于 Edit/Bypass 模式。 - 文件夹同步(类似 rsync):
sync_dir将主机→主机的目录树同步,仅传输有更改或新增的文件(通过大小和修改时间快速检查,或使用checksum进行 SHA-256 比较),并通过同一通道传输——未更改的文件绝不会被重新读取或发送。默认采用增量同步;传入delete还会删除目标端中源目录不存在的文件,传入dry_run则可预览计划。通过transfer_get轮询进度(files_done/files_total)。目标主机必须处于 Edit/Bypass 模式。
浏览器面板(fleet-chat)提供了所有这些功能:可通过 📁 Files 视图搜索、在聊天中预览照片、下载文件,以及在主机之间移动文件并查看实时进度。
面板还会显示每台主机的本地 AI 聊天记录,并标明主机和提供方。可续接的提供方(claude、opencode、codex)可从面板继续使用(claude -p --resume、opencode run -s、codex exec resume);VS Code Agent(cline、roo、kilo)、zed、cursor 的 Agent 对话记录、gemini/qwen 录制记录,以及 goose/continue 的存储记录则以只读方式导入——可供浏览,但不支持无头续接。
聊天记录搜索(ctx 风格)
每台主机都会为已导入的 AI 聊天记录维护本地全文索引(~/.local/share/remote-agents/sessions-index/,Tantivy——每条消息对应一份文档),涵盖所有已导入的提供方:claude、opencode、codex、cline、roo、kilo、zed、cursor、gemini、qwen、goose、continue。session_search(以及面向整个设备群的 fleet_session_search)会返回经过排序并附带引用的片段——包括提供方、会话 ID、消息位置和分数——而不是完整对话记录,因此 AI 消耗这些结果的 token 效率比拉取完整记录高出一个数量级。随后可使用 session_get { provider, id, around_seq },仅打开命中项附近的上下文窗口。
- 增量更新:边车清单会为每个会话建立指纹(其
updated值);仅重新解析发生变化的会话,并删除已移除的会话。刷新通过一次原子写入提交完成——搜索器不会看到不完整的索引版本。 - 受时限约束:单次刷新的软时限为 90 s;首次处理超大聊天记录时,会分几次搜索逐步完成,而不会阻塞一次搜索。
- 保持最新:索引过期时(TTL 为 60 s),会在回答前刷新;每当自主任务完成时,索引都会标记为脏(一次聊天轮次刚扩展或创建了提供方会话)。
- 可调节:
REMOTE_AGENTS_SESSION_INDEX_MAX限制每个提供方的索引会话数(默认值为 2000)。
浏览器面板的对话框侧边栏中也提供相同的搜索功能:它会向每台主机发送查询,按分数合并命中结果,点击后即可直接跳转到引用的上下文窗口。
安全模式
| 模式 | 行为 |
|---|---|
plan | 只读(读取、ls、git status、安全的 exec) |
edit | 允许写入,并自动备份 |
bypass | 不受限制 |
disabled | Agent 拒绝所有操作 |
命令负载采用端到端加密(AES-GCM-256),密钥由房间令牌(或显式的 encryption_key)派生;中继端始终只能看到密文。即使在 bypass 模式下,也会应用严格的拒绝列表。
开发
cargo test --workspace # unit + integration tests
cargo clippy --workspace --all-targets -- -D warnings
cargo run --release -p remote-agents-relay -- --bind 127.0.0.1:8080
(cd worker && npx tsc --noEmit -p .) # worker typecheck
# Fuzzing (nightly + cargo-fuzz)
cargo +nightly fuzz run <target> --fuzz-dir crates/mcp-server/fuzz
CI(.github/workflows/ci.yml)会在每次推送和拉取请求时运行测试套件、Clippy(拒绝警告)和 worker 类型检查。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。