@raultov/browser-control-mcp 0.3.2-beta.3 → 0.3.5-beta.5

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
@@ -10,6 +10,108 @@ from a copy of its code: entries describe the differences from that release.
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.3.5-beta.5] - 2026-10-28
14
+
15
+ Public **BETA**. Observation tools stop returning wrong or missing data
16
+ without saying so, an endless `evaluate_js` loop no longer kills a Chrome
17
+ tab, Firefox debugger calls no longer block other tabs, and WebMCP passes
18
+ every tool annotation through. Some replies change: `get_custom_events`
19
+ answers `{events, total, truncated}` with the newest events, and
20
+ `get_network_logs` requests may carry `error` and
21
+ `response_body_encoding`.
22
+
23
+ ### Fixed
24
+
25
+ - `webmcp_list_tools` drops no annotation: `consequential` (the page
26
+ declares the tool has real-world effects, such as a payment) and
27
+ `debugging` were silently lost, and any annotation a later Chrome adds is
28
+ now passed through. The output of a tool annotated `untrustedContent` is
29
+ flagged: `webmcp_invoke_tool` adds a note to treat it as data, not as
30
+ instructions, and `webmcp_get_invocation` says `untrustedContent: true`.
31
+ - `evaluate_js` with an endless loop no longer kills the tab on Chrome:
32
+ the script is stopped after 8 s and the call says so ("the script ran for
33
+ more than 8 s ... the page keeps working"); later calls work at once. It
34
+ used to fail after 20 s with `Runtime.evaluate timed out`, and every
35
+ later call on the tab timed out too. An expression waiting on a promise
36
+ that never settles says so after 10 s. Firefox cannot stop a running
37
+ script from outside: its error says so and points to `close_tab`.
38
+ - On Firefox, a slow debugger call on one tab (e.g. a long
39
+ `evaluate_on_call_frame`) no longer blocks the logs and debugger tools of
40
+ the other tabs: each tab's debugger has its own lock (one lock covered
41
+ them all, delaying `get_console_logs` on another tab by 9.5 s).
42
+ - `get_custom_events` returns the newest `limit` events (it returned the
43
+ oldest, so new events never showed once the buffer held more), answers
44
+ pure JSON `{"events", "total", "truncated"}` (the text started with
45
+ `Found N custom events.`), and takes `clear` to remove what it returned.
46
+ - `get_network_logs`: on Chrome the page's own document is in its
47
+ navigation's bucket, so `current_navigation_only` lists it and its body
48
+ is returned (it was left in the previous navigation, without a body). A
49
+ failed request carries `error` (Chrome `net::ERR_...`, Firefox
50
+ `NS_ERROR_...`, also in the summary); it looked like one still waiting on
51
+ Chrome, and Firefox put the error in `response_status_text`. A binary body
52
+ says `response_body_encoding: "base64"`.
53
+ - On Chrome, `get_console_logs` and `get_network_logs` connect first: on an
54
+ instance nothing had connected to (an attached Chrome) they answered
55
+ empty buffers. The console messages the page logged before are now
56
+ returned; `get_network_logs` notes that earlier requests are not
57
+ captured.
58
+
59
+ ## [0.3.4-beta.4] - 2026-10-27
60
+
61
+ Public **BETA**. The same server as 0.3.3-beta.4, which was published on
62
+ crates.io but without binaries, npm package or Homebrew formula: its
63
+ release notes made GitHub skip the builds. See 0.3.3-beta.4 below for the
64
+ changes.
65
+
66
+ ### Fixed
67
+
68
+ - The release notes no longer quote a URL with credentials, which GitHub
69
+ treats as a secret; `make check` now refuses one in this file.
70
+
71
+ ## [0.3.3-beta.4] - 2026-10-27
72
+
73
+ Public **BETA**. Tools that reported success for something that did not
74
+ happen now say what happened, and proxy credentials are handled more
75
+ safely. Some replies change: an unknown tool argument is an error,
76
+ `navigate`/`reload` add `status`, a download URL fails, and
77
+ `restart_browser`/`stop_browser` on an attached Chrome refuse or only
78
+ disconnect.
79
+
80
+ ### Fixed
81
+
82
+ - `open_instance` without `headless` follows the server's `--headless` flag.
83
+ It always opened a window, even on a server started with `--headless`
84
+ (where there may be no display, as in the Docker image).
85
+ - Credentials written in a proxy URL (a user and password before the host,
86
+ from `--proxy-server`, `open_instance`'s `proxy` or `restart_browser`)
87
+ no longer reach the browser: Chrome got them on its command line, readable
88
+ by any local user with `ps` (and ignored them), and Firefox refused to
89
+ launch. `enable_proxy_auth` now falls back to the credentials of
90
+ `--proxy-server`.
91
+ - `enable_proxy_auth` with wrong credentials no longer loops: a request the
92
+ proxy challenges again after two answers is cancelled. Firefox re-raised
93
+ the same request forever (about 50 challenges a second, each carrying the
94
+ password); Chrome retried tens of times. On Firefox, calling the tool
95
+ again also removes the previous intercept (each call added one more).
96
+ - On Chrome, an instance attached to a browser that was already running on
97
+ its port (not launched by the server) no longer reports a restart or stop
98
+ that did not happen. `restart_browser` (and a `copy_cookies` relaunch)
99
+ fails saying the server cannot relaunch it, and nothing is changed;
100
+ `stop_browser` disconnects and says the browser keeps running. Both said
101
+ "successfully" while the same process kept running without the presets.
102
+ - `navigate` and `reload` report the document's HTTP status (`"status":
103
+ 404`), and an error status (400 and up) adds a note. A 404 used to look
104
+ like any success, and an error with an empty body failed on Chrome
105
+ (`ERR_HTTP_RESPONSE_CODE_FAILURE`) but succeeded on Firefox: it is now a
106
+ success with its status on both.
107
+ - `navigate` to a URL the browser downloads fails with `Navigation failed:
108
+ the URL is a download...` on both browsers. Firefox answered "Navigated
109
+ to" the previous page; Chrome failed with `net::ERR_ABORTED`.
110
+ - A tool call with an argument the tool does not have now fails before
111
+ anything runs, naming the argument it was probably meant to be (`tabId`
112
+ answers "did you mean `tab_id`?"). Unknown arguments were ignored, so a
113
+ `tabId` typo ran on the active tab.
114
+
13
115
  ## [0.3.2-beta.3] - 2026-10-25
14
116
 
15
117
  Public **BETA**. Replies up to 256 MB no longer drop the browser connection
package/README.md CHANGED
@@ -11,7 +11,7 @@ It is the successor of
11
11
  from a copy of its code) and complements Playwright MCP or
12
12
  chrome-devtools-mcp with runtime JavaScript debugging on both browsers.
13
13
 
14
- > **Status: BETA (0.3.2-beta.3).** This version contains known bugs and differences
14
+ > **Status: BETA (0.3.5-beta.5).** This version contains known bugs and differences
15
15
  > between Chrome and Firefox (see [Limitations and TODO](#limitations-and-todo))
16
16
  > and parts that have not been verified (see [Untested](#untested)). Tool
17
17
  > replies may change in incompatible ways before 1.0. Please report problems
@@ -40,8 +40,8 @@ see the note.
40
40
  | `open_instance` | ✓ | partial | `features`, `copy_cookies` and `source_profile` are Chrome only |
41
41
  | `close_instance` | ✓ | ✓ | |
42
42
  | `list_instances` | ✓ | ✓ | each instance reports its `browser` and `capabilities` |
43
- | `restart_browser` | ✓ | ✓ | was `restart_chrome` |
44
- | `stop_browser` | ✓ | ✓ | was `stop_chrome`; on an attached Firefox it ends the session, the browser keeps running |
43
+ | `restart_browser` | ✓ | ✓ | was `restart_chrome`; refused on a Chrome already running on the port (attached, not launched by the server) |
44
+ | `stop_browser` | ✓ | ✓ | was `stop_chrome`; on an attached Chrome or Firefox it only disconnects (Firefox: ends the session), the browser keeps running and the reply says so |
45
45
  | `open_tab` | ✓ | ✓ | |
46
46
  | `close_tab` | ✓ | ✓ | |
47
47
  | `list_tabs` | ✓ | ✓ | |
@@ -54,10 +54,10 @@ see the note.
54
54
  | `click_element` | ✓ | ✓ | scrolls the element into view; fails without clicking when it is hidden or covered |
55
55
  | `fill_input` | ✓ | ✓ | picks `<select>` options; fails without typing on elements that cannot take the text; Chrome inserts the text, Firefox types keys |
56
56
  | `handle_dialog` | ✓ | ✓ | accepts or dismisses the open `alert` / `confirm` / `prompt` / `beforeunload` dialog |
57
- | `evaluate_js` | ✓ | ✓ | `value` at most 100 000 characters (`truncated: true`) |
57
+ | `evaluate_js` | ✓ | ✓ | `value` at most 100 000 characters (`truncated: true`); Chrome stops a script after 8 s, Firefox cannot (a looping tab is closed with `close_tab`) |
58
58
  | `get_console_logs` | ✓ | ✓ | a message keeps at most 10 000 characters; Firefox: page errors, CSS warnings and platform messages need the debugger port |
59
- | `get_network_logs` | ✓ | ✓ | bodies at most 64 000 characters, none over 2 MB; a WebSocket payload keeps 64 000 (`payload_len` is the whole); Firefox: WebSocket frames need the debugger port |
60
- | `get_custom_events` | ✓ | partial | params over 64 000 characters of JSON are replaced by `{truncated, characters}`; Firefox: events of the modules subscribed with `send_bidi_command` |
59
+ | `get_network_logs` | ✓ | ✓ | a failed request has `error`, a binary body `response_body_encoding: "base64"`; bodies at most 64 000 characters, none over 2 MB; a WebSocket payload keeps 64 000 (`payload_len` is the whole); Firefox: WebSocket frames need the debugger port |
60
+ | `get_custom_events` | ✓ | partial | `{events, total, truncated}`, the newest `limit` events; `clear` removes the returned ones; params over 64 000 characters of JSON are replaced by `{truncated, characters}`; Firefox: events of the modules subscribed with `send_bidi_command` |
61
61
  | `get_performance_metrics` | ✓ | partial | Firefox: `Nodes`, `Frames`, `Resources`, `TransferSize` from the Web Performance APIs (no Performance domain), plus a note |
62
62
  | `profile_page_performance` | ✓ | partial | Firefox: FCP, LCP, DCL and Load from the Web Performance APIs; no trace, so `total_blocking_time_ms` and `top_long_tasks` are `null` |
63
63
  | `set_breakpoint` | ✓ | partial | Firefox: by URL only (no `script_id` / `script_hash`) |
@@ -67,12 +67,12 @@ see the note.
67
67
  | `evaluate_on_call_frame` | ✓ | ✓ | |
68
68
  | `search_scripts` | ✓ | ✓ | a long line's preview is 100 characters on each side of the match |
69
69
  | `pause_on_load` | ✓ | ✗ | TODO on Firefox, see [Limitations and TODO](#limitations-and-todo) |
70
- | `enable_proxy_auth` | ✓ | partial | needs `--proxy-server`; untested on Firefox against a real proxy |
70
+ | `enable_proxy_auth` | ✓ | partial | needs `--proxy-server`; a request the proxy rejects twice is cancelled; untested on Firefox against a real proxy |
71
71
  | `send_cdp_command` | ✓ | ✗ | raw Chrome DevTools Protocol |
72
72
  | `send_bidi_command` | ✗ | ✓ | raw WebDriver BiDi; refuses `session.new`, `session.end`, `browser.close` |
73
73
  | `send_rdp_request` | ✗ | ✓ | raw Firefox RDP request to an actor (`thread`, `console`, `root` shortcuts) |
74
- | `webmcp_list_tools` | ✓ | ✗ | needs `--enable-webmcp`; WebMCP is a Chrome testing feature |
75
- | `webmcp_invoke_tool` | ✓ | ✗ | needs `--enable-webmcp` |
74
+ | `webmcp_list_tools` | ✓ | ✗ | needs `--enable-webmcp`; WebMCP is a Chrome testing feature; every annotation Chrome reports is listed (`readOnly`, `consequential`, `untrustedContent`, `debugging`, `autosubmit`, newer ones as they are) |
75
+ | `webmcp_invoke_tool` | ✓ | ✗ | needs `--enable-webmcp`; the output of an `untrustedContent` tool comes with a note to treat it as data |
76
76
  | `webmcp_get_invocation` | ✓ | ✗ | needs `--enable-webmcp` |
77
77
  | `webmcp_list_invocations` | ✓ | ✗ | needs `--enable-webmcp` |
78
78
 
@@ -273,13 +273,19 @@ claude mcp add browser-control-mcp -- npx -y @raultov/browser-control-mcp
273
273
  lazily, on the first tool that needs them, with an ephemeral profile.
274
274
  - **Tabs.** `open_tab`, `list_tabs`, `switch_tab`, `close_tab`. Every tool
275
275
  takes `instance_id` and `tab_id`; without them it targets the default
276
- instance and its active tab.
276
+ instance and its active tab. An argument a tool does not have fails the
277
+ call before anything runs (a `tabId` typo answers "did you mean
278
+ `tab_id`?"), so a typo never falls back to the active tab.
277
279
  - **Same replies on both browsers.** `navigate` and `reload` answer once the
278
280
  page fired `load` (at most 30 s, else with a note): a first line
279
281
  (`Navigated to <final URL>.` / `Page reloaded.`), then
280
282
  `{"url": "<final URL, after redirects>", "tab_id": "tab-N", "browser": {...}}`,
281
283
  where `browser` holds the protocol's ids (CDP `frameId`/`loaderId`, BiDi
282
- `navigation`). `open_tab` answers `{tab_id, target_id, url, label}` with the
284
+ `navigation`), plus `"status"`, the document's HTTP status, for http(s)
285
+ pages (an error status, 400 and up, also adds a note; an error page with
286
+ an empty body is reported the same way on both browsers). A URL the
287
+ browser downloads fails with `Navigation failed: the URL is a
288
+ download...`. `open_tab` answers `{tab_id, target_id, url, label}` with the
283
289
  final URL. A network error (unknown host, refused connection...) fails with
284
290
  `Navigation failed: <browser's code> (<url>)`, e.g.
285
291
  `net::ERR_NAME_NOT_RESOLVED` on Chrome and `NS_ERROR_UNKNOWN_HOST` on
@@ -304,7 +310,11 @@ claude mcp add browser-control-mcp -- npx -y @raultov/browser-control-mcp
304
310
  `{"messages": [...], "total", "truncated", "notes"?}`: at most `limit`
305
311
  (default 200) of the most recent matching messages, oldest first; `clear`
306
312
  removes only the returned ones; a note says when a site change cleared
307
- messages.
313
+ messages. `get_custom_events` answers `{"events", "total", "truncated"}`
314
+ the same way. On Chrome both log tools connect first, so on an attached
315
+ browser the first call already sees the page's console messages (Chrome
316
+ replays them; network requests sent before the connection are not
317
+ captured, and the reply says so).
308
318
  - **Firefox allows a single automation session.** Each Firefox instance holds
