machine-bridge-mcp 0.13.0 → 0.15.0

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,43 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.15.0 - 2026-07-13
4
+
5
+ ### Daily-profile browser verification and protocol safety
6
+
7
+ - Verify the unpacked extension in the user's ordinary Chrome profile with a localhost-only live smoke test covering the acknowledged protocol handshake, real tab lifecycle, semantic inspection, open Shadow DOM, complex form fill, fixed DevTools text/click input, waits, screenshot capture, and cleanup. `browser status` and loopback health now report extension version/protocol, that Machine Bridge did not launch the browser, and the fact that daily-vs-isolated profile identity is not machine-verifiable.
8
+ - Upgrade the extension protocol to an acknowledged `hello`/`hello_ack` state machine with exact packaged-version, protocol, and capability equality. WebSocket open is no longer treated as authenticated readiness, pairing material is persisted only after a successful capability handshake, failed candidate pairing preserves the prior configuration, pairing-page and broker ports must match, and extension WebSocket origins require a canonical 32-character Chromium extension ID.
9
+ - Prevent duplicate side effects after an ambiguous trusted-input failure. `auto` falls back to DOM only before any DevTools `Input` command starts; after dispatch begins, the operation fails with an explicit unknown-outcome instruction to inspect the page before retrying. Screenshot capture temporarily activates only the requested tab, never focuses its window, and restores the previous active tab unless the user changed it concurrently.
10
+
11
+ ### Bounded page processing and extension architecture
12
+
13
+ - Apply `max_bytes` and `max_elements` as aggregate request budgets across at most 64 accessible frames. Replace full `outerHTML` construction with a bounded iterative DOM serializer, cap page scans at 100,000 nodes, bound page-controlled metadata/text, cap reusable refs at 10,000 per frame, redact URL userinfo, mark contenteditable secret controls as sensitive, and report frame/node/text/ref truncation explicitly.
14
+ - Report partial multi-field form mutation precisely when a later field or submission fails. Navigation waits now inherit the bounded request deadline rather than using a hidden fixed 30-second timer.
15
+ - Extract tab/page/wait/source/screenshot orchestration into fixed `browser-operations.js`; the Manifest V3 service worker now owns only pairing, transport, acknowledged readiness, cancellation, and response routing. Architecture tests enforce this responsibility boundary.
16
+
17
+ ### Cross-platform audit and regression coverage
18
+
19
+ - Replace ad-hoc Windows Scheduled Task argument quoting with the Windows CRT-compatible backslash/quote algorithm, including drive-root and trailing-backslash paths.
20
+ - Add behavior tests for handshake readiness, provisional pairing persistence, trusted-input replay prevention, focus restoration, aggregate frame/source budgets, hostile DOM/text bounds, partial form failure, strict extension origins, and Windows command-line quoting. Synchronize architecture, security, operations, testing, audit, and tool documentation.
21
+
22
+ ## 0.14.0 - 2026-07-13
23
+
24
+ ### Windows installation and OAuth callback reliability
25
+
26
+ - Bootstrap installation through pinned npm 12.0.1 from an empty temporary directory before using `--allow-scripts`, declare the npm 12 requirement in package `engines`, and make `machine-mcp doctor` verify the active npm version. This removes the unsupported old-npm path shown by Windows and gives accurate diagnostics for `Unknown cli config "--allow-scripts"` and legacy `devEngines.node` errors without guessing which package supplied the invalid metadata.
27
+ - Construct OAuth callback destinations with the URL API and return `303 See Other` after consent instead of manually concatenating a `Location` string. Add an end-to-end ChatGPT callback regression with reserved state characters and exact origin/path checks.
28
+ - Extend the isolated install smoke test to require npm 12, install from an empty directory, verify the packaged npm engine requirement, and run the test on Linux, macOS, and Windows CI.
29
+
30
+ ### Existing-profile browser automation
31
+
32
+ - Keep the authenticated Manifest V3 extension as the primary browser backend so automation operates the user's ordinary Chromium profile, tabs, extensions, cookies, and login state instead of launching a separate profile. Add tab creation/activation/closure and explicit combined waits for URL, document readiness, page text, and element state.
33
+ - Replace fragile inspect-then-selector flows with bounded semantic snapshots containing stable per-document/frame element references, visibility/enabled/editable state, and viewport geometry. Page actions now wait for attachment, visibility, enabled/editable state, geometric stability, and unobscured pointer hit targets; ambiguous selectors and stale references fail explicitly.
34
+ - Add double-click, hover, append-text, and scroll-into-view actions. Top-frame click, double-click, hover, key press, and text input can use fixed short-lived Chromium DevTools Input commands through explicit `auto`, `trusted`, or `dom` modes. The extension exposes no caller-selected CDP method or arbitrary JavaScript and detaches the debugger in `finally`.
35
+
36
+ ### Architecture, security, tests, and documentation
37
+
38
+ - Extract browser command normalization into a focused local module and isolate trusted input in a fixed extension module. Add a versioned extension capability handshake, stale-build reload guidance, explicit keepalive handling, and replacement validation that preserves the current compatible connection until the candidate is accepted; accepted replacements reject in-flight direct and proxied requests with retry guidance instead of leaving them to time out. Preserve resource-backed secrets/files, strict action/value validation, bounded broker messages, cancellation, source limits, and the existing owner-only pairing model.
39
+ - Add behavior-level tests for command contracts, trusted-input command sequences and cleanup, semantic-ref stability, deterministic scrolling, obscured-target waiting, stale refs, broker routing, catalog parity, and architecture invariants. Update browser setup, permission, security, architecture, testing, and tool documentation.
40
+
3
41
  ## 0.13.0 - 2026-07-13
