@remcp/runtime 0.2.47 → 0.2.49

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
+ ## Unreleased
4
+
5
+ ## 0.2.49 — 2026-09-20
6
+
7
+ - Terminal process tools now return schema-validated structured session state, output ranges, match results and termination facts alongside their human-readable text.
8
+ - The runtime catalog and hosted tool contract align on bounded structured outputs and accurate read-only/destructive/idempotent/open-world annotations for the expanded computer-use surface.
9
+ - Preview references remain optional presentation metadata rather than replacing the source result used for model reasoning.
10
+ - Lockstep patch release with the ReMCP client at `0.2.49`.
11
+
12
+ ## 0.2.48 — 2026-09-20
13
+
14
+ - Migrate the local stdio runtime to the official `@modelcontextprotocol/server` v2 serving entry while preserving legacy 2025-era client compatibility.
15
+ - Add negotiated MCP `2026-07-28` support, including `server/discover`, cache hints, full structured output validation, and subscription-based `notifications/tools/list_changed` delivery.
16
+ - Keep the legacy `@modelcontextprotocol/sdk` and modern `@modelcontextprotocol/client` packages dev-only so CI continuously proves both protocol eras against the same runtime.
17
+ - Add optional Tesseract-backed OCR inside `computer_snapshot`/`computer_action`, including bounded word/line boxes and HiDPI/multi-monitor coordinate mapping, without adding another MCP tool or production dependency.
18
+ - Added 39 computer-use tools: native desktop/window automation, accessibility UI inspection/actions, browser CDP, diagnostics, and lightweight DOCX/XLSX/PDF operations.
19
+ - Live `tools/list` now advertises only capabilities available on the current operating system and sends `notifications/tools/list_changed` when the capability set changes; `--print-tools` remains the stable full 83-tool release contract.
20
+ - Added high-level `computer_snapshot` and `computer_action` primitives so agents can prefer semantic Accessibility/DOM targets and fall back to coordinates/screenshots only when necessary.
21
+ - Chrome DevTools Protocol endpoints are restricted to loopback addresses. New filesystem/document operations continue through the existing resolved-path allowlist, and launch/service/power operations reuse the runtime command policy.
22
+ - Fixed metadata output truncation once the JSON tool contract exceeded the operating-system pipe buffer by waiting for stdout writes to flush before exit.
23
+ - Terminal session tools now expose schema-validated structured `pid`, status, exit information, output ranges/matches, and session lists alongside their human-readable text, so hosted agents can chain process calls without parsing prose.
24
+ - No browser/document rendering stack was added; the runtime remains dependency-light and uses native OS facilities plus existing qpdf/poppler/zip helpers when available.
25
+
3
26
  ## 0.2.47 — 2026-09-19
4
27
 
5
28
  - Lockstep release with the ReMCP client. Runtime behavior is unchanged from 0.2.46; the client now recovers from transient HTTP handshake failures and migrates Linux systemd services to a stable launcher independent of nvm/Hermes prefixes.
package/README.md CHANGED
@@ -1,12 +1,13 @@
1
1
  # ReMCP local runtime
2
2
 
