You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 1aa89a9
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: mcp_servers/README.md
+23-9Lines changed: 23 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -146,23 +146,31 @@ claude mcp add seleniumbase-mcp -- uv run seleniumbase-mcp
146
146
147
147
(run from inside this folder, for the same reason as above.)
148
148
149
+
## Selectors
150
+
151
+
Most tools accept a `selector` argument. Behavior varies slightly by tool, so check a tool's own docstring when it matters:
152
+
153
+
-**CSS selectors** are preferred and supported by every tool that takes a selector.
154
+
-**XPath** is accepted by several (not all) tools. Some tools go through SeleniumBase's XPath-to-CSS conversion first; expressions that can't be converted (e.g. `contains(...)`) aren't supported by those tools.
155
+
-**SeleniumBase's visible-text selector** syntax, e.g. `a:contains("Sign in")`, is accepted by several tools (including `click`, when not using `all_matches`) but not all of them — `find_elements`, for example, only supports CSS/XPath.
156
+
149
157
## Tools exposed
150
158
151
-
Tools here are grouped around a shared `selector` convention: `selector` args accept a CSS selector, or visible text (e.g. `a:contains("Sign in")`). Several near-identical one-off tools (e.g. separate click/hover/drag/wait/cookie/storage variants) have been consolidated into a single tool with a `mode`/`action`/`state`/`check` parameter, so there are fewer near-neighbor tools to disambiguate between while every underlying capability stays available.
159
+
Tools here are grouped around a shared `selector` convention. Several near-identical one-off tools (e.g. separate click/hover/drag/wait/cookie/storage variants) have been consolidated into a single tool with a `mode`/`action`/`state`/`check` parameter, so there are fewer near-neighbor tools to disambiguate between while every underlying capability stays available.
## Design notes / things to adapt for your use case
168
176
@@ -178,19 +186,25 @@ Tools here are grouped around a shared `selector` convention: `selector` args ac
178
186
179
187
-**Navigation and history live in one tool: `manage_history`.** What used to be `navigate_history` is now `manage_history`, and it gained a fourth action: `"list"`, which returns the browser's navigation history as `{"position": <0-indexed current entry>, "entries": [...]}`, where each entry has `id`, `url`, `user_typed_url`, `title`, and `transition_type`. `"back"`, `"forward"`, and `"reload"` behave as before. This is the only way to retrieve navigation history now — `get_page_info` doesn't return it.
180
188
181
-
-**Content reading is consolidated into one tool.**`get_content` replaces what used to be three separate reads: page/element text, page/element HTML, and page-linked URLs. Pick the mode with `output_format` (`"text"`, `"html"`, or `"urls"`) rather than calling a dedicated `get_page_content` or `get_all_urls` tool — those no longer exist. Likewise, there's no standalone `get_user_agent` tool anymore; the User-Agent string is one of the fields returned by `get_page_info`.
189
+
-**`get_content` always reads from an element, not the whole document.**`selector` now defaults to `"body"` rather than `None`/whole-page, and there's no `include_shadow_dom` option anymore — `get_content` no longer calls `get_page_source` at all. `output_format="html"` returns a single element's outer HTML (`get_element_html`), and `output_format="urls"` returns URLs discovered within that element (`get_all_urls(selector=...)`), rather than the full raw page source including shadow roots. If you need the complete page source (shadow DOM included), that capability isn't exposed by any tool here currently. `get_content` also gained a `timeout` parameter (default 5s) for waiting on the target element.
190
+
191
+
-**`get_attributes` and `focus` now take a `timeout`.** Both default to 5 seconds and wait for the target element the same way most other interaction tools do; previously neither exposed a timeout.
182
192
183
193
-**`check_condition` is deliberately narrow.** Its `check` parameter only accepts `"present"` or `"visible"` — there's no built-in `"count"` check anymore; call `find_elements` and read the returned `count` field instead. Passing `text` checks whether that text is visible within `selector` and takes priority over `check` when both are given — so `check_condition(text="Sign in")` behaves differently from `check_condition(check="visible")`, not as two variants of the same check. Note that an empty string for `text` (or for `wait_for`'s `selector`/`text`) is treated as not provided, since both tools now branch on truthiness rather than on `is not None`.
184
194
185
-
-**`find_elements` defaults to a fast, non-raising lookup.** Its default `timeout` is 0.5 seconds (not 5, unlike most other tools here), and a failed lookup returns `{"count": 0, "matches": []}` instead of raising — there is no error string on a miss, just an empty result. Pass a longer `timeout` explicitly if the elements you're looking for may still be loading.
195
+
-**`find_elements` catches its own lookup failures.** Its default `timeout` is 0.5 seconds (not 5, unlike most other tools here). A failed or empty lookup never raises: no matches returns `{"count": 0, "matches": []}`, and an actual lookup error (e.g. an unsupported selector) returns `{"count": 0, "matches": [], "error": "<details>"}` — the error lives inside the returned dict rather than surfacing as a top-level string from `handle_sb_errors`. Pass a longer `timeout` explicitly if the elements you're looking for may still be loading.
196
+
197
+
-**`wait_seconds` was folded into `wait_for`.** There's no standalone `wait_seconds` tool anymore. Use `wait_for(state="seconds_passed", timeout=<seconds>)` instead — it ignores `selector`/`text` and blocks for the full `timeout` duration. All other `wait_for` states behave as before.
198
+
199
+
-**Hover, click-after-hover, and drag-and-drop share one tool.**`hover_action(selector1, selector2, action)` replaces the earlier separate `hover` and `drag_and_drop` tools. `action="none"` hovers `selector1` only; `action="click"` hovers `selector1` then clicks `selector2` (useful for dropdown/submenu items revealed by hovering); `action="drag_and_drop"` drags `selector1` onto `selector2`. (`selector2` is required when `action` is `"click"` or `"drag_and_drop"`.)
186
200
187
-
-**Hover, clicking after hover, and drag-and-drop share one tool.**`hover_action(selector1, selector2, action)` replaces the earlier separate `hover` and `drag_and_drop` tools. `action="none"` hovers `selector1` only; `action="click"` hovers `selector1` then clicks `selector2` (useful for dropdown/submenu items revealed by hovering); `action="drag_and_drop"` drags `selector1` onto `selector2`. (`selector2` is required when `action` is `"click"` or `"drag_and_drop"`.)
201
+
-**Non-activating element actions are `focus`.** What used to be `act_on_element` is now `focus(selector, action, timeout)`, with actions `scroll_to_element` (the default), `focus`, and `highlight` — note the default action is scrolling the element into view, not focusing it. None of these actions click, type into, select from, or otherwise activate the element; use `click`, `type_text`, `select_option`, or `hover_action` for that.
188
202
189
-
-**Non-activating element actions are `focus`.** What used to be `act_on_element` is now `focus(selector, action)`, with actions `scroll_to_element` (the default), `focus`, and `highlight` — note the default action is scrolling the element into view, not focusing it. None of these actions click, type into, select from, or otherwise activate the element; use `click`, `type_text`, `select_option`, or `hover_action` for that.
203
+
-**`scroll`'s `amount` isn't capped at 100.** Relative up/down scrolling by more than 100% of the viewport height is allowed (e.g. `amount=200` scrolls roughly two viewport heights); negative amounts are rejected for `"up"`/`"down"`.
190
204
191
205
-**Elements don't cross the wire as handles.** In native CDP Mode, `find_element()` returns a live object with its own methods (`el.click()`, `el.get_html()`, ...). MCP tools can only return JSON-serializable data, so `find_elements` resolves each match immediately to a plain dict (`tag_name`, `text`, and optionally `html`) instead of returning a handle you could call further methods on. If you need to act on one of several matches, use `click(selector, nth=...)` (acts by position) rather than "find, then click" as two separate steps.
-**CAPTCHA-solving.**`solve_captcha`attempts to detect and interact with several challenge types over CDP (e.g. Cloudflare Turnstile, reCAPTCHA, hCaptcha, DataDome Slider, FriendlyCaptcha), including slider-style drag interactions, without guaranteeing success.
194
208
195
209
-**Security.**`run_javascript` runs arbitrary JS, and `manage_storage` can expose authentication/session secrets; `manage_cookies` and `save_output` accept filenames/folders that can touch the filesystem. This server can also drive a real browser to real sites — don't expose it over an untrusted network transport; stdio + local trust (the default here) is the safe setup.
0 commit comments