4
42
 
5
43
  ### Automatic capability routing and observability
package/README.md CHANGED
@@ -47,10 +47,38 @@ This default prioritizes usability, not least privilege. `run_process` and proce
47
47
 
48
48
  Node.js 26 or newer and npm 12 or newer are required. The repository pins the active development versions in `.node-version`, `.nvmrc`, and `packageManager`; project installs fail on older Node runtimes.
49
49
 
50
+ Use a new temporary directory for the bootstrap. The existing `npm`/`npx` front-end may inspect nearby project metadata before it launches the requested npm version; starting from an empty directory prevents an unrelated legacy `devEngines` declaration from blocking the bootstrap. The actual installation is then executed by the pinned npm 12 CLI rather than whichever npm happens to be first on `PATH`.
51
+
52
+ macOS/Linux:
53
+
50
54
  ```sh
51
- npm install -g --omit=optional --allow-scripts=esbuild,workerd,sharp,fsevents machine-bridge-mcp@latest
55
+ install_dir="$(mktemp -d)"
56
+ (
57
+ cd "$install_dir"
58
+ npx --yes npm@12.0.1 install --global npm@12.0.1
59
+ npx --yes npm@12.0.1 install --global --omit=optional --allow-scripts=esbuild,workerd,sharp,fsevents machine-bridge-mcp@latest
60
+ )
61
+ rm -rf "$install_dir"
62
+ npm --version
63
+ machine-mcp doctor
52
64
  ```
53
65
 
66
+ Windows Command Prompt (`cmd.exe`):
67
+
68
+ ```bat
69
+ set "MBM_INSTALL_DIR=%TEMP%\machine-bridge-mcp-install-%RANDOM%-%RANDOM%"
70
+ mkdir "%MBM_INSTALL_DIR%"
71
+ pushd "%MBM_INSTALL_DIR%"
72
+ npx --yes npm@12.0.1 install --global npm@12.0.1
73
+ npx --yes npm@12.0.1 install --global --omit=optional --allow-scripts=esbuild,workerd,sharp,fsevents machine-bridge-mcp@latest
74
+ popd
75
+ rmdir /s /q "%MBM_INSTALL_DIR%"
76
+ npm --version
77
+ machine-mcp doctor
78
+ ```
79
+
80
+ `Unknown cli config "--allow-scripts"` proves the Machine Bridge install was executed by npm 11 or older rather than the required npm 12. `Invalid property "node"` or `Invalid property "devEngines.node"` means that npm parsed a legacy `devEngines` object; the npm debug log is required to identify which package supplied it. The empty-directory, pinned-npm procedure avoids relying on that old parser. If `npm --version` still reports an older version after the bootstrap, reopen the terminal and rerun `machine-mcp doctor`.
81
+
54
82
  Recent npm releases may otherwise warn that Wrangler's native dependencies (`esbuild`, `workerd`, and `sharp`) have install scripts awaiting approval. The scoped command approves the reviewed native script names that npm 12 evaluates during global resolution while `--omit=optional` keeps optional `fsevents` out of the installed runtime. `fsevents` is used for development-time filesystem watching rather than Machine Bridge runtime or deployment. Omitting `--omit=optional` can therefore produce a harmless blocked-script warning for `fsevents@2.3.3`; use the documented command rather than changing global npm policy. `machine-mcp doctor` remains the authoritative runtime check.
