@remcp/runtime 0.2.0 → 0.2.4

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.3
4
+
5
+ Full surface and review-aligned annotations. (0.2.0 was published from an earlier snapshot that
6
+ carried 23 tools; 0.2.1 is the release that matches this repository.)
7
+
8
+ - 37 tools: bulk reads and writes (`read_files` by glob, `write_files` for many files at once), binary transfer in both directions (`read_binary`, `write_binary`, base64 chunks),
9
+ archives (`create_archive`, `extract_archive` for tar, tar.gz, tar.bz2, tar.xz, zip), screenshots
10
+ (`take_screenshot`), `read_image`, `hash_file`, `diff_files`, `replace_lines`, `replace_in_files`,
11
+ `move_to_trash`, `get_system_info`, `wait_for_process_output`, runtime introspection, and a glob
12
+ filter on `list_directory`;
13
+ - no approval step anywhere: writes replace by default, moves and copies replace the destination,
14
+ `replace_in_files` applies immediately, and `dry_run` is opt-in for callers who want a preview;
15
+ - `dangerousCommands` defaults to `warn`: a catastrophic command runs and the result carries a note,
16
+ with `allow` for silence and `block` to refuse;
17
+ - annotations say what the tools do: 19 read-only, 14 destructive (including the tools that replace a
18
+ destination by default), 2 open-world;
19
+ - crash-resistance: a bad shell, a closed stdin, a stream with no newlines, a dead parent, or an
20
+ unparseable `runtime.json` cannot leave a device silently offline;
21
+ - `read_process_output` offsets are documented and implemented as zero-based line numbers, ranged
22
+ reads no longer consume the new-output cursor, and reads never sleep over buffered data;
23
+ - the contract commands work with no dependencies installed, so CI can diff the advertised tool
24
+ surface against the published tarball.
25
+
3
26
  ## 0.2.0
4
27
 
5
28
  First feature-complete first-party release. ReMCP no longer needs to install an upstream MCP server
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # ReMCP local runtime
2
2
 
