@browserstack/mcp-server 2.3.0-beta.1 → 2.3.0-beta.2

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.
@@ -342,8 +342,7 @@
342
342
  "404": {
343
343
  "$response": "WebDriverError"
344
344
  }
345
- },
346
- "disabled": true
345
+ }
347
346
  },
348
347
  {
349
348
  "name": "find_element",
@@ -356,7 +355,8 @@
356
355
  "The element id comes back under the W3C key value[\"element-6066-11e4-a52e-4f735466cecf\"]; pass that string as element_id.",
357
356
  "Take the selector from get_page_source rather than guessing: resource-id \u2192 \"id\", content-desc (Android) or name (iOS) \u2192 \"accessibility id\".",
358
357
  "No match is a 404 with error \"no such element\" \u2014 re-read the page source; the screen may have changed or the element may be off-screen and need a scroll first.",
359
- "\"-android uiautomator\" accepts a UiSelector expression, which can scroll an element into view: new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().text(\"Checkout\"))."
358
+ "\"-android uiautomator\" accepts a UiSelector expression, which can scroll an element into view: new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().text(\"Checkout\")).",
359
+ "find_elements answers the same query with a list and never a 404, which is how to ask whether something is present without treating absence as a failure."
360
360
  ],
361
361
  "path_params": [
362
362
  {
@@ -703,8 +703,7 @@
703
703
  "404": {
704
704
  "$response": "WebDriverError"
705
705
  }
706
- },
707
- "disabled": true
706
+ }
708
707
  },
709
708
  {
710
709
  "name": "delete_session",
@@ -1808,7 +1807,7 @@
1808
1807
  "Android takes appId and iOS takes bundleId \u2014 send exactly the one for the platform. The wrong name is refused with a 400 \"invalid argument\" that names the parameter it wanted, and no action is taken.",
1809
1808
  "Launching an app that is already in the foreground does nothing and still reports success.",
1810
1809
  "To restart an app from a clean state, call terminate_app first and then this.",
1811
- "Succeeding means the app was activated, not that it finished drawing; read the page source before acting.",
1810
+ "Succeeding means the app was activated, not that it finished drawing, so give it a moment and confirm before acting. An app that cannot be brought forward at all answers 400 rather than reporting success, and get_app_state reads 4 once it really is in front \u2014 sampled too early it can still report the home screen mid-switch.",
1812
1811
  "The app must be installed \u2014 a package that is not there fails rather than installing it."
1813
1812
  ],
1814
1813
  "path_params": [
@@ -1953,7 +1952,7 @@
1953
1952
  "Android takes appId and iOS takes bundleId \u2014 send exactly the one for the platform. The wrong name is refused with a 400 \"invalid argument\" that names the parameter it wanted, and no action is taken.",
1954
1953
  "The value is a number: 0 not installed, 1 installed but not running, 2 running in the background and suspended, 3 running in the background, 4 running in the foreground.",
1955
1954
  "4 is the only state in which the app is on screen and can be driven.",
1956
- "The same scale applies on both platforms. Sending an app to the background with press_button home leaves it at 2, and launching it again returns it to 4."
1955
+ "The same scale applies on both platforms. Sending an app to the background leaves it at 3 or 2 \u2014 the system suspends it a moment after it stops being visible \u2014 so treat anything below 4 as not on screen rather than waiting for one number. Launching it again returns it to 4."
1957
1956
  ],
1958
1957
  "path_params": [
1959
1958
  {
@@ -2638,6 +2637,67 @@
2638
2637
  }
2639
2638
  },
2640
2639
  "unavailable_note": "This server does not run on your own machine, so it cannot read a file you name \u2014 a path sent here would point at the machine hosting the server. Upload the build yourself with a multipart request carrying the file to the same endpoint, which the asset-upload helper will write out for you, and then use the bs:// url it returns as the app for create_session. upload_app_build does the same thing from a public download link, if the build is reachable at one."
2640
+ },
2641
+ {
2642
+ "name": "find_elements",
2643
+ "method": "POST",
2644
+ "path": "/wd/hub/session/{session_id}/elements",
2645
+ "mode": "read",
2646
+ "entity": "app_session",
2647
+ "intent": "Find every element matching a selector \u2014 use this to count matches, work through a list, or check whether something is present at all.",
2648
+ "guidance": [
2649
+ "No match is an EMPTY LIST and a 200, where find_element answers 404. That makes this the way to test whether something is there without handling an error.",
2650
+ "An empty list can be trusted to mean absent: a strategy this surface does not accept is refused before the request is sent, and an iOS strategy aimed at an Android screen comes back as a 400 \"invalid selector\" rather than as nothing found.",
2651
+ "Each entry carries the same element-6066-11e4-a52e-4f735466cecf key as find_element, and the ids go stale when the screen changes just as readily.",
2652
+ "The order is the UI tree's own, so it follows the screen's layout rather than anything meaningful to the app.",
2653
+ "Use find_element when exactly one match is expected: its 404 says plainly that the screen is not what you thought."
2654
+ ],
2655
+ "path_params": [
2656
+ {
2657
+ "name": "session_id",
2658
+ "type": "string",
2659
+ "required": true,
2660
+ "example": "0123456789abcdef0123456789abcdef01234567"
2661
+ }
2662
+ ],
2663
+ "body": [
2664
+ {
2665
+ "name": "using",
2666
+ "type": "string",
2667
+ "required": true,
2668
+ "values": [
2669
+ "id",
2670
+ "accessibility id",
2671
+ "xpath",
2672
+ "class name",
2673
+ "-android uiautomator",
2674
+ "-ios predicate string",
2675
+ "-ios class chain"
2676
+ ],
2677
+ "example": "accessibility id"
2678
+ },
2679
+ {
2680
+ "name": "value",
2681
+ "type": "string",
2682
+ "required": true,
2683
+ "description": "The selector itself, interpreted according to using.",
2684
+ "example": "nav-cart"
2685
+ }
2686
+ ],
2687
+ "returns": [
2688
+ "value"
2689
+ ],
2690
+ "responses": {
2691
+ "200": {
2692
+ "description": "Every matching element, possibly none.",
2693
+ "schema": {
2694
+ "$schema": "ElementListResponse"
2695
+ }
2696
+ },
2697
+ "404": {
2698
+ "$response": "WebDriverError"
2699
+ }
2700
+ }
2641
2701
  }