55
83
 
56
84
  From a source checkout, the checked-in exact-version `allowScripts` policy approves the reviewed native dependencies:
@@ -81,14 +109,13 @@ On first remote start, the CLI:
81
109
 
82
110
  A normal `machine-mcp` invocation is a foreground start: it remains attached to the terminal and prints `info` logs. Startup and other state-changing operations use an owner-token/process-identity lock and wait up to 30 seconds for an ordinary concurrent startup to finish instead of failing on a brief launchd/systemd race. After a global package upgrade, the CLI unloads the platform service and also checks the workspace lock for a detached/orphan `--daemon-only` process that the service manager no longer tracks. It terminates only a process whose PID, process start time, entrypoint, canonical workspace, canonical state root, and daemon-only arguments all match, waits up to 15 seconds for the PID and lock to disappear, and then starts the installed version in the foreground. A genuine foreground or unverifiable conflict is left untouched and reported with actionable guidance. To run only in the background, use `machine-mcp service start`; inspect its owner-only logs under `~/.local/state/machine-bridge-mcp/logs/`.
83
111
 
84
- Recommended upgrade sequence:
112
+ Recommended upgrade sequence: repeat the package-free temporary-directory installation above, then run:
85
113
 
86
114
  ```sh
87
- npm install -g --omit=optional --allow-scripts=esbuild,workerd,sharp,fsevents machine-bridge-mcp@latest
88
115
  machine-mcp --verbose
89
116
  ```
90
117
 
91
- The global install replaces files on disk but cannot hot-reload an already running Node process; the second command performs the bounded service and orphan-daemon takeover. Use the command exactly as shown: `--omit=optional` prevents the development-only optional `fsevents` package from producing a blocked-install-script warning. If takeover fails, run `machine-mcp service status` first; it reports the platform service and workspace daemon separately. Then run `machine-mcp service stop` and retry.
118
+ The global install replaces files on disk but cannot hot-reload an already running Node process; the foreground command performs the bounded service and orphan-daemon takeover. Keep `--omit=optional` in the installation step to prevent the development-only optional `fsevents` package from producing a blocked-install-script warning. If takeover fails, run `machine-mcp service status` first; it reports the platform service and workspace daemon separately. Then run `machine-mcp service stop` and retry.
92
119
 
93
120
  Use the printed values in the MCP client:
94
121
 
@@ -97,7 +124,7 @@ MCP Server URL: https://<worker>.<account>.workers.dev/mcp
97
124
  MCP connection password: mcp_password_...
98
125
  ```
99
126
 
100
- The remote authorization flow uses an authorization code, PKCE S256, exact redirect/resource binding, expiring access tokens stored as hashes, and a token-version value for bulk revocation.
127
+ The remote authorization flow uses an authorization code, PKCE S256, exact redirect/resource binding, expiring access tokens stored as hashes, and a token-version value for bulk revocation. After password approval, the Worker constructs the registered callback with the URL API and returns `303 See Other`, so OAuth response parameters are encoded and the browser performs a GET to the callback.
101
128
 
102
129
  ## Optional local stdio MCP
103
130
 
@@ -158,8 +185,8 @@ Skill discovery follows Codex-style progressive disclosure. Default project root
158
185
  Under canonical `full`, Machine Bridge also exposes structured local automation:
159
186
 
160
187
  - installed application discovery/opening and macOS Accessibility inspection/actions;
161
- - a packaged Chromium extension that controls the user's existing daily browser profile, active tabs, login state, and windows;
162
- - current DOM source and frame/open-Shadow-DOM inspection, structured page actions, complex multi-field forms, resource-backed secret fields, resource-backed file uploads, and screenshots.
188
+ - a packaged Chromium extension that controls the profile into which the user loads it, including that profile's tabs, login state, and windows; Machine Bridge does not launch a separate browser process;
189
+ - current DOM source and frame/open-Shadow-DOM inspection, stable semantic element references, actionability waits, fixed trusted mouse/keyboard input, explicit browser waits, tab management, complex multi-field forms, resource-backed secret fields, resource-backed file uploads, and screenshots.
163
190
 
164
191
  One-time browser setup:
165
192
 
@@ -168,7 +195,7 @@ machine-mcp browser setup
168
195
  machine-mcp browser status
169
196
  ```
