2323having to choose between multiple near-identical tools.
2424
2525Tool-selection philosophy:
26- - Use get_page_info for browser/page metadata such as URL, title, origin,
27- and navigation history.
26+ - Use get_page_info for browser/page metadata such as URL, title, or origin.
2827- Use get_content for reading visible text or HTML.
2928- Use find_elements for discovering and inspecting multiple matching
3029 elements as structured data.
31- - Use check_state for an immediate, non-waiting state check.
30+ - Use check_for_condition for an immediate, non-waiting state check.
3231- Use wait_for when the agent needs to wait for a condition to become true.
3332- Use assert_condition when the agent needs to verify an expected condition
3433 and treat failure as an assertion error.
@@ -205,18 +204,33 @@ def start_browser(
205204 f"(url={ url !r} , headless={ effective_headless } , "
206205 f"use_chromium={ use_chromium } )"
207206 )
208- except Exception as e :
209- if _sb is not None :
210- try :
211- _sb .quit ()
212- except Exception :
213- pass
214- _sb = None
215-
216- return (
217- f"Error starting browser: "
218- f"{ e .__class__ .__name__ } - { str (e ).strip ()} "
219- )
207+ except Exception :
208+ # Retry once if the first launch attempt fails.
209+ # (A retry helped when testing on Glama's MCP Inspector.)
210+ try :
211+ if _sb is not None :
212+ try :
213+ _sb .quit ()
214+ except Exception :
215+ pass
216+ _sb = None
217+ _sb = sb_cdp .Chrome (url , ** kwargs )
218+ return (
219+ f"Started Pure CDP Mode browser "
220+ f"(url={ url !r} , headless={ effective_headless } , "
221+ f"use_chromium={ use_chromium } )"
222+ )
223+ except Exception as e :
224+ if _sb is not None :
225+ try :
226+ _sb .quit ()
227+ except Exception :
228+ pass
229+ _sb = None
230+ return (
231+ f"Error starting browser: "
232+ f"{ e .__class__ .__name__ } - { str (e ).strip ()} "
233+ )
220234
221235
222236@mcp .tool ()
@@ -268,14 +282,12 @@ def get_page_info() -> dict | str:
268282 - title: The current document title.
269283 - origin: The current page origin (scheme, host, and port).
270284 - user_agent: The browser's current User-Agent string.
271- - history: The browser navigation history for the current session.
272285
273286 Tool selection:
274- - Need URL, title, origin, User-Agent, or navigation history ->
275- use get_page_info.
287+ - Need URL, title, origin, or User-Agent -> use get_page_info.
276288 - Need visible page text or HTML -> use get_content.
277289 - Need information about matching elements -> use find_elements.
278- - Need an immediate state check -> use check_state .
290+ - Need an immediate state check -> use check_for_condition .
279291 - Need to wait for a condition -> use wait_for.
280292 - Need to verify an expected condition -> use assert_condition.
281293
@@ -296,7 +308,6 @@ def get_page_info() -> dict | str:
296308 "title" : _sb .get_title (),
297309 "origin" : _sb .get_origin (),
298310 "user_agent" : _sb .get_user_agent (),
299- "history" : _sb .get_navigation_history (),
300311 }
301312 except Exception as e :
302313 return {
@@ -436,7 +447,7 @@ def find_elements(
436447 use get_content.
437448 - Need to click one of several matches -> use click with nth.
438449 - Need to know whether an element is present/visible ->
439- use check_state .
450+ use check_for_condition .
440451
441452 Note:
442453 Element handles cannot be persisted across MCP calls. If you find
@@ -512,15 +523,14 @@ def get_content(
512523 URLs before navigating to them.
513524
514525 Tool selection:
515- - Need URL, title, origin, User-Agent, or navigation history ->
516- use get_page_info.
526+ - Need URL, title, origin, or User-Agent -> use get_page_info.
517527 - Need visible text -> use output_format="text".
518528 - Need page or element HTML -> use output_format="html".
519529 - Need URLs from the page or an element -> use output_format="urls".
520530 - Need structured information about matching elements ->
521531 use find_elements.
522532 - Need to check whether an element is present or visible ->
523- use check_state .
533+ use check_for_condition .
524534 - Need to wait for content to appear -> use wait_for.
525535 """
526536 sb = _get_sb ()
@@ -568,7 +578,7 @@ def get_attributes(
568578 - Need to discover multiple matching elements or inspect their text ->
569579 use 'find_elements'.
570580 - Need visible text or HTML content -> use 'get_content'.
571- - Need to check presence or visibility -> use 'check_state '.
581+ - Need to check presence or visibility -> use 'check_for_condition '.
572582
573583 This is a read-only operation and does not modify the element.
574584 """
@@ -582,7 +592,7 @@ def get_attributes(
582592
583593@mcp .tool ()
584594@handle_sb_errors
585- def check_state (
595+ def check_for_condition (
586596 check : Literal ["present" , "visible" , "count" , "text_visible" ] = "visible" ,
587597 selector : str = "body" ,
588598 text : str | None = None ,
@@ -610,7 +620,7 @@ def check_state(
610620 count. Missing elements do not cause an exception for these checks.
611621
612622 Tool selection:
613- - Immediate yes/no/count observation -> use check_state .
623+ - Immediate yes/no/count observation -> use check_for_condition .
614624 - Wait until a state becomes true/false -> use wait_for.
615625 - Verify an expected condition and fail when it is not met ->
616626 use assert_condition.
@@ -970,8 +980,9 @@ def wait_for(
970980 Use this tool when the page is dynamic and an automation step must wait
971981 for a condition before continuing.
972982
973- Unlike check_state, this tool intentionally waits. Unlike assert_condition,
974- its purpose is synchronization rather than validating a test expectation.
983+ Unlike check_for_condition, this tool intentionally waits.
984+ Unlike assert_condition, its purpose is synchronization
985+ rather than validating a test expectation.
975986
976987 Args:
977988 state:
@@ -990,7 +1001,7 @@ def wait_for(
9901001 A confirmation when the requested condition is reached.
9911002
9921003 Tool selection:
993- - Check current state immediately -> use check_state .
1004+ - Check current state immediately -> use check_for_condition .
9941005 - Wait for a state/content transition -> use wait_for.
9951006 - Verify an expected value/condition -> use assert_condition.
9961007 """
@@ -1038,9 +1049,10 @@ def assert_condition(
10381049) -> str :
10391050 """Verify an expected browser condition and fail when it is not met.
10401051
1041- Use this tool for explicit verification. Unlike check_state, which simply
1042- reports the current state, assert_condition treats a failed expectation
1043- as an error. Unlike wait_for, URL/title checks do not wait.
1052+ Use this tool for explicit verification. Unlike check_for_condition,
1053+ which simply reports True or False on the current state,
1054+ assert_condition treats a failed expectation as an error.
1055+ Unlike wait_for, URL/title checks do not wait.
10441056
10451057 Args:
10461058 check:
@@ -1067,7 +1079,7 @@ def assert_condition(
10671079 fails; the MCP error wrapper converts it to a descriptive result.
10681080
10691081 Tool selection:
1070- - Just inspect current state -> use check_state .
1082+ - Just inspect current state -> use check_for_condition .
10711083 - Wait for a condition to become true -> use wait_for.
10721084 - Verify that an expected condition is true -> use assert_condition.
10731085 """
@@ -1201,6 +1213,24 @@ def manage_storage(
12011213) -> Any :
12021214 """Get or set a key in localStorage or sessionStorage.
12031215
1216+ Use this tool when the browser workflow needs to inspect or modify
1217+ JavaScript Web Storage belonging to the current page origin.
1218+
1219+ Tool selection:
1220+ - Need localStorage/sessionStorage -> use this tool.
1221+ - Need cookies or authentication cookies -> use manage_cookies.
1222+ - Need arbitrary JavaScript or storage operations not covered here ->
1223+ use run_javascript.
1224+ - Need visible page content or HTML -> use get_content.
1225+ - Need an element's HTML attributes -> use get_attributes.
1226+
1227+ When not to use:
1228+ - Do not use this tool for HTTP cookies; use manage_cookies instead.
1229+ - Do not use this tool for arbitrary page JavaScript;
1230+ use run_javascript when a higher-level tool is insufficient.
1231+ - Do not use this tool to inspect values from another origin;
1232+ storage is scoped to the current page origin.
1233+
12041234 Args:
12051235 key: Storage key to read or modify.
12061236 value: Value to store when action="set". Required for set.
@@ -1219,27 +1249,6 @@ def manage_storage(
12191249 Storage belongs to the current page origin. Values from one website
12201250 are not generally available to another origin.
12211251 """
1222- sb = _get_sb ()
1223-
1224- if action not in ("get" , "set" ):
1225- return "Error: action must be 'get' or 'set'."
1226-
1227- if action == "set" and value is None :
1228- return "Error: value is required when action='set'."
1229-
1230- if storage == "local" :
1231- if action == "get" :
1232- return sb .get_local_storage_item (key )
1233- sb .set_local_storage_item (key , value )
1234- return f"Set localStorage[{ key !r} ]"
1235-
1236- if storage == "session" :
1237- if action == "get" :
1238- return sb .get_session_storage_item (key )
1239- sb .set_session_storage_item (key , value )
1240- return f"Set sessionStorage[{ key !r} ]"
1241-
1242- return f"Error: unknown storage '{ storage } '. Use 'local' or 'session'."
12431252
12441253
12451254# ---------------------------------------------------------------------------
@@ -1453,8 +1462,8 @@ def solve_captcha() -> str:
14531462 1. Inspect the page with get_content when you need to determine
14541463 whether CAPTCHA-related controls are present.
14551464 2. Call solve_captcha to attempt the interaction.
1456- 3. Use get_page_info, get_content, check_state, or manage_cookies
1457- to inspect resulting page/session state.
1465+ 3. Use get_page_info, get_content, check_for_condition,
1466+ or manage_cookies to inspect resulting page/session state.
14581467
14591468 Returns:
14601469 A message confirming that the CAPTCHA interaction was attempted, not
@@ -1521,22 +1530,51 @@ def save_output(
15211530@mcp .tool ()
15221531@handle_sb_errors
15231532def run_javascript (expression : str ) -> Any :
1524- """Evaluate arbitrary JavaScript in the current page context.
1533+ """Evaluate a JavaScript expression in the current page context.
15251534
15261535 Use this only when the required browser operation cannot be accomplished
15271536 through the higher-level SeleniumBase tools.
15281537
1529- The expression is evaluated through the Chrome DevTools Protocol
1530- Runtime.evaluate mechanism. Promise results are awaited and values are
1531- returned by value.
1538+ The expression is evaluated through Chrome DevTools Protocol
1539+ Runtime.evaluate in the currently active page. It executes with access
1540+ to the page's JavaScript context, including DOM APIs, browser storage,
1541+ and other same-origin page resources available to JavaScript.
1542+
1543+ Tool selection:
1544+ - Prefer click, type_text, select_option, hover_with_action,
1545+ focus_on, scroll, and other higher-level tools for normal browser
1546+ interactions.
1547+ - Prefer get_content, get_attributes, and find_elements for reading
1548+ page content or element information.
1549+ - Prefer manage_storage for ordinary localStorage/sessionStorage
1550+ reads and writes.
1551+ - Prefer manage_cookies for browser cookie operations.
1552+ - Use this tool when a required operation needs arbitrary JavaScript
1553+ that the higher-level tools do not expose.
15321554
15331555 Args:
1534- expression: JavaScript expression to evaluate in the current page
1535- context.
1556+ expression: A JavaScript expression or executable JavaScript code
1557+ evaluated in the current page. It may reference standard browser
1558+ globals such as document and window and may use DOM APIs.
1559+
1560+ Examples:
1561+ - "document.title"
1562+ - "document.querySelector('button')?.textContent"
1563+ - "localStorage.getItem('theme')"
1564+ - "document.body.classList.contains('dark')"
1565+ - "document.querySelector('#slider').value = '50'"
1566+
1567+ The expression should produce a value when a result is needed.
1568+ JavaScript that returns a Promise is supported and its resolved
1569+ value is returned.
15361570
15371571 Returns:
1538- The JavaScript evaluation result when it can be represented across
1539- the MCP boundary.
1572+ The JavaScript evaluation result when it can be serialized and
1573+ returned across the MCP boundary. Primitive values, arrays, plain
1574+ objects, and null are generally suitable return values. DOM objects,
1575+ functions, symbols, and other non-serializable JavaScript values may
1576+ not be returned directly; extract the needed property or convert the
1577+ value to a serializable form first.
15401578
15411579 Security:
15421580 This provides unrestricted JavaScript execution in the current browser
0 commit comments