3
3
  `@remcp/runtime` is the local device runtime for [ReMCP](https://remcp.site). It is an MCP
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.
4
+ server that runs on a computer you paired with ReMCP and executes file, image, search, terminal,
5
+ process, desktop UI, browser, diagnostics, and document tools exposed through the hosted ReMCP MCP endpoint.
6
6
 
7
7
  The ReMCP device agent starts this runtime as a child process and talks to it over stdio. The runtime
8
- never talks to the network on its own: it only answers the paired agent, which holds the device
9
- credential you can revoke at any time.
8
+ has no independent cloud service or telemetry endpoint: browser automation connects only to a loopback
9
+ Chrome DevTools endpoint, while the explicit `network` diagnostic and commands you run can reach the
10
+ network when requested. The device credential remains in the paired agent and can be revoked at any time.
10
11
 
11
12
  ## Install
12
13
 
@@ -27,8 +28,10 @@ npx @remcp/runtime # MCP server over stdio
27
28
 
28
29
  ## Tools
29
30
 
30
- 44 tools, all implemented in this repository. Nothing is gated behind an approval step: a tool call
31
- executes.
31
+ 83 tools are implemented in this repository: the original 44 filesystem/search/terminal/process tools
32
+ plus 39 computer-use, browser, diagnostics, and document tools. The release contract contains all 83;
33
+ the live local MCP `tools/list` omits optional platform-specific tools that the current computer cannot
34
+ support and emits `notifications/tools/list_changed` when that capability set changes. The stdio server is dual-era: existing 2025-era clients continue to work unchanged, while clients that negotiate MCP `2026-07-28` use `server/discover`, cache hints, unrestricted structured output validation, and `subscriptions/listen` for list-change delivery.
32
35
 
33
36
  | Area | Tools |
34
37
  | --- | --- |
@@ -41,18 +44,27 @@ executes.
41
44
  | Search | `start_search`, `get_more_search_results`, `stop_search`, `list_searches` |
42
45
  | Processes | `start_process`, `read_process_output`, `wait_for_process_output`, `interact_with_process`, `force_terminate`, `list_sessions`, `list_processes`, `kill_process` |
43
46
  | Runtime | `get_system_info`, `get_runtime_info`, `get_runtime_stats`, `set_config_value` |
47
+ | Computer use | `computer_snapshot`, `computer_action`, `list_windows`, `window_action`, `launch_app`, `ui_snapshot`, `ui_find`, `ui_action`, `type_text`, `keyboard`, `pointer`, `drag_drop`, `scroll`, `wait_for_ui`, `clipboard`, `display_inventory`, `screenshot_region`, `open_path`, `reveal_path`, `notification` |
48
+ | Browser | `browser_tabs`, `browser_navigate`, `browser_snapshot`, `browser_find`, `browser_action`, `browser_wait`, `browser_evaluate` |
49
+ | Diagnostics | `service`, `event_log`, `network`, `installed_apps`, `environment`, `audio`, `power_action`, `record_screen` |
50
+ | Documents | `read_document`, `edit_spreadsheet`, `edit_document`, `pdf_action` |
44
51
 
45
- The hosted ReMCP endpoint adds eight account/relay tools — `list_devices`, `ping_device`,
52
+ The hosted ReMCP endpoint adds eleven account/presentation tools — `list_devices`, `ping_device`,
46
53
  `who_am_i`, `create_pairing_command`, `get_recent_tool_calls`, `get_usage_statistics`,
47
- `get_configuration`, and `rename_device` — for a 52-tool public surface. Everything else the
48
- agent may need, including service management, package installs, git and docker, runs through
49
- `start_process` with the permissions of the account running the agent.
54
+ `get_configuration`, `render_file_preview`, `render_image_preview`, `render_terminal_preview`, and
55
+ `rename_device` — for a 94-tool MCP Apps catalog. Plain MCP clients receive 91 tools because the
56
+ three presentation-only render tools are omitted unless the UI extension is negotiated.
50
57
 
51
- `set_config_value` is deliberately narrow: it can change only `telemetryEnabled`,
58
+ `computer_snapshot` and `computer_action` keep OCR inside the compact high-level surface: when a local `tesseract` binary is available, snapshot can return bounded OCR text/boxes and click targeting can fall back through Accessibility → browser DOM/CDP → OCR → coordinates. OCR is optional and never adds another MCP tool or bundled OCR dependency.
59
+
60
+ For frontend QA, use semantic data to operate the page and rendered pixels to verify it: `browser_action(action="set_viewport")` sets an exact responsive-test viewport, `browser_wait` waits for the real application state, and `browser_snapshot(include_screenshot=true, selector=...)` recenters the component, returns its bounds, and attaches the real CDP-rendered viewport PNG. This intentionally treats screenshots as the visual oracle without making screenshot-driven coordinate guessing the primary control path.
61
+
62
+ `set_config_value` remains deliberately narrow: it can change only `telemetryEnabled`,
52
63
  `maxReadLines`, `maxBufferedLines`, and `maxOutputBytes`. Access roots, blocked commands,
53
64
  the command guardrail, shell, write limit, runtime name, and unrestricted mode stay with the person
54
- at the computer. There is no `write_pdf`/spreadsheet/DOCX tooling; use `start_process` with the
55
- document tools already installed on your machine.
65
+ at the computer. DOCX/XLSX edits operate directly on OOXML, while structural PDF writes use existing
66
+ system tools such as qpdf/poppler when present; ReMCP still does not bundle Chromium, Puppeteer,
67
+ `sharp`, or `exceljs`.
56
68
 
57
69
  `--print-tools` prints the exact JSON contract (schemas and annotations) the runtime advertises, and
58
70
  `src/catalog.mjs` is the single source of truth for it.
@@ -60,8 +72,14 @@ document tools already installed on your machine.
60
72
  ## No approval staircase
61
73
 
62
74
  ReMCP is a remote control for computers you own, with the same trust model as SSH: the tool call runs,
63
- and the user's request is the authorization. There is no approval prompt, no "are you sure", and no
64
- dry-run detour unless you ask for one.
75
+ and the user's request is the authorization. ReMCP adds no per-tool approval prompt, no "are you sure",
76
+ and no dry-run detour unless you ask for one.
77
+
78
+ Operating-system security boundaries still apply. macOS can require Accessibility/Screen Recording grants,
79
+ and GNOME Wayland requires a one-time XDG RemoteDesktop consent before low-level keyboard/pointer input.
80
+ ReMCP does not bypass those controls: after GNOME grants access, the portal restore token is stored locally
81
+ under the runtime config directory with mode `0600` and reused when the portal permits it. Semantic AT-SPI
82
+ UI actions and the XDG Screenshot portal remain separate from that low-level input permission.
65
83
 
66
84
  - file writes replace by default (`mode: "append"` to add), moves and copies replace the destination
67
85
  (`overwrite: false` refuses instead), `replace_in_files` applies immediately (`dry_run: true`
@@ -106,9 +124,10 @@ in `~/.config/remcp/runtime.json`. `--describe` always reports the current state
106
124
 
107
125
  ## Runtime properties
108
126
 
109
- - **No network calls of its own.** The runtime opens no sockets: every byte it emits goes to the
110
- paired agent. Shell commands it runs can of course reach the network, exactly as they would from
111
- your own terminal.
127
+ - **No independent cloud control plane.** Telemetry and device RPC still leave only through the paired
128
+ agent. Browser control accepts only loopback CDP endpoints. The explicit `network` diagnostic can
129
+ open a bounded TCP connection to a host/port, and shell/browser actions can reach the network when
130
+ the requested operation itself requires it.
112
131
  - **Optional confinement.** `allowedRoots` is empty by default. When you set it, it is enforced
113
132
  against the resolved real path of the deepest existing ancestor rather than the lexical string, so
114
133
  `<allowed>/link -> /etc` cannot be used to read or write outside the allowed directories.
@@ -194,8 +213,8 @@ MCP server.
194
213
 
195
214
  | | Desktop Commander 0.2.50 | ReMCP runtime |
196
215
  | --- | --- | --- |
197
- | Tools | 26, including config mutators and document tooling | 44, including binary transfer, bulk file operations, archives, screenshots, search, process control, and narrowly scoped runtime preferences |
198
- | Runtime dependencies | 34 (Supabase, Puppeteer/md-to-pdf, `sharp`, `exceljs`, Tiptap, ripgrep download) | 2 direct (`@modelcontextprotocol/sdk`, `@jellybrick/dbus-next`) |
216
+ | Tools | 26, including config mutators and document tooling | 83, including filesystem/terminal plus native desktop UI, browser CDP, diagnostics, and lightweight document operations |
217
+ | Runtime dependencies | 34 (Supabase, Puppeteer/md-to-pdf, `sharp`, `exceljs`, Tiptap, ripgrep download) | 2 production-direct (`@modelcontextprotocol/server` v2, `@jellybrick/dbus-next`); legacy/modern clients are dev-only compatibility tests |
199
218
  | Install scripts | `postinstall` posts an install payload that ignores the telemetry setting | none |
200
219
  | Telemetry | opt-out, 51 event names, remote feature flags, A/B assignment, third-party processor | opt-out, whitelisted event schema, no endpoint, no flags |
201
220
  | Package footprint | 3.78 MB unpacked, 249 files | small first-party runtime package; no bundled browser or document-rendering stack |
@@ -206,12 +225,12 @@ MCP server.
206
225
  | Images | file preview UI in a specific client | `read_image` returns the image to any MCP client |
207
226
  | Termination | session kill only | whole process group, plus runtime supervision and restart |
208
227
 
209
- What ReMCP deliberately does not implement, and why: document rendering (`write_pdf`) and spreadsheet
210
- handling would put Puppeteer, `sharp`, and `exceljs` on your computer; unrestricted configuration
211
- mutation is intentionally absent — `set_config_value` is limited to four non-security preferences,
212
- while access roots and command security remain local; local usage history would write your arguments
213
- to disk; URL reads in `read_file` would add an SSRF surface. Everything else the upstream server can
214
- do has an equivalent here, and the tool count is higher.
228
+ What ReMCP deliberately does not bundle: browser/document rendering stacks such as Puppeteer,
229
+ `sharp`, and `exceljs`. Spreadsheet and DOCX edits use OOXML directly, and PDF structural operations
230
+ use existing system utilities when installed. Unrestricted configuration mutation is intentionally
231
+ absent — `set_config_value` is limited to four non-security preferences, while access roots and
232
+ command security remain local; local usage history would write arguments to disk; URL reads in
233
+ `read_file` remain absent to avoid an implicit SSRF surface.
215
234
 
216
235
  ## License
217
236
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@remcp/runtime",
3
- "version": "0.2.47",
4
- "description": "First-party ReMCP local device runtime: file, search, terminal and process tools over MCP for computers paired with ReMCP.",
3
+ "version": "0.2.49",
4
+ "description": "First-party ReMCP local device runtime: filesystem, terminal, computer-use, browser, diagnostics and document tools over MCP.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "homepage": "https://remcp.site",
@@ -25,6 +25,10 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@jellybrick/dbus-next": "^0.11.3",
28
+ "@modelcontextprotocol/server": "^2.0.0"
29
+ },
30
+ "devDependencies": {
31
+ "@modelcontextprotocol/client": "^2.0.0",
28
32
  "@modelcontextprotocol/sdk": "^1.30.0"
29
33
  },
30
34
  "repository": {
package/src/catalog.mjs CHANGED
@@ -16,6 +16,72 @@ export const TEXT_OUTPUT_SCHEMA = {
16
16
  additionalProperties: false,
17
17
  };
18
18
 
19
+ const NULLABLE_NUMBER_SCHEMA = { anyOf:[{ type:'number' }, { type:'null' }] };
20
+ const NULLABLE_STRING_SCHEMA = { anyOf:[{ type:'string' }, { type:'null' }] };
21
+ const TERMINAL_SESSION_PROPERTIES = {
22
+ pid:{ type:'number', description:'Process/session id used by follow-up terminal tools.' },
23
+ status:{ type:'string', description:'running or exited, with an exit code/signal when known.' },
24
+ runtimeMs:{ type:'number' },
25
+ lines:{ type:'number', description:'Total output lines produced by the session.' },
26
+ exited:{ type:'boolean' },
27
+ exitCode:NULLABLE_NUMBER_SCHEMA,
28
+ signal:NULLABLE_STRING_SCHEMA,
29
+ };
30
+ function terminalOutputSchema(extraProperties = {}, extraRequired = []) {
31
+ return {
32
+ type:'object',
33
+ properties:{ ...TERMINAL_SESSION_PROPERTIES, ...extraProperties },
34
+ required:['pid','status','runtimeMs','lines','exited','exitCode','signal', ...extraRequired],
35
+ additionalProperties:false,
36
+ };
37
+ }
38
+ const START_PROCESS_OUTPUT_SCHEMA = terminalOutputSchema({
39
+ command:{ type:'string' },
40
+ output:{ type:'string' },
41
+ partial:{ type:'string' },
42
+ warning:{ type:'string' },
43
+ }, ['command','output']);
44
+ const READ_PROCESS_OUTPUT_SCHEMA = terminalOutputSchema({
45
+ range:{ type:'string' },
46
+ output:{ type:'string' },
47
+ explicitOffset:{ type:'boolean' },
48
+ }, ['range','output','explicitOffset']);
49
+ const WAIT_PROCESS_OUTPUT_SCHEMA = terminalOutputSchema({
50
+ pattern:{ type:'string' },
51
+ matched:{ type:'boolean' },
52
+ bufferedMatch:{ type:'boolean' },
53
+ timeoutMs:{ type:'number' },
54
+ output:{ type:'string' },
55
+ }, ['pattern','matched','bufferedMatch','timeoutMs','output']);
56
+ const INTERACT_PROCESS_OUTPUT_SCHEMA = terminalOutputSchema({
57
+ output:{ type:'string' },
58
+ }, ['output']);
59
+ const TERMINATE_PROCESS_OUTPUT_SCHEMA = terminalOutputSchema({
60
+ terminated:{ type:'boolean' },
61
+ alreadyExited:{ type:'boolean' },
62
+ escalated:{ type:'boolean' },
63
+ }, ['terminated','alreadyExited','escalated']);
64
+ const LIST_SESSIONS_OUTPUT_SCHEMA = {
65
+ type:'object',
66
+ properties:{
67
+ sessions:{
68
+ type:'array',
69
+ items:{
70
+ type:'object',
71
+ properties:{
72
+ ...TERMINAL_SESSION_PROPERTIES,
73
+ blocked:{ type:'string' },
74
+ command:{ type:'string' },
75
+ },
76
+ required:['pid','status','runtimeMs','lines','exited','exitCode','signal','blocked','command'],
77
+ additionalProperties:false,
78
+ },
79
+ },
80
+ },
81
+ required:['sessions'],
82
+ additionalProperties:false,
83
+ };
84
+
19
85
  const readOnly = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
20
86
  const readOnlyNonIdempotent = { readOnlyHint: true, destructiveHint: false, idempotentHint: false, openWorldHint: false };
21
87
  const additive = { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false };
@@ -26,7 +92,7 @@ export const toolDefinitions = [
26
92
  {
27
93
  name: 'read_file',
28
94
  title: 'Read file',
29
- description: 'Read a file on this computer: text as text, and .docx or .pdf as their extracted document text (a scanned or font-obfuscated PDF says so instead of returning noise). Use offset and length to page through large files; a negative offset reads from the end of the file.',
95
+ description: 'Read a plain text or line-oriented file on this computer: source, config, Markdown, scripts or logs. Use read_document for PDF, DOCX, XLSX and other structured documents. Legacy .docx/.pdf extraction remains supported for compatibility. Use offset and length to page through large text files; a negative offset reads from the end.',
30
96
  inputSchema: {
31
97
  type: 'object',
32
98
  properties: {
@@ -606,6 +672,7 @@ export const toolDefinitions = [
606
672
  additionalProperties: false,
607
673
  },
608
674
  annotations: command,
675
+ outputSchema: START_PROCESS_OUTPUT_SCHEMA,
609
676
  handler: terminalToolHandlers.start_process,
610
677
  },
611
678
  {
@@ -626,6 +693,7 @@ export const toolDefinitions = [
626
693
  // Reading without an explicit offset advances the session cursor, so retries can return
627
694
  // different output even after the process exits. It never modifies user files.
628
695
  annotations: readOnlyNonIdempotent,
696
+ outputSchema: READ_PROCESS_OUTPUT_SCHEMA,
629
697
  handler: terminalToolHandlers.read_process_output,
630
698
  },
631
699
  {
@@ -643,6 +711,7 @@ export const toolDefinitions = [
643
711
  additionalProperties: false,
644
712
  },
645
713
  annotations: command,
714
+ outputSchema: INTERACT_PROCESS_OUTPUT_SCHEMA,
646
715
  handler: terminalToolHandlers.interact_with_process,
647
716
  },
648
717
  {
@@ -660,6 +729,7 @@ export const toolDefinitions = [
660
729
  additionalProperties: false,
661
730
  },
662
731
  annotations: readOnlyNonIdempotent,
732
+ outputSchema: WAIT_PROCESS_OUTPUT_SCHEMA,
663
733
  handler: terminalToolHandlers.wait_for_process_output,
664
734
  },
665
735
  {
@@ -675,6 +745,7 @@ export const toolDefinitions = [
675
745
  additionalProperties: false,
676
746
  },
677
747
  annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
748
+ outputSchema: TERMINATE_PROCESS_OUTPUT_SCHEMA,
678
749
  handler: terminalToolHandlers.force_terminate,
679
750
  },
680
751
  {
@@ -683,6 +754,7 @@ export const toolDefinitions = [
683
754
  description: 'List terminal sessions started during this ReMCP runtime session with their status and how long they have been running.',
684
755
  inputSchema: { type: 'object', properties: {}, additionalProperties: false },
685
756
  annotations: readOnly,
757
+ outputSchema: LIST_SESSIONS_OUTPUT_SCHEMA,
686
758
  handler: terminalToolHandlers.list_sessions,
687
759
  },
688
760
  {