remote-agents 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +250 -25
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,24 +1,187 @@
1
- # remote-agents
1
+ # Remote Agents
2
2
 
3
- Unified, [MCP](https://modelcontextprotocol.io)-compatible control plane for
4
- fleets of remote machines, driven by AI agents (Claude, opencode).
3
+ [![CI](https://github.com/47-ronn/tunshell_mcp_agents/actions/workflows/ci.yml/badge.svg)](https://github.com/47-ronn/tunshell_mcp_agents/actions/workflows/ci.yml)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
5
 
6
- This npm package is a thin launcher: on install it downloads the prebuilt
7
- `remote-agent` binary for your platform from the matching GitHub release.
6
+ A unified, [MCP](https://modelcontextprotocol.io)-compatible system for
7
+ controlling fleets of remote machines through AI agents (Claude, opencode).
8
+ Agents connect outbound to a relay; an MCP server lets the AI run commands,
9
+ manage files, drive git, schedule tasks, and orchestrate the whole fleet — all
10
+ over end-to-end-encrypted channels.
11
+
12
+ ## Features
13
+
14
+ - **Single Rust binary** (`remote-agent`) — runs as an agent daemon (`run`), an
15
+ MCP stdio server (`mcp`), or installs itself as a service (`install`).
16
+ - **End-to-end encryption** (AES-GCM-256) on by default; the relay forwards only
17
+ ciphertext.
18
+ - **Safety modes** per host — `plan` (read-only), `edit` (writes with backups),
19
+ `bypass`, `disabled` — with path/command allow- & deny-lists.
20
+ - **Fleet as one computer** — run any operation (`exec`/`read`/`write`/`git`)
21
+ across all agents, by tags, or by OS family; results aggregated per host.
22
+ - **Distributed MapReduce** — partition data across the fleet, map with a shell
23
+ command, reduce the outputs, with per-partition retry.
24
+ - **Autonomous mode** — delegate AI tasks to a host that runs them with its own
25
+ credentials (token-saving orchestration).
26
+ - **Two interchangeable relays** — Cloudflare Workers (Durable Objects) or a
27
+ self-hosted Rust WebSocket relay; switch by changing `relay_url`.
28
+ - **Direct UDP data channel** with hole-punching and WebSocket fallback.
29
+
30
+ ## Architecture
31
+
32
+ ```
33
+ ┌──────────────────────────────────────────────────────────────┐
34
+ │ opencode / Claude Desktop │
35
+ │ remote-agent mcp (Rust binary, MCP stdio server) │
36
+ └───────────────────────────────┬──────────────────────────────┘
37
+ │ wss:// (CF Worker or self-hosted relay)
38
+
39
+ ┌───────────────────────────────────┐
40
+ │ Relay (rooms route by token) │
41
+ └───────────────────────────────────┘
42
+ ▲ ▲ ▲
43
+ │ wss │ wss │ wss
44
+ ┌──────┴─────┐ ┌──────┴─────┐ ┌──────┴─────┐
45
+ │ Agent │ │ Agent │ │ Agent │
46
+ │ (daemon) │ │ (daemon) │ │ (daemon) │
47
+ └────────────┘ └────────────┘ └────────────┘
48
+ ```
49
+
50
+ ## Workspace layout
51
+
52
+ | Crate / dir | Purpose |
53
+ |------------------------|-----------------------------------------------------------|
54
+ | `crates/shared` | Wire protocol, AES-GCM crypto, UDP channel types |
55
+ | `crates/mcp-server` | The `remote-agent` binary: agent, MCP server, executors |
56
+ | `crates/relay` | Self-hosted Rust WebSocket relay (`remote-agents-relay`) |
57
+ | `worker/` | Cloudflare Worker relay (Durable Objects) |
8
58
 
9
59
  ## Install
10
60
 
11
61
  ```bash
62
+ # Via npm (downloads the prebuilt binary for your platform)
63
+ npm install -g remote-agents # then: remote-agents --help
64
+ # or run on demand:
65
+ npx remote-agents mcp --help
66
+ ```
67
+
68
+ ```bash
69
+ # From source
70
+ cargo build --release --workspace
71
+ cargo install --path crates/mcp-server # → ~/.cargo/bin/remote-agent
72
+ ```
73
+
74
+ Prebuilt binaries for macOS / Linux / Windows are also attached to each GitHub
75
+ release.
76
+
77
+ ## Running: one binary, two ways
78
+
79
+ `remote-agents` is **one binary** that behaves the same whether you launch it
80
+ directly with flags or an AI host (opencode / Claude) starts it as an MCP
81
+ server. Connection settings resolve identically in both cases:
82
+ **CLI flag > `REMOTE_AGENTS_*` env var > `config.toml` > default**.
83
+
84
+ It is a flat **peer network** — there are no controller/agent roles. Every node
85
+ joins a relay room as an equal peer: visible to all, able to dispatch work, and
86
+ (unless `--no-agent`) able to execute commands from others.
87
+
88
+ | Mode | Command | The node… |
89
+ |------|---------|-----------|
90
+ | `run` | `remote-agents run …` | is a headless full peer (executes + dispatches), no local AI |
91
+ | `mcp` | `remote-agents mcp …` | is a full peer **plus** an MCP server for a local AI (opencode / Claude) |
92
+ | `hybrid` | `remote-agents hybrid …` | alias for `mcp` (kept for compatibility) |
93
+
94
+ Every mode is a **full peer that accepts commands by default**. Add `--no-agent`
95
+ to make a node **send-only** (stays visible and dispatches work, but never runs
96
+ others' commands — for prod controllers or browser dashboards). `--no-agent`
97
+ also works in an MCP `env` block as `REMOTE_AGENTS_*` config.
98
+
99
+ Common flags: `--relay <wss://host>` `--room <name>` `--token <secret>`
100
+ `--name <id>` `--tags a,b` `--no-agent`.
101
+
102
+ ### Keeping a host always online
103
+
104
+ A `mcp` node lives only as long as the AI host (opencode / Claude) keeps it
105
+ running — close the session and the node leaves the room. For a host that should
106
+ stay in the fleet **24/7, independent of any AI session**, install it as a
107
+ background service running `run`:
108
+
109
+ ```bash
110
+ remote-agents install --room dev --token <secret> --relay wss://<your-relay-host>
111
+ # systemd user service (Linux) / launchd LaunchAgent (macOS); auto-starts,
112
+ # survives logout/reboot, auto-restarts. Remove with: remote-agents uninstall
113
+ ```
114
+
115
+ A machine has **one persistent identity** (`agent-id`), and the relay keys peers
116
+ by id, so don't run both a `run` service and an `mcp` session on the same machine
117
+ with the same id — they'd evict each other. Typical topology: target hosts run
118
+ the `run` service (always online); the workstation that drives the fleet runs
119
+ `mcp` per session.
120
+
121
+ ## Quick start
122
+
123
+ ### 1. Run an agent on a remote host (with flags)
124
+
125
+ ```bash
126
+ # Install once (downloads the prebuilt binary for your platform):
12
127
  npm install -g remote-agents
13
- # or run without installing:
14
- npx remote-agents --help
128
+
129
+ # Run as a peer agent:
130
+ remote-agents run --relay wss://<your-relay-host> --room dev --token <secret> \
131
+ --name web-1 --tags backend
132
+
133
+ # ...or install it as an auto-starting user service (systemd / launchd):
134
+ remote-agents install --room dev --token <secret> --relay wss://<your-relay-host>
15
135
  ```
16
136
 
17
- Supported platforms: linux x64/arm64, macOS x64/arm64, windows x64.
137
+ ### 2. Choose a relay
18
138
 
19
- ## Use as an MCP server
139
+ **Self-hosted (Rust):**
20
140
 
21
- ```jsonc
141
+ ```bash
142
+ remote-agents-relay --bind 0.0.0.0:8080
143
+ # agents/MCP then use relay_url = ws://<host>:8080
144
+ ```
145
+
146
+ **Cloudflare Worker:**
147
+
148
+ ```bash
149
+ cd worker
150
+ npm install
151
+ CLOUDFLARE_API_TOKEN=<token> npx wrangler deploy
152
+ # → wss://<your-worker-subdomain>.workers.dev
153
+ ```
154
+
155
+ ### 3. Install as an MCP server for Claude Desktop / opencode
156
+
157
+ After `npm install -g remote-agents`, point your AI host at the same binary in
158
+ `mcp` mode (stdio). The machine joins the room as a full peer (executes commands
159
+ from others) — add `"--no-agent"` to the args if it should be a send-only
160
+ controller instead:
161
+
162
+ ```json
163
+ {
164
+ "mcpServers": {
165
+ "remote-agents": {
166
+ "command": "remote-agents",
167
+ "args": [
168
+ "mcp",
169
+ "--relay", "wss://<your-relay-host>",
170
+ "--room", "myroom",
171
+ "--token", "<secret>"
172
+ ]
173
+ }
174
+ }
175
+ }
176
+ ```
177
+
178
+ (opencode uses the same shape under its own `mcp` config key — see
179
+ `~/.config/opencode/opencode.json`.)
180
+
181
+ Connection settings are resolved as **CLI flag > env var > `config.toml` >
182
+ default**, so you can instead supply them via `env` in the MCP config:
183
+
184
+ ```json
22
185
  {
23
186
  "mcpServers": {
24
187
  "remote-agents": {
@@ -34,38 +197,100 @@ Supported platforms: linux x64/arm64, macOS x64/arm64, windows x64.
34
197
  }
35
198
  ```
36
199
 
37
- `remote-agents <subcommand>` forwards to the native binary (`run`, `mcp`,
38
- `install`, …). See the [project README](https://github.com/47-ronn/tunshell_mcp_agents#readme)
39
- for the full documentation.
200
+ Without any relay/room/token the server runs locally only (no remote agent
201
+ control); nothing points at a hosted endpoint by default.
40
202
 
41
- ## One-command client registration
203
+ ### One-command client registration
42
204
 
43
- Skip hand-editing config files register `remote-agents` as an MCP server in
44
- your agent directly. Connection flags are baked into the entry:
205
+ Instead of hand-editing each agent's config, let the binary write it. The
206
+ connection flags are baked into the registered server's args:
45
207
 
46
208
  ```bash
47
209
  remote-agents install-mcp --client cursor \
48
210
  --relay wss://<your-relay-host> --room myroom --token <secret>
211
+ # ✓ Registered MCP server 'remote-agents' for Cursor (created ~/.cursor/mcp.json)
49
212
 
50
213
  remote-agents install-mcp # no --client: list supported clients
51
214
  ```
52
215
 
53
216
  Supported: `claude-desktop`, `claude-code`, `cursor`, `cline`, `roo`, `kilo`,
54
- `windsurf`, `zed`, `opencode` (config merged in place, preserving existing
55
- servers) and `continue`, `goose` (YAML — a paste-able snippet is printed).
217
+ `windsurf`, `zed`, `opencode` (config merged in place, preserving any servers
218
+ you already have) and `continue`, `goose` (YAML — a ready-to-paste snippet is
219
+ printed). Add `--server-name`, `--name`, `--tags`, or `--no-agent` to customize
220
+ the registered entry.
221
+
222
+ ## MCP tools
223
+
224
+ | Tool | Description |
225
+ |------|-------------|
226
+ | `exec` | Run a shell command (locally or on a remote agent via `agent_id`) |
227
+ | `read_file` / `write_file` / `list_dir` | File operations (write requires Edit/Bypass) |
228
+ | `get_info` / `set_mode` | Inspect / change an agent's mode at runtime |
229
+ | `git_status` / `git_pull` / `git_commit` / `git_push` | Git operations |
230
+ | `schedule_add` / `schedule_remove` / `schedule_list` | Cron-style tasks on a host |
231
+ | `task_dispatch` / `task_get` / `task_list` / `task_wait` | Autonomous AI tasks run with the host's own credentials |
232
+ | `list_agents` | List agents connected to the relay room |
233
+ | `fleet_exec` / `fleet_read` / `fleet_write` / `fleet_git` / `fleet_search` | Run an operation across the fleet — `target = all \| tag1,tag2 \| os:<family>` |
234
+ | `file_search` / `file_stat` / `send_file` / `transfer_get` | Find files on a host, and move a file host→host (UDP, SHA-256 verified) |
235
+ | `mapreduce` | Distributed map/reduce over the fleet (shell map/reduce functions) |
236
+
237
+ Each agent advertises platform metadata (OS family, distro, kernel, shell) and
238
+ is aware of its peers, so the orchestrator can target hosts by OS and tailor
239
+ commands per platform.
240
+
241
+ ## File search, download & transfer
56
242
 
57
- ## Update checks
243
+ Find and move files across the fleet — over the same end-to-end-encrypted
244
+ channel:
58
245
 
59
- When started in a long-running mode (`run` / `mcp` / `hybrid`), the launcher does
60
- a best-effort check against the npm registry and logs a notice if a newer
61
- version is published. It is **notify-only** the agent never self-updates, so a
62
- running task is never interrupted. Update at your convenience with:
246
+ - **Search** a host's files by name, content, or images-only (`file_search`,
247
+ with sensible default roots: home + Pictures/Documents/Downloads/Desktop). When
248
+ a deterministic search comes up empty, the host's AI can locate the file.
249
+ - **Preview & download** to the browser: images get a host-generated thumbnail;
250
+ any file downloads via a **binary-safe, chunked pull** through the relay (each
251
+ chunk is its own request, staying under the relay's frame limit — no UDP needed
252
+ in the browser).
253
+ - **Host↔host transfer**: `send_file` streams a file from one host to another
254
+ over the **direct UDP data channel** (a channel is opened on demand, with
255
+ automatic relay fallback), verified end-to-end with SHA-256. Receiving writes
256
+ to disk and requires Edit/Bypass mode on the destination.
257
+
258
+ The browser panel (`fleet-chat`) exposes all of this: a 📁 Files view to search,
259
+ preview photos in chat, download, and move files between hosts with live
260
+ progress.
261
+
262
+ It also surfaces each host's **local AI-chat history**, labelled by host and
263
+ provider. Resumable providers (`claude`, `opencode`) can be continued from the
264
+ panel; the VS Code agents (`cline`, `roo`, `kilo`) and `zed` are imported
265
+ read-only — their transcripts are shown for browsing but have no headless resume.
266
+
267
+ ## Security modes
268
+
269
+ | Mode | Behavior |
270
+ |------|----------|
271
+ | `plan` | Read-only (read, ls, git status, safe exec) |
272
+ | `edit` | Writes allowed, with automatic backups |
273
+ | `bypass` | Unrestricted |
274
+ | `disabled` | Agent rejects all operations |
275
+
276
+ Command payloads are encrypted end-to-end (AES-GCM-256) with a key derived from
277
+ the room token (or an explicit `encryption_key`); the relay only ever sees
278
+ ciphertext. A hard deny-list applies even in `bypass` mode.
279
+
280
+ ## Development
63
281
 
64
282
  ```bash
65
- npm i -g remote-agents@latest
283
+ cargo test --workspace # unit + integration tests
284
+ cargo clippy --workspace --all-targets -- -D warnings
285
+ cargo run --release -p remote-agents-relay -- --bind 127.0.0.1:8080
286
+ (cd worker && npx tsc --noEmit -p .) # worker typecheck
287
+
288
+ # Fuzzing (nightly + cargo-fuzz)
289
+ cargo +nightly fuzz run <target> --fuzz-dir crates/mcp-server/fuzz
66
290
  ```
67
291
 
68
- Set `REMOTE_AGENTS_NO_UPDATE_CHECK=1` to disable the check entirely.
292
+ CI (`.github/workflows/ci.yml`) runs the test suite, Clippy (deny-warnings), and
293
+ the worker typecheck on every push and pull request.
69
294
 
70
295
  ## License
71
296
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remote-agents",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "mcpName": "io.github.47-ronn/remote-agents",
5
5
  "description": "Unified MCP server for controlling fleets of remote machines through AI agents (Claude, opencode)",
6
6
  "keywords": [