@remcp/remcp 0.2.29 → 0.2.31
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/README.md +47 -0
- package/package.json +1 -1
- package/src/cli.mjs +32 -1
package/README.md
CHANGED
|
@@ -27,12 +27,33 @@ remcp install Install or repair the user service
|
|
|
27
27
|
remcp uninstall Remove the user service
|
|
28
28
|
remcp uninstall --purge Remove the service and the global packages
|
|
29
29
|
remcp telemetry [status|on|off]
|
|
30
|
+
remcp godmode [status|on|off]
|
|
30
31
|
remcp --version
|
|
31
32
|
```
|
|
32
33
|
|
|
33
34
|
`remcp status` reports the runtime the device would install, whether the agent service is running,
|
|
34
35
|
and the current usage-metrics state, so a support request can be answered with one paste.
|
|
35
36
|
|
|
37
|
+
## Unrestricted mode
|
|
38
|
+
|
|
39
|
+
`remcp godmode on` removes the runtime's own safety rails on **this** computer: file access is no
|
|
40
|
+
longer confined to the allowed roots, the configured command blocklist is ignored, and the
|
|
41
|
+
catastrophic-command guardrail is set to allow. `remcp godmode off` puts them back; `remcp godmode
|
|
42
|
+
status` says which state you are in and where it comes from.
|
|
43
|
+
|
|
44
|
+
Two things it deliberately does not do:
|
|
45
|
+
|
|
46
|
+
- **It is not reachable from a model.** `set_config_value` lists the settings a model may change and
|
|
47
|
+
this is not one of them; only a person at the computer (this command, `REMCP_RUNTIME_UNRESTRICTED=1`,
|
|
48
|
+
or `unrestricted: true` in `~/.config/remcp/runtime.json`) can turn it on. That is what keeps a
|
|
49
|
+
prompt injection from becoming root.
|
|
50
|
+
- **It does not make the agent root.** Commands run as the user the agent runs as. `sudo` is no longer
|
|
51
|
+
blocked, but the operating system still asks for a password unless your sudoers rules say otherwise;
|
|
52
|
+
a non-interactive command cannot type one. Nothing in this mode grants root by itself.
|
|
53
|
+
|
|
54
|
+
While it is on, `get_runtime_info` reports `policy.unrestricted: true`, so the model can see it and
|
|
55
|
+
say so instead of assuming the guardrails are still there.
|
|
56
|
+
|
|
36
57
|
## macOS folder permissions
|
|
37
58
|
|
|
38
59
|
macOS protects Desktop, Documents, Downloads and iCloud Drive. Until it is granted access, ReMCP
|
|
@@ -43,6 +64,32 @@ background service: open **System Settings → Privacy & Security → Full Disk
|
|
|
43
64
|
binary that `remcp doctor` prints, and run `remcp start`. Folders outside those four need no new
|
|
44
65
|
permission, and `remcp doctor` reports the state of each one.
|
|
45
66
|
|
|
67
|
+
## Updates
|
|
68
|
+
|
|
69
|
+
The agent asks the server which versions it should run when it connects and every six hours, installs
|
|
70
|
+
a newer client and runtime in the background, and restarts the service so they take effect. A failed
|
|
71
|
+
install is retried no more often than every thirty minutes, so a broken release cannot turn into an
|
|
72
|
+
install loop. `remcp update` does the same immediately; `remcp auto-update off` turns the automatic
|
|
73
|
+
check off for a machine that must not change on its own.
|
|
74
|
+
|
|
75
|
+
## Screenshots
|
|
76
|
+
|
|
77
|
+
`take_screenshot` returns the screen of this computer as an image, and each desktop keeps its own
|
|
78
|
+
gate — ReMCP names the one that refused instead of printing a generic error:
|
|
79
|
+
|
|
80
|
+
- **macOS** wants Screen Recording for the binary that runs the tools (`remcp doctor` prints its
|
|
81
|
+
path), then `remcp start`.
|
|
82
|
+
- **Windows** needs an unlocked interactive session; a locked or signed-out machine cannot be
|
|
83
|
+
captured.
|
|
84
|
+
- **Linux on Wayland** needs a capture backend: `grim` on wlroots desktops (sway, hyprland), and
|
|
85
|
+
`gnome-screenshot` on GNOME — GNOME refuses the shell's own screenshot API to background processes
|
|
86
|
+
and `grim` cannot read a GNOME session. On X11, `scrot`, ImageMagick `import` or `gnome-screenshot`
|
|
87
|
+
all work.
|
|
88
|
+
- A machine with no graphical session (a server, a container) says so: there is nothing to capture.
|
|
89
|
+
|
|
90
|
+
A screenshot larger than the inline limit is saved on the computer, and the result says where it is
|
|
91
|
+
and how to fetch it in chunks.
|
|
92
|
+
|
|
46
93
|
## What runs on your computer
|
|
47
94
|
|
|
48
95
|
- the agent (`remcp start`), which holds the device credential and dials
|
package/package.json
CHANGED
package/src/cli.mjs
CHANGED
|
@@ -487,7 +487,7 @@ function assertRuntimeTrust(server, flags) {
|
|
|
487
487
|
}
|
|
488
488
|
|
|
489
489
|
function printHelp() {
|
|
490
|
-
console.log(`ReMCP ${VERSION}\n\nCommands:\n remcp start\n remcp status\n remcp doctor\n remcp update\n remcp install\n remcp uninstall\n remcp uninstall --purge\n remcp telemetry [status|on|off]\n remcp --version\n\nPairing commands are generated in the ReMCP workspace.\n\nUsage metrics are opt-out (tool names, timings, outcomes only, sent to your own ReMCP\naccount through the paired agent). Disable them at any time with: remcp telemetry off
|
|
490
|
+
console.log(`ReMCP ${VERSION}\n\nCommands:\n remcp start\n remcp status\n remcp doctor\n remcp update\n remcp install\n remcp uninstall\n remcp uninstall --purge\n remcp telemetry [status|on|off]\n remcp godmode [status|on|off]\n remcp --version\n\nPairing commands are generated in the ReMCP workspace.\n\nUsage metrics are opt-out (tool names, timings, outcomes only, sent to your own ReMCP\naccount through the paired agent). Disable them at any time with: remcp telemetry off\n\nUnrestricted mode (remcp godmode on) lifts the access roots and the command guardrails for this\ncomputer only. It is deliberately not reachable from a model or an MCP tool.`);
|
|
491
491
|
}
|
|
492
492
|
|
|
493
493
|
export async function main(argv = process.argv.slice(2)) {
|
|
@@ -602,6 +602,37 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
602
602
|
throw new Error('Usage: remcp telemetry [status|on|off]');
|
|
603
603
|
}
|
|
604
604
|
|
|
605
|
+
// The switch that lifts every guardrail: no access roots, no command blocklist, no catastrophic
|
|
606
|
+
// command protection. It lives here, on the machine, because a model that could turn it on would
|
|
607
|
+
// turn any prompt injection into root. The runtime refuses to set it through MCP
|
|
608
|
+
// (`set_config_value` lists what it accepts, and this is not on the list).
|
|
609
|
+
if (command === 'godmode' || command === 'unrestricted') {
|
|
610
|
+
const action = String(positional[0] || 'status').toLowerCase();
|
|
611
|
+
if (action === 'status') {
|
|
612
|
+
const runtimeFile = readJsonFile(runtimeConfigFile);
|
|
613
|
+
const state = runtimeFile.unrestricted === true || process.env.REMCP_RUNTIME_UNRESTRICTED === '1';
|
|
614
|
+
console.log(JSON.stringify({
|
|
615
|
+
unrestricted: state,
|
|
616
|
+
source: runtimeFile.unrestricted === true ? runtimeConfigFile : process.env.REMCP_RUNTIME_UNRESTRICTED === '1' ? 'REMCP_RUNTIME_UNRESTRICTED' : 'default',
|
|
617
|
+
meaning: state
|
|
618
|
+
? 'Every path and every command is allowed. Commands run as the user the agent runs as, so sudo still needs your own sudoers rules; nothing here grants root by itself.'
|
|
619
|
+
: 'The runtime confines file access to its allowed roots and applies its command guardrails.',
|
|
620
|
+
}, null, 2));
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
if (!['on', 'off', 'enable', 'disable'].includes(action)) throw new Error('Usage: remcp godmode [status|on|off]');
|
|
624
|
+
const enabled = action === 'on' || action === 'enable';
|
|
625
|
+
writeJsonFile(runtimeConfigFile, { ...readJsonFile(runtimeConfigFile), unrestricted: enabled });
|
|
626
|
+
const restarted = restartPersistentServiceIfInstalled();
|
|
627
|
+
if (enabled) {
|
|
628
|
+
console.error('Unrestricted mode is ON for this computer: every path and every command is allowed, including sudo. Anything the model is asked to do -- and anything a prompt injection asks it to do -- can now change this machine. Turn it off with `remcp godmode off` when you are done.');
|
|
629
|
+
} else {
|
|
630
|
+
console.log('Unrestricted mode is off: the runtime is back to its allowed roots and command guardrails.');
|
|
631
|
+
}
|
|
632
|
+
console.log(JSON.stringify({ unrestricted: enabled, configFile: runtimeConfigFile, restarted }, null, 2));
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
|
|
605
636
|
if (command === 'status' || command === 'doctor') {
|
|
606
637
|
const cfg = loadConfig();
|
|
607
638
|
const health = await fetch(`${cfg.serverUrl}/health?fresh=${Date.now()}`, { cache: 'no-store' }).then(r => r.json()).catch(error => ({ error: error.message }));
|