170
197
 
171
- Load the printed unpacked-extension directory once in Chrome, Edge, Brave, Vivaldi, or another compatible Chromium browser. The extension badge reports connection state, and clicking it opens the saved local pairing page. The local pairing token remains in owner-only state and the loopback pairing page; it is not returned through MCP. For a mass-market release, distribute the same extension as a signed browser-store build rather than asking end users to enable Developer mode. See [Local application and browser automation](docs/LOCAL_AUTOMATION.md).
198
+ Load the printed unpacked-extension directory in the Chromium profile you actually use; Machine Bridge does not install it into Playwright or a separate automation profile. After every Machine Bridge upgrade, reload the unpacked extension and accept any new browser permission. `machine-mcp browser status` reports both the expected packaged extension build and the authenticated connected build/protocol, and states that Machine Bridge did not launch the browser. It cannot infer whether the extension was loaded into a daily or isolated profile; that is determined by where the user installed it. Trusted input uses the Chromium `debugger` permission only for fixed, short-lived DevTools Input commands. The badge shows `ON` only after the broker acknowledges the version/capability handshake. The local pairing token remains in owner-only state and non-cacheable loopback HTML; it is not returned through MCP. For a mass-market release, distribute the same extension as a signed browser-store build rather than asking end users to enable Developer mode. See [Local application and browser automation](docs/LOCAL_AUTOMATION.md).
172
199
 
173
200
  Machine Bridge can discover, refresh, rank, and load capabilities automatically. The ChatGPT/MCP host still owns tool selection and approval, so the server cannot force a host to expose or invoke a recommended skill, command, app, or browser operation. Check `server_info.observability.capability_routing` or `project_overview.capabilityRouting` to distinguish “the host never called the resolver” from “the resolver ran but found no relevant capability.”
174
201
 
@@ -319,12 +346,14 @@ The exact `tools/list` response reflects the active local policy. Definitions co
319
346
  - `browser_status`
320
347
  - `pair_browser_extension`
321
348
  - `browser_list_tabs`
322
- - `browser_get_source` — bounded current DOM HTML, including selected frames
323
- - `browser_inspect_page`
324
- - `browser_action`
349
+ - `browser_manage_tabs` — create, activate, or close tabs
350
+ - `browser_get_source` — bounded current DOM HTML with one aggregate byte budget across up to 64 accessible frames
351
+ - `browser_inspect_page` — semantic controls, bounded LRU refs, state, geometry, and explicit frame/node/ref truncation metadata
352
+ - `browser_wait` — bounded URL/load/text/element-state waits
353
+ - `browser_action` — actionability checks plus `auto`, `trusted`, or `dom` input mode; ambiguous post-dispatch failures are never replayed through DOM
325
354
  - `browser_fill_form`
326
355
  - `browser_upload_files` — registered local resources to file inputs
327
- - `browser_screenshot`
356
+ - `browser_screenshot` — restores the prior active tab and does not focus another window
328
357
 
329
358
 
330
359
  ### Mutation
package/SECURITY.md CHANGED
@@ -71,13 +71,13 @@ The global `model_instructions_file` is an explicit user trust decision. It is r
71
71
 
72
72
  ## Browser and application automation
73
73
 
74
- Canonical `full` exposes structured browser and desktop UI authority. The browser extension operates the user's existing Chromium profile, including active login state, and has broad host access so it can inspect arbitrary pages and fill complex forms. An authorized client may therefore read page content, click controls, submit forms, upload registered files, and cause transactions with the user's browser identity. macOS Accessibility actions similarly operate applications with the local user's UI authority.
74
+ Canonical `full` exposes structured browser and desktop UI authority. The browser extension operates the user's existing Chromium profile, including active login state, and has broad host access plus Chromium `debugger` permission so it can inspect arbitrary pages, fill complex forms, and issue trusted input. An authorized client may therefore read page content, click controls, submit forms, upload registered files, and cause transactions with the user's browser identity. macOS Accessibility actions similarly operate applications with the local user's UI authority.
75
75
 
