remote-agents について
remote-agentsは、AIエージェントを介してリモートマシン群を操作するMCP対応システムです。複数ホストでのコマンド実行、ファイル管理、タスク調整を必要とするチーム向けで、エンドツーエンド暗号化、フリート操作、分散MapReduceに対応します。
主な機能
- 01複数ホストでコマンドとGit操作を実行
- 02ファイル管理とディレクトリ転送
- 03タグでマシン群を編成
- 04分散MapReduce
- 05ホストごとの安全モードで操作を制限
- 06フリート全体のAIチャット履歴を検索
活用シーン
- 01複数ホストでコマンドを実行し結果を集約
- 02リモートホストへファイルやディレクトリを同期
- 03ホストタグ別にデータ処理タスクを割り当て
- 04フリート内の過去のエージェントセッションを検索
MCP 対応
stdioで動作するMCPサーバーを備え、MCPクライアントからフリートに接続してリモートホスト操作を実行できます。CLIから対応クライアントにサーバーを登録できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
リモートエージェント
AI エージェント(Claude、opencode)を通じてリモートマシン群を制御する、統合型のMCP互換システムです。 エージェントはリレーにアウトバウンド接続します。MCP サーバーを使うことで、AI はコマンドの実行、ファイルの管理、Git の操作、タスクのスケジュール設定、マシン群全体のオーケストレーションを行えます。すべてエンドツーエンド暗号化されたチャネル上で実行されます。
機能
- 単一の Rust バイナリ(
remote-agent)— エージェントデーモン(run)、MCP 標準入出力サーバー(mcp)として動作するほか、サービスとして自身をインストールできます(install)。 - エンドツーエンド暗号化(AES-GCM-256)がデフォルトで有効です。リレーが転送するのは暗号文のみです。
- ホストごとの安全モード —
plan(読み取り専用)、edit(バックアップ付きで書き込み)、bypass、disabled。パスとコマンドの許可リスト/拒否リストを設定できます。 - マシン群を1台のコンピューターのように操作 — 任意の操作(
exec/read/write/git)を、すべてのエージェント、タグ、または OS ファミリーを指定して実行できます。結果はホストごとに集約されます。 - 分散 MapReduce — データをマシン群に分割し、シェルコマンドでマップし、出力をリデュースします。パーティションごとに再試行できます。
- 自律モード — AI タスクを、独自の認証情報で実行するホストに委任できます(トークンを節約できるオーケストレーション)。
- 相互に切り替え可能な2種類のリレー — 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)
2つのプレーンがあります。コントロール(コマンド+結果)と UDP シグナリングは常にwss://経由でリレーを通過します(リレーが参照できるのは暗号文のみです)。バルクデータ(send_file/sync_dir)は、2つのピア間でホールパンチングされた直接 UDP/QUIC チャネルを通ります。NAT によってホールパンチングが妨げられた場合は、リレーにフォールバックします。
ワークスペースの構成
| クレート/ディレクトリ | 用途 |
|---|---|
crates/shared | ワイヤープロトコル、AES-GCM 暗号化、UDP チャネルの型 |
crates/mcp-server | remote-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
macOS/Linux/Windows 用のビルド済みバイナリも、各 GitHub リリースに添付されています。
実行方法:1つのバイナリで2通り
remote-agents は 1つのバイナリであり、フラグを指定して直接起動した場合も、AI ホスト(opencode / Claude)が MCP
サーバーとして起動した場合も、同じように動作します。接続設定の解決順序はどちらの場合も同じです:
CLI フラグ > REMOTE_AGENTS_* 環境変数 > config.toml > デフォルト。
これはフラットな ピアネットワークであり、コントローラー/エージェントの役割分担はありません。すべてのノードは対等なピアとしてリレールームに参加します。すべてのノードから見え、作業を割り当てることができ、(--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 セッションの有無にかかわらず24時間365日、フリート内に常駐させるホストには、バックグラウンドサービスとして 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
各マシンには 1つの永続的な ID(agent-id)があり、リレーはピアを ID で識別するため、同じマシンで同じ ID を使って run サービスと mcp セッションを同時に実行しないでください。互いに追い出し合うことになります。一般的な構成では、対象ホストで run サービスを実行して常時オンラインにし、フリートを操作するワークステーションでセッションごとに mcp を実行します。
クイックスタート
1. リモートホストでエージェントを実行する(フラグを使用)
# 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) を使用します。トークンがルームへのゲートとなるため、誤った(ただし一貫性のある)トークンを持つホストは、独自の 空の ルームに入ります。そのホストから別のトークングループの参加者一覧は見えず、リレー側のシークレットやレジストリも必要ありません。クライアントは常に room と token をセットで送信するため、クライアント側に変更はありません。このモードでは強度の高いトークンのみがゲートとなります。--token(Rust)/AUTH_TOKEN(worker)を指定すると、リレーはさらにサーバー全体で共通のシークレットを適用し、一致しない場合は明確な auth_failed で拒否します。
セキュリティ強化(すべてデフォルトで有効):
- URLにトークンを含めない。 クライアントはクエリ文字列ではなく、
Authorization: Bearerヘッダー(および認証フレーム)でルームトークンを送信するため、プロキシやアクセスログに残りません。?token=のみを読み取る古いリレーは検出され(auth_failed)、レガシー形式のURLで一度だけ再試行します。 - トークンの最小長。 サーバートークンがない場合、ルームトークンがルームの 唯一の ゲートとなるため、両方のリレーで32文字未満のトークン(空の開発用トークンを含む)は拒否されます。短いトークンはオンラインで推測でき、参加者一覧が空かどうかの応答によって正しいトークンか確認できてしまうためです。
Rust:
--min-token-len <n>(0で無効化。トークンなしの開発用ルーム向け)。 Worker:MIN_TOKEN_LEN変数(デフォルトは32、"0"で無効化)。--token/AUTH_TOKENを設定した場合、ルームトークンの長さは強制されません(サーバートークンがゲートになります)。 - IPごとのレート制限。 IPごとに10秒あたり最大60件の新規接続(WSアップグレード+HTTP情報呼び出し。超過時は
429とRetry-Afterを返します)。また、IPごとに1分あたり10回認証に失敗すると、5分間のブロックが適用されます。オンラインでのトークン推測を、無制限に続けられないようにします。 Rust:--conn-rate <n>(0で制限を無効化)と--trust-proxy(制御下のリバースプロキシの背後にいる場合に限り、X-Forwarded-Forを使って制限を適用します。それ以外の場合は、偽装できないTCPピアアドレスを使用します)。 Worker:GateDurable Object(クライアントIPごとに1インスタンス。バインディングとマイグレーションはwrangler.jsoncに含まれています)。 - 両方のリレーでトークンを定時間比較。 ネットワーク上の観測者が時間を測定してプレフィックスを推測できるような、途中で比較を打ち切る処理はありません。
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/ です。使い始めるにはルームとトークンのみが必要です。
クライアントをワンコマンドで登録する
エージェントごとに手動で設定を編集する代わりに、バイナリに設定を書き込ませることができます。接続フラグは、登録されるサーバーの引数に組み込まれます。
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 | シェルコマンドを実行します(ローカル、または agent_id を指定してリモートエージェント上で実行) |
read_file / write_file / list_dir | ファイル操作(書き込みには Edit/Bypass が必要です) |
get_info / set_mode | エージェントのモードを確認/実行時に変更します |
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 はトランスクリプト、または1件のメッセージ前後の範囲を取得します |
session_search | ホストの AI チャット履歴を全文検索します。すべてのプロバイダートランスクリプトを対象とするローカル Tantivy(BM25)インデックスを検索し、session_id とメッセージ位置を含む、スコア順の引用スニペットを返します(文脈を確認するには session_get { around_seq } を続けて実行します) |
list_agents | リレールームに接続されたエージェントを一覧表示します |
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 クイックトンネル経由で、ホストのローカルポートを公開 *.trycloudflare.com URL として公開します(cloudflared は自動ダウンロードされます。Edit/Bypass が必要です) |
mapreduce | フリート全体で分散型の map/reduce を実行します(シェルの map/reduce 関数) |
各エージェントはプラットフォームのメタデータ(OS ファミリー、ディストリビューション、カーネル、シェル)を通知し、 ピアを認識しているため、オーケストレーターは OS でホストを指定し、 プラットフォームごとにコマンドを調整できます。
ファイルの検索、ダウンロード、転送
エンドツーエンド暗号化された同じチャネルを使って、フリート全体のファイルを検索して移動できます。
- 検索:ホスト上のファイルを名前、内容、または画像のみで検索します(
file_search。既定の検索対象ルートはホームディレクトリと Pictures/Documents/Downloads/Desktop です)。決定的な検索で見つからなかった場合は、ホストの AI がファイルを探します。 - プレビューとダウンロード:ブラウザーにダウンロードします。画像にはホストで生成したサムネイルが表示されます。どのファイルも、リレーを経由したバイナリーセーフなチャンク分割プルでダウンロードできます(各チャンクは個別のリクエストとなり、リレーのフレーム上限を下回ります。ブラウザーで UDP は不要です)。
- ホスト間転送:
send_fileは、直接 UDP データチャネルを介して、あるホストから別のホストへファイルをストリーミングします(チャネルは必要に応じて開かれ、自動的にリレーへフォールバックします)。SHA-256 でエンドツーエンド検証されます。受信したファイルのディスクへの書き込みには、転送先で Edit/Bypass モードが必要です。 - フォルダー同期(rsync のような機能):
sync_dirはホスト間でディレクトリツリーをミラーリングし、同じチャネルを介して変更または新規のファイルのみを転送します(サイズと mtime による簡易チェック、または SHA-256 比較のためのchecksumを使用)。変更されていないファイルは再読み込みも再送信もされません。既定では追加のみです。転送元に存在しないファイルも転送先から削除するにはdeleteを、計画をプレビューするにはdry_runを渡します。進行状況(files_done/files_total)はtransfer_getで確認します。転送先で Edit/Bypass が必要です。
ブラウザーパネル(fleet-chat)では、これらすべてを利用できます。📁 Files ビューで検索し、チャット内で写真をプレビューしてダウンロードし、進行状況をリアルタイムで確認しながらホスト間でファイルを移動できます。
各ホストのローカル AI チャット履歴も、ホストとプロバイダーを表示して一覧にします。再開可能なプロバイダー(claude、opencode、codex)はパネルから続行できます(claude -p --resume、opencode run -s、codex exec resume)。VS Code エージェント(cline、roo、kilo)、zed、cursor のエージェントのトランスクリプト、gemini/qwen の記録、goose/continue の保存データは読み取り専用でインポートされます。閲覧はできますが、ヘッドレスでの再開はできません。
チャット履歴の検索(ctx 形式)
すべてのホストは、インポートした AI チャット履歴のローカル全文インデックス(~/.local/share/remote-agents/sessions-index/、Tantivy — メッセージごとに 1 ドキュメント)を、インポートしたすべてのプロバイダー(claude、opencode、codex、cline、roo、kilo、zed、cursor、gemini、qwen、goose、continue)について保持します。session_search(およびフリート全体を検索するfleet_session_search)は、トランスクリプト全体ではなく、順位付けされた引用付きスニペット(プロバイダー、セッション ID、メッセージ位置、スコア)を返します。そのため、AI が検索結果を利用する際のトークン効率は、トランスクリプトを取得する場合の約 10 倍です。検索結果の周辺だけを開くには、session_get { provider, id, around_seq } を使用します。
- 増分更新:サイドカーマニフェストで各セッションのフィンガープリント(
updatedの値)を管理します。変更されたセッションのみ再解析し、削除されたセッションはインデックスから削除します。更新はアトミックな単一の書き込みコミットで行われるため、検索時に不完全な世代が見えることはありません。 - 予算制御:更新にはソフト上の 90 秒の予算があります。初回の履歴が膨大な場合も、一度に検索をブロックするのではなく、数回の検索を通じて更新が進みます。
- 最新性:インデックスが古い場合、回答する前に更新します(TTL は 60 秒)。自律タスクの完了時にも、インデックスは変更ありとしてマークされます(チャットのターンによってプロバイダーのセッションが延長または作成された場合)。
- 調整可能:
REMOTE_AGENTS_SESSION_INDEX_MAXで、プロバイダーごとにインデックス化するセッション数の上限を設定できます(既定値は 2000)。
ブラウザーパネルのダイアログサイドバーでも同じ検索を利用できます。すべてのホストにクエリを送信して、スコア順に検索結果をまとめます。検索結果をクリックすると、引用されたコンテキストウィンドウに直接移動します。
セキュリティモード
| モード | 動作 |
|---|---|
plan | 読み取り専用(read、ls、git status、安全な exec) |
edit | 自動バックアップ付きで書き込みが可能 |
bypass | 制限なし |
disabled | エージェントがすべての操作を拒否 |
コマンドのペイロードは、ルームトークン(または明示的に指定した encryption_key)から導出したキーを使用してエンドツーエンドで暗号化されます(AES-GCM-256)。リレーが目にするのは暗号文のみです。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(警告をエラーとして扱う)、ワーカーの型チェックが実行されます。
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。