@raultov/browser-control-mcp 0.10.0-beta.15 → 0.11.0-beta.16
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 +66 -0
- package/README.md +10 -8
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,72 @@ from a copy of its code: entries describe the differences from that release.
|
|
|
10
10
|
|
|
11
11
|
## [Unreleased]
|
|
12
12
|
|
|
13
|
+
## [0.11.0-beta.16] - 2026-11-02
|
|
14
|
+
|
|
15
|
+
Public **BETA**. `audit_page` (`perf` group) audits the rendered page for
|
|
16
|
+
accessibility, SEO and best-practice problems on Chrome and Firefox, with the
|
|
17
|
+
same script and no Lighthouse bundle (each failing check lists its first 10
|
|
18
|
+
elements with their snapshot refs); `emulate` gains `cpu_throttling` and
|
|
19
|
+
`network_throttling` on Chrome; `profile_page_performance` adds INP, LCP image
|
|
20
|
+
discovery, DOM size, oversized/unsized images and third-party weight on both
|
|
21
|
+
browsers, and on Chrome extracts `forced_reflows` from the trace, measures
|
|
22
|
+
`unused_code` (JavaScript and CSS) on a reload and saves the raw trace with
|
|
23
|
+
`save_path`; `get_performance_metrics` takes `collect_garbage: true` and reads
|
|
24
|
+
`Memory.getDOMCounters` on Chrome. Behaviour changes: `get_performance_metrics`
|
|
25
|
+
sorts its metrics by name.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- `emulate` gains `cpu_throttling` (`1` to `20`, e.g. `4` for a 4× slowdown)
|
|
30
|
+
and `network_throttling` (`slow-3g`, `fast-3g`, `4g` or `none`; Chrome
|
|
31
|
+
DevTools names such as `Slow 3G` and `Fast 3G` are accepted too) on Chrome,
|
|
32
|
+
kept in the tab's emulation state across calls, reported in the reply and
|
|
33
|
+
cleared by `reset: true`. On Firefox, where WebDriver BiDi has no CPU or
|
|
34
|
+
bandwidth/latency throttling, they fail naming them. (#52)
|
|
35
|
+
- `profile_page_performance` with `insights: true` adds Interaction to Next
|
|
36
|
+
Paint (`inp`: worst interaction, target and input/processing/presentation
|
|
37
|
+
breakdown), LCP image discovery (`lazy_loaded`, `fetch_priority`), DOM
|
|
38
|
+
size (`nodes`, `max_depth`, `widest_element`, `max_children`), oversized
|
|
39
|
+
or unsized images (`images`) and third-party origins (`third_parties`),
|
|
40
|
+
with findings when they cross the web.dev and Lighthouse thresholds, on
|
|
41
|
+
both Chrome and Firefox. (#53)
|
|
42
|
+
- `audit_page` (`perf` group) audits the rendered page for accessibility
|
|
43
|
+
(images without alt text; fields, buttons and links without a name;
|
|
44
|
+
`html lang`; heading order; duplicate ids; broken `aria-labelledby` and
|
|
45
|
+
`aria-describedby`; `tabindex` above 0; targets under 24×24 px too close
|
|
46
|
+
to another; text contrast under WCAG AA), SEO (title, meta description,
|
|
47
|
+
viewport, vague link text, uncrawlable links, canonical, `noindex`) and
|
|
48
|
+
best practices (doctype and quirks mode, HTTPS, mixed content, distorted
|
|
49
|
+
images, console errors), with the same script on Chrome and Firefox and
|
|
50
|
+
no Lighthouse bundle. Each failing check lists its first 10 elements with
|
|
51
|
+
a snapshot ref, a selector, its start tag and a detail; `categories`
|
|
52
|
+
narrows it. (#55)
|
|
53
|
+
- `get_performance_metrics` takes `collect_garbage: true`, which collects
|
|
54
|
+
garbage before reading on Chrome (`HeapProfiler.collectGarbage`), and adds
|
|
55
|
+
the live `Documents`, `Nodes` and `JSEventListeners` of
|
|
56
|
+
`Memory.getDOMCounters`, so reads after repeating an action show what it
|
|
57
|
+
leaked; its metrics are sorted by name. On Firefox, where WebDriver BiDi
|
|
58
|
+
cannot force a collection, a note says so. (#57)
|
|
59
|
+
- `profile_page_performance` with `insights: true` and `action: "reload"`
|
|
60
|
+
adds `unused_code` on Chrome: the bytes of JavaScript that never ran and
|
|
61
|
+
of CSS that matched nothing during the load (`Profiler` precise coverage
|
|
62
|
+
and `CSS` rule usage, as Lighthouse's "Reduce unused JavaScript / CSS"),
|
|
63
|
+
with the 5 files that waste most and a finding over 50 KB. Without a
|
|
64
|
+
reload, and on Firefox (no coverage over WebDriver BiDi), it is `null`
|
|
65
|
+
with a note saying why. (#54)
|
|
66
|
+
- `profile_page_performance` on Chrome extracts `forced_reflows` from the
|
|
67
|
+
trace when `insights: true` (`Layout` and `UpdateLayoutTree` events with a
|
|
68
|
+
JavaScript stack, grouped by call site, with a finding over 30 ms; `null`
|
|
69
|
+
with a note on Firefox) and takes `save_path` (`.json` or `.json.gz` under
|
|
70
|
+
the upload roots) to write the raw trace for Chrome DevTools or Perfetto
|
|
71
|
+
(refused on Firefox before running). (#56)
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
|
|
75
|
+
- `snapshot` names an element by the text slotted into its shadow tree
|
|
76
|
+
(a web component's button labelled by a `<span><slot></span>`):
|
|
77
|
+
`innerText` does not see slotted nodes, so it had no name. (#55)
|
|
78
|
+
|
|
13
79
|
## [0.10.0-beta.15] - 2026-11-02
|
|
14
80
|
|
|
15
81
|
Public **BETA**. Fixes from a comparison round against Playwright MCP,
|
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ It is the successor of
|
|
|
13
13
|
from a copy of its code) and complements Playwright MCP or
|
|
14
14
|
chrome-devtools-mcp with runtime JavaScript debugging on both browsers.
|
|
15
15
|
|
|
16
|
-
> **Status: BETA (0.
|
|
16
|
+
> **Status: BETA (0.11.0-beta.16).** This version contains known bugs and differences
|
|
17
17
|
> between Chrome and Firefox (see [Limitations and TODO](#limitations-and-todo))
|
|
18
18
|
> and parts that have not been verified (see [Untested](#untested)). Tool
|
|
19
19
|
> replies may change in incompatible ways before 1.0. Please report problems
|
|
@@ -29,7 +29,7 @@ the same stdio client through the same tasks on Chrome 156 (headless,
|
|
|
29
29
|
Linux). Every outcome was checked in the page, not taken from the reply.
|
|
30
30
|
Tokens are estimated as characters / 4 for every server. browser-control's
|
|
31
31
|
tool lists and the HTTP authentication row were measured again on
|
|
32
|
-
2026-11-02,
|
|
32
|
+
2026-11-02, with the changes of #46 to #55.
|
|
33
33
|
|
|
34
34
|
**What each one can do**
|
|
35
35
|
|
|
@@ -48,7 +48,8 @@ tool lists and the HTTP authentication row were measured again on
|
|
|
48
48
|
| PDF | ✓ file or inline | ✓ file | ✗ |
|
|
49
49
|
| Cookies and web storage | ✓ values hidden unless asked | ✓ values shown | ✗ |
|
|
50
50
|
| Secrets masked in output (`--secrets`) | ✓ | ✓ | ✗ |
|
|
51
|
-
| Performance | vitals + insights (LCP breakdown, layout shifts, render-blocking, long scripts) | trace file | trace + insights
|
|
51
|
+
| Performance | vitals + insights (INP, LCP breakdown and discovery, layout shifts, render-blocking, long scripts, DOM size, images, third parties; on Chrome: forced reflows, unused JS/CSS, trace export `.json`/`.gz`, DOM/listener counters after GC); CPU and network throttling on Chrome | trace file | trace + insights; CPU and network throttling |
|
|
52
|
+
| Page audit (accessibility, SEO, best practices) | ✓ `audit_page`, on Chrome and Firefox: failing elements with snapshot refs, no bundle | ✗ | Lighthouse, Chrome only: scores, failing elements with selectors, reports saved to disk |
|
|
52
53
|
| Heap snapshots, CSS styles, screencast | ✗ | video, tracing | ✓ |
|
|
53
54
|
| Generates Playwright test code | ✗ | ✓ | ✗ |
|
|
54
55
|
| Telemetry | **none** | none found | usage statistics on by default; traced URLs sent to CrUX |
|
|
@@ -59,7 +60,7 @@ tool lists and the HTTP authentication row were measured again on
|
|
|
59
60
|
| Task | browser-control-mcp | Playwright MCP | chrome-devtools-mcp |
|
|
60
61
|
| --- | --- | --- | --- |
|
|
61
62
|
| Tool list in context, default tools | 6 730 tokens | 5 330 tokens | 7 770 tokens |
|
|
62
|
-
| Tool list in context, every opt-in tool on | 10
|
|
63
|
+
| Tool list in context, every opt-in tool on | 10 880 tokens | 12 040 tokens | not measured (optional categories) |
|
|
63
64
|
| Snapshot of Hacker News | **4 588 tokens** | 12 356 tokens | 6 869 tokens |
|
|
64
65
|
| Snapshot of Wikipedia "Web browser" | **12 643 tokens** (cut, searchable) | 34 349 tokens | 27 656 tokens |
|
|
65
66
|
| Snapshot of MDN `<input>` | **12 625 tokens** (cut, searchable) | 158 077 tokens | 76 654 tokens |
|
|
@@ -95,7 +96,7 @@ tools are off by default and listed only with `--tool-groups`:
|
|
|
95
96
|
| `storage` | `cookies`, `web_storage` | reads and changes session tokens |
|
|
96
97
|
| `files` | `upload_file`, `save_pdf` | reads and writes files of the machine |
|
|
97
98
|
| `raw` | `send_cdp_command`, `send_bidi_command`, `send_rdp_request`, `get_custom_events` | anything the protocol allows |
|
|
98
|
-
| `perf` | `get_performance_metrics`, `profile_page_performance` | niche |
|
|
99
|
+
| `perf` | `get_performance_metrics`, `profile_page_performance`, `audit_page` | niche |
|
|
99
100
|
| `emulation` | `emulate` | niche |
|
|
100
101
|
| `network` | `mock_route`, `list_routes`, `remove_route`, `set_offline` | changes what the page receives |
|
|
101
102
|
|
|
@@ -125,7 +126,7 @@ see the note.
|
|
|
125
126
|
| `navigate` | ✓ | ✓ | `history: "back"` or `"forward"` instead of `url` moves one entry in the tab's history and waits for the page to load (also when it comes from the back-forward cache, which fires no `load`); at either end it fails without moving; a URL the browser saves instead of opening (a download: `Content-Disposition: attachment`, or a type such as CSV) fails saying so, and the tab stays where it was; a page behind HTTP authentication (401) fails at once naming its scheme and realm and how to log in (credentials in the URL, `http://user:password@host/path`, which the browser keeps for the session); a page that pauses at a breakpoint or opens a dialog while loading fails at once naming it (see `resume`, `handle_dialog`) |
|
|
126
127
|
| `reload` | ✓ | ✓ | a pause, a dialog or HTTP authentication while loading fails at once, as with `navigate` |
|
|
127
128
|
| `scroll` | ✓ | ✓ | reports the window positions before and after |
|
|
128
|
-
| `emulate` | ✓ | partial | `emulation` group; `width`/`height`, `device_scale_factor`, `mobile` (touch), `color_scheme`, `reduced_motion`, `forced_colors`, `media` (`print`), `user_agent`, `locale`, `timezone` (checked by the page's `Intl` first), `geolocation` (the page is granted the permission to read it), `reset`; each call adds to the earlier ones; answers what the page now sees (with the position it reads); Firefox: no `mobile
|
|
129
|
+
| `emulate` | ✓ | partial | `emulation` group; `width`/`height`, `device_scale_factor`, `mobile` (touch), `color_scheme`, `reduced_motion`, `forced_colors`, `media` (`print`), `user_agent`, `locale`, `timezone` (checked by the page's `Intl` first), `geolocation` (the page is granted the permission to read it), `cpu_throttling` (1–20×), `network_throttling` (`slow-3g`, `fast-3g`, `4g`, `none`), `reset`; each call adds to the earlier ones; answers what the page now sees (with the position it reads and the active throttling); Firefox: no `mobile`, media or throttling options (BiDi has no media, touch or throttling emulation yet; they fail naming them) |
|
|
129
130
|
| `wait_for` | ✓ | ✓ | waits (checking every 100 ms, at most 30 s) until a visible text appears or is gone, a selector is `visible` / `hidden` / `attached` / `detached`, or the URL contains a text; a dialog or debugger pause ends the wait at once |
|
|
130
131
|
| `inspect_dom` | ✓ | ✓ | includes open shadow roots and same-origin iframes (cross-origin ones are noted); at most 100 000 characters without `query` (cut in the page) |
|
|
131
132
|
| `snapshot` | ✓ | ✓ | outline of the page: role, name, states, value and a ref (`e12`) per element, through open shadow roots and same-origin iframes, and on Chrome closed shadow roots too (pages up to 20 000 elements; their elements are reached by ref, not by `>>>`); frames of another origin are read too (at most 20, 5 deep), their iframe marked `[frame=f2]` and their refs prefixed (`f2e5`), and `selector: "f2"` outlines one; tables without headers (`th`, `thead`, `caption`) are layout and leave only their content, and a cell is named by its text only when it holds nothing else; comboboxes, spinbuttons and sliders built with ARIA show their value (the field's text, `aria-valuetext` or `aria-valuenow`, the option a button-like combobox shows), progress bars and meters theirs (`40/100`), and a `<details>` summary `[expanded=true|false]`; a field the page rejects (`aria-invalid`) or the browser does (`:user-invalid`, once the user changed it or tried to submit) is `[invalid]`, with `[error="..."]` from its `aria-errormessage`, `aria-describedby` or the browser's validation message; a native `<select>` lists its options under its combobox (`[selected]`, `[disabled]`, optgroups as groups; no refs: `fill_input` picks one), the first 25 and how many more, all of them for `find_in_snapshot`; what the page made inert is left out: `inert` subtrees and, while a modal `<dialog>` is open (marked `[modal]`), everything outside it; an element that is only clickable (a handler or a pointer cursor), draggable (`draggable="true"`, marked `[draggable]`) or a drop zone (`ondrop`/`ondragover`) is one named line with a ref for `drag`, unless it holds links, buttons or fields, which are listed under it; at most 50 000 characters (`selector` and `depth` narrow it); the same JavaScript on both browsers |
|
|
@@ -150,8 +151,9 @@ see the note.
|
|
|
150
151
|
| `remove_route` | ✓ | ✓ | `network` group; one route by id, or all |
|
|
151
152
|
| `set_offline` | ✓ | ✓ | `network` group; requests fail as without a network and `navigator.onLine` is false, until set back (Chrome `Network.emulateNetworkConditions`, Firefox `emulation.setNetworkConditions`); mocked routes still answer; Chrome still serves what its HTTP cache holds, as an offline browser does, Firefox fails every request |
|
|
152
153
|
| `get_custom_events` | ✓ | partial | `raw` group; `{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` |
|
|
153
|
-
| `get_performance_metrics` | ✓ | partial | `perf` group; Firefox: `Nodes`, `Frames`, `Resources`, `TransferSize` from the Web Performance APIs (no Performance domain), plus
|
|
154
|
-
| `profile_page_performance` | ✓ | partial | `perf` group; `insights: true` adds what explains the numbers, read with the Web Performance APIs (same JavaScript on both): the document's TTFB, server time and compression, the LCP element
|
|
154
|
+
| `get_performance_metrics` | ✓ | partial | `perf` group; Chrome's metrics sorted by name, with the live `Documents`, `Nodes` and `JSEventListeners` of `Memory.getDOMCounters`; `collect_garbage: true` collects garbage first (`HeapProfiler.collectGarbage`), so reads after repeating an action show what it leaked; Firefox: `Nodes`, `Frames`, `Resources`, `TransferSize` from the Web Performance APIs (no Performance domain) and no garbage collection (WebDriver BiDi has none), plus notes |
|
|
155
|
+
| `profile_page_performance` | ✓ | partial | `perf` group; `save_path` (Chrome only) writes the raw trace (`.json` or `.json.gz`, under the upload roots) for Chrome DevTools or Perfetto; `insights: true` adds what explains the numbers, read with the Web Performance APIs and the DOM (same JavaScript on both): the document's TTFB, server time and compression, the LCP element, its breakdown (TTFB, load delay, load, render delay) and image discovery (`lazy_loaded`, `fetch_priority`), Interaction to Next Paint (`inp`: duration, event, target and input/processing/presentation breakdown), layout-shift culprits, render-blocking requests, the slowest requests, the scripts of long animation frames, DOM size (`nodes`, `max_depth`, `widest_element`, `max_children`), oversized or unsized images, and third-party origins by duration and bytes (at most 5 each), plus `findings` from the web.dev and Lighthouse thresholds; on Chrome, `forced_reflows` from the trace (`Layout`/`UpdateLayoutTree` forced by a script, grouped by call site, a finding over 30 ms) and, with `action: "reload"`, `unused_code` (`unused_js_bytes`, `unused_css_bytes` and the 5 files with most unused bytes, from the `Profiler` precise coverage and `CSS` rule usage of the reload; a finding over 50 KB; without a reload it is `null`: code run before the recording would count as unused); Firefox: FCP, LCP, DCL and Load; no trace (`save_path` fails), so `total_blocking_time_ms` and `top_long_tasks` are `null`, and its insights have no layout shifts, render-blocking requests, long frames, forced reflows or unused code (`null`, with notes) |
|
|
156
|
+
| `audit_page` | ✓ | ✓ | `perf` group; accessibility (images without alt, fields, buttons and links without a name, `html lang`, heading order, duplicate ids, broken `aria-labelledby`/`aria-describedby`, `tabindex` > 0, targets under 24×24 px too close to another, text contrast under WCAG AA), SEO (title, meta description, viewport, vague link text, uncrawlable links, canonical, `noindex`) and best practices (doctype and quirks mode, HTTPS, mixed content, distorted images, console errors); the same script on both browsers; each failing check lists its first 10 elements with a snapshot ref, a selector, its start tag and a detail (the contrast ratio, the size...), then the ids that passed or did not apply; `categories` narrows it; not checked: text over background images or gradients, iframes, closed shadow roots, response headers |
|
|
155
157
|
| `set_breakpoint` | ✓ | partial | Firefox: by URL only (no `script_id` / `script_hash`) |
|
|
156
158
|
| `remove_breakpoint` | ✓ | ✓ | |
|
|
157
159
|
| `resume` | ✓ | ✓ | |
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"hasInstallScript": true,
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"name": "@raultov/browser-control-mcp",
|
|
22
|
-
"version": "0.
|
|
22
|
+
"version": "0.11.0-beta.16"
|
|
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.
|
|
51
|
+
"version": "0.11.0-beta.16"
|
|
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
|
+
"https://github.com/raultov/browser-control-mcp/releases/download/v0.11.0-beta.16"
|
|
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.
|
|
95
|
+
"version": "0.11.0-beta.16",
|
|
96
96
|
"volta": {
|
|
97
97
|
"node": "18.14.1",
|
|
98
98
|
"npm": "9.5.0"
|