76
- The browser loopback broker validates loopback `Host`, requires a random owner-only bearer subprotocol, accepts extension sockets only with a `chrome-extension://` origin, and authenticates additional local runtimes separately. Initial extension pairing is trust-on-first-use; after pairing, a different localhost page cannot replace the stored broker unless the user clicks the extension action while the genuine pairing page is active. The pairing token is never returned by MCP or written to operational logs. These controls defend against casual cross-origin and DNS-rebinding access; they do not protect against malicious code already running as the same OS user or a compromised browser extension profile.
76
+ The browser loopback broker validates loopback `Host`, requires a random owner-only bearer subprotocol, accepts extension sockets only from a canonical 32-character Chromium extension ID, requires the pairing page and WebSocket endpoint to use the same loopback port, and authenticates additional local runtimes separately. Initial extension pairing is trust-on-first-use; after pairing, a different localhost page cannot replace the stored broker unless the user clicks the extension action while the genuine pairing page is active. The pairing token is never returned by MCP or written to operational logs. These controls defend against casual cross-origin and DNS-rebinding access; they do not protect against malicious code already running as the same OS user or a compromised browser extension profile.
77
77
 
78
- Caller-supplied JavaScript, AppleScript, and JXA source are deliberately unsupported. Actions use fixed implementation code and structured selectors. This removes an avoidable arbitrary-evaluation surface but does not make DOM or Accessibility actions safe. Pages can contain prompt injection, misleading labels, hidden consequences, cross-origin frames unavailable to inspection, or state that changes between inspection and submission. High-impact account, financial, legal, medical, publishing, deletion, and purchase actions require contextual review and any host/user confirmation the client provides.
78
+ Caller-supplied JavaScript, AppleScript, JXA source, and arbitrary DevTools methods are deliberately unsupported. Actions use fixed implementation code and structured selectors. The debugger adapter is restricted to fixed `Input` commands, attaches only around one trusted action, and detaches in `finally`. `auto` falls back only before any Input dispatch; after dispatch begins, failure is reported as an unknown outcome and is never replayed through DOM. The broker and extension require a protocol-3 `hello`/`hello_ack` exchange plus exact packaged-version and capability equality before either reports readiness. Pairing material is persisted only after acknowledgement, and an invalid replacement candidate cannot displace the current connection or overwrite its stored endpoint/token. This removes an avoidable arbitrary-evaluation surface but does not make DOM or Accessibility actions safe. Pages can contain prompt injection, misleading labels, hidden consequences, cross-origin frames unavailable to inspection, or state that changes between inspection and submission. High-impact account, financial, legal, medical, publishing, deletion, and purchase actions require contextual review and any host/user confirmation the client provides.
79
79
 
80
- Text and file resources can be injected locally so their contents do not appear in MCP arguments or results. The destination page/application still receives the value, and remote tool metadata/results still traverse the Worker and host. Page source and screenshots can themselves contain secrets. Browser/app tool arguments, source, screenshots, field values, and results are intentionally omitted from operational logs.
80
+ Text and file resources can be injected locally so their contents do not appear in MCP arguments or results. The destination page/application still receives the value, and remote tool metadata/results still traverse the Worker and host. Page source and screenshots can themselves contain secrets. Source/inspection budgets are aggregate across frames, page-controlled metadata is bounded, URL userinfo is removed from semantic snapshots, and contenteditable controls with secret-like identity are treated as sensitive; these limits reduce accidental exposure but do not classify every possible secret. Browser/app tool arguments, source, screenshots, field values, and results are intentionally omitted from operational logs.
81
81
 
82
82
  ## Filesystem exposure
83
83
 
@@ -145,7 +145,7 @@ Runner diagnostic logs are owner-only and do not receive child stdout/stderr. St
145
145
 
146
146
  ## OAuth and public endpoints
147
147
 
148
- Remote mode uses authorization code flow with PKCE S256, exact redirect/resource/client binding, expiring authorization codes and access tokens, hashed token storage, token-version revocation, and bounded dynamic client registration.
148
+ Remote mode uses authorization code flow with PKCE S256, exact redirect/resource/client binding, expiring authorization codes and access tokens, hashed token storage, token-version revocation, and bounded dynamic client registration. Successful consent constructs the registered callback through the URL API and returns `303 See Other`; response parameters are encoded rather than concatenated into an unchecked header string.
149
149
 
150
150
  The authorization page displays the validated client name and redirect URI. Enter the connection password only after initiating the connection and recognizing both values.
151
151