2642
2702
  ],
2643
2703
  "schemas": {
@@ -3065,6 +3125,23 @@
3065
3125
  }
3066
3126
  }
3067
3127
  }
3128
+ },
3129
+ "ElementListResponse": {
3130
+ "type": "object",
3131
+ "properties": {
3132
+ "value": {
3133
+ "type": "array",
3134
+ "items": {
3135
+ "type": "object",
3136
+ "properties": {
3137
+ "element-6066-11e4-a52e-4f735466cecf": {
3138
+ "type": "string",
3139
+ "description": "The element id to pass as element_id."
3140
+ }
3141
+ }
3142
+ }
3143
+ }
3144
+ }
3068
3145
  }
3069
3146
  },
3070
3147
  "responses": {
@@ -3139,7 +3216,8 @@
3139
3216
  "press_button",
3140
3217
  "get_simulated_location",
3141
3218
  "get_active_app_info",
3142
- "read_device_property"
3219
+ "read_device_property",
3220
+ "find_elements"
3143
3221
  ]
3144
3222
  },
3145
3223
  "device": {
@@ -246,7 +246,8 @@
246
246
  "A session starts in seconds rather than the tens of seconds a device session takes, but it still holds a browser and consumes Automate minutes until it ends: always finish with set_session_status and then delete_session.",
247
247
  "The session ends itself after idle_timeout seconds without a command, and after 2 hours in total.",
248
248
  "console_logs and network_logs must be asked for here; they cannot be turned on once the session is running, and get_session only links to them when they were.",
249
- "Credentials belong in the Authorization header, never inside bstack:options: capabilities are echoed back in session-not-created errors."
249
+ "Credentials belong in the Authorization header, never inside bstack:options: capabilities are echoed back in session-not-created errors.",
250
+ "resolution takes one of a fixed set of values per operating system, not any width and height: an unsupported pair is refused outright rather than rounded to the nearest one. The browser window is well short of the screen it sits on \u2014 1920x1080 gives a viewport around 930x860 \u2014 so measure it rather than assuming the request was honoured."
250
251
  ],
251
252
  "body": [
252
253
  {
@@ -317,7 +318,7 @@
317
318
  "name": "resolution",
318
319
  "type": "string",
319
320
  "json_path": "/capabilities/alwaysMatch/bstack:options/resolution",
320
- "description": "Desktop screen resolution. The browser window is smaller than this; read the real size from get_window_rect.",
321
+ "description": "Desktop screen resolution, from a fixed set the chosen OS supports \u2014 an unsupported value is refused with \"The specified screen resolution is not compatible with the chosen OS version\" and no session starts. 1920x1080 is accepted on Windows 11; 2560x1440 is not. The browser window is much smaller than the screen either way, so read the real size rather than assuming it.",
321
322
  "example": "1920x1080"
322
323
  },
323
324
  {
@@ -648,8 +649,7 @@
648
649
  "404": {
649
650
  "$response": "WebDriverError"
650
651
  }
651
- },
652
- "disabled": true
652
+ }
653
653
  },
654
654
  {
655
655
  "name": "find_element",
@@ -820,7 +820,7 @@
820
820
  "guidance": [
821
821
  "APPENDS to whatever the field already holds. Call clear_element first to replace the value rather than adding to it.",
822
822
  "Read the result back with get_element_property on \"value\", not get_element_text, which is empty for an input.",
823
- "A \\n at the end submits the form, which is usually quicker than finding and clicking the submit button.",
823
+ "A \\n at the end submits the form on a desktop browser and on Chrome for Android, and is quicker than finding the submit button. IT DOES NOT SUBMIT ON SAFARI FOR iOS \u2014 the text lands in the field and the page stays where it is, whether the newline is sent with the text or on its own. There, click the form's submit button, or call arguments[0].form.submit() through execute_script with the field as the argument.",
824
824
  "The element must be editable; typing into anything else answers \"element not interactable\".",
825
825
  "A site's own autocomplete or dropdown may swallow the keystrokes and require a click on a suggestion instead."
826
826
  ],
@@ -1213,8 +1213,7 @@
1213
1213
  "404": {
1214
1214
  "$response": "WebDriverError"
1215
1215
  }
1216
- },
1217
- "disabled": true
1216
+ }
1218
1217
  },
1219
1218
  {
1220
1219
  "name": "set_window_rect",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@browserstack/mcp-server",
3
- "version": "2.3.0-beta.1",
3
+ "version": "2.3.0-beta.2",
4
4
  "description": "BrowserStack's Official MCP Server",
5
5
  "mcpName": "io.github.browserstack/mcp-server",
6
6
  "main": "dist/index.js",