@raultov/browser-control-mcp 0.6.0-beta.9 → 0.8.0-beta.12
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 +142 -0
- package/README.md +28 -14
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,148 @@ from a copy of its code: entries describe the differences from that release.
|
|
|
10
10
|
|
|
11
11
|
## [Unreleased]
|
|
12
12
|
|
|
13
|
+
## [0.8.0-beta.12] - 2026-10-31
|
|
14
|
+
|
|
15
|
+
Public **BETA**. Reaches into frames of another origin (payment forms,
|
|
16
|
+
embedded editors, playgrounds, widgets), which Playwright MCP already did:
|
|
17
|
+
`snapshot` reads them in place with frame refs (`f2e5`), and the input tools
|
|
18
|
+
act in them through those refs, on Chrome and Firefox. Behaviour changes:
|
|
19
|
+
`snapshot` and `find_in_snapshot` now show the content of such frames
|
|
20
|
+
instead of a "not readable" line, iframes read get a `[frame=f2]` mark, and
|
|
21
|
+
selectors starting with `f` and a number (`f2e5`, `f2 >>> css`) name
|
|
22
|
+
elements of those frames.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- Frames of another origin (payment forms, embedded editors and playgrounds,
|
|
27
|
+
widgets): `snapshot` and `find_in_snapshot` read them in place, at most 20
|
|
28
|
+
and 5 deep, marking each iframe with its frame number (`[frame=f2]`) and
|
|
29
|
+
prefixing its refs (`f2e5`); `snapshot` with `selector: "f2"` outlines one
|
|
30
|
+
frame. Every selector argument takes those refs and `f2 >>> css`:
|
|
31
|
+
`click_element`, `hover`, `drag`, `fill_input`, `fill_form`, `press_key`,
|
|
32
|
+
`scroll`, `wait_for` and `upload_file` check and act in the frame. Chrome
|
|
33
|
+
reaches an out-of-process frame through its own target (attached for the
|
|
34
|
+
call) and an in-process one through its document, and sends mouse events
|
|
35
|
+
to the tab offset by where the frame shows; Firefox acts in the frame's
|
|
36
|
+
browsing context. Before, such a frame was a "not readable" line and
|
|
37
|
+
nothing inside it could be reached. `evaluate_js` still runs in the page,
|
|
38
|
+
and `capture_screenshot` refuses an element inside such a frame. (#27)
|
|
39
|
+
|
|
40
|
+
## [0.7.0-beta.11] - 2026-10-31
|
|
41
|
+
|
|
42
|
+
Public **BETA**. Closes gaps with Playwright MCP and chrome-devtools-mcp and
|
|
43
|
+
fixes editors found in real pages: a new `drag` tool (sortable lists,
|
|
44
|
+
boards, sliders, HTML5 drag and drop), `navigate` back and forward in the
|
|
45
|
+
tab's history, `fill_input` with `append`, and `capture_screenshot` of one
|
|
46
|
+
element; `fill_input` now types into Monaco, CodeMirror 6 on Firefox and
|
|
47
|
+
TinyMCE on Firefox, and `snapshot` shows the value of ARIA comboboxes,
|
|
48
|
+
spinbuttons and sliders. Behaviour changes: the default tool list has one
|
|
49
|
+
more tool (about 390 more tokens), `navigate`'s `url` is optional (pass it
|
|
50
|
+
or `history`), and `fill_input` on an editor whose content the page does
|
|
51
|
+
not expose answers that the text was not checked.
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
|
|
55
|
+
- `drag` tool: drags an element onto another with the mouse. It waits for
|
|
56
|
+
running animations to end (a sortable list animating its last
|
|
57
|
+
reordering starts no drag), presses on `from` (checked like
|
|
58
|
+
`click_element`), moves in 10 steps 40 ms apart to the centre of `to` and
|
|
59
|
+
releases, so pointer-driven libraries (sortable lists, boards, sliders)
|
|
60
|
+
and HTML5 drag and drop both work. Chrome does both natively; Firefox's
|
|
61
|
+
WebDriver input starts a native HTML5 drag but never drops it, leaving the
|
|
62
|
+
page stuck mid-drag, so there the native `dragstart` is cancelled and the
|
|
63
|
+
drag replayed by script along the path (the reply says so). Checked on
|
|
64
|
+
SortableJS and the-internet's drag and drop on both browsers. (#30)
|
|
65
|
+
- `fill_input` takes `append: true`: the text is typed at the end of what
|
|
66
|
+
the field already holds instead of replacing it, in text fields,
|
|
67
|
+
textareas and contenteditable elements, rich text editors included (the
|
|
68
|
+
caret goes to the end of their last text, so the editor records the
|
|
69
|
+
edit). A number, email or date field, which has no caret to move, is
|
|
70
|
+
emptied and retyped whole. The reply says `appended`; a field that did
|
|
71
|
+
not change is an error. Adding to a draft took one `press_key` per
|
|
72
|
+
character before. (#32)
|
|
73
|
+
- `navigate` takes `history: "back"` or `"forward"` instead of `url`: it
|
|
74
|
+
moves one entry in the tab's history and waits for that page to load,
|
|
75
|
+
answering like a URL navigation (`Went back to <url>.`). A page restored
|
|
76
|
+
from the back-forward cache, or an entry of the same document
|
|
77
|
+
(`pushState`), answers at once; at either end of the history it fails
|
|
78
|
+
without moving. Before, going back took `evaluate_js` with
|
|
79
|
+
`history.back()`, which answered before the page loaded. (#31)
|
|
80
|
+
- `capture_screenshot` takes a `selector` and captures only that element
|
|
81
|
+
(CSS, `host >>> inner` into shadow roots and iframes, or a snapshot ref):
|
|
82
|
+
scrolled into view, clipped to its box, whole even when taller than the
|
|
83
|
+
viewport (at most 16 384 px per side, with a note). Checking one component
|
|
84
|
+
no longer costs a whole viewport image. (#33)
|
|
85
|
+
|
|
86
|
+
### Fixed
|
|
87
|
+
|
|
88
|
+
- On Firefox, `fill_input`, `fill_form` and `press_key` type into an
|
|
89
|
+
element inside an iframe (TinyMCE): its script focus left the top
|
|
90
|
+
document's focus on its `<body>`, where Firefox sent the keys, so nothing
|
|
91
|
+
reached the editor and `fill_input` reported that the field held
|
|
92
|
+
"something other than the text". Each iframe the element is in is now
|
|
93
|
+
focused first. (#35)
|
|
94
|
+
- `fill_input` replaces the content of CodeMirror 6 on Firefox: the text
|
|
95
|
+
was typed before the old content, because CodeMirror puts its own caret
|
|
96
|
+
back once focused and drops the selection #23 made with a DOM range. A
|
|
97
|
+
contenteditable element now also gets the keys a user presses after the
|
|
98
|
+
range: Control+A (Command+A on macOS) to replace, Control+End with
|
|
99
|
+
`append`. Checked with CodeMirror 6, ProseMirror, Lexical and the test
|
|
100
|
+
page's editor on both browsers. (#34)
|
|
101
|
+
- `fill_input` types into editors of their own, such as Monaco (VS Code
|
|
102
|
+
for the web): the snapshot named Monaco's input `textbox "JavaScript
|
|
103
|
+
Input"`, but `fill_input` refused it (not an input, textarea or
|
|
104
|
+
contenteditable element) on Chrome, where it is an `EditContext`
|
|
105
|
+
element, and on Firefox, where it is a hidden textarea, reported success
|
|
106
|
+
while the editor never got the text. Such an editor (an `EditContext`,
|
|
107
|
+
a focusable `textbox` role, or a text field without a visible box) now
|
|
108
|
+
gets a click on its visible container when its input has none, Control+A
|
|
109
|
+
(Command+A on macOS) or, with `append`, Control+End, then the text; its
|
|
110
|
+
content cannot be read back, so the reply says it was not checked. (#28)
|
|
111
|
+
- `snapshot` and `find_in_snapshot` show the value of ARIA widgets: an
|
|
112
|
+
`<input role="combobox">` its text (MUI Autocomplete after a pick), a
|
|
113
|
+
spinbutton or slider its `aria-valuetext` or `aria-valuenow` (MUI X
|
|
114
|
+
DatePicker sections), and a button-like combobox the option it shows
|
|
115
|
+
(Radix Select). Before, only text fields, sliders and `<select>` had one,
|
|
116
|
+
so the agent could not see that a pick took. (#29)
|
|
117
|
+
|
|
118
|
+
## [0.6.0-beta.10] - 2026-10-31
|
|
119
|
+
|
|
120
|
+
Public **BETA**. Fixes four input and snapshot bugs found while driving a
|
|
121
|
+
real web app (Discord): `fill_input` now types into rich text editors
|
|
122
|
+
(Slate, Lexical, ProseMirror) so the editor records the edit, styled
|
|
123
|
+
checkboxes covered by their own label are clicked, controls shown only on
|
|
124
|
+
hover are revealed and clicked, and `snapshot` lists the links and buttons
|
|
125
|
+
inside a clickable container. Behaviour change: a covered element now gets
|
|
126
|
+
a mouse move before the click is refused.
|
|
127
|
+
|
|
128
|
+
### Fixed
|
|
129
|
+
|
|
130
|
+
- `click_element`, `hover` and `fill_form` reach controls shown only while
|
|
131
|
+
the mouse is over something (a message's actions, a row's toolbar): a
|
|
132
|
+
covered element now gets the mouse first and is checked again 100 ms
|
|
133
|
+
later. Discord's message "More" button failed with "covered by
|
|
134
|
+
'div.message…'". An element that stays covered still fails, naming what
|
|
135
|
+
covers it, without a click. (#26)
|
|
136
|
+
- `snapshot` and `find_in_snapshot` list what a clickable container holds:
|
|
137
|
+
an element without a role that has a click handler or a pointer cursor
|
|
138
|
+
was a leaf named from its whole text, so a container that sets
|
|
139
|
+
`cursor: pointer` hid every link and button inside it (Discord's whole
|
|
140
|
+
channel list was one line). A clickable that holds interactive elements
|
|
141
|
+
now lists them; one with text only is still one named line. (#25)
|
|
142
|
+
- `click_element`, `hover` and `fill_form` click a control covered by its
|
|
143
|
+
own label (or the element its `aria-labelledby` names), as styled
|
|
144
|
+
checkboxes and switches are: they failed with "covered by 'span…'". An
|
|
145
|
+
element under anything else still fails, naming it. (#24)
|
|
146
|
+
- `fill_input` and `fill_form` work in rich text editors (Slate, Lexical,
|
|
147
|
+
ProseMirror, Draft.js): a contenteditable element was emptied with
|
|
148
|
+
`textContent = ''`, which removed the nodes the editor renders from its
|
|
149
|
+
own model, so the typed text showed in the page but the editor did not
|
|
150
|
+
record it (Discord's channel topic was never saved), and the tool
|
|
151
|
+
reported success. The content is now selected and the first typed key
|
|
152
|
+
replaces it, as when a user selects all and types; an empty text deletes
|
|
153
|
+
it through the editing commands. (#23)
|
|
154
|
+
|
|
13
155
|
## [0.6.0-beta.9] - 2026-10-31
|
|
14
156
|
|
|
15
157
|
Public **BETA**. Spends fewer tokens and answers what the agent needs, after
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# browser-control-mcp
|
|
2
2
|
|
|
3
|
+
[](https://discord.gg/JDfcmD73A)
|
|
4
|
+
|
|
3
5
|
**Browser Control MCP** lets an AI agent control **and debug** real browsers
|
|
4
6
|
at runtime: breakpoints, pause on load, call frames, evaluation in a paused
|
|
5
7
|
frame, stepping and script search on **Chrome (CDP)** and **Firefox
|
|
@@ -11,13 +13,13 @@ It is the successor of
|
|
|
11
13
|
from a copy of its code) and complements Playwright MCP or
|
|
12
14
|
chrome-devtools-mcp with runtime JavaScript debugging on both browsers.
|
|
13
15
|
|
|
14
|
-
> **Status: BETA (0.
|
|
16
|
+
> **Status: BETA (0.8.0-beta.12).** This version contains known bugs and differences
|
|
15
17
|
> between Chrome and Firefox (see [Limitations and TODO](#limitations-and-todo))
|
|
16
18
|
> and parts that have not been verified (see [Untested](#untested)). Tool
|
|
17
19
|
> replies may change in incompatible ways before 1.0. Please report problems
|
|
18
20
|
> in the [issues](https://github.com/raultov/browser-control-mcp/issues).
|
|
19
21
|
|
|
20
|
-
💬 Questions, ideas or feedback: join us on [Discord](https://discord.gg/
|
|
22
|
+
💬 Questions, ideas or feedback: join us on [Discord](https://discord.gg/JDfcmD73A), where every release is announced in #announcements.
|
|
21
23
|
|
|
22
24
|
## Comparison with Playwright MCP and chrome-devtools-mcp
|
|
23
25
|
|
|
@@ -35,6 +37,7 @@ Tokens are estimated as characters / 4 for every server.
|
|
|
35
37
|
| Firefox | **✓ next to Chrome, same tools** | ✓ one browser per server | ✗ |
|
|
36
38
|
| Several browsers and instances at once | **✓** | ✗ | ✗ |
|
|
37
39
|
| Selectors | CSS, snapshot refs, `host >>> inner` into shadow roots and iframes | CSS, snapshot refs | snapshot refs only |
|
|
40
|
+
| Frames of another origin (payment forms, embedded editors) | ✓ in the snapshot, refs `f2e5` for every input tool | ✓ refs `f1e5` | ✗ |
|
|
38
41
|
| Snapshot of a long page | **bounded at 50 000 characters**, `find_in_snapshot` searches the rest | unbounded | unbounded |
|
|
39
42
|
| Waits for the page to react after an action | ✓ ~50 ms when nothing reacts | ✓ ~500 ms | ✓ ~200 ms |
|
|
40
43
|
| Clicking a covered or hidden element | **fails at once, naming the overlay** | fails after a 5 s timeout | reports success (the overlay gets the click) |
|
|
@@ -52,8 +55,8 @@ Tokens are estimated as characters / 4 for every server.
|
|
|
52
55
|
|
|
53
56
|
| Task | browser-control-mcp | Playwright MCP | chrome-devtools-mcp |
|
|
54
57
|
| --- | --- | --- | --- |
|
|
55
|
-
| Tool list in context, default tools | 6
|
|
56
|
-
| Tool list in context, every opt-in tool on | 9
|
|
58
|
+
| Tool list in context, default tools | 6 450 tokens | 5 330 tokens | 7 770 tokens |
|
|
59
|
+
| Tool list in context, every opt-in tool on | 9 910 tokens | 12 040 tokens | not measured (optional categories) |
|
|
57
60
|
| Snapshot of Hacker News | **4 588 tokens** | 12 356 tokens | 6 869 tokens |
|
|
58
61
|
| Snapshot of Wikipedia "Web browser" | **12 643 tokens** (cut, searchable) | 34 349 tokens | 27 656 tokens |
|
|
59
62
|
| Snapshot of MDN `<input>` | **12 625 tokens** (cut, searchable) | 158 077 tokens | 76 654 tokens |
|
|
@@ -94,7 +97,7 @@ tools are off by default and listed only with `--tool-groups`:
|
|
|
94
97
|
| `network` | `mock_route`, `list_routes`, `remove_route`, `set_offline` | changes what the page receives |
|
|
95
98
|
|
|
96
99
|
`--tool-groups all` lists every group. The page, input, observation and
|
|
97
|
-
debugger tools are always listed (
|
|
100
|
+
debugger tools are always listed (34 tools), plus `enable_proxy_auth` with
|
|
98
101
|
`--proxy-server` and the WebMCP tools with `--enable-webmcp`. A tool of a
|
|
99
102
|
group that is off fails naming the flag. The list is fixed for the server's
|
|
100
103
|
life: it never changes during a session, so clients can cache it.
|
|
@@ -116,20 +119,21 @@ see the note.
|
|
|
116
119
|
| `close_tab` | ✓ | ✓ | |
|
|
117
120
|
| `list_tabs` | ✓ | ✓ | |
|
|
118
121
|
| `switch_tab` | ✓ | ✓ | |
|
|
119
|
-
| `navigate` | ✓ | ✓ | |
|
|
122
|
+
| `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 |
|
|
120
123
|
| `reload` | ✓ | ✓ | |
|
|
121
124
|
| `scroll` | ✓ | ✓ | reports the window positions before and after |
|
|
122
125
|
| `emulate` | ✓ | partial | `emulation` group; `width`/`height`, `device_scale_factor`, `mobile` (touch), `color_scheme`, `reduced_motion`, `forced_colors`, `media` (`print`), `reset`; answers what the page now sees; Firefox: viewport and device pixel ratio only (BiDi has no media or touch emulation yet; those options fail naming them) |
|
|
123
126
|
| `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 |
|
|
124
127
|
| `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) |
|
|
125
|
-
| `snapshot` | ✓ | ✓ | outline of the page: role, name, states, value and a ref (`e12`) per element, through open shadow roots and same-origin iframes; 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; at most 50 000 characters (`selector` and `depth` narrow it); the same JavaScript on both browsers |
|
|
128
|
+
| `snapshot` | ✓ | ✓ | outline of the page: role, name, states, value and a ref (`e12`) per element, through open shadow roots and same-origin iframes; 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); an element that is only clickable (a handler or a pointer cursor) is one named line, 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 |
|
|
126
129
|
| `find_in_snapshot` | ✓ | ✓ | `text` (case-insensitive) or `regex` over the whole outline; matching lines under their ancestors, at most 20 |
|
|
127
130
|
| `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` |
|
|
128
|
-
| `capture_screenshot` | ✓ | ✓ | `format` `png`, `jpeg` (or `jpg`) or `webp`; `full_page` at most 16 384 px per side (a text note says when cut) |
|
|
129
|
-
| `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 or covered; `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}`) |
|
|
130
|
-
| `fill_input` | ✓ | ✓ | picks `<select>` options; fails without typing on elements that cannot take the text; 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 |
|
|
131
|
+
| `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 |
|
|
132
|
+
| `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 or 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); `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}`) |
|
|
133
|
+
| `fill_input` | ✓ | ✓ | picks `<select>` options; fails without typing on elements that cannot take the text; `append: true` types after the content instead of replacing it (a number, email or date 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 |
|
|
131
134
|
| `press_key` | ✓ | ✓ | one key (a character, Enter, Tab, Escape, arrows, F1–F12...) with Control / Shift / Alt / Meta held, in `selector` (focused first) or the focused element; a shortcut types nothing |
|
|
132
135
|
| `hover` | ✓ | ✓ | moves the mouse over the element (scrolled into view; fails when hidden or covered) |
|
|
136
|
+
| `drag` | ✓ | ✓ | presses on `from` (checked like `click_element`), moves in steps to the centre of `to` (which must then be in the viewport) and releases: sortable lists, boards, sliders; HTML5 drag and drop is real on Chrome and simulated with script events on Firefox (its WebDriver input starts a native drag but never drops it), and the reply says so |
|
|
133
137
|
| `fill_form` | ✓ | ✓ | several fields in one call: text and `<select>` as `fill_input`, a checkbox or radio takes `true`/`false` and is clicked only when its state differs; stops at the first failing field naming what was done; never echoes values |
|
|
134
138
|
| `upload_file` | ✓ | ✓ | `files` group; sets the files of an `<input type=file>` (Chrome `DOM.setFileInputFiles`, Firefox `input.setFiles`); files must be under the upload roots (`--upload-root`, default the working and temp directories) |
|
|
135
139
|
| `handle_dialog` | ✓ | ✓ | accepts or dismisses the open `alert` / `confirm` / `prompt` / `beforeunload` dialog |
|
|
@@ -161,8 +165,8 @@ see the note.
|
|
|
161
165
|
| `webmcp_get_invocation` | ✓ | ✗ | needs `--enable-webmcp` |
|
|
162
166
|
| `webmcp_list_invocations` | ✓ | ✗ | needs `--enable-webmcp` |
|
|
163
167
|
|
|
164
|
-
After `click_element`, `hover`, `fill_input`, `fill_form` and
|
|
165
|
-
the server waits for the page to settle before answering: until its DOM
|
|
168
|
+
After `click_element`, `hover`, `drag`, `fill_input`, `fill_form` and
|
|
169
|
+
`press_key` the server waits for the page to settle before answering: until its DOM
|
|
166
170
|
stays unchanged for 50 ms (style changes, often animations, aside) and the
|
|
167
171
|
requests the action started finished, at most 1 s, on both browsers. An
|
|
168
172
|
action nothing reacts to costs those 50 ms and keeps its reply; otherwise
|
|
@@ -407,7 +411,13 @@ claude mcp add browser-control-mcp -- npx -y @raultov/browser-control-mcp
|
|
|
407
411
|
their ancestors. The `selector` of `click_element`, `fill_input`,
|
|
408
412
|
`scroll` and `wait_for` takes such a ref, a CSS selector, or
|
|
409
413
|
`host >>> inner` to reach into an open shadow root or a same-origin
|
|
410
|
-
iframe (`#checkout >>> #card-number`, chainable).
|
|
414
|
+
iframe (`#checkout >>> #card-number`, chainable). A frame of another
|
|
415
|
+
origin (a payment form, an embedded editor) is read as well, through its
|
|
416
|
+
own target on Chrome and its own browsing context on Firefox: its iframe
|
|
417
|
+
line says `[frame=f2]` and its elements have refs such as `f2e5`, which
|
|
418
|
+
every selector argument takes, as does `f2 >>> css`; the input tools then
|
|
419
|
+
check and act in that frame (one call acts in one document: `fill_form`
|
|
420
|
+
and `drag` refuse selectors of two frames). An element keeps its ref
|
|
411
421
|
in later snapshots while it is in the page; refs end when the page
|
|
412
422
|
navigates (a stale ref fails saying so). Roles and names are computed in
|
|
413
423
|
the page, an approximation of the browser's accessibility tree that is
|
|
@@ -509,7 +519,7 @@ Chrome and Firefox take the same calls:
|
|
|
509
519
|
with that location.
|
|
510
520
|
5. `evaluate_on_call_frame` reads locals of the paused frame; `step_over`
|
|
511
521
|
moves one statement; `resume` continues. While paused, the input tools
|
|
512
|
-
(`click_element`, `hover`, `fill_input`, `fill_form`, `press_key`) fail
|
|
522
|
+
(`click_element`, `hover`, `drag`, `fill_input`, `fill_form`, `press_key`) fail
|
|
513
523
|
at once naming the pause and do nothing: the page would handle their
|
|
514
524
|
events only after `resume`. `evaluate_js` still answers
|
|
515
525
|
while paused, in the page's global scope. A promise it returns cannot
|
|
@@ -610,6 +620,10 @@ incompatible:
|
|
|
610
620
|
- `get_network_logs` with `include_details: true` has no total size limit (each
|
|
611
621
|
Firefox body is capped at 2 MB): use `url_filter` on busy pages.
|
|
612
622
|
- The Docker image is amd64 only.
|
|
623
|
+
- Frames of another origin: `evaluate_js` runs in the page only, and
|
|
624
|
+
`capture_screenshot` cannot clip to an element inside such a frame (pass
|
|
625
|
+
the iframe's ref instead); `snapshot` reads at most 20 of them, 5 deep;
|
|
626
|
+
the coordinates in the replies of the input tools are the frame's.
|
|
613
627
|
|
|
614
628
|
## Untested
|
|
615
629
|
|
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.8.0-beta.12"
|
|
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.8.0-beta.12"
|
|
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.8.0-beta.12"
|
|
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.8.0-beta.12",
|
|
96
96
|
"volta": {
|
|
97
97
|
"node": "18.14.1",
|
|
98
98
|
"npm": "9.5.0"
|