seleniumbase-mcp 1.3.2__tar.gz → 1.3.4__tar.gz
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.
- {seleniumbase_mcp-1.3.2/seleniumbase_mcp.egg-info → seleniumbase_mcp-1.3.4}/PKG-INFO +11 -17
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/README.md +9 -15
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/cdp_server.py +126 -112
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/driver_server.py +2 -2
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/sb_server.py +7 -27
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4/seleniumbase_mcp.egg-info}/PKG-INFO +11 -17
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/seleniumbase_mcp.egg-info/requires.txt +1 -1
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/setup.py +2 -2
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/tests/test_mcp.py +2 -2
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/LICENSE +0 -0
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/pyproject.toml +0 -0
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/seleniumbase_mcp.egg-info/SOURCES.txt +0 -0
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/seleniumbase_mcp.egg-info/dependency_links.txt +0 -0
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/seleniumbase_mcp.egg-info/entry_points.txt +0 -0
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/seleniumbase_mcp.egg-info/top_level.txt +0 -0
- {seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase-mcp
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.4
|
|
4
4
|
Summary: MCP servers exposing SeleniumBase as tools for MCP clients.
|
|
5
5
|
Home-page: https://github.com/seleniumbase/seleniumbase-mcp
|
|
6
6
|
Author: Michael Mintz
|
|
@@ -55,7 +55,7 @@ Classifier: Topic :: Utilities
|
|
|
55
55
|
Requires-Python: >=3.10
|
|
56
56
|
Description-Content-Type: text/markdown
|
|
57
57
|
License-File: LICENSE
|
|
58
|
-
Requires-Dist: seleniumbase[mcp]>=4.54.
|
|
58
|
+
Requires-Dist: seleniumbase[mcp]>=4.54.4
|
|
59
59
|
Requires-Dist: mcp[cli]<3.0.0,>=2.2.0
|
|
60
60
|
Provides-Extra: deploy
|
|
61
61
|
Requires-Dist: build>=1.0.0; extra == "deploy"
|
|
@@ -177,7 +177,7 @@ The location of `claude_desktop_config.json` depends on your system:
|
|
|
177
177
|
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
178
178
|
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
179
179
|
|
|
180
|
-
Restart Claude Desktop. You should see a 🔨 tools icon indicating the server(s) connected, with tools like `start_browser`, `
|
|
180
|
+
Restart Claude Desktop. You should see a 🔨 tools icon indicating the server(s) connected, with tools like `start_browser`, `open_url`, `click_element`, etc. available. Only keep the entries you actually want. Three separate browser-automation servers is a lot if you only need one.
|
|
181
181
|
|
|
182
182
|
## 4. Connect it to Claude Code
|
|
183
183
|
|
|
@@ -225,14 +225,14 @@ claude mcp add seleniumbase-sb -- uv run seleniumbase-sb
|
|
|
225
225
|
|---|---|
|
|
226
226
|
| `start_browser(browser, headless, uc, incognito)` | Launch a browser session (headless defaults to `False`) |
|
|
227
227
|
| `close_browser()` | End the session |
|
|
228
|
-
| `
|
|
228
|
+
| `open_url(url)` | Go to a URL |
|
|
229
229
|
| `go_back()` / `go_forward()` / `refresh_page()` | History navigation |
|
|
230
230
|
| `get_current_url()` / `get_title()` | Page metadata |
|
|
231
231
|
| `get_page_source()` | Full HTML |
|
|
232
232
|
| `get_text(selector)` | Visible text of an element |
|
|
233
233
|
| `find_elements_count(selector)` | Count matches |
|
|
234
234
|
| `is_element_visible(selector)` | Visibility check |
|
|
235
|
-
| `
|
|
235
|
+
| `click_element(selector, timeout)` | Click (CSS or XPath) |
|
|
236
236
|
| `type_text(selector, text, clear_first, timeout)` | Fill a field |
|
|
237
237
|
| `select_option_by_text(dropdown_selector, option)` | Choose a dropdown option |
|
|
238
238
|
| `wait_for_element_present(selector, timeout)` | Explicit wait |
|
|
@@ -279,16 +279,16 @@ in the loop at all. Reference:
|
|
|
279
279
|
| Group | Tool(s) |
|
|
280
280
|
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
281
281
|
| Session | `start_browser(url, headless, use_chromium, browser_executable_path, incognito, guest, ad_block, proxy)`, `close_browser` |
|
|
282
|
-
| Navigation | `
|
|
283
|
-
| Finding & reading | `find_elements(selector, timeout, include_html)`, `get_content(selector, output_format: text/html/urls
|
|
284
|
-
| Interacting | `
|
|
285
|
-
| Waiting | `
|
|
282
|
+
| Navigation | `open_url`, `manage_history(action: back/forward/reload/list)`, `get_page_info` (running status, url, title, origin, user agent, history in one call) |
|
|
283
|
+
| Finding & reading | `find_elements(selector, timeout, include_html)`, `get_content(selector, output_format: text/html/urls)`, `get_attributes`, `check_for_condition(check: present/visible/count/text_visible)` |
|
|
284
|
+
| Interacting | `click_element(selector, nth, all_matches, only_if_visible, parent_selector, timeout, scroll)`, `hover_action(selector1, selector2, action: hover/hover_and_click/drag_and_drop)`, `type_text(mode: fill_input/append/fast_type/set_value/clear_only)`, `select_option(by: text/value/index)`, `focus_element(action: scroll_to_element/focus/highlight)` |
|
|
285
|
+
| Waiting | `wait_for_condition(state: present/visible/not_visible/absent/seconds_passed, text)` |
|
|
286
286
|
| Assertions | `assert_condition(check: element_present/element_visible/text_visible/title/url/url_contains)` |
|
|
287
287
|
| Cookies & storage | `manage_cookies(action: get_all/clear/save/load)`, `manage_storage(storage: local/session, action: get/set)` |
|
|
288
|
-
| Scrolling | `
|
|
288
|
+
| Scrolling | `scroll_page(direction: up/down/top/bottom, amount)` |
|
|
289
289
|
| Windows & tabs | `manage_window(action: get_rect/set_rect/maximize/minimize)`, `manage_tabs(action: list/open/switch/switch_newest/close_active)` |
|
|
290
290
|
| Captcha | `solve_captcha` |
|
|
291
|
-
| Output & misc | `
|
|
291
|
+
| Output & misc | `save_page(format: screenshot/html/pdf)`, `run_javascript` |
|
|
292
292
|
|
|
293
293
|
### CDP-specific design notes
|
|
294
294
|
|
|
@@ -306,12 +306,6 @@ in the loop at all. Reference:
|
|
|
306
306
|
- **Session teardown.** `sb.quit()` (used by `close_browser`) is the
|
|
307
307
|
documented way to end a session; the browser also auto-closes if the
|
|
308
308
|
process exits without it.
|
|
309
|
-
- **Not wrapped:** PyAutoGUI-based `gui_*` methods (excluded by design —
|
|
310
|
-
see the top-level design notes), low-level plumbing
|
|
311
|
-
(`get_websocket_url`, `add_handler`, permission grants, raw
|
|
312
|
-
`get_document`/`get_flattened_document`), and exact method aliases
|
|
313
|
-
(`open`/`goto` vs `get`) were left out to keep the tool list focused —
|
|
314
|
-
add them the same way as any other tool if you need them.
|
|
315
309
|
|
|
316
310
|
---
|
|
317
311
|
|
|
@@ -97,7 +97,7 @@ The location of `claude_desktop_config.json` depends on your system:
|
|
|
97
97
|
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
98
98
|
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
99
99
|
|
|
100
|
-
Restart Claude Desktop. You should see a 🔨 tools icon indicating the server(s) connected, with tools like `start_browser`, `
|
|
100
|
+
Restart Claude Desktop. You should see a 🔨 tools icon indicating the server(s) connected, with tools like `start_browser`, `open_url`, `click_element`, etc. available. Only keep the entries you actually want. Three separate browser-automation servers is a lot if you only need one.
|
|
101
101
|
|
|
102
102
|
## 4. Connect it to Claude Code
|
|
103
103
|
|
|
@@ -145,14 +145,14 @@ claude mcp add seleniumbase-sb -- uv run seleniumbase-sb
|
|
|
145
145
|
|---|---|
|
|
146
146
|
| `start_browser(browser, headless, uc, incognito)` | Launch a browser session (headless defaults to `False`) |
|
|
147
147
|
| `close_browser()` | End the session |
|
|
148
|
-
| `
|
|
148
|
+
| `open_url(url)` | Go to a URL |
|
|
149
149
|
| `go_back()` / `go_forward()` / `refresh_page()` | History navigation |
|
|
150
150
|
| `get_current_url()` / `get_title()` | Page metadata |
|
|
151
151
|
| `get_page_source()` | Full HTML |
|
|
152
152
|
| `get_text(selector)` | Visible text of an element |
|
|
153
153
|
| `find_elements_count(selector)` | Count matches |
|
|
154
154
|
| `is_element_visible(selector)` | Visibility check |
|
|
155
|
-
| `
|
|
155
|
+
| `click_element(selector, timeout)` | Click (CSS or XPath) |
|
|
156
156
|
| `type_text(selector, text, clear_first, timeout)` | Fill a field |
|
|
157
157
|
| `select_option_by_text(dropdown_selector, option)` | Choose a dropdown option |
|
|
158
158
|
| `wait_for_element_present(selector, timeout)` | Explicit wait |
|
|
@@ -199,16 +199,16 @@ in the loop at all. Reference:
|
|
|
199
199
|
| Group | Tool(s) |
|
|
200
200
|
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
201
201
|
| Session | `start_browser(url, headless, use_chromium, browser_executable_path, incognito, guest, ad_block, proxy)`, `close_browser` |
|
|
202
|
-
| Navigation | `
|
|
203
|
-
| Finding & reading | `find_elements(selector, timeout, include_html)`, `get_content(selector, output_format: text/html/urls
|
|
204
|
-
| Interacting | `
|
|
205
|
-
| Waiting | `
|
|
202
|
+
| Navigation | `open_url`, `manage_history(action: back/forward/reload/list)`, `get_page_info` (running status, url, title, origin, user agent, history in one call) |
|
|
203
|
+
| Finding & reading | `find_elements(selector, timeout, include_html)`, `get_content(selector, output_format: text/html/urls)`, `get_attributes`, `check_for_condition(check: present/visible/count/text_visible)` |
|
|
204
|
+
| Interacting | `click_element(selector, nth, all_matches, only_if_visible, parent_selector, timeout, scroll)`, `hover_action(selector1, selector2, action: hover/hover_and_click/drag_and_drop)`, `type_text(mode: fill_input/append/fast_type/set_value/clear_only)`, `select_option(by: text/value/index)`, `focus_element(action: scroll_to_element/focus/highlight)` |
|
|
205
|
+
| Waiting | `wait_for_condition(state: present/visible/not_visible/absent/seconds_passed, text)` |
|
|
206
206
|
| Assertions | `assert_condition(check: element_present/element_visible/text_visible/title/url/url_contains)` |
|
|
207
207
|
| Cookies & storage | `manage_cookies(action: get_all/clear/save/load)`, `manage_storage(storage: local/session, action: get/set)` |
|
|
208
|
-
| Scrolling | `
|
|
208
|
+
| Scrolling | `scroll_page(direction: up/down/top/bottom, amount)` |
|
|
209
209
|
| Windows & tabs | `manage_window(action: get_rect/set_rect/maximize/minimize)`, `manage_tabs(action: list/open/switch/switch_newest/close_active)` |
|
|
210
210
|
| Captcha | `solve_captcha` |
|
|
211
|
-
| Output & misc | `
|
|
211
|
+
| Output & misc | `save_page(format: screenshot/html/pdf)`, `run_javascript` |
|
|
212
212
|
|
|
213
213
|
### CDP-specific design notes
|
|
214
214
|
|
|
@@ -226,12 +226,6 @@ in the loop at all. Reference:
|
|
|
226
226
|
- **Session teardown.** `sb.quit()` (used by `close_browser`) is the
|
|
227
227
|
documented way to end a session; the browser also auto-closes if the
|
|
228
228
|
process exits without it.
|
|
229
|
-
- **Not wrapped:** PyAutoGUI-based `gui_*` methods (excluded by design —
|
|
230
|
-
see the top-level design notes), low-level plumbing
|
|
231
|
-
(`get_websocket_url`, `add_handler`, permission grants, raw
|
|
232
|
-
`get_document`/`get_flattened_document`), and exact method aliases
|
|
233
|
-
(`open`/`goto` vs `get`) were left out to keep the tool list focused —
|
|
234
|
-
add them the same way as any other tool if you need them.
|
|
235
229
|
|
|
236
230
|
---
|
|
237
231
|
|
|
@@ -34,20 +34,23 @@ having to choose between multiple near-identical tools.
|
|
|
34
34
|
|
|
35
35
|
Tool-selection philosophy:
|
|
36
36
|
- Use 'start_browser'/'close_browser' for opening/quitting the web browser.
|
|
37
|
-
- Use '
|
|
37
|
+
- Use 'open_url'/'manage_history' for browser navigation and history
|
|
38
|
+
inspection.
|
|
38
39
|
- Use 'get_page_info' for reading browser/page metadata such as URL/title.
|
|
39
40
|
- Use 'get_content'/'get_attributes' for reading text, HTML, or attributes.
|
|
40
41
|
- Use 'find_elements' for discovering and inspecting multiple matching
|
|
41
42
|
elements as structured data.
|
|
42
|
-
- Use '
|
|
43
|
-
- Use '
|
|
43
|
+
- Use 'check_if_condition' for an immediate, non-waiting state check.
|
|
44
|
+
- Use 'wait_for_condition' when the agent needs to wait for a condition
|
|
45
|
+
to become true.
|
|
44
46
|
- Use 'assert_condition' when the agent needs to verify an expected condition
|
|
45
47
|
and treat failure as an assertion error.
|
|
46
|
-
- Use '
|
|
48
|
+
- Use 'click_element'/'type_text'/'select_option' for standard page
|
|
49
|
+
interactions.
|
|
47
50
|
- Use 'hover_action' for just a hover, with a click, or with a drag/drop.
|
|
48
|
-
- Use '
|
|
51
|
+
- Use 'focus_element' for element positioning and visual focus.
|
|
49
52
|
- Use 'solve_captcha' for clicking the checkbox of a CAPTCHA on the page.
|
|
50
|
-
- Use '
|
|
53
|
+
- Use 'save_page' for saving page output as a PNG, a PDF, or an HTML file.
|
|
51
54
|
"""
|
|
52
55
|
from __future__ import annotations
|
|
53
56
|
import atexit
|
|
@@ -109,8 +112,8 @@ def start_browser(
|
|
|
109
112
|
) -> str:
|
|
110
113
|
"""Launch a persistent SeleniumBase Pure CDP Mode browser session.
|
|
111
114
|
|
|
112
|
-
Call this before using browser interaction tools such as
|
|
113
|
-
get_content,
|
|
115
|
+
Call this before using browser interaction tools such as open_url,
|
|
116
|
+
get_content, click_element, type_text, or find_elements. The same browser
|
|
114
117
|
session remains active across subsequent MCP tool calls until
|
|
115
118
|
close_browser is called or the server process exits.
|
|
116
119
|
|
|
@@ -301,8 +304,8 @@ def get_page_info() -> dict[str, Any]:
|
|
|
301
304
|
- Need URL, title, origin, or User-Agent -> use get_page_info.
|
|
302
305
|
- Need visible page text or HTML -> use get_content.
|
|
303
306
|
- Need information about matching elements -> use find_elements.
|
|
304
|
-
- Need an immediate state check -> use
|
|
305
|
-
- Need to wait for a condition -> use
|
|
307
|
+
- Need an immediate state check -> use check_if_condition.
|
|
308
|
+
- Need to wait for a condition -> use wait_for_condition.
|
|
306
309
|
- Need to verify an expected condition -> use assert_condition.
|
|
307
310
|
|
|
308
311
|
Unlike a dedicated browser-status tool, get_page_info is the single
|
|
@@ -336,8 +339,8 @@ def get_page_info() -> dict[str, Any]:
|
|
|
336
339
|
|
|
337
340
|
@mcp.tool()
|
|
338
341
|
@handle_sb_errors
|
|
339
|
-
def
|
|
340
|
-
"""Navigate the current browser tab to
|
|
342
|
+
def open_url(url: str) -> str:
|
|
343
|
+
"""Navigate the current browser tab to the URL provided.
|
|
341
344
|
|
|
342
345
|
Use this when the browser needs to visit a new URL rather than move
|
|
343
346
|
through its existing back/forward history.
|
|
@@ -348,17 +351,18 @@ def navigate(url: str) -> str:
|
|
|
348
351
|
|
|
349
352
|
Navigation waits for the browser's navigation operation to complete
|
|
350
353
|
before returning. Dynamic content may still be loading;
|
|
351
|
-
use
|
|
354
|
+
use wait_for_condition when synchronization is required.
|
|
355
|
+
If there's an error, that gets propagated through @handle_sb_errors.
|
|
352
356
|
|
|
353
357
|
Args:
|
|
354
|
-
url:
|
|
355
|
-
"https://example.com" or a hostname such as "example.com".
|
|
358
|
+
url: The destination URL. May be a complete URL such as
|
|
359
|
+
"https://example.com", or a hostname such as "example.com".
|
|
356
360
|
|
|
357
361
|
Returns:
|
|
358
|
-
A confirmation message containing the requested URL.
|
|
362
|
+
A confirmation message containing the requested URL if successful.
|
|
359
363
|
|
|
360
364
|
Tool selection:
|
|
361
|
-
-
|
|
365
|
+
- Navigate to a new URL -> use open_url.
|
|
362
366
|
- Return to the previous page -> use manage_history(action="back").
|
|
363
367
|
- Go forward in history -> use manage_history(action="forward").
|
|
364
368
|
- Refresh the current page -> use manage_history(action="reload").
|
|
@@ -377,7 +381,7 @@ def manage_history(
|
|
|
377
381
|
|
|
378
382
|
Use 'back' or 'forward' for history navigation, 'reload' to refresh
|
|
379
383
|
while bypassing the cache, or 'list' to inspect history.
|
|
380
|
-
Use '
|
|
384
|
+
Use 'open_url' for navigation to an arbitrary URL.
|
|
381
385
|
|
|
382
386
|
Args:
|
|
383
387
|
action:
|
|
@@ -473,9 +477,9 @@ def find_elements(
|
|
|
473
477
|
use find_elements.
|
|
474
478
|
- Need the visible text/HTML of a page or a single element ->
|
|
475
479
|
use get_content.
|
|
476
|
-
- Need to click one of several matches -> use
|
|
480
|
+
- Need to click one of several matches -> use click_element with nth.
|
|
477
481
|
- Need to know whether an element is present/visible ->
|
|
478
|
-
use
|
|
482
|
+
use check_if_condition.
|
|
479
483
|
|
|
480
484
|
Notes:
|
|
481
485
|
Element handles cannot be persisted across MCP calls. If you find
|
|
@@ -524,6 +528,7 @@ def get_content(
|
|
|
524
528
|
|
|
525
529
|
Args:
|
|
526
530
|
selector: CSS selector or SeleniumBase-supported XPath selector.
|
|
531
|
+
Default: "body".
|
|
527
532
|
|
|
528
533
|
output_format:
|
|
529
534
|
- "text": Return visible text from the selected element.
|
|
@@ -532,18 +537,18 @@ def get_content(
|
|
|
532
537
|
selected element. Returned URLs are normalized to full URLs
|
|
533
538
|
with their protocol prefixes.
|
|
534
539
|
|
|
535
|
-
|
|
536
540
|
timeout: Maximum seconds to wait for the target element. Default: 5.
|
|
537
541
|
|
|
538
542
|
Tool selection:
|
|
539
543
|
- Need URL, title, origin, or User-Agent -> use get_page_info.
|
|
540
|
-
- Need visible text -> use
|
|
541
|
-
- Need page or element HTML -> use output_format="html".
|
|
542
|
-
- Need URLs from the page or an element -> use output_format="urls".
|
|
544
|
+
- Need visible text, html, or URLs on a page -> use get_content.
|
|
543
545
|
- Need structured information about matching elements ->
|
|
544
546
|
use find_elements.
|
|
545
|
-
- Need to check element presence/visibility -> use
|
|
546
|
-
- Need to wait for content to appear -> use
|
|
547
|
+
- Need to check element presence/visibility -> use check_if_condition.
|
|
548
|
+
- Need to wait for content to appear -> use wait_for_condition.
|
|
549
|
+
|
|
550
|
+
If there's no matching element found within the timeout,
|
|
551
|
+
then @handle_sb_errors returns details from the exception raised.
|
|
547
552
|
"""
|
|
548
553
|
sb = _get_sb()
|
|
549
554
|
|
|
@@ -583,21 +588,19 @@ def get_attributes(
|
|
|
583
588
|
|
|
584
589
|
timeout: Maximum seconds to wait for the target element. Default: 5.
|
|
585
590
|
|
|
586
|
-
Returns:
|
|
587
|
-
The requested attribute(s).
|
|
588
|
-
|
|
589
591
|
Tool selection:
|
|
590
592
|
- Need one or more HTML attribute values from a specific element ->
|
|
591
593
|
use this tool.
|
|
592
594
|
- Need to discover multiple matching elements or inspect their text ->
|
|
593
595
|
use 'find_elements'.
|
|
594
596
|
- Need visible text or HTML content -> use 'get_content'.
|
|
595
|
-
- Need to check element presence/visibility ->
|
|
597
|
+
- Need to check element presence/visibility ->
|
|
598
|
+
use 'check_if_condition'.
|
|
596
599
|
|
|
597
600
|
This is a read-only operation.
|
|
598
601
|
|
|
599
602
|
If there's no matching element found within the timeout,
|
|
600
|
-
then @handle_sb_errors
|
|
603
|
+
then @handle_sb_errors returns details from the exception raised.
|
|
601
604
|
"""
|
|
602
605
|
sb = _get_sb()
|
|
603
606
|
|
|
@@ -609,7 +612,7 @@ def get_attributes(
|
|
|
609
612
|
|
|
610
613
|
@mcp.tool()
|
|
611
614
|
@handle_sb_errors
|
|
612
|
-
def
|
|
615
|
+
def check_if_condition(
|
|
613
616
|
check: Literal["present", "visible"] = "visible",
|
|
614
617
|
selector: str = "body",
|
|
615
618
|
text: str | None = None,
|
|
@@ -618,9 +621,10 @@ def check_condition(
|
|
|
618
621
|
for the condition to become true.
|
|
619
622
|
|
|
620
623
|
Use this tool when you need an immediate boolean observation of the current
|
|
621
|
-
page state. Use
|
|
622
|
-
workflow should wait for it. Use assert_condition when the
|
|
623
|
-
expected requirement and failure should be treated as an
|
|
624
|
+
page state. Use wait_for_condition when the condition may become true later
|
|
625
|
+
and the workflow should wait for it. Use assert_condition when the
|
|
626
|
+
condition is an expected requirement and failure should be treated as an
|
|
627
|
+
assertion error.
|
|
624
628
|
|
|
625
629
|
Args:
|
|
626
630
|
check:
|
|
@@ -645,8 +649,8 @@ def check_condition(
|
|
|
645
649
|
exception. If there's an error, returns a string with error details.
|
|
646
650
|
|
|
647
651
|
Tool selection:
|
|
648
|
-
- Immediate boolean observation -> use
|
|
649
|
-
- Wait for a state/content transition -> use
|
|
652
|
+
- Immediate boolean observation -> use check_if_condition.
|
|
653
|
+
- Wait for a state/content transition -> use wait_for_condition.
|
|
650
654
|
- Verify an expected condition -> use assert_condition.
|
|
651
655
|
- Need element details of matching elements -> use find_elements.
|
|
652
656
|
- Need to read page or element content -> use get_content.
|
|
@@ -654,7 +658,7 @@ def check_condition(
|
|
|
654
658
|
Notes:
|
|
655
659
|
This tool does not intentionally wait for elements or text to appear.
|
|
656
660
|
It is intended for checking the current state only. If page timing or
|
|
657
|
-
asynchronous loading matters, use
|
|
661
|
+
asynchronous loading matters, use wait_for_condition instead.
|
|
658
662
|
|
|
659
663
|
When `text` is provided, `check` is ignored.
|
|
660
664
|
"""
|
|
@@ -680,7 +684,7 @@ def check_condition(
|
|
|
680
684
|
|
|
681
685
|
@mcp.tool()
|
|
682
686
|
@handle_sb_errors
|
|
683
|
-
def
|
|
687
|
+
def click_element(
|
|
684
688
|
selector: str,
|
|
685
689
|
nth: int | None = None,
|
|
686
690
|
all_matches: bool = False,
|
|
@@ -709,7 +713,7 @@ def click(
|
|
|
709
713
|
clicks; do not use them with `all_matches=True`.
|
|
710
714
|
|
|
711
715
|
nth: 1-based occurrence to click when multiple elements match.
|
|
712
|
-
Must be >= 1. Takes precedence over `all_matches`,
|
|
716
|
+
Must be >= 1 if provided. Takes precedence over `all_matches`,
|
|
713
717
|
`only_if_visible`, and `parent_selector`.
|
|
714
718
|
|
|
715
719
|
all_matches: If True, click every currently visible matching element
|
|
@@ -733,15 +737,18 @@ def click(
|
|
|
733
737
|
indexed click. Default: True.
|
|
734
738
|
|
|
735
739
|
Examples:
|
|
736
|
-
- Click one element: `
|
|
737
|
-
- Click the 2nd matching element: `
|
|
738
|
-
- Click all visible matches:
|
|
739
|
-
|
|
740
|
-
- Click
|
|
740
|
+
- Click one element: `click_element("button.submit")`
|
|
741
|
+
- Click the 2nd matching element: `click_element("button", nth=2)`
|
|
742
|
+
- Click all visible matches:
|
|
743
|
+
`click_element(".dismiss", all_matches=True)`
|
|
744
|
+
- Click only if already visible:
|
|
745
|
+
`click_element("#menu", only_if_visible=True)`
|
|
746
|
+
- Click inside a container:
|
|
747
|
+
`click_element(".item", parent_selector="#result")`
|
|
741
748
|
"""
|
|
742
749
|
sb = _get_sb()
|
|
743
750
|
|
|
744
|
-
if nth
|
|
751
|
+
if nth:
|
|
745
752
|
if nth < 1:
|
|
746
753
|
return "Error: nth must be >= 1."
|
|
747
754
|
sb.click_nth_element(selector, nth, scroll=scroll)
|
|
@@ -766,13 +773,10 @@ def click(
|
|
|
766
773
|
@mcp.tool()
|
|
767
774
|
@handle_sb_errors
|
|
768
775
|
def hover_action(
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
action: Literal[
|
|
772
|
-
|
|
773
|
-
"click",
|
|
774
|
-
"drag_and_drop",
|
|
775
|
-
] = "none",
|
|
776
|
+
selector: str,
|
|
777
|
+
secondary_selector: str | None = None,
|
|
778
|
+
action: Literal["hover", "hover_and_click", "drag_and_drop"] = "hover",
|
|
779
|
+
timeout: float = 5,
|
|
776
780
|
) -> str:
|
|
777
781
|
"""Hover over an element, optionally click another, or drag-and-drop.
|
|
778
782
|
|
|
@@ -780,62 +784,71 @@ def hover_action(
|
|
|
780
784
|
drag-and-drop operations.
|
|
781
785
|
|
|
782
786
|
Args:
|
|
783
|
-
|
|
787
|
+
selector:
|
|
784
788
|
The primary element selector.
|
|
785
|
-
For action="
|
|
786
|
-
For action="
|
|
787
|
-
clicking
|
|
789
|
+
For action="hover", this is the element to hover over.
|
|
790
|
+
For action="hover_and_click", this is the element to hover over
|
|
791
|
+
before clicking 'secondary_selector'.
|
|
788
792
|
For action="drag_and_drop", this is the draggable source element.
|
|
789
793
|
|
|
790
|
-
|
|
794
|
+
secondary_selector:
|
|
791
795
|
The secondary element selector.
|
|
792
|
-
Required for action="
|
|
793
|
-
|
|
796
|
+
Required for action="hover_and_click", where it identifies
|
|
797
|
+
the element to click after hovering 'selector'.
|
|
794
798
|
Required for action="drag_and_drop", where it identifies the
|
|
795
799
|
destination/drop target.
|
|
796
|
-
Not used for action="
|
|
800
|
+
Not used for action="hover".
|
|
797
801
|
|
|
798
802
|
action:
|
|
799
|
-
- "
|
|
800
|
-
- "
|
|
801
|
-
|
|
803
|
+
- "hover": Hover over 'selector' only.
|
|
804
|
+
- "hover_and_click": Hover over 'selector', then click
|
|
805
|
+
'secondary_selector' after a short moment has passed.
|
|
806
|
+
- "drag_and_drop": Drag 'selector' and drop it onto
|
|
807
|
+
'secondary_selector'.
|
|
808
|
+
|
|
809
|
+
timeout: Maximum seconds to wait for 'selector'.
|
|
810
|
+
For drag_and_drop, the same timeout applies to secondary_selector.
|
|
811
|
+
For hover_and_click, SeleniumBase uses its own short wait for
|
|
812
|
+
secondary_selector; this parameter does not extend that secondary
|
|
813
|
+
wait.
|
|
802
814
|
|
|
803
815
|
Returns:
|
|
804
|
-
A confirmation message describing the performed operation.
|
|
805
|
-
|
|
806
|
-
Tool selection:
|
|
807
|
-
- Simple hover -> action="none".
|
|
808
|
-
- Hover over one element and then click another -> action="click".
|
|
809
|
-
- Drag one element onto another -> action="drag_and_drop".
|
|
816
|
+
A confirmation message describing the performed operation's result.
|
|
810
817
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
the
|
|
818
|
+
Errors:
|
|
819
|
+
If a required element cannot be found or interacted with within the
|
|
820
|
+
applicable wait period, or if an error occurs during the action, the
|
|
821
|
+
resulting exception message is returned through @handle_sb_errors.
|
|
814
822
|
|
|
815
|
-
For action="drag_and_drop", selector1 is the source and selector2
|
|
816
|
-
is the destination.
|
|
817
823
|
"""
|
|
818
824
|
sb = _get_sb()
|
|
819
825
|
|
|
820
|
-
if
|
|
821
|
-
|
|
822
|
-
|
|
826
|
+
if timeout < 0:
|
|
827
|
+
return "Error: timeout must be >= 0."
|
|
828
|
+
|
|
829
|
+
if action == "hover":
|
|
830
|
+
sb.hover_element(selector, timeout=timeout)
|
|
831
|
+
return f"Hovered {selector}"
|
|
823
832
|
|
|
824
|
-
if action == "
|
|
825
|
-
if
|
|
826
|
-
return
|
|
827
|
-
|
|
828
|
-
|
|
833
|
+
if action == "hover_and_click":
|
|
834
|
+
if not secondary_selector:
|
|
835
|
+
return (
|
|
836
|
+
"Error: action='hover_and_click' requires secondary_selector."
|
|
837
|
+
)
|
|
838
|
+
sb.hover_and_click(selector, secondary_selector, timeout=timeout)
|
|
839
|
+
return f"Hovered {selector} and clicked {secondary_selector}"
|
|
829
840
|
|
|
830
841
|
if action == "drag_and_drop":
|
|
831
|
-
if
|
|
832
|
-
return
|
|
833
|
-
|
|
834
|
-
|
|
842
|
+
if not secondary_selector:
|
|
843
|
+
return (
|
|
844
|
+
"Error: action='drag_and_drop' requires secondary_selector."
|
|
845
|
+
)
|
|
846
|
+
sb.drag_and_drop(selector, secondary_selector, timeout=timeout)
|
|
847
|
+
return f"Dragged {selector} onto {secondary_selector}"
|
|
835
848
|
|
|
836
849
|
return (
|
|
837
850
|
f"Error: unknown action '{action}'. "
|
|
838
|
-
"Use '
|
|
851
|
+
"Use 'hover', 'hover_and_click', or 'drag_and_drop'."
|
|
839
852
|
)
|
|
840
853
|
|
|
841
854
|
|
|
@@ -934,8 +947,8 @@ def select_option(
|
|
|
934
947
|
An error when the dropdown or requested option cannot be found.
|
|
935
948
|
|
|
936
949
|
This tool is for native <select> elements. For custom JavaScript
|
|
937
|
-
dropdowns made from div/button/list elements, use
|
|
938
|
-
element-interaction tools instead.
|
|
950
|
+
dropdowns made from div/button/list elements, use click_element
|
|
951
|
+
or other element-interaction tools instead.
|
|
939
952
|
"""
|
|
940
953
|
sb = _get_sb()
|
|
941
954
|
|
|
@@ -953,7 +966,7 @@ def select_option(
|
|
|
953
966
|
|
|
954
967
|
@mcp.tool()
|
|
955
968
|
@handle_sb_errors
|
|
956
|
-
def
|
|
969
|
+
def focus_element(
|
|
957
970
|
selector: str,
|
|
958
971
|
action: Literal[
|
|
959
972
|
"scroll_to_element",
|
|
@@ -965,7 +978,8 @@ def focus(
|
|
|
965
978
|
"""Scroll to, focus, or highlight an element.
|
|
966
979
|
|
|
967
980
|
This tool does not click, type, select, hover, or otherwise activate the
|
|
968
|
-
element. Use `
|
|
981
|
+
element. Use `click_element`, `type_text`, or `hover_action` for those
|
|
982
|
+
operations.
|
|
969
983
|
|
|
970
984
|
Args:
|
|
971
985
|
selector: CSS selector or SeleniumBase selector identifying the target.
|
|
@@ -980,7 +994,7 @@ def focus(
|
|
|
980
994
|
timeout: Maximum seconds to wait for the target element. Default: 5.
|
|
981
995
|
|
|
982
996
|
If there's no matching element found within the timeout,
|
|
983
|
-
then @handle_sb_errors
|
|
997
|
+
then @handle_sb_errors returns details from the exception raised.
|
|
984
998
|
"""
|
|
985
999
|
sb = _get_sb()
|
|
986
1000
|
|
|
@@ -1005,7 +1019,7 @@ def focus(
|
|
|
1005
1019
|
|
|
1006
1020
|
@mcp.tool()
|
|
1007
1021
|
@handle_sb_errors
|
|
1008
|
-
def
|
|
1022
|
+
def wait_for_condition(
|
|
1009
1023
|
state: Literal[
|
|
1010
1024
|
"present",
|
|
1011
1025
|
"visible",
|
|
@@ -1024,7 +1038,7 @@ def wait_for(
|
|
|
1024
1038
|
condition is met or the timeout expires. It does not intentionally scroll,
|
|
1025
1039
|
click, or otherwise modify the page while waiting.
|
|
1026
1040
|
|
|
1027
|
-
Use
|
|
1041
|
+
Use check_if_condition to inspect the current state without waiting.
|
|
1028
1042
|
Use assert_condition to verify an expected condition rather than
|
|
1029
1043
|
synchronize with a changing page.
|
|
1030
1044
|
|
|
@@ -1063,8 +1077,8 @@ def wait_for(
|
|
|
1063
1077
|
the tool returns the error produced by its error handler.
|
|
1064
1078
|
|
|
1065
1079
|
Tool selection:
|
|
1066
|
-
- Inspect current state immediately ->
|
|
1067
|
-
- Wait for a state change ->
|
|
1080
|
+
- Inspect current state immediately -> check_if_condition.
|
|
1081
|
+
- Wait for a state change -> wait_for_condition.
|
|
1068
1082
|
- Verify an expectation -> assert_condition.
|
|
1069
1083
|
"""
|
|
1070
1084
|
sb = _get_sb()
|
|
@@ -1139,10 +1153,10 @@ def assert_condition(
|
|
|
1139
1153
|
handled by `handle_sb_errors` and returned as a descriptive tool error;
|
|
1140
1154
|
it is not reported as a successful result.
|
|
1141
1155
|
|
|
1142
|
-
Unlike
|
|
1156
|
+
Unlike check_if_condition, this tool does not merely return whether a
|
|
1143
1157
|
condition is true: a failed expectation is an error.
|
|
1144
|
-
Unlike
|
|
1145
|
-
synchronize with a changing page.
|
|
1158
|
+
Unlike wait_for_condition, its purpose is to verify an expectation,
|
|
1159
|
+
not merely synchronize with a changing page.
|
|
1146
1160
|
|
|
1147
1161
|
Args:
|
|
1148
1162
|
check:
|
|
@@ -1176,8 +1190,8 @@ def assert_condition(
|
|
|
1176
1190
|
instead of a success message.
|
|
1177
1191
|
|
|
1178
1192
|
Tool selection:
|
|
1179
|
-
- Inspect a condition without failing ->
|
|
1180
|
-
- Wait for a condition to become true ->
|
|
1193
|
+
- Inspect a condition without failing -> check_if_condition.
|
|
1194
|
+
- Wait for a condition to become true -> wait_for_condition.
|
|
1181
1195
|
- Verify that an expected condition is true -> assert_condition.
|
|
1182
1196
|
"""
|
|
1183
1197
|
sb = _get_sb()
|
|
@@ -1379,7 +1393,7 @@ def manage_storage(
|
|
|
1379
1393
|
|
|
1380
1394
|
@mcp.tool()
|
|
1381
1395
|
@handle_sb_errors
|
|
1382
|
-
def
|
|
1396
|
+
def scroll_page(
|
|
1383
1397
|
direction: Literal["up", "down", "top", "bottom"] = "down",
|
|
1384
1398
|
amount: int = 25,
|
|
1385
1399
|
) -> str:
|
|
@@ -1399,8 +1413,8 @@ def scroll(
|
|
|
1399
1413
|
Values greater than 100 for `amount` are allowed.
|
|
1400
1414
|
For example, 200 means approximately two viewport heights.
|
|
1401
1415
|
|
|
1402
|
-
Use
|
|
1403
|
-
specific element rather than scroll the page by a relative amount.
|
|
1416
|
+
Use focus_element(action="scroll_to_element") when the goal is to reveal
|
|
1417
|
+
a specific element rather than scroll the page by a relative amount.
|
|
1404
1418
|
"""
|
|
1405
1419
|
sb = _get_sb()
|
|
1406
1420
|
|
|
@@ -1506,7 +1520,7 @@ def manage_tabs(
|
|
|
1506
1520
|
"""Manage browser tabs, including opening new ones.
|
|
1507
1521
|
|
|
1508
1522
|
Use this for listing, opening, switching, or closing tabs.
|
|
1509
|
-
Use `
|
|
1523
|
+
Use `open_url` and `manage_history` for navigation within the active tab.
|
|
1510
1524
|
|
|
1511
1525
|
Args:
|
|
1512
1526
|
action:
|
|
@@ -1603,7 +1617,7 @@ def solve_captcha() -> str:
|
|
|
1603
1617
|
1. Inspect the webpage with get_content when you need to
|
|
1604
1618
|
determine whether CAPTCHA-related controls are present.
|
|
1605
1619
|
2. Call solve_captcha to attempt the CAPTCHA interaction.
|
|
1606
|
-
3. Use get_page_info, get_content,
|
|
1620
|
+
3. Use get_page_info, get_content, check_if_condition,
|
|
1607
1621
|
or manage_cookies to inspect resulting page/session state.
|
|
1608
1622
|
|
|
1609
1623
|
Returns:
|
|
@@ -1621,7 +1635,7 @@ def solve_captcha() -> str:
|
|
|
1621
1635
|
|
|
1622
1636
|
@mcp.tool()
|
|
1623
1637
|
@handle_sb_errors
|
|
1624
|
-
def
|
|
1638
|
+
def save_page(
|
|
1625
1639
|
format: Literal["screenshot", "html", "pdf"] = "screenshot",
|
|
1626
1640
|
filename: str | None = None,
|
|
1627
1641
|
folder: str | None = None,
|
|
@@ -1673,7 +1687,7 @@ def save_output(
|
|
|
1673
1687
|
- Do not use this tool when you only need page metadata such as the
|
|
1674
1688
|
URL or title; use get_page_info instead.
|
|
1675
1689
|
- Do not use this tool to manipulate the page; use the appropriate
|
|
1676
|
-
interaction tool such as
|
|
1690
|
+
interaction tool such as click_element, type_text, or select_option.
|
|
1677
1691
|
|
|
1678
1692
|
Returns:
|
|
1679
1693
|
A confirmation message containing the requested output format and
|
|
@@ -1713,9 +1727,9 @@ def run_javascript(expression: str) -> Any:
|
|
|
1713
1727
|
and other same-origin page resources available to JavaScript.
|
|
1714
1728
|
|
|
1715
1729
|
Tool selection:
|
|
1716
|
-
- Prefer
|
|
1717
|
-
|
|
1718
|
-
interactions.
|
|
1730
|
+
- Prefer click_element, type_text, select_option, hover_action,
|
|
1731
|
+
focus_element, scroll_page, and other higher-level tools for normal
|
|
1732
|
+
browser interactions.
|
|
1719
1733
|
- Prefer get_content, get_attributes, and find_elements for reading
|
|
1720
1734
|
page content or element information.
|
|
1721
1735
|
- Prefer manage_storage for ordinary localStorage/sessionStorage
|
|
@@ -139,7 +139,7 @@ def close_browser() -> str:
|
|
|
139
139
|
|
|
140
140
|
@mcp.tool()
|
|
141
141
|
@handle_sb_errors
|
|
142
|
-
def
|
|
142
|
+
def open_url(url: str) -> str:
|
|
143
143
|
"""Navigate to the given URL in the web browser.
|
|
144
144
|
If the URL doesn't start with a protocol (eg: `https://`),
|
|
145
145
|
then `https://` is automatically prefixed in before navigation.
|
|
@@ -232,7 +232,7 @@ def is_element_visible(selector: str) -> bool:
|
|
|
232
232
|
|
|
233
233
|
@mcp.tool()
|
|
234
234
|
@handle_sb_errors
|
|
235
|
-
def
|
|
235
|
+
def click_element(selector: str, timeout: float = 7) -> str:
|
|
236
236
|
"""Click an element matched by the given selector.
|
|
237
237
|
Raises an exception if the element isn't found within the timeout."""
|
|
238
238
|
d = _get_driver()
|
|
@@ -193,7 +193,7 @@ def page_snapshot() -> dict:
|
|
|
193
193
|
|
|
194
194
|
@mcp.tool()
|
|
195
195
|
@handle_sb_errors
|
|
196
|
-
def
|
|
196
|
+
def open_url(url: str) -> str:
|
|
197
197
|
"""Navigate to the given URL in the web browser.
|
|
198
198
|
If the URL doesn't start with a protocol (eg: `https://`),
|
|
199
199
|
then `https://` is automatically prefixed in before navigation.
|
|
@@ -342,10 +342,7 @@ def is_selected(selector: str) -> bool | str:
|
|
|
342
342
|
|
|
343
343
|
@mcp.tool()
|
|
344
344
|
@handle_sb_errors
|
|
345
|
-
def
|
|
346
|
-
selector: str,
|
|
347
|
-
timeout: float = 7,
|
|
348
|
-
) -> str:
|
|
345
|
+
def click_element(selector: str, timeout: float = 7) -> str:
|
|
349
346
|
"""Click an element matched by the given CSS selector.
|
|
350
347
|
Raises an exception if the element isn't found within the timeout."""
|
|
351
348
|
_get_sb().click(selector, timeout=timeout)
|
|
@@ -391,10 +388,7 @@ def click_link(link_text: str) -> str:
|
|
|
391
388
|
|
|
392
389
|
@mcp.tool()
|
|
393
390
|
@handle_sb_errors
|
|
394
|
-
def double_click(
|
|
395
|
-
selector: str,
|
|
396
|
-
timeout: float = 7,
|
|
397
|
-
) -> str:
|
|
391
|
+
def double_click(selector: str, timeout: float = 7) -> str:
|
|
398
392
|
"""Double-click an element.
|
|
399
393
|
Raises an exception if the element isn't found within the default timeout.
|
|
400
394
|
"""
|
|
@@ -439,11 +433,7 @@ def type_text(
|
|
|
439
433
|
|
|
440
434
|
@mcp.tool()
|
|
441
435
|
@handle_sb_errors
|
|
442
|
-
def set_value(
|
|
443
|
-
selector: str,
|
|
444
|
-
text: str,
|
|
445
|
-
timeout: float = 7,
|
|
446
|
-
) -> str:
|
|
436
|
+
def set_value(selector: str, text: str, timeout: float = 7) -> str:
|
|
447
437
|
"""Set an input's value directly (e.g. for sliders, fast form fills).
|
|
448
438
|
Raises an exception if the element isn't found within the timeout.
|
|
449
439
|
"""
|
|
@@ -453,10 +443,7 @@ def set_value(
|
|
|
453
443
|
|
|
454
444
|
@mcp.tool()
|
|
455
445
|
@handle_sb_errors
|
|
456
|
-
def clear_input(
|
|
457
|
-
selector: str,
|
|
458
|
-
timeout: float = 7,
|
|
459
|
-
) -> str:
|
|
446
|
+
def clear_input(selector: str, timeout: float = 7) -> str:
|
|
460
447
|
"""Clear an input field.
|
|
461
448
|
Raises an exception if the element isn't found within the timeout.
|
|
462
449
|
"""
|
|
@@ -466,10 +453,7 @@ def clear_input(
|
|
|
466
453
|
|
|
467
454
|
@mcp.tool()
|
|
468
455
|
@handle_sb_errors
|
|
469
|
-
def submit(
|
|
470
|
-
selector: str,
|
|
471
|
-
timeout: float = 7,
|
|
472
|
-
) -> str:
|
|
456
|
+
def submit(selector: str, timeout: float = 7) -> str:
|
|
473
457
|
"""Submit a form via a selector inside it.
|
|
474
458
|
Raises an exception if the element isn't found within the timeout.
|
|
475
459
|
"""
|
|
@@ -560,11 +544,7 @@ def nested_click(parent_selector: str, selector: str) -> str:
|
|
|
560
544
|
|
|
561
545
|
@mcp.tool()
|
|
562
546
|
@handle_sb_errors
|
|
563
|
-
def choose_file(
|
|
564
|
-
selector: str,
|
|
565
|
-
file_path: str,
|
|
566
|
-
timeout: float = 7,
|
|
567
|
-
) -> str:
|
|
547
|
+
def choose_file(selector: str, file_path: str, timeout: float = 7) -> str:
|
|
568
548
|
"""Set a <input type="file"> element to upload a local file."""
|
|
569
549
|
_get_sb().choose_file(selector, file_path, timeout=timeout)
|
|
570
550
|
return f"Set file input {selector} to {file_path}"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase-mcp
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.4
|
|
4
4
|
Summary: MCP servers exposing SeleniumBase as tools for MCP clients.
|
|
5
5
|
Home-page: https://github.com/seleniumbase/seleniumbase-mcp
|
|
6
6
|
Author: Michael Mintz
|
|
@@ -55,7 +55,7 @@ Classifier: Topic :: Utilities
|
|
|
55
55
|
Requires-Python: >=3.10
|
|
56
56
|
Description-Content-Type: text/markdown
|
|
57
57
|
License-File: LICENSE
|
|
58
|
-
Requires-Dist: seleniumbase[mcp]>=4.54.
|
|
58
|
+
Requires-Dist: seleniumbase[mcp]>=4.54.4
|
|
59
59
|
Requires-Dist: mcp[cli]<3.0.0,>=2.2.0
|
|
60
60
|
Provides-Extra: deploy
|
|
61
61
|
Requires-Dist: build>=1.0.0; extra == "deploy"
|
|
@@ -177,7 +177,7 @@ The location of `claude_desktop_config.json` depends on your system:
|
|
|
177
177
|
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
178
178
|
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
179
179
|
|
|
180
|
-
Restart Claude Desktop. You should see a 🔨 tools icon indicating the server(s) connected, with tools like `start_browser`, `
|
|
180
|
+
Restart Claude Desktop. You should see a 🔨 tools icon indicating the server(s) connected, with tools like `start_browser`, `open_url`, `click_element`, etc. available. Only keep the entries you actually want. Three separate browser-automation servers is a lot if you only need one.
|
|
181
181
|
|
|
182
182
|
## 4. Connect it to Claude Code
|
|
183
183
|
|
|
@@ -225,14 +225,14 @@ claude mcp add seleniumbase-sb -- uv run seleniumbase-sb
|
|
|
225
225
|
|---|---|
|
|
226
226
|
| `start_browser(browser, headless, uc, incognito)` | Launch a browser session (headless defaults to `False`) |
|
|
227
227
|
| `close_browser()` | End the session |
|
|
228
|
-
| `
|
|
228
|
+
| `open_url(url)` | Go to a URL |
|
|
229
229
|
| `go_back()` / `go_forward()` / `refresh_page()` | History navigation |
|
|
230
230
|
| `get_current_url()` / `get_title()` | Page metadata |
|
|
231
231
|
| `get_page_source()` | Full HTML |
|
|
232
232
|
| `get_text(selector)` | Visible text of an element |
|
|
233
233
|
| `find_elements_count(selector)` | Count matches |
|
|
234
234
|
| `is_element_visible(selector)` | Visibility check |
|
|
235
|
-
| `
|
|
235
|
+
| `click_element(selector, timeout)` | Click (CSS or XPath) |
|
|
236
236
|
| `type_text(selector, text, clear_first, timeout)` | Fill a field |
|
|
237
237
|
| `select_option_by_text(dropdown_selector, option)` | Choose a dropdown option |
|
|
238
238
|
| `wait_for_element_present(selector, timeout)` | Explicit wait |
|
|
@@ -279,16 +279,16 @@ in the loop at all. Reference:
|
|
|
279
279
|
| Group | Tool(s) |
|
|
280
280
|
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
281
281
|
| Session | `start_browser(url, headless, use_chromium, browser_executable_path, incognito, guest, ad_block, proxy)`, `close_browser` |
|
|
282
|
-
| Navigation | `
|
|
283
|
-
| Finding & reading | `find_elements(selector, timeout, include_html)`, `get_content(selector, output_format: text/html/urls
|
|
284
|
-
| Interacting | `
|
|
285
|
-
| Waiting | `
|
|
282
|
+
| Navigation | `open_url`, `manage_history(action: back/forward/reload/list)`, `get_page_info` (running status, url, title, origin, user agent, history in one call) |
|
|
283
|
+
| Finding & reading | `find_elements(selector, timeout, include_html)`, `get_content(selector, output_format: text/html/urls)`, `get_attributes`, `check_for_condition(check: present/visible/count/text_visible)` |
|
|
284
|
+
| Interacting | `click_element(selector, nth, all_matches, only_if_visible, parent_selector, timeout, scroll)`, `hover_action(selector1, selector2, action: hover/hover_and_click/drag_and_drop)`, `type_text(mode: fill_input/append/fast_type/set_value/clear_only)`, `select_option(by: text/value/index)`, `focus_element(action: scroll_to_element/focus/highlight)` |
|
|
285
|
+
| Waiting | `wait_for_condition(state: present/visible/not_visible/absent/seconds_passed, text)` |
|
|
286
286
|
| Assertions | `assert_condition(check: element_present/element_visible/text_visible/title/url/url_contains)` |
|
|
287
287
|
| Cookies & storage | `manage_cookies(action: get_all/clear/save/load)`, `manage_storage(storage: local/session, action: get/set)` |
|
|
288
|
-
| Scrolling | `
|
|
288
|
+
| Scrolling | `scroll_page(direction: up/down/top/bottom, amount)` |
|
|
289
289
|
| Windows & tabs | `manage_window(action: get_rect/set_rect/maximize/minimize)`, `manage_tabs(action: list/open/switch/switch_newest/close_active)` |
|
|
290
290
|
| Captcha | `solve_captcha` |
|
|
291
|
-
| Output & misc | `
|
|
291
|
+
| Output & misc | `save_page(format: screenshot/html/pdf)`, `run_javascript` |
|
|
292
292
|
|
|
293
293
|
### CDP-specific design notes
|
|
294
294
|
|
|
@@ -306,12 +306,6 @@ in the loop at all. Reference:
|
|
|
306
306
|
- **Session teardown.** `sb.quit()` (used by `close_browser`) is the
|
|
307
307
|
documented way to end a session; the browser also auto-closes if the
|
|
308
308
|
process exits without it.
|
|
309
|
-
- **Not wrapped:** PyAutoGUI-based `gui_*` methods (excluded by design —
|
|
310
|
-
see the top-level design notes), low-level plumbing
|
|
311
|
-
(`get_websocket_url`, `add_handler`, permission grants, raw
|
|
312
|
-
`get_document`/`get_flattened_document`), and exact method aliases
|
|
313
|
-
(`open`/`goto` vs `get`) were left out to keep the tool list focused —
|
|
314
|
-
add them the same way as any other tool if you need them.
|
|
315
309
|
|
|
316
310
|
---
|
|
317
311
|
|
|
@@ -70,7 +70,7 @@ if sys.argv[-1] == "publish":
|
|
|
70
70
|
|
|
71
71
|
setup(
|
|
72
72
|
name="seleniumbase-mcp",
|
|
73
|
-
version="1.3.
|
|
73
|
+
version="1.3.4",
|
|
74
74
|
description="MCP servers exposing SeleniumBase as tools for MCP clients.",
|
|
75
75
|
long_description=long_description,
|
|
76
76
|
long_description_content_type="text/markdown",
|
|
@@ -140,7 +140,7 @@ setup(
|
|
|
140
140
|
],
|
|
141
141
|
python_requires=">=3.10",
|
|
142
142
|
install_requires=[
|
|
143
|
-
"seleniumbase[mcp]>=4.54.
|
|
143
|
+
"seleniumbase[mcp]>=4.54.4",
|
|
144
144
|
"mcp[cli]>=2.2.0,<3.0.0",
|
|
145
145
|
],
|
|
146
146
|
extras_require={
|
|
@@ -24,7 +24,7 @@ async def test_server(name: str, command: str) -> None:
|
|
|
24
24
|
|
|
25
25
|
assert "start_browser" in tools
|
|
26
26
|
assert "close_browser" in tools
|
|
27
|
-
assert "
|
|
27
|
+
assert "open_url" in tools
|
|
28
28
|
|
|
29
29
|
result = await client.call_tool(
|
|
30
30
|
"start_browser",
|
|
@@ -33,7 +33,7 @@ async def test_server(name: str, command: str) -> None:
|
|
|
33
33
|
assert not result.is_error
|
|
34
34
|
|
|
35
35
|
result = await client.call_tool(
|
|
36
|
-
"
|
|
36
|
+
"open_url",
|
|
37
37
|
{
|
|
38
38
|
"url": (
|
|
39
39
|
"data:text/html,"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/seleniumbase_mcp.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{seleniumbase_mcp-1.3.2 → seleniumbase_mcp-1.3.4}/seleniumbase_mcp.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|