@raultov/browser-control-mcp 0.11.0-beta.16 → 0.11.0-beta.17
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 +82 -0
- package/README.md +20 -11
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,88 @@ 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.17] - 2026-11-02
|
|
14
|
+
|
|
15
|
+
Public **BETA**. Fixes found probing the debugger, tab and raw protocol tools
|
|
16
|
+
on both browsers. The browser's front tab now stays on the active tab (pages
|
|
17
|
+
in background tabs were hidden, with `requestAnimationFrame` stopped and
|
|
18
|
+
Chrome screenshots timing out); a click whose handler pauses or opens a
|
|
19
|
+
dialog after an `await` is noted at once; Chrome `snapshot`,
|
|
20
|
+
`find_in_snapshot` and `emulate` answer on a paused page; Firefox
|
|
21
|
+
`search_scripts` sees inline scripts and modules, `step_over` and `resume`
|
|
22
|
+
report a breakpoint hit again in a loop, and `get_custom_events` keeps every
|
|
23
|
+
subscribed event and RDP event packets; Chrome `navigate` to a hash route
|
|
24
|
+
reports the new URL; `webmcp_invoke_tool` passes a page tool's error and
|
|
25
|
+
blocks through. Behaviour changes: `open_tab` makes the new tab active.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- `open_tab` makes the new tab the active one (the tools that omit `tab_id`
|
|
30
|
+
act on it), as the browser shows it, Playwright MCP's `browser_tabs` and
|
|
31
|
+
chrome-devtools-mcp's `new_page` do. Before, the previous tab stayed
|
|
32
|
+
active while the browser showed the new one. (#68)
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Firefox: `profile_page_performance` with `action: "reload"` and
|
|
37
|
+
`disable_cache: true` no longer fails with `Argument "ignoreCache" is
|
|
38
|
+
not supported yet`: it bypasses the cache with `network.setCacheBehavior`
|
|
39
|
+
(restored on every exit path). A reload Firefox aborts with
|
|
40
|
+
`NS_BINDING_ABORTED` right after navigating to a page that mounts frames
|
|
41
|
+
during hydration (as MDN does) is retried once after 50 ms instead of
|
|
42
|
+
failing. `forced_reflows.total_ms` no longer serializes `-0.0` when there
|
|
43
|
+
are none. (#58)
|
|
44
|
+
- Firefox: `search_scripts` finds every script of the page, not only the
|
|
45
|
+
first one Firefox announced: inline scripts, modules and scripts loaded
|
|
46
|
+
later were missing (`Total cached scripts: 1` on a page with five). Each
|
|
47
|
+
thread is now asked for its `sources`, merged with the announced ones;
|
|
48
|
+
pause locations and breakable columns use the same list. (#62)
|
|
49
|
+
- The browser's front tab is kept on the active tab. After a click that
|
|
50
|
+
opened a tab (`target=_blank`, a popup, `window.open`), after
|
|
51
|
+
`close_tab` and after a page or the user closed a tab, the active tab was
|
|
52
|
+
left in the background: its page was `hidden`, `requestAnimationFrame`
|
|
53
|
+
stopped (Chrome) or ran at about 1 s (Firefox), and on Chrome an element
|
|
54
|
+
screenshot hung 10 s before a raw CDP timeout. On Chrome,
|
|
55
|
+
`capture_screenshot` of a tab still in the background now fails at once,
|
|
56
|
+
naming `switch_tab`. On Chrome, a click whose reply came before the new
|
|
57
|
+
tab was registered no longer misses the "opened tab" note: it waits (at
|
|
58
|
+
most 2 s) for the pages Chrome announced. (#68)
|
|
59
|
+
- Chrome: `snapshot`, `find_in_snapshot` and `emulate` answer at once on a
|
|
60
|
+
page paused in the debugger, instead of failing after 10 s with
|
|
61
|
+
`CDP Error: Command Runtime.evaluate timed out after 10s`: their
|
|
62
|
+
synchronous snippets are no longer awaited (Chrome runs no microtask while
|
|
63
|
+
paused). `emulate` with `geolocation` on a paused page says the position
|
|
64
|
+
is read once the page resumes. (#64)
|
|
65
|
+
- An input action (`click_element`, `press_key`, `fill_form`, `drag`,
|
|
66
|
+
`hover`) whose handler pauses in the debugger or opens a dialog after an
|
|
67
|
+
async step (an `await`, a timer, a fetch) no longer waits 2 s and answers
|
|
68
|
+
a plain success: the watch of the page settling ends at once and the
|
|
69
|
+
reply notes `{paused, location}` or `{dialog}`, as for a handler that
|
|
70
|
+
blocks right away. Both browsers. (#65)
|
|
71
|
+
- Chrome: `navigate` to another fragment of the current page (a hash route
|
|
72
|
+
such as `#/contact`) answers the new URL; it often answered the previous
|
|
73
|
+
one, read from a history entry Chrome had not updated yet. The URL now
|
|
74
|
+
comes from the page's `Page.navigatedWithinDocument`. (#70)
|
|
75
|
+
- Firefox: `step_over` and `resume` that stop at the same place again (a
|
|
76
|
+
breakpoint in a loop, hit on the next iteration) report the pause with
|
|
77
|
+
its location, instead of waiting 2 s and answering `paused: false` while
|
|
78
|
+
the page was paused. (#63)
|
|
79
|
+
- `webmcp_invoke_tool` maps a page tool's MCP-shaped result
|
|
80
|
+
(`{content: [...], isError}`) to its own reply: the page's text and image
|
|
81
|
+
blocks as they are, and `isError: true` as a tool error. Before, a failed
|
|
82
|
+
page tool answered as a success with its error buried in the text, and
|
|
83
|
+
its output came as JSON escaped inside a string. (#72)
|
|
84
|
+
- Firefox: `get_custom_events` gets every event the agent subscribed to
|
|
85
|
+
with `send_bidi_command`, also those the server handles itself
|
|
86
|
+
(`browsingContext.load`, `contextCreated`, `log.entryAdded`,
|
|
87
|
+
`network.*`...), which were silently dropped. A tab opening or closing,
|
|
88
|
+
and an event without a context (`script.realmDestroyed`), go to the
|
|
89
|
+
active tab. The event packets an actor sends after a `send_rdp_request`
|
|
90
|
+
to it (`evaluationResult` after `evaluateJSAsync`, `pageError` after
|
|
91
|
+
`startListeners`) are kept too, as `rdp.<type>` (at most 16 actors
|
|
92
|
+
watched). Firefox itself sends `script.realmCreated` only for a new
|
|
93
|
+
tab's first document. (#71)
|
|
94
|
+
|
|
13
95
|
## [0.11.0-beta.16] - 2026-11-02
|
|
14
96
|
|
|
15
97
|
Public **BETA**. `audit_page` (`perf` group) audits the rendered page for
|
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.11.0-beta.
|
|
16
|
+
> **Status: BETA (0.11.0-beta.17).** 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
|
|
@@ -119,8 +119,8 @@ see the note.
|
|
|
119
119
|
| `list_instances` | ✓ | ✓ | each instance reports its `browser` and `capabilities` |
|
|
120
120
|
| `restart_browser` | ✓ | ✓ | was `restart_chrome`; refused on a Chrome already running on the port (attached, not launched by the server) |
|
|
121
121
|
| `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 |
|
|
122
|
-
| `open_tab` | ✓ | ✓ | |
|
|
123
|
-
| `close_tab` | ✓ | ✓ | |
|
|
122
|
+
| `open_tab` | ✓ | ✓ | the new tab becomes the active one, in front |
|
|
123
|
+
| `close_tab` | ✓ | ✓ | the next active tab is brought to the front |
|
|
124
124
|
| `list_tabs` | ✓ | ✓ | |
|
|
125
125
|
| `switch_tab` | ✓ | ✓ | |
|
|
126
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`) |
|
|
@@ -132,8 +132,8 @@ see the note.
|
|
|
132
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 |
|
|
133
133
|
| `find_in_snapshot` | ✓ | ✓ | `text` (case-insensitive) or `regex` over the whole outline; matching lines under their ancestors, at most 20 |
|
|
134
134
|
| `save_pdf` | ✓ | ✓ | `files` group; prints the tab as the browser's print does (`landscape`, `print_background`, `scale` 0.1–2, `page_ranges` like `1-3, 5`); with `path` (an absolute `.pdf` under the upload roots) writes the file and answers `{path, bytes, pages}`, else returns the PDF as an embedded `application/pdf` resource (at most 5 MB); Chrome `Page.printToPDF`, Firefox `browsingContext.print` |
|
|
135
|
-
| `capture_screenshot` | ✓ | ✓ | `format` `png`, `jpeg` (or `jpg`) or `webp`; `full_page` at most 16 384 px per side (a text note says when cut); `selector` captures one element (CSS, `host >>> inner` or a snapshot ref), scrolled into view, whole even when taller than the viewport |
|
|
136
|
-
| `click_element` | ✓ | ✓ | scrolls the element into view; `button` (left/right/middle), `click_count` (2 = double click) and `modifiers`; fails without clicking when it is hidden, covered (its own label on top does not count: styled checkboxes and switches are clicked through it; a covered element first gets the mouse, so controls shown only on hover are revealed and clicked) or a disabled control, whose handler would never run; an element a CSS selector does not find yet, or a disabled control, is checked again for up to 2 s, as pages add elements and enable buttons a moment after the previous action (a ref that names nothing, a hidden or a covered element fail at once); `host >>> inner` selectors reach open shadow roots and same-origin iframes (also in `fill_input`, `scroll`, `wait_for`); a dialog or debugger pause the click causes is noted in a successful reply (`{dialog}` or `{paused, location}`) |
|
|
135
|
+
| `capture_screenshot` | ✓ | ✓ | `format` `png`, `jpeg` (or `jpg`) or `webp`; `full_page` at most 16 384 px per side (a text note says when cut); `selector` captures one element (CSS, `host >>> inner` or a snapshot ref), scrolled into view, whole even when taller than the viewport; on Chrome a tab in the background (hidden) is refused at once, naming `switch_tab` |
|
|
136
|
+
| `click_element` | ✓ | ✓ | scrolls the element into view; `button` (left/right/middle), `click_count` (2 = double click) and `modifiers`; fails without clicking when it is hidden, covered (its own label on top does not count: styled checkboxes and switches are clicked through it; a covered element first gets the mouse, so controls shown only on hover are revealed and clicked) or a disabled control, whose handler would never run; an element a CSS selector does not find yet, or a disabled control, is checked again for up to 2 s, as pages add elements and enable buttons a moment after the previous action (a ref that names nothing, a hidden or a covered element fail at once); `host >>> inner` selectors reach open shadow roots and same-origin iframes (also in `fill_input`, `scroll`, `wait_for`); a dialog or debugger pause the click causes is noted in a successful reply (`{dialog}` or `{paused, location}`), also when its handler blocks the page after an `await` or a timer, while the page is watched to settle |
|
|
137
137
|
| `fill_input` | ✓ | ✓ | picks `<select>` options (on a `<select multiple>`, exactly the ones named one per line; an unknown one changes nothing); sets `date`, `time`, `datetime-local`, `month`, `week`, `range` and `color` inputs to the text in their own format (`2026-10-31`, `13:45`, `72`, `#ff0000`), firing `input` and `change`, noting a value the input adjusted (a range snaps to its step) and failing, without changing it, on a malformed one; fails without typing on elements that cannot take the text; `append: true` types after the content instead of replacing it (a number or email field, which has no caret, is retyped whole); an editor of its own (an element with an `EditContext` or a focusable `textbox` role, or the hidden input of a code editor such as Monaco or Ace) gets the keys a user presses: a click on the editor when its input has no visible box, Control+A (Command+A on macOS) or Control+End, then the text, and the reply says its content could not be checked; in a contenteditable element (including rich text editors such as Slate, Lexical, ProseMirror or CodeMirror 6) it selects the content (a range, then Control+A as a user would) and types over it, so the editor records the edit; types key by key on both (key handlers run; newlines and tabs inserted as text), about 1 ms per character; `change` on leaving the field, or at the end when the window has no focus |
|
|
138
138
|
| `press_key` | ✓ | ✓ | one key (a character, Enter, Tab, Escape, arrows, F1–F12...) with Control / Shift / Alt / Meta held (in `modifiers`, or written before the key as `Control+a`, `Shift+Tab` or `ControlOrMeta+c`: Meta on macOS, Control elsewhere), in `selector` (focused first) or the focused element; a shortcut types nothing |
|
|
139
139
|
| `hover` | ✓ | ✓ | moves the mouse over the element (scrolled into view; fails when hidden or covered) |
|
|
@@ -150,7 +150,7 @@ see the note.
|
|
|
150
150
|
| `list_routes` | ✓ | ✓ | `network` group; the tab's routes with the `hits` each answered |
|
|
151
151
|
| `remove_route` | ✓ | ✓ | `network` group; one route by id, or all |
|
|
152
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 |
|
|
153
|
-
| `get_custom_events` | ✓ |
|
|
153
|
+
| `get_custom_events` | ✓ | ✓ | `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` (also those the server handles, such as `browsingContext.load`; a tab opening or closing, or an event without a context, goes to the active tab) and the event packets of actors addressed with `send_rdp_request` (`rdp.<type>`, e.g. `rdp.evaluationResult`) |
|
|
154
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
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
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 |
|
|
@@ -159,14 +159,14 @@ see the note.
|
|
|
159
159
|
| `resume` | ✓ | ✓ | |
|
|
160
160
|
| `step_over` | ✓ | ✓ | |
|
|
161
161
|
| `evaluate_on_call_frame` | ✓ | ✓ | |
|
|
162
|
-
| `search_scripts` | ✓ | ✓ | a long line's preview is 100 characters on each side of the match; frames of another origin too (Chrome ids such as `2.17`) |
|
|
162
|
+
| `search_scripts` | ✓ | ✓ | a long line's preview is 100 characters on each side of the match; inline scripts and modules included; frames of another origin too (Chrome ids such as `2.17`) |
|
|
163
163
|
| `pause_on_load` | ✓ | ✗ | TODO on Firefox, see [Limitations and TODO](#limitations-and-todo) |
|
|
164
164
|
| `enable_proxy_auth` | ✓ | partial | needs `--proxy-server`; a request the proxy rejects twice is cancelled; untested on Firefox against a real proxy |
|
|
165
165
|
| `send_cdp_command` | ✓ | ✗ | `raw` group; raw Chrome DevTools Protocol; refuses `Network`/`Page`/`Runtime`/`Log`/`Debugger.disable` and `Browser.close`; `Fetch.enable` comes with a note |
|
|
166
166
|
| `send_bidi_command` | ✗ | ✓ | `raw` group; raw WebDriver BiDi; refuses `session.new`, `session.end`, `browser.close` |
|
|
167
|
-
| `send_rdp_request` | ✗ | ✓ | `raw` group; raw Firefox RDP request to an actor (`thread`, `console`, `root` shortcuts) |
|
|
167
|
+
| `send_rdp_request` | ✗ | ✓ | `raw` group; raw Firefox RDP request to an actor (`thread`, `console`, `root` shortcuts); the event packets that actor sends afterwards go to `get_custom_events` (at most 16 actors watched) |
|
|
168
168
|
| `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) |
|
|
169
|
-
| `webmcp_invoke_tool` | ✓ | ✗ | needs `--enable-webmcp`; the output of an `untrustedContent` tool comes with a note to treat it as data |
|
|
169
|
+
| `webmcp_invoke_tool` | ✓ | ✗ | needs `--enable-webmcp`; a tool answering in MCP shape (`{content, isError}`) gives its own text and image blocks, and its `isError` makes the reply an error; other output comes as JSON; the output of an `untrustedContent` tool comes with a note to treat it as data |
|
|
170
170
|
| `webmcp_get_invocation` | ✓ | ✗ | needs `--enable-webmcp` |
|
|
171
171
|
| `webmcp_list_invocations` | ✓ | ✗ | needs `--enable-webmcp` |
|
|
172
172
|
|
|
@@ -379,7 +379,12 @@ claude mcp add browser-control-mcp -- npx -y @raultov/browser-control-mcp
|
|
|
379
379
|
lazily, on the first tool that needs them, with an ephemeral profile.
|
|
380
380
|
- **Tabs.** `open_tab`, `list_tabs`, `switch_tab`, `close_tab`. Every tool
|
|
381
381
|
takes `instance_id` and `tab_id`; without them it targets the default
|
|
382
|
-
instance and its active tab.
|
|
382
|
+
instance and its active tab. The active tab is the one the browser shows:
|
|
383
|
+
`open_tab` makes its new tab active, `close_tab` brings the next one to
|
|
384
|
+
the front, and after a page opens or closes a tab (a `target=_blank`
|
|
385
|
+
link, a popup, `window.close()`) the active tab is brought back to the
|
|
386
|
+
front. Background tabs are hidden to their pages (no
|
|
387
|
+
`requestAnimationFrame`, throttled timers). An argument a tool does not have fails the
|
|
383
388
|
call before anything runs (a `tabId` typo answers "did you mean
|
|
384
389
|
`tab_id`?"), so a typo never falls back to the active tab.
|
|
385
390
|
- **Same replies on both browsers.** `navigate` and `reload` answer once the
|
|
@@ -513,7 +518,7 @@ one subscription per session, routed by browsing context id.
|
|
|
513
518
|
|
|
514
519
|
Chrome and Firefox take the same calls:
|
|
515
520
|
|
|
516
|
-
1. `navigate` to the page (or `open_tab`
|
|
521
|
+
1. `navigate` to the page (or `open_tab`).
|
|
517
522
|
2. `search_scripts` with a needle to find the script URL and line.
|
|
518
523
|
3. `set_breakpoint` with `url` and `line_number` (0-based).
|
|
519
524
|
4. Trigger the code (`click_element`, `evaluate_js` with a `setTimeout`, a
|
|
@@ -601,6 +606,10 @@ incompatible:
|
|
|
601
606
|
- **TODO** `rust-mcp-sdk` 2.0: the server stays on 1.1.0 (MCP protocol
|
|
602
607
|
2025-11-25). 2.0 moves to the stateless MCP protocol (2026-07-28), which
|
|
603
608
|
today's MCP clients probably do not speak yet; upgrade once the clients do.
|
|
609
|
+
- On Firefox, a reload with `disable_cache: true` bypasses the cache with
|
|
610
|
+
`network.setCacheBehavior` (Firefox rejects `ignoreCache` on
|
|
611
|
+
`browsingContext.reload`); a reload Firefox aborts with
|
|
612
|
+
`NS_BINDING_ABORTED` is retried once after 50 ms.
|
|
604
613
|
- `get_performance_metrics` and `profile_page_performance` are partial on
|
|
605
614
|
Firefox: it has no Performance or Tracing domain, so they read what the
|
|
606
615
|
Web Performance APIs give and say what is missing (JS heap, layout and
|
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.11.0-beta.
|
|
22
|
+
"version": "0.11.0-beta.17"
|
|
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.11.0-beta.
|
|
51
|
+
"version": "0.11.0-beta.17"
|
|
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.11.0-beta.
|
|
3
|
+
"https://github.com/raultov/browser-control-mcp/releases/download/v0.11.0-beta.17"
|
|
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.11.0-beta.
|
|
95
|
+
"version": "0.11.0-beta.17",
|
|
96
96
|
"volta": {
|
|
97
97
|
"node": "18.14.1",
|
|
98
98
|
"npm": "9.5.0"
|