309
319
  one WebDriver BiDi session shared by its tabs; `close_instance`,
310
320
  `stop_browser` and every server shutdown path end it, so the next run can
@@ -316,7 +326,7 @@ claude mcp add browser-control-mcp -- npx -y @raultov/browser-control-mcp
316
326
  | --- | --- | --- | --- |
317
327
  | `--browser <chrome\|firefox>` | `chrome` | browser of the default instance | browser of the default instance |
318
328
  | `--local` | off | navigation limited to local addresses | same |
319
- | `--headless` | off | headless Chrome | headless Firefox |
329
+ | `--headless` | off | headless Chrome (also the default of `open_instance`'s `headless`) | headless Firefox (same) |
320
330
  | `--window-size <W>x<H>` | `1920x1080` | window of launched Chrome (`--window-size`) | window of launched Firefox (`--width`/`--height`) |
321
331
  | `--host <HOST>` | `127.0.0.1` | debugging host | debugging host |
322
332
  | `--port <PORT>` | `9222` | debugging port of the default instance | ignored (use `--firefox-port`) |
@@ -333,6 +343,11 @@ claude mcp add browser-control-mcp -- npx -y @raultov/browser-control-mcp
333
343
  | `--firefox-rdp-port <PORT>` | none | — | debugger port of the attached Firefox (needs `--firefox-port`) |
334
344
  | `--no-firefox-debugger` | off | — | launch Firefox without its debugger port (no debugger tools) |
335
345
 
346
+ Credentials written in a proxy URL (`http://user:pass@host:port`) never reach
347
+ the browser's command line; `enable_proxy_auth` uses those of `--proxy-server`
348
+ when neither its arguments nor `--proxy-username`/`--proxy-password` give
349
+ them.
350
+
336
351
  `--proxy` and `--webmcp` are aliases. To attach to your own Firefox, start it
337
352
  with `--remote-debugging-port <port>` (and `--start-debugger-server ws:<rdp>`
338
353
  plus `devtools.debugger.remote-enabled` and `devtools.chrome.enabled` for the
@@ -423,13 +438,14 @@ incompatible:
423
438
 
424
439
  | Tool | 0.1.x | 0.2.0 |
425
440
  | --- | --- | --- |
426
- | `navigate`, `reload` | Chrome: raw `Page.navigate` reply (`frameId`, `loaderId`, `errorText`) without waiting, `{}` on reload; Firefox: `{navigation, url}` | `{url, tab_id, browser, notes?}` after `load`; `url` is the final URL; protocol ids under `browser` |
441
+ | `navigate`, `reload` | Chrome: raw `Page.navigate` reply (`frameId`, `loaderId`, `errorText`) without waiting, `{}` on reload; Firefox: `{navigation, url}` | `{url, tab_id, browser, status?, notes?}` after `load`; `url` is the final URL; protocol ids under `browser`; `status` is the document's HTTP status |
427
442
  | `navigate`, `open_tab` to an unreachable host | Chrome: success (`errorText` inside, or a `chrome-error://` tab) | error `Navigation failed: <code> (<url>)`; `open_tab` names the tab, which stays open |
428
443
  | `evaluate_js` | Chrome: `{"result": {type, value, ...}}`; Firefox: the bare value | `{value, type, subtype?, description?}` |
429
444
  | `set_breakpoint` | Chrome: CDP id (`1:3:0:http://…`) and `locations`; Firefox: `{breakpointId, url, lineNumber, columnNumber}` | `{breakpoint_id: "bp-N", url, line_number, column_number, resolved}` |
430
445
  | `remove_breakpoint` | Chrome: CDP id, reply `{}` | `bp-N` id, reply `{removed}` |
431
446
  | `step_over`, `resume` | Chrome: text only; Firefox `step_over`: `{paused, location: {line (1-based), column}}` | `{paused, location: {url, line_number, column_number} \| null}`, 0-based |
432
447
  | `evaluate_on_call_frame` | Chrome: raw `RemoteObject` (exceptions as success); Firefox: bare value | the `evaluate_js` shape; exceptions are errors (`Evaluation threw: ...`) |
448
+ | `get_custom_events` | `Found N custom events. Captured events: [...]`, the oldest events | `{events, total, truncated}`, the newest `limit` events; `clear` removes the returned ones |
433
449
  | `get_console_logs` | a JSON array; `clear` emptied the whole buffer | `{messages, total, truncated, notes?}`, at most `limit` (200) messages; `clear` removes the returned ones; the buffer is cleared on cross-site navigation |
434
450
 
435
451
  ## Limitations and TODO
@@ -500,7 +516,7 @@ incompatible:
500
516
 
501
517
  ```sh
502
518
  make check # fmt, clippy -D warnings, tests, docs, duplication, packaging, version
503
- make e2e # E2E smoke against real, visible Chrome and Firefox (Linux, macOS)
519
+ make e2e # E2E smoke against real Chrome and Firefox, headless (E2E_VISIBLE=1 shows them; Linux, macOS)
504
520
  make check-all # both
505
521
  ```
506
522
 
@@ -19,7 +19,7 @@
19
19
  "hasInstallScript": true,
20
20
  "license": "MIT",
21
21
  "name": "@raultov/browser-control-mcp",
22
- "version": "0.3.2-beta.3"
22
+ "version": "0.3.5-beta.5"
23
23
  },
24
24
  "node_modules/detect-libc": {
25
25
  "engines": {
@@ -48,5 +48,5 @@
48
48
  }
49
49
  },
50
50
  "requires": true,
51
- "version": "0.3.2-beta.3"
51
+ "version": "0.3.5-beta.5"
52
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "artifactDownloadUrls": [
3
- "https://github.com/raultov/browser-control-mcp/releases/download/v0.3.2-beta.3"
3
+ "https://github.com/raultov/browser-control-mcp/releases/download/v0.3.5-beta.5"
4
4
  ],
5
5
  "author": "raultov <raultov@protonmail.com>",
6
6
  "bin": {
@@ -92,7 +92,7 @@
92
92
  "zipExt": ".tar.xz"
93
93
  }
94
94
  },
95
- "version": "0.3.2-beta.3",
95
+ "version": "0.3.5-beta.5",
96
96
  "volta": {
97
97
  "node": "18.14.1",
98
98
  "npm": "9.5.0"