3
3
  `@remcp/runtime` is the local device runtime for [ReMCP](https://remcp.delio24.com). It is an MCP
4
- server that runs on a computer you paired with ReMCP and executes the file, search, terminal, and
5
- process tools that the hosted ReMCP MCP endpoint exposes to ChatGPT and Codex.
4
+ server that runs on a computer you paired with ReMCP and executes the file, image, search, terminal,
5
+ and process tools that the hosted ReMCP MCP endpoint exposes to ChatGPT and Codex.
6
6
 
7
7
  The ReMCP device agent starts this runtime as a child process and talks to it over stdio. The runtime
8
8
  never talks to the network on its own: it only answers the paired agent, which holds the device
@@ -27,25 +27,52 @@ npx @remcp/runtime # MCP server over stdio
27
27
 
28
28
  ## Tools
29
29
 
30
- 23 tools, all implemented in this repository.
30
+ 35 tools, all implemented in this repository. Nothing is gated behind an approval step: a tool call
31
+ executes.
31
32
 
32
- | Tool | Behavior |
33
+ | Area | Tools |
33
34
  | --- | --- |
34
- | `read_file`, `read_multiple_files` | Read text files, with line paging and per-file errors in batch reads. |
35
- | `list_directory`, `get_file_info` | Inspect directory contents and file metadata. |
36
- | `write_file`, `edit_block` | Create, replace, or append file content; apply an exact-context text edit with a whitespace-tolerant fallback. |
37
- | `create_directory`, `move_file`, `copy_file` | Create directories; move, rename, or copy without overwriting an existing path unless asked. |
38
- | `start_search`, `get_more_search_results`, `stop_search`, `list_searches` | Streaming filename and content search with pagination, using `rg` when it is installed. |
39
- | `start_process`, `read_process_output`, `wait_for_process_output`, `interact_with_process`, `force_terminate`, `list_sessions` | Run and drive terminal sessions, including REPLs, with pattern waits instead of polling. |
40
- | `list_processes`, `kill_process` | Inspect and terminate operating-system processes. |
41
- | `get_runtime_info`, `get_runtime_stats` | Read-only introspection of configuration, limits, guardrails, and local counters. |
42
-
43
- There is deliberately no `set_config_value`: a model must not be able to rewrite its own device
44
- limits. Configuration is file- and environment-based, owned by the person at the computer.
35
+ | Read | `read_file`, `read_multiple_files`, `read_image`, `read_binary`, `list_directory` (glob filter), `get_file_info`, `hash_file`, `diff_files` |
36
+ | Write | `write_file`, `write_binary`, `edit_block` (whitespace-tolerant fallback, optional `dry_run`), `replace_lines`, `replace_in_files` |
37
+ | Organise | `create_directory`, `move_file`, `copy_file`, `move_to_trash`, `create_archive`, `extract_archive` |
38
+ | Transfer | `read_binary` / `write_binary` stream any file as base64 chunks in both directions; `create_archive` / `extract_archive` move whole trees |
39
+ | Screen | `take_screenshot` returns the desktop as an image on Linux, macOS, and Windows |
40
+ | Search | `start_search`, `get_more_search_results`, `stop_search`, `list_searches` |
41
+ | Processes | `start_process`, `read_process_output`, `wait_for_process_output`, `interact_with_process`, `force_terminate`, `list_sessions`, `list_processes`, `kill_process` |
42
+ | Introspection | `get_system_info`, `get_runtime_info`, `get_runtime_stats` |
43
+
44
+ The hosted ReMCP endpoint adds `list_devices` so a model can pick a machine. Everything else the
45
+ agent may need service management, package installs, git, docker, `sudo` runs through
46
+ `start_process`, which is an unrestricted shell for the account running the agent.
47
+
48
+ There is deliberately no `set_config_value` (a model must not rewrite its own device limits; use the
49
+ file) and no `write_pdf`/spreadsheet/DOCX tooling (that is what drags Puppeteer, `sharp`, and
50
+ `exceljs` onto your computer — use `start_process` with whatever tool you already have).
45
51
 
46
52
  `--print-tools` prints the exact JSON contract (schemas and annotations) the runtime advertises, and
47
53
  `src/catalog.mjs` is the single source of truth for it.
48
54
 
55
+ ## No approval staircase
56
+
57
+ ReMCP is a remote control for computers you own, with the same trust model as SSH: the tool call runs,
58
+ and the user's request is the authorization. There is no approval prompt, no "are you sure", and no
59
+ dry-run detour unless you ask for one.
60
+
61
+ - file writes replace by default (`mode: "append"` to add), moves and copies replace the destination
62
+ (`overwrite: false` refuses instead), `replace_in_files` applies immediately (`dry_run: true`
63
+ previews), and `move_to_trash` is there when you want an undo;
64
+ - the destructive-command guardrail defaults to `warn`: the command runs and the result carries a note
65
+ when it matches the catastrophic list (`mkfs`, raw device writes, repartitioning, host power
66
+ control, fork bombs, recursive root deletion). `allow` removes even the note, `block` refuses
67
+ before running, and `blockedCommands` adds your own deny list;
68
+ - `allowedRoots` is empty, so the device reaches everything the agent's account can reach. Set it to
69
+ confine a device to specific directories, enforced against the resolved real path.
70
+
71
+ The guarantees that remain are about correctness rather than permission: a bad shell, a closed stdin,
72
+ or a 40 MB line cannot take the runtime down; a crashed runtime is restarted by the agent; terminal
73
+ sessions run in their own process group so `force_terminate` stops the whole pipeline; and a
74
+ misconfigured `runtime.json` stops the device loudly instead of silently dropping your settings.
75
+
49
76
  ## Usage metrics
50
77
 
51
78
  Usage metrics are **opt-out**, matching the ReMCP client. They cover tool names, durations, outcomes,
@@ -72,25 +99,33 @@ export REMCP_RUNTIME_DISABLE_TELEMETRY=1 # environment
72
99
 
73
100
  in `~/.config/remcp/runtime.json`. `--describe` always reports the current state.
74
101
 
75
- ## Safety model
76
-
77
- - **No network calls.** The runtime opens no sockets. Every byte it emits goes to the paired agent.
78
- - **Symlink-aware confinement.** `allowedRoots` is enforced against the resolved real path of the
79
- deepest existing ancestor, not against the lexical string, so `<allowed>/link -> /etc` cannot be
80
- used to read or write outside the allowed directories.
81
- - **No silent overwrites.** `move_file` fails when the destination exists; `copy_file` requires
82
- `overwrite: true`; `edit_block` fails unless the number of matched blocks equals
83
- `expected_replacements`.
84
- - **Catastrophic-command guardrail.** Commands that format filesystems, write raw block devices,
85
- repartition disks, power off the host, fork-bomb, or recursively destroy a root path are refused
86
- before they run (`dangerousCommands: block`, the default). `warn` runs them and reports the match;
87
- `allow` disables the built-in list. User `blockedCommands` entries are always enforced.
102
+ ## Runtime properties
103
+
104
+ - **No network calls of its own.** The runtime opens no sockets: every byte it emits goes to the
105
+ paired agent. Shell commands it runs can of course reach the network, exactly as they would from
106
+ your own terminal.
107
+ - **Optional confinement.** `allowedRoots` is empty by default. When you set it, it is enforced
108
+ against the resolved real path of the deepest existing ancestor rather than the lexical string, so
109
+ `<allowed>/link -> /etc` cannot be used to read or write outside the allowed directories.
110
+ `allowedRoots: ["/"]` means the whole filesystem and works as written.
111
+ - **Command guardrail.** `dangerousCommands` defaults to `warn`: a catastrophic command still runs and
112
+ the result carries a note. `allow` silences the note, `block` refuses before running. Rules match the
113
+ *command word* of each shell segment, so `grep -n format README.md` is never affected. User
114
+ `blockedCommands` entries are always enforced.
115
+ - **A bad configuration is loud.** If `runtime.json` cannot be parsed, the device refuses to start and
116
+ says why, instead of quietly dropping your `allowedRoots` and re-enabling usage metrics.
88
117
  - **Secret masking.** `list_processes` masks command arguments that look like tokens, passwords, or
89
118
  API keys before returning them.
90
- - **Bounded everything.** Tool results are capped (`maxOutputBytes`), writes are capped
91
- (`maxWriteBytes`), buffered session output is capped (`maxBufferedLines`), and reads are paged.
119
+ - **Bounded everything.** Tool results are capped (`maxOutputBytes`, also clamped below the MCP
120
+ transport limit), writes are capped (`maxWriteBytes`), buffered session output is capped by both
121
+ line count and total characters - a stream with no newlines cannot grow without limit - and reads
122
+ are paged or chunked.
123
+ - **Crash-resistant sessions.** A bogus shell, a closed stdin, or a dead parent cannot take the
124
+ runtime down; sessions run in their own process group so `force_terminate` stops a whole pipeline;
125
+ the agent restarts the runtime if it ever exits, so a device recovers instead of going silently
126
+ offline.
92
127
  - **Protected processes.** `kill_process` refuses pid 1, the runtime itself, and the ReMCP agent that
93
- hosts it.
128
+ hosts it - the three ways a model could otherwise cut its own connection.
94
129
 
95
130
  These are guardrails, not an operating-system sandbox. A user who can run a shell can reach anything
96
131
  their account can reach; use a container, a VM, or a dedicated user account when that matters.
@@ -108,7 +143,7 @@ Optional settings live in `~/.config/remcp/runtime.json` (override the directory
108
143
  "name": "workstation",
109
144
  "allowedRoots": ["~/projects", "/srv/data"],
110
145
  "blockedCommands": ["rm -rf /", "shutdown"],
111
- "dangerousCommands": "block",
146
+ "dangerousCommands": "warn",
112
147
  "telemetryEnabled": true,
113
148
  "maxOutputBytes": 1048576,
114
149
  "maxReadLines": 2000,
@@ -131,7 +166,9 @@ directories.
131
166
  ## Session behavior
132
167
 
133
168
  Terminal sessions and searches live in memory for the lifetime of the runtime process. They end when
134
- the agent restarts, and exited sessions are dropped 30 minutes after they finish.
169
+ the agent restarts, and exited sessions are dropped 30 minutes after they finish. The agent watches
170
+ this process and restarts it with backoff if it ever exits, so a device recovers instead of staying
171
+ silently offline.
135
172
 
136
173
  ## Development
137
174
 
@@ -141,16 +178,34 @@ npm run check
141
178
  npm test
142
179
  ```
143
180
 
144
- ## Relationship to other MCP servers
181
+ The contract commands (`--help`, `--version`, `--print-tools`, `--describe`) work without
182
+ dependencies installed, so CI can diff the advertised tool surface against the published tarball.
183
+
184
+ ## How it compares with Desktop Commander
145
185
 
146
186
  This runtime is an independent implementation written for ReMCP. It is not a fork of, and shares no
147
- code with, Desktop Commander or any other MCP server. Compared with
148
- [DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP) it keeps the same core
149
- remote-computer workflow while dropping the parts ReMCP does not want on a user's machine: 34 runtime
150
- dependencies (Supabase, Puppeteer/md-to-pdf, sharp, exceljs, Tiptap), the install-tracking postinstall
151
- script, remote feature flags and A/B tests, unredacted local tool logs, URL fetching in `read_file`,
152
- and `set_config_value`. What it adds is symlink-aware confinement, the catastrophic-command
153
- guardrail, `copy_file`, pattern waits, whitespace-tolerant edits, and read-only introspection.
187
+ code with, [DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP) or any other
188
+ MCP server.
189
+
190
+ | | Desktop Commander 0.2.50 | ReMCP runtime 0.2.0 |
191
+ | --- | --- | --- |
192
+ | Tools | 26, including config mutators and document tooling | 35, including binary transfer, archives, screenshots, and diffs |
193
+ | Runtime dependencies | 34 (Supabase, Puppeteer/md-to-pdf, `sharp`, `exceljs`, Tiptap, ripgrep download) | 1 (`@modelcontextprotocol/sdk`) |
194
+ | Install scripts | `postinstall` posts an install payload that ignores the telemetry setting | none |
195
+ | Telemetry | opt-out, 51 event names, remote feature flags, A/B assignment, third-party processor | opt-out, whitelisted event schema, no endpoint, no flags |
196
+ | Install size | 3.78 MB unpacked, 249 files | ~110 kB unpacked, 20 files |
197
+ | `read_file` | also fetches arbitrary URLs (SSRF surface) | local files only; `read_binary` transfers any file as base64 |
198
+ | Command guardrails | always on, 32 substring-blocked commands, advisory; also refuses read-only mentions | `warn` by default (never blocks), `allow`/`block` opt-in, command-word matching |
199
+ | Confinement | always on, checked against the lexical path | opt-in, checked against the resolved real path |
200
+ | Local history | writes tool arguments to disk unredacted | none |
201
+ | Images | file preview UI in a specific client | `read_image` returns the image to any MCP client |
202
+ | Termination | session kill only | whole process group, plus runtime supervision and restart |
203
+
204
+ What ReMCP deliberately does not implement, and why: document rendering (`write_pdf`) and spreadsheet
205
+ handling would put Puppeteer, `sharp`, and `exceljs` on your computer; `get_config`/`set_config_value`
206
+ would let the model change its own limits; local usage history would write your arguments to disk;
207
+ URL reads in `read_file` would add an SSRF surface. Everything else the upstream server can do has an
208
+ equivalent here, and the tool count is higher.
154
209
 
155
210
  ## License
156
211
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remcp/runtime",
3
- "version": "0.2.0",
3
+ "version": "0.2.4",
4
4
  "description": "First-party ReMCP local device runtime: file, search, terminal and process tools over MCP for computers paired with ReMCP.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,7 +28,8 @@
28
28
  },
29
29
  "repository": {
30
30
  "type": "git",
31
- "url": "git+https://github.com/antonbaider/remcp-runtime.git"
31
+ "url": "git+https://github.com/antonbaider/remcp.git",
32
+ "directory": "packages/runtime"
32
33
  },
33
34
  "bugs": {
34
35
  "url": "https://github.com/antonbaider/remcp/issues"