Skip to main content
Glama
WebDriverIO MCP Server

WebDriverIO MCP Server

Official

WebDriverIO MCP Server

A Model Context Protocol (MCP) server that enables AI assistants to interact with web browsers, local Electron applications, and mobile applications using WebdriverIO. Automate Chrome, Firefox, Edge, Safari, Electron, iOS, and Android through a unified interface.

Installation

mcp MCP server

Add the following configuration to your MCP client settings:

Standard config (works in most clients):

{
  "mcpServers": {
    "wdio-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@wdio/mcp@latest"
      ]
    }
  }
}

Install in VS Code Install in VS Code Insiders

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS), %APPDATA%\Claude\claude_desktop_config.json (Windows), or ~/.config/Claude/claude_desktop_config.json (Linux):

{
  "mcpServers": {
    "wdio-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@wdio/mcp@latest"
      ]
    }
  }
}
claude mcp add wdio-mcp -- npx -y @wdio/mcp@latest

Add to your VS Code settings.json or cline_mcp_settings.json file:

{
  "mcpServers": {
    "wdio-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@wdio/mcp@latest"
      ]
    }
  }
}

Go to Cursor Settings → MCP → Add new MCP Server, or create .cursor/mcp.json:

{
  "mcpServers": {
    "wdio-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@wdio/mcp@latest"
      ]
    }
  }
}

Use the Codex CLI:

codex mcp add wdio-mcp npx "@wdio/mcp@latest"

Or edit ~/.codex/config.toml:

[mcp_servers.wdio-mcp]
command = "npx"
args = ["@wdio/mcp@latest"]

Go to Advanced settings → Extensions → Add custom extension, or run:

goose configure

Or edit ~/.config/goose/config.yaml:

extensions:
  wdio-mcp:
    name: WebDriverIO MCP
    cmd: npx
    args: [ -y, "@wdio/mcp@latest" ]
    enabled: true
    type: stdio

Edit ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "wdio-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@wdio/mcp@latest"
      ]
    }
  }
}

Edit Zed settings (~/.config/zed/settings.json):

{
  "context_servers": {
    "wdio-mcp": {
      "source": "custom",
      "command": "npx",
      "args": [
        "-y",
        "@wdio/mcp@latest"
      ]
    }
  }
}
code --add-mcp '{"name":"wdio-mcp","command":"npx","args":["-y","@wdio/mcp@latest"]}'

⚠️ Restart Required: After adding the configuration, fully restart your MCP client to apply the changes.

Option 2: Global Installation

If you prefer to install globally:

npm install -g @wdio/mcp

Then use wdio-mcp as the command:

{
  "mcpServers": {
    "wdio-mcp": {
      "command": "wdio-mcp"
    }
  }
}

📖 Need help? Follow the MCP install guide.

HTTP Transport (for non-subprocess clients)

By default the server uses stdio (subprocess) transport. For clients that cannot launch subprocesses (e.g. llama.cpp, OpenAI Codex secure mode), enable HTTP transport:

npx @wdio/mcp --http --port 3000

Flag

Default

Description

--http

—

Enable HTTP transport mode

--port

3000

Port to listen on

--allowedHosts

localhost,127.0.0.1,::1

Allowed Host header values (DNS rebinding protection)

--allowedOrigins

(none — browser clients blocked)

Allowed Origin values for CORS. Use * to allow all.

Then point your MCP client at http://localhost:3000/mcp.

Prerequisites For Mobile App Automation

  • Appium Server: Install globally with npm install -g appium

  • Platform Drivers:

    • iOS: appium driver install xcuitest (requires Xcode on macOS)

    • Android: appium driver install uiautomator2 (requires Android Studio)

  • Devices/Emulators:

    • iOS Simulator (macOS) or physical device

    • Android Emulator or physical device

  • For iOS Real Devices: You'll need the device's UDID (Unique Device Identifier)

    • Find UDID on macOS: Connect device → Open Finder → Select device → Click device name/model to reveal UDID

    • Find UDID on Windows: Connect device → iTunes or Apple Devices app → Click device icon → Click "Serial Number" to reveal UDID

    • Xcode method: Window → Devices and Simulators → Select device → UDID shown as "Identifier"

Start the Appium server before using mobile features:

appium
# Server runs at http://127.0.0.1:4723 by default

Related MCP server: Selenium MCP Server

Cloud Providers

Run browser and mobile app tests on cloud real devices and browsers without any local setup. Currently supports BrowserStack, Sauce Labs, LambdaTest, TestingBot, and Digital.ai Testing.

Prerequisites

Set your provider credentials as environment variables or in your MCP client config:

export BROWSERSTACK_USERNAME=your_username
export BROWSERSTACK_ACCESS_KEY=your_access_key
{
  "mcpServers": {
    "wdio-mcp": {
      "command": "npx",
      "args": ["-y", "@wdio/mcp@latest"],
      "env": {
        "BROWSERSTACK_USERNAME": "your_username",
        "BROWSERSTACK_ACCESS_KEY": "your_access_key"
      }
    }
  }
}
export SAUCE_USERNAME=your_username
export SAUCE_ACCESS_KEY=your_access_key
{
  "mcpServers": {
    "wdio-mcp": {
      "command": "npx",
      "args": ["-y", "@wdio/mcp@latest"],
      "env": {
        "SAUCE_USERNAME": "your_username",
        "SAUCE_ACCESS_KEY": "your_access_key"
      }
    }
  }
}

| SAUCE_USERNAME | Sauce Labs username (required) | | SAUCE_ACCESS_KEY | Sauce Labs access key (required) |

The data center is set per-session via the region parameter in start_session (defaults to eu-central-1).

export TESTMU_USERNAME=your_username
export TESTMU_ACCESS_KEY=your_access_key
{
  "mcpServers": {
    "wdio-mcp": {
      "command": "npx",
      "args": ["-y", "@wdio/mcp@latest"],
      "env": {
        "TESTMU_USERNAME": "your_username",
        "TESTMU_ACCESS_KEY": "your_access_key"
      }
    }
  }
}

| TESTMU_USERNAME | LambdaTest username (required) | | TESTMU_ACCESS_KEY | LambdaTest access key (required) |

export TESTINGBOT_KEY=your_key
export TESTINGBOT_SECRET=your_secret
{
  "mcpServers": {
    "wdio-mcp": {
      "command": "npx",
      "args": ["-y", "@wdio/mcp@latest"],
      "env": {
        "TESTINGBOT_KEY": "your_key",
        "TESTINGBOT_SECRET": "your_secret"
      }
    }
  }
}

| TESTINGBOT_KEY | TestingBot key (required) | | TESTINGBOT_SECRET | TestingBot secret (required) |

export DIGITALAI_CLOUD_URL=https://your-cloud.example.com
export DIGITALAI_ACCESS_KEY=your_access_key
{
  "mcpServers": {
    "wdio-mcp": {
      "command": "npx",
      "args": ["-y", "@wdio/mcp@latest"],
      "env": {
        "DIGITALAI_CLOUD_URL": "https://your-cloud.example.com",
        "DIGITALAI_ACCESS_KEY": "your_access_key"
      }
    }
  }
}

| DIGITALAI_CLOUD_URL | Digital.ai cloud host, e.g. https://your-cloud.example.com (required) | | DIGITALAI_ACCESS_KEY | Digital.ai access key (required) |

The access key is sent via the digitalai:options capability (mobile) or the flat digitalai:accessKey capability (web).

Report pass/fail status: WebdriverIO defaults to the BiDi protocol, over which Digital.ai's cloud cannot observe command failures — so reports default to "Passed". To make the cloud reflect actual pass/fail, opt in to classic WebDriver per session:

start_session({
  provider: 'digitalai', platform: 'browser', browser: 'chrome', os: 'Windows 10',
  capabilities: { 'wdio:enforceWebDriverClassic': true }
})

(Pure client-side assertion failures still report as "Passed" — only failures that reach the cloud as WebDriver command errors are detected.)

Mobile (Appium): configure your Digital.ai project for Appium-server execution and pick its default Appium version via the project's "Manage default Appium server version" setting — the version is chosen at the project level (and tracks the versions your cloud supports), so this MCP does not pin one. See Appium Server Test Execution.

Browser Sessions

Run a browser on a specific OS/version combination:

// BrowserStack
start_session({
    provider: 'browserstack',
    platform: 'browser',
    browser: 'chrome',           // chrome | firefox | edge | safari
    browserVersion: 'latest',    // default: latest
    os: 'Windows',               // e.g. "Windows", "OS X"
    osVersion: '11',             // e.g. "11", "Sequoia"
    reporting: {
        project: 'My Project',
        build: 'v1.2.0',
        session: 'Login flow'
    }
})

// Sauce Labs
start_session({
    provider: 'saucelabs',
    platform: 'browser',
    browser: 'chrome',
    os: 'Windows',               // combined with osVersion → platformName
    osVersion: '11',             // e.g. "11", "15" (numbered Mac naming)
    region: 'eu-central-1',      // default: eu-central-1
    reporting: {
        build: 'v1.2.0',
        session: 'Login flow'
    }
})

// LambdaTest
start_session({
    provider: 'testmu',
    platform: 'browser',
    browser: 'chrome',
    os: 'Windows',               // combined with osVersion → platformName
    osVersion: '11',             // e.g. "11", "Sequoia" (optional)
    reporting: {
        project: 'My Project',
        build: 'v1.2.0',
        session: 'Login flow'
    }
})

// TestingBot
start_session({
    provider: 'testingbot',
    platform: 'browser',
    browser: 'chrome',
    os: 'Windows',               // combined with osVersion → platformName (default: Windows 11)
    osVersion: '11',
    reporting: {
        build: 'v1.2.0',
        session: 'Login flow'
    }
})

// Digital.ai
start_session({
    provider: 'digitalai',
    platform: 'browser',
    browser: 'chrome',
    os: 'Windows',               // combined with osVersion → digitalai:osName (optional)
    osVersion: '11',
    reporting: {
        session: 'Login flow'    // → digitalai:testName (flat capability, not nested)
    }
})

Provider-specific os / osVersion behavior:

  • BrowserStack — os and osVersion map to separate bstack:options.os / bstack:options.osVersion fields.

  • Sauce Labs / LambdaTest / TestingBot — os and osVersion are combined into the W3C platformName capability (e.g., os: 'Windows' + osVersion: '11' → platformName: 'Windows 11'). These providers use platformName values like "Windows 11", "MacOS Sequoia", or "Linux". TestingBot defaults to Windows 11 when os is omitted.

  • Digital.ai — os and osVersion are combined into the flat digitalai:osName capability (NOT platformName), e.g. os: 'Windows' + osVersion: '11' → digitalai:osName: 'Windows 11'.

Mobile App Sessions

Test on cloud real devices. First upload your app (or use an existing app URL):

// BrowserStack: returns bs:// URL
upload_app({ provider: 'browserstack', path: '/path/to/app.apk' })

// Sauce Labs: returns storage:filename= reference
upload_app({ provider: 'saucelabs', path: '/path/to/app.apk' })

// LambdaTest: returns lt:// URL
upload_app({ provider: 'testmu', path: '/path/to/app.apk' })

// TestingBot: returns tb:// URL
upload_app({ provider: 'testingbot', path: '/path/to/app.apk' })

// Digital.ai: returns cloud:<package-or-bundle> reference
upload_app({ provider: 'digitalai', path: '/path/to/app.apk' })

// Start a session
start_session({
    provider: 'browserstack',
    platform: 'android',
    app: 'bs://abc123...',
    deviceName: 'Samsung Galaxy S23',
    platformVersion: '13.0'
})

// Sauce Labs native app
start_session({
    provider: 'saucelabs',
    platform: 'android',
    app: 'storage:filename=myapp.apk',
    deviceName: 'Samsung.*',
    platformVersion: '16'
})

// LambdaTest native app
start_session({
    provider: 'testmu',
    platform: 'android',
    app: 'lt://abc123...',
    deviceName: 'Pixel 7',
    platformVersion: '13'
})

// TestingBot native app
start_session({
    provider: 'testingbot',
    platform: 'android',
    app: 'tb://abc123...',
    deviceName: 'Pixel 7',
    platformVersion: '13'
})

// Digital.ai native app — devices are selected via a deviceQuery
start_session({
    provider: 'digitalai',
    platform: 'android',
    app: 'cloud:com.example.app',
    deviceQuery: "@os='android' and @version='14' and @name='.*Pixel.*'"
    // or omit deviceQuery and pass deviceName / platformVersion to build one
})

Mobile Browser Sessions

Run a browser on a cloud mobile device — real device or emulator/simulator — without uploading an app:

// BrowserStack — Chrome on Android emulator
start_session({
    provider: 'browserstack',
    platform: 'android',
    browser: 'chrome',
    deviceName: 'Google Pixel 7',
    platformVersion: '13'
})

// Sauce Labs — Safari on iOS simulator
start_session({
    provider: 'saucelabs',
    platform: 'ios',
    browser: 'safari',
    deviceName: 'iPhone 15',
    platformVersion: '18',
    region: 'eu-central-1'
})

// LambdaTest — Chrome on Android emulator
start_session({
    provider: 'testmu',
    platform: 'android',
    browser: 'chrome',
    deviceName: 'Pixel 7',
    platformVersion: '13'
})

// TestingBot — Chrome on Android emulator
start_session({
    provider: 'testingbot',
    platform: 'android',
    browser: 'chrome',
    deviceName: 'Pixel 7',
    platformVersion: '13'
})

// Digital.ai — Chrome on an Android device (real or emulator; selected via a deviceQuery)
start_session({
    provider: 'digitalai',
    platform: 'android',
    browser: 'chrome',
    deviceName: 'Pixel 7',
    platformVersion: '13'
    // or omit deviceName / platformVersion and pass deviceQuery directly, e.g.
    // deviceQuery: "@os='android' and @emulator='true'" to force an emulator
})

Note: Mobile browser sessions do not require app, appPath, or noReset. The provider launches a browser directly on the selected device — real or emulator/simulator.

Use list_apps to see previously uploaded apps:

list_apps({ provider: 'browserstack' })
list_apps({ provider: 'saucelabs', sortBy: 'app_name' })
list_apps({ provider: 'testmu' })
list_apps({ provider: 'testingbot' })
list_apps({ provider: 'digitalai' })
list_apps({ provider: 'browserstack', organizationWide: true })

Local Tunnel

To test against URLs that are only accessible on your local machine or internal network, enable a local tunnel:

// Auto-start tunnel (provider manages lifecycle)
start_session({
    provider: 'saucelabs',
    platform: 'browser',
    tunnel: true                  // auto-starts tunnel before session
})

// Use an already-running tunnel
start_session({
    provider: 'saucelabs',
    platform: 'browser',
    tunnel: 'external'            // uses existing tunnel
})

The tunnel parameter replaces the deprecated browserstackLocal, saucelabsLocal, and testmuLocal params. Set it to true to auto-start the tunnel (stopped automatically after the session), or 'external' to use a tunnel already running on your machine.

Note: With tunnel: true the provider downloads and manages the tunnel binary for you. For tunnel: 'external' you run it yourself — the wdio://saucelabs/local-binary, wdio://testmu/local-binary, and wdio://testingbot/local-binary resources provide download URLs and setup instructions. The TestingBot Tunnel is a single cross-platform Java JAR (requires Java 11+) rather than a per-platform binary.

Reporting Labels

All session types support reporting labels that appear in the provider dashboard:

Field

Description

reporting.project

Group sessions under a project name

reporting.build

Tag sessions with a build/version label

reporting.session

Name for the individual test session

Cloud Provider Tools

Tool

Description

upload_app

Upload a local .apk or .ipa to the provider; returns an app URL/reference

list_apps

List apps previously uploaded to the provider's app storage

Both tools require a provider parameter ('browserstack', 'saucelabs', 'testmu', 'testingbot', or 'digitalai').

Features

Browser Automation

  • Session Management: Start and close browser sessions (Chrome, Firefox, Edge, Safari) with headless/headed modes

  • Navigation & Interaction: Navigate URLs, click elements, fill forms, and retrieve content

  • Page Analysis: Get visible elements, accessibility trees, take screenshots

  • Cookie Management: Get, set, and delete cookies

  • Scrolling: Smooth scrolling with configurable distances

  • Attach to running Chrome: Connect to an existing Chrome window via --remote-debugging-port — ideal for testing authenticated or pre-configured sessions

  • Connect to existing WebDriver endpoints: Reuse an already-running Selenium-compatible WebDriver endpoint, such as a framework-managed browser or a desktop webview automation bridge (like Tauri)

  • Device emulation: Apply mobile/tablet presets (iPhone 15, Pixel 7, etc.) to simulate responsive layouts without a physical device

  • Session Recording: All tool calls are automatically recorded and exportable as runnable WebdriverIO JS

Mobile App Automation (iOS/Android)

  • Native App Testing: Test iOS (.app/.ipa) and Android (.apk) apps via Appium

  • Touch Gestures: Tap, swipe, long-press, drag-and-drop

  • App Lifecycle: Launch, background, terminate, check app state

  • Context Switching: Seamlessly switch between native and webview contexts for hybrid apps

  • Device Control: Rotate, lock/unlock, geolocation, keyboard control, notifications

  • Cross-Platform Selectors: Accessibility IDs, XPath, UiAutomator (Android), Predicates (iOS)

Available Tools

The server lists only the tools that fit the current session: browser sessions get the page tools below, mobile sessions the gestures and device tools, Electron sessions the Electron tools. Rarely used groups (mocks, cookies, device emulation, extensions, attaching, the raw element list, cloud app uploads) are listed after the agent calls enable_tools, so their definitions aren't sent with every request. With several live sessions, tools are listed for the union of their platforms. Set WDIO_MCP_TOOLS=all to list everything up front.

Set WDIO_MCP_NETWORK_LOGS to configure the default Chromium network/performance log capture mode for start_session: none (default, off), failures (Network.loadingFailed and Network.responseReceived entries with HTTP status >= 400), or all (every Chromium performance log entry). Individual sessions can override this default via start_session({ networkLogs: 'none' | 'failures' | 'all' }).

Tool

Description

enable_tools

Add a group of tools: mocks, cookies, device, extensions, attach, elements, cloud-apps

Session Management

Tool

Description

start_session

Start a browser, local Electron application, or mobile app session; attach: true retains the existing Chrome CDP connection mode. Optional name and onExisting: "close" | "keep" (keep runs it alongside existing sessions; the new session is not made the default)

attach_session

Attach to an existing remote WebDriver/Appium session by sessionId without creating a new session; optional name and onExisting. With only a name, looks up a live session

launch_chrome

Launch a new Chrome instance with remote debugging enabled (for use with start_session({ attach: true }))

close_session

Close or detach from the default session, or the one named by the optional session target (supports detach: true to disconnect without terminating)

emulate_device

Emulate a mobile/tablet device preset (viewport, DPR, UA, touch); requires BiDi session

open_web_extension

Install a web extension through WebDriver BiDi and open one of its extension pages so normal page tools can drive its UI

Multiple sessions

By default the server keeps one session: starting a new one closes the previous one. To run sessions side by side, pass onExisting: "keep" and a name to start_session. The new session is not made the default, so the original keeps answering calls that omit a target.

Every session-bound tool accepts an optional session argument, either a name or a sessionId (sessionId is matched first). Omitting it uses the default session, and targeting a session never changes the default. When a call is targeted, or more than one session is live, the result starts with [session: name (id8)]. Calls to the same session queue and run in order; calls to different sessions run concurrently. An unknown target, or no default session while others are live, returns an error that lists the live sessions. Names are scoped to one server process. The wdio://session/current/* resources always refer to the default session.

start_session({ platform: "browser", browser: "chrome", name: "alice" })
start_session({ platform: "browser", browser: "chrome", name: "bob", onExisting: "keep" })
navigate({ url: "https://example.com", session: "bob" })

Navigation & Page Interaction (Web & Mobile)

Tool

Description

navigate

Navigate to a URL. In browsers the result shows the new page's interactive elements with refs

snapshot

The page as an accessibility tree with refs (button "Save" [ref=e3]), interactive elements by default (plain text is dropped, full: true shows it); pass refs to perform_actions for several steps; find returns only the parts containing a text (link targets included), full: true adds all text, viewport: true keeps only what is on screen. Works for apps too (the screen's accessibility tree).

get_elements

Get visible, interactable elements with bounds. Supports inViewportOnly (default: true) and includeContainers (default: false). Mobile and Electron; listed after enable_tools({ groups: ['elements'] }), use snapshot first

get_accessibility_tree

Get the accessibility tree with roles, names, and selectors. Electron-only; browsers use snapshot

get_screenshot

Take a screenshot of the current page or screen (base64-encoded, auto-resized to max 2000px / 1MB)

get_tabs

List all open browser tabs with handle, title, URL, and active status. Browser-only.

scroll

Scroll in a direction (up/down) by specified pixels. Browser-only.

execute_script

Execute arbitrary JavaScript in the browser, or Appium mobile commands on devices

execute_electron_script

Execute privileged JavaScript in the Electron main process (Electron sessions only)

trigger_electron_deeplink

Trigger an Electron deeplink whose scheme was explicitly configured at session start

mock

Configure a session-scoped mock: an Electron main-process API function or a browser network request

get_mock_calls

Inspect call arguments (Electron) or intercepted request records (browser) for a session-scoped mock

manage_mock

Clear, reset, or restore a session-scoped mock

switch_tab

Switch to a different browser tab by handle or 0-based index. Browser-only.

switch_frame

Switch into an iframe by CSS/XPath selector, or back to the top-level frame if no selector is given. Browser-only.

Element Interaction (Web & Mobile)

Tool

Description

click_element

Click an element

set_value

Replace the text of an input or textarea

select_option

Select an option of a <select> by its text; for several steps use perform_actions. Browser-only.

press_key

Press a key or combination (Enter, Control+a) in the focused element, optionally times (1-100) to repeat it; for several steps use perform_actions. Browser-only.

perform_actions

Run several clicks, fills, selects, checks and key presses (press accepts times to repeat) in one call; stops at the first failure, when a step loads a new page, or before a key press that follows a click, select, check or uncheck that changed the page. Works for apps too (select, check and uncheck are web-only).

click_element, set_value, tap_element and perform_actions take a ref from snapshot (e12) as well as a selector, in browsers and apps, and each result lists what the action changed on the page or screen: new or changed elements with their refs, or the page it navigated to. An agent rarely needs a separate screenshot or snapshot to see the effect.

Recommended workflow (also sent to clients as server instructions):

  • snapshot, then act with refs.

  • Several steps in a row (fill a form, then submit): one perform_actions call.

  • Refs from the latest result stay valid until the page changes.

Tool

Description

get_cookies

Get all cookies for the current session, or a single cookie by name

set_cookie

Set a cookie with name, value, and optional attributes

delete_cookies

Delete all cookies or a specific cookie

Mobile Gestures (iOS/Android)

Tool

Description

tap_element

Tap an element by selector or coordinates

swipe

Swipe in a direction (up/down/left/right)

drag_and_drop

Drag from one location to another

Context Switching (Hybrid Apps)

Tool

Description

get_contexts

List available automation contexts (NATIVE_APP, WEBVIEW_*) and the currently active one

switch_context

Switch between native and webview contexts

Device Control (iOS/Android)

Tool

Description

get_app_state

Get the current lifecycle state of a mobile app (not installed / not running / background / foreground)

rotate_device

Rotate to portrait or landscape

hide_keyboard

Hide on-screen keyboard

set_geolocation

Set device GPS location

Tool

Description

query_docs

Search the official WebdriverIO documentation and return the most relevant excerpts with page, section and source URL. query is required (2-3 distinctive keywords — a sentence dilutes the ranking); limit defaults to 5 (max 20); fullPage (default: false) returns the full matched pages instead of excerpts. Session-independent

MCP Resources (read-only, no tool call needed)

Resource

Description

wdio://sessions

Index of all recorded sessions

wdio://session/current/steps

Step log for the default session

wdio://session/current/code

Generated runnable WebdriverIO JS for the default session

wdio://session/{id}/steps

Step log for any past session by ID

wdio://session/{id}/code

Generated JS for any past session by ID

wdio://session/current/elements

Interactable elements (viewport-only by default)

wdio://session/current/accessibility

Accessibility tree

wdio://session/current/screenshot

Screenshot (base64)

wdio://session/current/cookies

Browser cookies

wdio://session/current/tabs

Open browser tabs

wdio://session/current/contexts

Native/webview contexts (mobile)

wdio://session/current/context

Currently active context (mobile)

wdio://session/current/app-state/{bundleId}

Mobile app lifecycle state for a given bundle ID

wdio://session/current/geolocation

Device geolocation

wdio://session/current/capabilities

Resolved WebDriver capabilities for the default session

wdio://session/current/logs

Crash/console logs for the default session. Auto-detects session type — browser: console logs + JS exceptions; Android: logcat; iOS: crashlog + syslog

wdio://browserstack/local-binary

BrowserStack Local binary download URL and start command

wdio://saucelabs/local-binary

Sauce Connect binary download URL and start command

wdio://testmu/local-binary

TestMu Tunnel binary download URL and start command

wdio://testingbot/local-binary

TestingBot Tunnel JAR download URL and start command (Java 11+)

wdio://docs/index

Every page of the official WebdriverIO documentation as tab-separated title, source path and slug

wdio://docs/page/{slug}

Full markdown of one documentation page, truncated at 40000 characters. Slugs come from wdio://docs/index ("~" in place of "/")

Usage Examples

Real-World Test Cases

Example 1: Testing Demo Android App (Book Scanning)

Test the Demo Android app at C:\Users\demo-liveApiGbRegionNonMinifiedRelease-3018788.apk on emulator-5554:
1. Start the app with auto-grant permissions
2. Get visible elements on the onboarding screen
3. Tap "Skip" to bypass onboarding
4. Verify main screen loads
5. Take a screenshot

Example 2: Testing World of Books E-commerce Site

You are a Testing expert, and want to assess the basic workflows of worldofbooks.com:
- Open World of Books (accept all cookies)
- Get visible elements to see navigation structure
- Search for a fiction book
- Choose one and validate if there are NEW and used book options
- Report your findings at the end

Browser Automation

Basic web testing prompt:

You are a Testing expert, and want to assess the basic workflows of a web application:
- Open World of Books (accept all cookies)
- Search for a fiction book
- Choose one and validate if there are NEW and used book options
- Report your findings at the end

Browser configuration options:

// Default settings (headed mode, 1280x1080)
start_session({platform: 'browser'})

// Firefox
start_session({platform: 'browser', browser: 'firefox'})

// Edge
start_session({platform: 'browser', browser: 'edge'})

// Safari (headed only; requires macOS)
start_session({platform: 'browser', browser: 'safari'})

// Headless mode
start_session({platform: 'browser', headless: true})

// Custom dimensions
start_session({platform: 'browser', windowWidth: 1920, windowHeight: 1080})

// Pass custom capabilities (e.g. Chrome extensions, profile, prefs)
start_session({
    platform: 'browser',
    headless: false,
    capabilities: {
        'goog:chromeOptions': {
            args: ['--user-data-dir=/tmp/wdio-mcp-profile', '--load-extension=/path/to/unpacked-extension']
        }
    }
})

Mocking

Mocking is available through mock, get_mock_calls, and manage_mock (listed after enable_tools({ groups: ['mocks'] })), for both Electron main-process API functions and browser network requests.

mockType accepts 'electron' or 'browser'. Browser mocks are the default in WebDriver sessions when mockType is omitted. Electron sessions require an explicit selection because they can target both kinds of mocks. iOS/Android Appium sessions do not support mocking.

mock({
  mockType: 'electron', apiName: 'dialog', funcName: 'showOpenDialog',
  behavior: 'mockResolvedValue', value: { canceled: false, filePaths: ['/tmp/example.txt'] }
})
// Interact with the renderer to open the application's file picker, then inspect its calls.
get_mock_calls({ mockType: 'electron', apiName: 'dialog', funcName: 'showOpenDialog' })
manage_mock({ mockType: 'electron', apiName: 'dialog', funcName: 'showOpenDialog', action: 'restore' })

Electron behavior defaults to mockReturnValue; mockResolvedValue and mockRejectedValue support async APIs. Each has a Once variant for queued responses. Repeated configuration preserves the existing mock and call history. Values must be JSON; omit value for undefined. clear removes call history, reset also removes behavior and queued responses, and restore reinstates the original function. These tools support individual API functions; class mocks and arbitrary mock implementations are not exposed.

Browser mocks intercept network requests matching a url glob (for example **/api/todos) with an optional method filter. behavior is optional: omit it to passively record matching requests without altering them — the mock still continues every request. respond and respondOnce require value (the JSON response body) and accept optional statusCode and headers; abort/abortOnce fail the request, and redirect/redirectOnce send it to the URL in value. get_mock_calls returns { calls, callCount } for the intercepted requests, and manage_mock takes clear, reset, or restore.

start_session({ platform: 'browser', browser: 'chrome', capabilities: { webSocketUrl: true } })

// Observe-only: record every request to /api/todos without changing responses.
mock({ mockType: 'browser', url: '**/api/todos' })
navigate({ url: 'https://example.com/todos' })
get_mock_calls({ mockType: 'browser', url: '**/api/todos' })

// Or overwrite the response instead.
mock({ mockType: 'browser', url: '**/api/todos', method: 'GET', behavior: 'respond', value: [{ id: 1, title: 'Buy milk' }], statusCode: 200 })

// Interact with the page, then inspect the intercepted requests.
get_mock_calls({ mockType: 'browser', url: '**/api/todos', method: 'GET' })
manage_mock({ mockType: 'browser', url: '**/api/todos', method: 'GET', action: 'restore' })

Browser mocks require a BiDi-enabled session — start it with capabilities: { webSocketUrl: true }. Attached sessions default to BiDi off, so browser mocks do not work there unless the attached session negotiated BiDi; in Electron sessions browser mocks additionally require BiDi. Handles belong to the active browser session and cannot be reused after it closes or is replaced. All three tools participate in tracing and generated replay.

Electron applications

Electron support is local-only and uses the official @wdio/electron-service standalone lifecycle. It requires Node.js 22.23.4, 24.22.1, 26.12.1 or a later release of these lines, as the server does. Put service options such as appBinaryPath, appEntryPoint, and appArgs in capabilities['wdio:electronServiceOptions']; use top-level electronRootDir for the service's Electron Builder/Electron Forge discovery. When testing a binary outside the project, set browserVersion to the Electron version so the service can select a compatible Chromedriver.

start_session({
  platform: 'electron',
  browserVersion: '33.2.1',
  capabilities: {
    'wdio:electronServiceOptions': {
      appBinaryPath: '/path/to/MyApp.app/Contents/MacOS/MyApp',
      appArgs: ['--disable-gpu']
    }
  }
})

// Privileged: this code runs in the Electron main process, not the renderer.
execute_electron_script({ script: 'return electron.app.getName()' })

Existing browser DOM tools work against the Electron renderer. close_session always tears down MCP-managed Electron sessions; detach: true is intentionally unsupported. Main/renderer log capture can be enabled with captureMainProcessLogs or captureRendererLogs plus logDir. To trigger an app deeplink, explicitly configure its URI scheme when starting the Electron session. The scheme has no colon and only URLs with that exact scheme can be dispatched:

start_session({
  platform: 'electron',
  electronDeeplinkScheme: 'myapp',
  capabilities: {
    'wdio:electronServiceOptions': {
      appBinaryPath: '/path/to/MyApp.app/Contents/MacOS/MyApp'
    }
  }
})
trigger_electron_deeplink({ url: 'myapp://open/item' })

Attach to a running Chrome instance:

// First, launch Chrome with remote debugging enabled:
//
//   macOS (must quit Chrome first — open -a ignores args if Chrome is already running):
//     pkill -x "Google Chrome" && sleep 1
//     /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
//       --remote-debugging-port=9222 \
//       --user-data-dir=/tmp/chrome-debug &
//
//   Linux:
//     google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug &
//
//   Verify it's ready: curl http://localhost:9222/json/version
start_session({attach: true})
start_session({attach: true, port: 9333})
start_session({attach: true, port: 9222, navigationUrl: 'https://app.example.com'})

Connect to an existing WebDriver endpoint:

Use provider: 'external' when another process already owns the browser or webview lifecycle and exposes a W3C WebDriver endpoint. This is useful for Selenium Grid sessions, externally managed browser drivers, or desktop apps like Tauri apps that embed a webview and expose WebDriver separately. The MCP server connects to the endpoint; it does not launch or stop the target application, start tunnels, or manage framework-specific setup.

// Defaults to http://127.0.0.1:4445/ and browserName: 'chrome'
start_session({provider: 'external', platform: 'browser'})

// Custom WebDriver endpoint and capabilities
start_session({
    provider: 'external',
    platform: 'browser',
    webdriverConfig: {
        protocol: 'http',
        hostname: '127.0.0.1',
        port: 4445,
        path: '/'
    },
    capabilities: {
        browserName: 'tauri'
    }
})

For desktop webview apps such as Tauri, first start the app and its WebDriver bridge outside of this MCP server, then pass the endpoint and the required capabilities. For example, a Tauri WebDriver bridge may require capabilities: {browserName: 'tauri'}.

Attach to an existing WebDriver or Appium session:

Use attach_session when the session has already been created by another process. The MCP reuses the selected provider's endpoint and credentials, registers the appropriate browser/mobile command set locally, and does not issue a new-session request. Attached sessions are externally managed: close_session() detaches by default, while close_session({detach: false}) explicitly terminates the remote session.

// Existing BrowserStack App Automate session
attach_session({
    provider: 'browserstack',
    platform: 'ios',
    sessionId: 'existing-browserstack-session-id',
    capabilities: {
        'appium:deviceName': 'iPhone 15',
        'appium:automationName': 'XCUITest'
    }
})

// Existing session on a local Appium server
attach_session({
    provider: 'local',
    platform: 'android',
    sessionId: 'existing-appium-session-id',
    appiumConfig: {
        protocol: 'http',
        host: '127.0.0.1',
        port: 4723,
        path: '/'
    }
})

// Existing mobile session on a custom W3C WebDriver endpoint
attach_session({
    provider: 'external',
    platform: 'ios',
    sessionId: 'existing-grid-session-id',
    webdriverConfig: {
        protocol: 'https',
        hostname: 'grid.example.com',
        port: 443,
        path: '/wd/hub'
    }
})

An existing cloud session must keep using the tunnel it was created with. attach_session never starts or stops a tunnel, so keep the original tunnel process alive for as long as the session needs it.

Device emulation (requires BiDi session):

// Device emulation (requires BiDi session)
start_session({capabilities: {webSocketUrl: true}})
emulate_device()                         // list available presets
emulate_device({device: 'iPhone 15'})    // activate emulation
emulate_device({device: 'Pixel 7'})      // switch device
emulate_device({device: 'reset'})        // restore desktop defaults

Web extensions (requires BiDi session):

start_session({platform: 'browser', browser: 'chrome', capabilities: {webSocketUrl: true}})

open_web_extension({
    extensionData: {type: 'path', path: '/path/to/unpacked-extension'},
    path: 'options.html'
})

// Drive the extension UI with the normal page tools.
get_elements()
click_element({selector: '#save'})

// For remote/cloud sessions, send a packaged extension archive as base64.
open_web_extension({
    extensionData: {type: 'base64', value: '<base64-encoded-zip>'},
    path: 'options.html'
})

Mobile App Automation

Testing an iOS app on simulator:

Test my iOS app located at /path/to/MyApp.app on iPhone 15 Pro simulator:
1. Start the app session
2. Tap the login button
3. Enter "testuser" in the username field
4. Take a screenshot of the home screen
5. Close the session

Preserving app state between sessions:

Test my Android app without resetting data:
1. Start app session with noReset: true and fullReset: false
2. App launches with existing login state and user data preserved
3. Run test scenarios
4. Close session (app remains installed with data intact)

Testing an iOS app on real device:

Test my iOS app on my physical iPhone:
1. Start app session with:
   - platform: iOS
   - appPath: /path/to/MyApp.ipa
   - deviceName: My iPhone
   - udid: 00008030-001234567890ABCD (your device's UDID)
   - platformVersion: 17.0
2. Run your test scenario
3. Close the session

Testing an Android app:

Test my Android app /path/to/app.apk on the Pixel_6_API_34 emulator:
1. Start the app with auto-grant permissions
2. Get visible elements (use inViewportOnly: false to see all elements)
3. Swipe up to scroll
4. Tap on the "Settings" button using text matching
5. Verify the settings screen is displayed

Advanced element detection:

Test my app and debug layout issues:
1. Start the app session
2. Get visible elements with includeContainers: true to see the layout hierarchy
3. Analyze ViewGroup, FrameLayout, and ScrollView containers
4. Use inViewportOnly: false to find off-screen elements that need scrolling

Hybrid app testing (switching contexts):

Test my hybrid app:
1. Start the Android app session
2. Tap "Open Web" button in native context
3. List available contexts
4. Switch to WEBVIEW context
5. Click the login button using CSS selector
6. Switch back to NATIVE_APP context
7. Verify we're back on the home screen

Important Notes

⚠️ Session Management:

  • Only one session (browser OR app) can be active at a time

  • Always close sessions when done to free system resources

  • To switch between browser and mobile, close the current session first

  • Use close_session({ detach: true }) to disconnect without terminating the session on the Appium server

  • State preservation can be controlled with noReset and fullReset parameters during session creation

  • Sessions created with noReset: true or without appPath will automatically detach on close

  • Sessions adopted with attach_session always detach on close unless detach: false is explicitly requested

⚠️ Task Planning:

  • Break complex automation into smaller, focused operations

  • Claude may consume message limits quickly with extensive automation

⚠️ Mobile Automation:

  • Appium server must be running before starting mobile sessions

  • Ensure emulators/simulators are running and devices are connected

  • iOS automation requires macOS with Xcode installed

  • iOS Real Devices: Testing on physical iOS devices requires the device's UDID (40-character unique identifier). See Prerequisites section for how to find your UDID

Selector Syntax Quick Reference

Web (CSS/XPath):

  • CSS: button.my-class, #element-id

  • XPath: //button[@class='my-class']

  • Text: button=Exact text, a*=Contains text

Mobile (Cross-Platform):

  • Accessibility ID: ~loginButton (works on both iOS and Android)

  • Android UiAutomator: android=new UiSelector().text("Login")

  • iOS Predicate: -ios predicate string:label == "Login" AND visible == 1

  • XPath: //android.widget.Button[@text="Login"]

Advanced Features

App State Preservation

State Preservation with noReset/fullReset: Control app state when creating new sessions using the noReset and fullReset parameters:

noReset

fullReset

Behavior

true

false

Preserve state: App stays installed, data preserved

false

false

Clear app data but keep app installed (default)

false

true

Full reset: Uninstall and reinstall app (clean slate)

Example with state preservation:

// Preserve login state between test runs
start_session({
    platform: 'android',
    appPath: '/path/to/app.apk',
    deviceName: 'emulator-5554',
    noReset: true,         // Don't reset app state
    fullReset: false,      // Don't uninstall
    autoGrantPermissions: true,
    capabilities: {
        'appium:chromedriverExecutable': '/path/to/chromedriver',
        'appium:autoWebview': true
    }
})
// App launches with existing user data, login tokens, preferences intact

Detach from Sessions: The close_session tool supports a detach parameter that disconnects from the session without terminating it on the Appium server:

// Detach without killing the session
close_session({detach: true})

// Explicit session termination (closes the app and removes session)
close_session({detach: false})

Sessions created with noReset: true or without appPath will automatically detach on close. Sessions adopted with attach_session are externally managed and also detach by default; pass detach: false only when the MCP should deliberately terminate the existing remote session.

This is particularly useful when:

  • Preserving app state for manual testing continuation

  • Debugging multi-step workflows (leave session running between tool invocations)

  • Testing scenarios where you want the app to remain installed and in current state

Smart Element Detection

  • Platform-specific element classification: Automatically identifies interactable elements vs layout containers

    • Android: Button, EditText, CheckBox vs ViewGroup, FrameLayout, ScrollView

    • iOS: Button, TextField, Switch vs View, StackView, CollectionView

  • Multiple locator strategies: Each element provides accessibility ID, resource ID, text, XPath, and platform-specific selectors

  • Viewport filtering: Control whether to get only visible elements or all elements including off-screen

  • Layout debugging: Optionally include container elements to understand UI hierarchy

Automatic Permission & Alert Handling

Both iOS and Android sessions now support automatic handling of system permissions and alerts:

  • autoGrantPermissions (default: true): Automatically grants app permissions (camera, location, etc.)

  • autoAcceptAlerts (default: true): Automatically accepts system alerts and dialogs

  • autoDismissAlerts (optional): Set to true to dismiss alerts instead of accepting them

This eliminates the need to manually handle permission popups during automated testing.

Technical Details

  • Built with: TypeScript, WebDriverIO, Appium

  • Browser Support: Chrome, Firefox, Edge (headed/headless, automated driver management), Safari (headed only; macOS)

  • Mobile Support: iOS (XCUITest) and Android (UiAutomator2/Espresso)

  • Protocol: Model Context Protocol (MCP) for Claude Desktop integration

  • Session Model: One default session, with optional named sessions running alongside (browser or mobile app)

  • Data Format: TOON (Token-Oriented Object Notation) for efficient LLM communication

  • Element Detection: XML-based page source parsing with intelligent filtering and multi-strategy locator generation

Session Recording & Code Export

Every tool call is automatically recorded to a session history. You can inspect sessions and export runnable code via MCP resources — no extra tool calls needed:

  • wdio://sessions — lists all recorded sessions with type, timestamps, and step count

  • wdio://session/current/steps — step log for the default session

  • wdio://session/current/code — generated runnable WebdriverIO JS for the default session

  • wdio://session/{sessionId}/steps — step log for any past session by ID

  • wdio://session/{sessionId}/code — generated JS for any past session by ID

The generated script reconstructs the full session — including capabilities, navigation, clicks, and inputs — as a standalone import { remote } from 'webdriverio' file. For cloud provider sessions it includes the full try/catch/finally with automatic session result marking via the provider's REST API.

Trace Recording

Passing trace: true to start_session produces a Playwright-compatible .trace zip in the .trace/ directory when the session closes. The zip is playable at player.vibium.dev and shows a filmstrip of screenshots alongside the action timeline.

How screenshots are timed

Appium's takeScreenshot round-trip takes 700–1300 ms on a local emulator, which is long enough for the previous action's animations to settle. We exploit this: each screenshot is captured before the next action fires, so what the Appium server returns is already the settled result of the prior action.

The tricky part is making the trace player show that screenshot under the right action. The player associates a screencast-frame event with whichever action's time window contains the frame's timestamp field. If the timestamp is set to "now" (capture time), it falls before the current action's startTime and the player labels it as the before state of the next action — one action out of sync.

The fix: stamp each screencast-frame with lastAfterEndTime — the endTime of the action that just completed. That places the frame inside the previous action's window, so the player shows it as the result of that action, not the precursor to the next one.

Timeline (monotonic ms):

  prev.endTime ← frame timestamp stamped here
        │
        │   [screenshot captured here — shows settled state after prev action]
        │
  curr.startTime
        │
        │   [action executes]
        │
  curr.endTime ← next frame will be stamped here

The final screenshot at session close is stamped with the last action's endTime, so it renders under that action rather than appearing as an orphaned frame after the timeline ends.

Session Logs

The wdio://session/current/logs resource returns crash reports, console errors, and system logs for the current session, auto-detecting the session type to fetch the right log buffer:

Session Type

Log Sources

Contents

Browser

getLogs('browser')

Console output + uncaught JS exceptions

Android

getLogs('logcat')

System logs, crash dumps, fatal exceptions

iOS

getLogs('crashlog') + getLogs('syslog')

Crash/panic reports + system diagnostics

Note: Reading this resource clears the log buffer (per the WebDriver spec). Subsequent reads return only entries accumulated since the last read. Browser logs require Chromium (Chrome/Edge) — Firefox and Safari do not support the getLogs command.

The response is JSON with sessionType, logTypes (available log types), and entries — each entry includes level, message, timestamp (Unix ms), and timestampISO.

Troubleshooting

Browser automation not working?

  • Ensure Chrome, Firefox, Edge, or Safari is installed (Safari requires macOS)

  • Try restarting Claude Desktop completely

  • Check that no other WebDriver instances are running

Mobile automation not working?

  • Verify Appium server is running: appium

  • Check device/emulator is running: adb devices (Android) or Xcode Devices (iOS)

  • Ensure correct platform drivers are installed

  • Verify app path is correct and accessible

Found issues or have suggestions? Please share your feedback!

Available Tools

17 tools
click_elementA

Clicks an element. On web pages the result lists what changed (new elements with refs, or the new page). In apps it does not: take a snapshot to see the new screen. Several steps in a row: perform_actions.

NameRequiredDescriptionDefault
sessionNoTarget session: map name or sessionId. Omit to use the default session.
selectorYesRef from snapshot (e12) or selector: CSS, XPath, "button=Exact text", "a*=Partial text"

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare destructiveHint=false, so the description carries most of the burden and does it well: it discloses that on web pages the result lists what changed (new elements with refs or the new page), while in apps it returns nothing useful and a snapshot is needed. This is genuinely non-obvious behavior an agent could not infer from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action and each carrying distinct information (web result, app behavior, batching alternative). The telegraphic phrasing ("In apps it does not") is efficient but slightly terse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly explains what comes back on web vs app, which is the key gap an agent would otherwise hit. Missing only minor details like failure behavior for stale refs or selector-not-found cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters (session, selector) are already documented, including the ref/CSS/XPath/text selector formats. The description adds no additional meaning about parameter usage, which matches the baseline 3 when the schema does the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Clicks an element") and implies differentiation from snapshot and perform_actions. It doesn't explicitly say what it is NOT (e.g. vs set_value or select_option for input fields), so it stops short of full sibling disambiguation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives actionable routing: use perform_actions for several steps in a row, and take a snapshot in apps to observe the resulting screen. No exclusions for when clicking is the wrong choice (e.g. typing into fields), so it is clear context but not complete when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

close_sessionA
Destructive

Closes the session, or with detach: true disconnects and leaves it running. Attached sessions and Appium sessions with noReset are detached unless detach: false.

NameRequiredDescriptionDefault
detachNo
sessionNoTarget session: map name or sessionId. Omit to use the default session.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only flag destructiveHint=true; the description adds the important nuance that the operation may not destroy anything at all — with detach it disconnects and leaves the session running, and that is the default for attached and Appium noReset sessions. It stops short of describing what state is lost on a hard close or what the call returns.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with no filler; the primary action comes first and the conditional detach semantics follow. Every clause carries distinct information about behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter tool with only a destructiveHint annotation and no output schema, the description covers the non-obvious branch (detach defaults and override) well. Minor gaps remain around what a hard close discards, but nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: the session parameter is documented in the schema, but detach is a bare boolean with no schema description. The description fully compensates by defining both values of detach, its default per session type, and the explicit override.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Closes the session") and immediately qualifies it with the detach variant, so the agent knows exactly what the tool does. It does not name the counterpart sibling start_session, which keeps it just short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete conditions governing the detach behavior: attached sessions and Appium sessions with noReset are detached by default, and detach: false overrides that. This tells the agent when the default differs from expectation, though it does not state when to call this versus leaving a session open or any other alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

enable_toolsA
Read-onlyIdempotent

Adds more tools: mocks (mock network requests or Electron APIs); cookies (read, set and delete cookies); device (emulate a phone or tablet, fake the location); extensions (install and open a browser extension); attach (launch Chrome with remote debugging, attach to a running WebDriver or Appium session); elements (raw element list with bounds); cloud-apps (upload and list mobile apps on BrowserStack, Sauce Labs, TestMu, TestingBot, Digital.ai).

NameRequiredDescriptionDefault
groupsYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description's word "Adds" implies session state mutation that the readOnly hint does not fully surface, and it never says whether enabling is cumulative, whether groups can be disabled, or whether the newly added tools become available immediately in the same turn. With annotations carrying the safety burden, a 3 is appropriate, but the session-scoping gap is real.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the action, then a semicolon-delimited list where each clause earns its place by defining a distinct selectable group. The density of the parenthetical run-on hurts scanability slightly, but there is no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description should say what happens after the call — whether the tools appear, whether the call is a no-op for already-enabled groups, and any session prerequisite. None of that is present. For a one-parameter enablement gate that other tools depend on, this leaves the agent guessing about call ordering.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the single `groups` parameter is an enum whose seven values the description explains in plain language ("device (emulate a phone or tablet, fake the location)"), which is exactly the meaning an agent needs to choose values. This is meaningful value beyond the bare enum list. It doesn't say how to select multiple groups or that at least one is required, leaving a small gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource pairing ("Adds more tools") and then enumerates each addable group with a one-line purpose, so an agent can tell exactly what capability is being unlocked. It is clearly distinct from every sibling in the list, which are all action tools on the current page/session. It stops short of stating that the mechanism is a `groups` argument, but the enumeration compensates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The per-group notes imply when to call it (you need mocking, cookies, device emulation, etc.), which is more than nothing. However, there is no explicit statement of the wrapper use case ("if a tool you need isn't available, enable its group first"), no guidance on calling it before vs. after session start, and no note about what happens if a group is already enabled.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

execute_scriptA

Runs JavaScript in the page (return a value; string args that match a selector are passed as elements) or, on Appium, a "mobile: " with args. Prefer the dedicated tools for clicks and typing.

NameRequiredDescriptionDefault
argsNoScript arguments, or the mobile command's parameters
scriptYesJavaScript, or "mobile: <command>" on Appium
sessionNoTarget session: map name or sessionId. Omit to use the default session.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare destructiveHint=false, so the description carries most of the burden and delivers real behavior: the script may `return` a value, and string args matching a selector are auto-resolved to elements. The Appium command format is also disclosed. Missing: that this executes arbitrary code with the page's privileges and typically returns the script's return value only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both earning their place: the first defines the two execution modes and the return/argument behavior, the second gives the routing preference. Dense in the first sentence but front-loaded and free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by saying `return` a value is how results come back. Session targeting and arg mechanics are covered between schema and description. A brief note on error behavior or the privilege of arbitrary code execution would make it fully complete for a script-execution tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema coverage the baseline is 3, but the description adds semantics the schema lacks: the `script` string is JavaScript in web mode or a "mobile: <command>" in Appium, and string entries in `args` that match selectors are converted to elements. That coercion rule is not stated anywhere in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: runs JavaScript in the page, or a "mobile: <command>" on Appium. It also implicitly distinguishes itself from click_element/set_value by naming the dedicated alternatives, so an agent knows this is the escape-hatch execution tool rather than a UI interaction tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Prefer the dedicated tools for clicks and typing" explicitly routes the agent away from this tool for common interactions and establishes it as the fallback. It also splits usage between web (JS with return) and Appium (mobile: command) modes. It stops short of saying when script execution is actually warranted (e.g., reading page state not exposed by snapshot).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_screenshotA
Read-onlyIdempotent

Takes a screenshot of the current page or screen and returns a base64-encoded image, resized and compressed for model context limits.

NameRequiredDescriptionDefault
sessionNoTarget session: map name or sessionId. Omit to use the default session.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds genuinely useful behavior beyond that: the result is base64-encoded and already resized/compressed to fit model context limits, which tells the agent not to expect raw full-resolution output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-formed sentence that front-loads the action and then the return format. Every clause earns its place and nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With one optional parameter documented in the schema and no output schema, the description covers the essential points: what is captured and what comes back. It omits image format (PNG/JPEG) and roughly how much compression occurs, which would help an agent reason about output size, but nothing critical to calling it is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single optional 'session' parameter is fully documented in the schema, so the baseline is 3. The description adds no extra meaning about session targeting or what omitting it does (the schema already says it defaults to the default session).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ("takes a screenshot of the current page or screen") and adds the return shape (base64-encoded image, resized/compressed). It does not distinguish itself from the sibling 'snapshot' tool, so an agent cannot tell from this text alone which one to pick for visual vs. DOM capture.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the tool for capturing the current visual state. There is no explicit when-to-use/when-not, no routing to the closely related 'snapshot' sibling, and no mention that a session must be started first.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_tabsA
Read-onlyIdempotent

Lists all browser tabs with handle, title, URL, and which is active. Use before switch_tab to find the target handle or index. Browser-only.

NameRequiredDescriptionDefault
sessionNoTarget session: map name or sessionId. Omit to use the default session.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint, so safety is covered. The description adds useful context by specifying the return payload and the browser-only constraint, though it says nothing about pagination or limits on large tab sets.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, zero waste, with the core purpose and return fields front-loaded ahead of the workflow guidance and scope note.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description compensates by listing the returned fields. Combined with the pre-switch_tab workflow note and browser-only scope, an agent has everything needed to call it and use the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and there is only one optional parameter, so the schema already documents the session targeting. The description adds nothing about session semantics beyond what the schema states, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Lists all browser tabs') and enumerates exactly what is returned: handle, title, URL, and active flag. This is clearly distinguishable from siblings like snapshot or get_screenshot.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly prescribes the workflow: 'Use before switch_tab to find the target handle or index', naming the alternative tool and the condition that selects it. The 'Browser-only' note also scopes when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

perform_actionsA

Runs several actions in one call, e.g. fill a form and submit it, on the page or app screen, and returns what each one changed on web pages. Steps the current session does not support are rejected before any step runs. Stops at the first failure, when a step loads a new page, or before a key press that follows a click, select, check or uncheck that changed the page (continue with the new refs). value is the text for fill, the option for select and the keys for press.

NameRequiredDescriptionDefault
actionsYes
sessionNoTarget session: map name or sessionId. Omit to use the default session.

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds substantial behavioral detail beyond the sparse annotations: unsupported steps are rejected before any step runs, execution stops at first failure or page-changing steps, and key presses after page-changing actions require new refs. It also explains that the tool returns what each action changed on web pages. No annotation contradiction is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and every sentence carries useful information about execution, stopping, or parameter meaning. The stopping-conditions sentence is dense but necessary for a batch tool; overall it is appropriately sized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex nested-action tool with no output schema, the description covers purpose, pre-validation, stopping semantics, and value meaning well. It does not describe the return shape or whether changes from earlier steps persist after a stop, which are minor remaining gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 50% schema description coverage, the description compensates by explaining that 'value' means text for fill, an option for select, and keys for press. It also clarifies selector refs through the stopping guidance, though it does not explain every nested field such as 'times' or the session parameter beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it runs several UI actions in one call, with an example of filling and submitting a form. It implicitly distinguishes itself from single-action siblings like click_element or set_value by emphasizing batching, though it does not name those alternatives explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'Runs several actions in one call' and the form-filling example, so an agent can infer this is for multi-step sequences. However, there is no explicit guidance on when to choose this tool over individual sibling tools such as click_element or press_key, nor any exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

press_keyA

Presses a key or combination in the focused element, e.g. Enter, Tab, Escape, Control+a. The result lists what changed on the page. Several steps in a row: perform_actions.

NameRequiredDescriptionDefault
keysYesKey or combination
timesNoPress it this many times, e.g. to move a slider
sessionNoTarget session: map name or sessionId. Omit to use the default session.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=false, and the description usefully adds that the result reports what changed on the page, which goes beyond the annotation. However, it says nothing about permission or focus requirements (what happens when no element is focused), which is the main behavioral risk for this action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, each doing distinct work: action, return behavior, and sibling routing. Nothing repeats the name or title and nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly fills the gap by stating the result lists page changes, and params are fully covered by the schema. The remaining gap is how focus is established before pressing (click_element/switch_frame), which an agent must infer.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds key-syntax meaning ('Control+a') that the schema's bare 'Key or combination' does not convey. The times and session parameters are left entirely to the schema, which is acceptable given full coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (presses a key or combination) plus the target scope (the focused element), and gives concrete examples like Enter, Tab, Control+a. It explicitly separates itself from perform_actions for multi-step sequences, so an agent can pick between them without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The line 'Several steps in a row: perform_actions' names the sibling and the condition that selects it, which is exactly the routing guidance an agent needs for short vs. chained input. It does not mention alternatives for text entry (e.g., set_value) or what to do if nothing is focused, so exclusions are only partially covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_docsA
Read-onlyIdempotent

Search the official WebdriverIO documentation and return the most relevant excerpts with page, section and source URL. Use before answering any question about WebdriverIO APIs, configuration, services, reporters, selectors, or debugging.

Query with 2-3 distinctive keywords, never a sentence: "appium setup", "devtools trace.zip" and "allure reporter" each return the right page first, while "how do I wire up appium in my config file" does not. A word can also collide with an unrelated page — wire matches Wire Protocol — so if a query misses, retry with the exact page title, which beats any paraphrase. Set fullPage for the whole page. To browse instead, read wdio://docs/index for every page title and its slug, then wdio://docs/page/{slug} for one page in full.

Cite the path of any page you rely on.

NameRequiredDescriptionDefault
limitNo
queryYes2-3 distinctive keywords: an API name, config key, page title or feature (e.g. "appium setup", "devtools trace.zip", "browserstack capabilities"). A sentence dilutes the ranking.
fullPageNoReturn the full matched pages instead of excerpts

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description goes well beyond annotations by explaining query sensitivity ('a sentence dilutes the ranking'), failure recovery ('retry with the exact page title'), the fullPage switch, and the browsing pseudo-URLs. It also specifies that results are excerpts with source URLs, giving the agent a clear behavioral model.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and return format, then moves to usage triggers and query examples. Every sentence adds operational value: query style, collision warning, retry strategy, fullPage, browsing alternative, and citation requirement. There is no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with no output schema, the description covers input format, expected output, edge cases, and an alternative browsing path. It tells the agent what to return (excerpts with path/section/URL) and how to cite pages. Nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%, with query and fullPage already described in the schema. The description adds valuable semantics for query formation (2-3 distinctive keywords, examples, page titles beat paraphrase) and reinforces fullPage behavior. The limit parameter is not covered in prose, but its schema constraints (default 5, min 1, max 20) are self-explanatory, so the gap is minor.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb (Search), resource (official WebdriverIO documentation), and return value (most relevant excerpts with page, section and source URL). It clearly distinguishes itself from the sibling tools, which are all device/session automation actions, by stating it is for documentation lookup before answering questions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Use before answering any question about WebdriverIO APIs, configuration, services, reporters, selectors, or debugging.' It also provides concrete query strategies, retry advice on word collisions, and an alternative browsing mode via wdio://docs/index and wdio://docs/page/{slug}. This is strong when-to-use and how-to-use guidance with no ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scrollA

Scrolls the page vertically by a pixel amount. Browser-only — for mobile scrolling use swipe. Only supports up/down; no horizontal scrolling.

NameRequiredDescriptionDefault
pixelsNoNumber of pixels to scroll
sessionNoTarget session: map name or sessionId. Omit to use the default session.
directionYesScroll direction

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare destructiveHint=false and a title; the description adds genuine behavioral context beyond that — that it is browser-only, limited to vertical direction, and by implication a viewport-state change rather than a data mutation. It does not describe what happens on scroll to boundary or return values, which keeps it from a 5, but it clearly fills gaps the annotations leave.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, zero filler, with the core action front-loaded followed by the scope constraints. Every clause carries distinct information — verb, unit, platform restriction, direction restriction — with nothing repeated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 3-param tool with a fully-described schema and no output schema, the description supplies the essential constraints an agent needs. The main residual gap is the reference to a non-sibling 'swipe' tool and the absence of edge-case behavior (e.g., scrolling past the page end), but overall it is sufficient to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with direction enum and pixel default already documented inline, so the schema carries the parameter burden. The description reinforces the vertical-only direction constraint and the pixel unit, adding marginal but non-redundant meaning. Baseline 3 is appropriate when the schema is fully documented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (scrolls), the resource (the page), and the unit of movement (vertical pixel amount). It explicitly delimits scope — vertical only, browser-only — so it is easily distinguished from interaction siblings like click_element or press_key. No ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names an explicit alternative with its condition: 'for mobile scrolling use swipe.' It also states the when-not condition for horizontal movement ('no horizontal scrolling'). It falls short of 5 because the referenced alternative (swipe) is not present among the listed sibling tools, so the routing advice points outside the available set.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

select_optionA

Selects an option of a by its text. The result lists what changed on the page. Several steps in a row: perform_actions.

NameRequiredDescriptionDefault
valueYesOption text
sessionNoTarget session: map name or sessionId. Omit to use the default session.
selectorYesRef from snapshot (e12) or selector of the <select>

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds useful behavioral context beyond the annotations: the result lists what changed on the page, which is valuable because there is no output schema. It also implicitly conveys a non-destructive interaction, consistent with destructiveHint=false, though it does not mention event side effects or authorization needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, each front-loaded with a distinct point: purpose, result behavior, and multi-step alternative. There is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple selection tool with full schema coverage and no output schema, the description covers the essential behavior and return context. It could be slightly richer about page-change side effects or when not to use it, but nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents selector, value, and session. The description adds only the phrase 'by its text' for the value parameter, which is already covered by the schema's 'Option text' description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: selecting an option of a <select> by its text. This clearly distinguishes it from siblings like click_element or set_value, which do not target a select option by text.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage guidance for chaining several steps by pointing to perform_actions. However, it does not explicitly state when to use this instead of set_value or click_element for similar interactions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_valueA
Idempotent

Replaces the text of an input or textarea. On web pages the result lists what changed (new elements with refs, or the new page). In apps it does not: take a snapshot to see the new screen. To fill several fields or fill and then click, use one perform_actions call.

NameRequiredDescriptionDefault
valueYesText to enter into the element
sessionNoTarget session: map name or sessionId. Omit to use the default session.
selectorYesRef from snapshot (e12) or selector: CSS, XPath, "button=Exact text", "a*=Partial text"

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only state idempotentHint=true and destructiveHint=false; the description adds real value by explaining that on web pages the result lists what changed (new elements with refs or the new page), while in apps it does not and a snapshot is required. That return-behavior divergence is exactly the kind of context an agent cannot infer from structured fields, though waiting/retry behavior is still unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, no padding, and the core action is stated first with routing guidance following. The second sentence ('In apps it does not') is slightly elliptical, requiring the reader to carry over 'lists what changed', but that is a minor cost.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates by describing what the response contains in each environment. Combined with the schema and annotations, an agent has everything needed to call this correctly and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so selector, value, and session are already fully documented in the schema. The description only indirectly reinforces the selector concept via 'new elements with refs' and adds no syntax or format detail beyond the schema, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: 'Replaces the text of an input or textarea.' It is immediately distinguishable from sibling tools like click_element or perform_actions, and the scope (text-entry elements) is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names the alternative explicitly ('use one perform_actions call') along with the condition that selects it ('To fill several fields or fill and then click'). It also directs the agent to snapshot when running in an app, so both routing decisions are spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

snapshotA
Read-onlyIdempotent

The page or app screen as an accessibility tree with refs, e.g. button "Save" [ref=e3]. Pass refs to perform_actions for several steps, or to click_element/set_value/select_option for one. Default: interactive elements only, plain text is dropped; full: true shows it. find returns only the parts of the page that contain the text (with their refs); full: true includes all text; viewport: true limits it to what is on screen (not together with find).

NameRequiredDescriptionDefault
findNoText to look for
fullNoInclude text, not just interactive elements
scopeNoOnly below this ref or selector
sessionNoTarget session: map name or sessionId. Omit to use the default session.
viewportNoOnly what is on screen

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds real behavioral detail beyond that: the default drops plain text and keeps only interactive elements, full:true restores it, and viewport cannot be combined with find. It doesn't say anything about output size or truncation on large pages.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded paragraph that opens with what the tool is and an example, then moves to how to use the refs. Dense but every clause carries information; only mild run-on density keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter read tool with full schema coverage, no annotations gap, and no output schema, the description supplies the output shape and mode interactions an agent needs. Session and scope behavior are left entirely to the schema, a minor remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline would be 3, but the description adds genuine semantics beyond the schema: 'find returns only the parts of the page that contain the text (with their refs)' and the exclusion between find and viewport are behavioral constraints the schema does not encode. scope and session are left to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states precisely what the tool returns — the page as an accessibility tree with refs — and includes a concrete output example (`button "Save" [ref=e3]`). It does not explicitly distinguish itself from get_screenshot or query_docs among the siblings, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It routes the agent downstream clearly: refs go to perform_actions for multi-step work, or to click_element/set_value/select_option for a single action. It also states the find+viewport incompatibility, but gives no guidance on when to prefer this over get_screenshot or query_docs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

start_sessionA

Starts a browser, Electron app or mobile app session (closes the active one unless onExisting: "keep"). Browsers run headless at 1280x800 by default; pass navigationUrl to open a page right away. attach: true connects to a running Chrome via CDP.

NameRequiredDescriptionDefault
osNoCloud browser OS, provider-native, passed as-is: BrowserStack "OS X"/"Windows", Sauce Labs and TestMu "macOS"/"Windows", TestingBot "SEQUOIA"/"WIN11"
appNoCloud app URL from upload_app (bs://, storage:filename=, lt://, tb://, cloud:<name>)
nameNoName for this session, unique among live sessions. Target it from other tools with session: <name>.
udidNoiOS real device UDID
traceNoSave a Playwright-compatible trace zip to .trace/ on close_session
attachNoAttach to a running Chrome (attachConfig, default localhost:9222)
regionNoSauce Labs onlyeu-central-1
tunnelNoCloud: true starts a tunnel, "external" uses a running one
appPathNoMobile: local .app/.apk/.ipa
browserNoRequired for platform browser
noResetNo
headlessNo
platformYes
providerNoDefault local. Cloud providers read credentials from env. external: a W3C WebDriver endpoint (webdriverConfig).local
fullResetNo
osVersionNoCloud browser OS version, provider-native: BrowserStack and TestMu "Sequoia", Sauce Labs "15", Windows "11"; omit for TestingBot
reportingNoCloud reporting labels
deviceNameNoMobile: device, emulator or simulator name (required)
onExistingNoclose (default) replaces the active session. keep is an explicit opt-in to run this session alongside the existing ones; the new session is NOT made the default when one exists, so target it with session: <name>.close
tunnelNameNo
deviceQueryNoDigital.ai mobile device query
networkLogsNoLocal Chromium performance log capture (default from WDIO_MCP_NETWORK_LOGS or "none")
testmuLocalNoDeprecated: tunnel
windowWidthNo
appiumConfigNoLocal Appium server
attachConfigNo
capabilitiesNoExtra capabilities to merge, e.g. "wdio:electronServiceOptions"
windowHeightNo
navigationUrlNoURL to open after starting
automationNameNo
browserVersionNoCloud only
saucelabsLocalNoDeprecated: tunnel
appWaitActivityNoAndroid launch activity to wait for
electronRootDirNoElectron: project root for Builder/Forge discovery
platformVersionNoMobile OS version, e.g. "17.0"
webdriverConfigNoprovider external only
autoAcceptAlertsNoMobile, default true
autoDismissAlertsNo
browserstackLocalNoDeprecated: tunnel
newCommandTimeoutNoAppium, seconds
autoGrantPermissionsNoMobile, default true
electronDeeplinkSchemeNoElectron: URI scheme (no ":") allowed for trigger_electron_deeplink

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide only destructiveHint: false, so the description carries most of the burden — and it does disclose the most dangerous behavior: the active session is closed unless onExisting: "keep". It also surfaces the headless 1280x800 default and the CDP attach mode. It does not cover cloud provider credential requirements (env-based per the schema) or what the tool returns, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, all front-loaded: core action, destructive side effect, then orientation for the two most confusing options. Nothing repeats the schema verbatim and no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 42-parameter, nested-object tool with almost no annotation coverage and no output schema, the description covers only the top gotchas. It omits the platform→required-parameter matrix, cloud credential prerequisites, and any hint of what a started session returns or how to address it afterward — gaps an agent will hit on a first call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 42 parameters at 76% schema description coverage, the schema already does most of the parameter work and baseline 3 applies. The description adds real meaning to the highest-risk flags (onExisting, attach, navigationUrl, headless/window defaults) but leaves the platform-conditional requirements — browser for platform browser, deviceName for mobile — entirely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb + resource ('Starts a browser, Electron app or mobile app session'), and its role as the counterpart to close_session is unambiguous. The three supported platforms are named. It stops short of naming sibling alternatives (navigate, close_session), so it lands at 4 rather than 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated — an agent infers this is the entry point before navigate/click_element/etc., and gets concrete guidance for navigationUrl and attach. There is no explicit 'call this first' instruction and no discussion of when a session is already live versus not, so guidance is contextual rather than directive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

switch_frameA
Idempotent

Switches into an iframe (ref or selector), or back to the top page when selector is omitted. Later tools act inside the frame until you switch back. Returns the frame's elements.

NameRequiredDescriptionDefault
sessionNoTarget session: map name or sessionId. Omit to use the default session.
selectorNoRef or selector of the iframe; omit for the top page

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare idempotency and non-destructiveness; the description adds the important stateful behavior that subsequent tools operate inside the frame until switched back, and that the frame's elements are returned. That is real context beyond the structured fields, though auth/pagination/error behavior is unmentioned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences, front-loaded with the core action and followed by the two facts an agent needs (scoping persistence and return value). No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With only two params and no output schema, the description covers the action, the return value ('the frame's elements'), and the stateful implication of the switch. Nothing critical is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are already documented. The description restates the 'ref or selector' and omit-for-top-page semantics, adding little beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (switches) and resource (iframe), plus the dual mode: enter a frame or return to the top page. The iframe framing distinguishes it from switch_tab implicitly, though it never names that sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear conditional ('omit selector to return to the top page') and the persistence rule ('later tools act inside the frame until you switch back'), which is genuinely usable guidance. It does not, however, explicitly contrast with switch_tab or say when frame switching is unnecessary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

switch_tabA
Idempotent

Switches to a tab by handle or 0-based index (see get_tabs). Later tools act on that tab.

NameRequiredDescriptionDefault
indexNo0-based tab index to switch to
handleNoWindow handle to switch to
sessionNoTarget session: map name or sessionId. Omit to use the default session.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare idempotentHint=true and destructiveHint=false, so safety is covered. The description adds genuine value by disclosing the persistent side effect that subsequent tools operate on the switched tab, but says nothing about behavior when neither index nor handle is supplied or what happens to the previously active tab.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and target, with no filler. The downstream-effect note is placed immediately after the action statement where it is most useful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a small, annotation-covered tool this is close to sufficient, but all three parameters are optional and the description never explains what happens with no arguments given — a real ambiguity for an agent deciding whether it must supply index or handle.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3, and the description adds the either/or framing (by handle OR by index) plus a pointer to get_tabs as the source of handles, which the schema does not state. It says nothing about the optional session parameter, but that is documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (switches) and resource (tab) with the two addressing modes, and cross-references get_tabs. It does not explicitly contrast with the sibling switch_frame, so an agent must infer tab-vs-frame distinction from the names alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Later tools act on that tab" tells the agent this is a setup step that must precede other browser actions, and "see get_tabs" points at how to obtain valid targets. It stops short of stating when not to use it (e.g., when already on the target tab) or how it differs from switch_frame.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 15 tool updatesv4.1.0
    • Changedclick_element1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedclose_session1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedexecute_script1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedget_screenshot1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedget_tabs1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changednavigate1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedperform_actions1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedpress_key1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedscroll1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedselect_option1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedset_value1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedsnapshot1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedstart_session6 fields changed
      • changedInput schema / properties / app / description
        Previous value: -"Cloud app URL from upload_app (bs://, storage:filename=, lt://, tb://, cloud:<id>)"New value: +"Cloud app URL from upload_app (bs://, storage:filename=, lt://, tb://, cloud:<name>)"
      • addedInput schema / properties / name
        Added value: +{
        +  "description": "Name for this session, unique among live sessions. Target it from other tools with session: <name>.",
        +  "minLength": 1,
        +  "type": "string"
        +}
      • addedInput schema / properties / networkLogs
        Added value: +{
        +  "description": "Local Chromium performance log capture (default from WDIO_MCP_NETWORK_LOGS or \"none\")",
        +  "enum": [
        +    "none",
        +    "failures",
        +    "all"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / onExisting
        Added value: +{
        +  "default": "close",
        +  "description": "close (default) replaces the active session. keep is an explicit opt-in to run this session alongside the existing ones; the new session is NOT made the default when one exists, so target it with session: <name>.",
        +  "enum": [
        +    "close",
        +    "keep"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / os / description
        Previous value: -"Cloud browser OS, e.g. \"Windows\", \"macOS\""New value: +"Cloud browser OS, provider-native, passed as-is: BrowserStack \"OS X\"/\"Windows\", Sauce Labs and TestMu \"macOS\"/\"Windows\", TestingBot \"SEQUOIA\"/\"WIN11\""
      • changedInput schema / properties / osVersion / description
        Previous value: -"Cloud browser OS version, e.g. \"11\", \"Sequoia\""New value: +"Cloud browser OS version, provider-native: BrowserStack and TestMu \"Sequoia\", Sauce Labs \"15\", Windows \"11\"; omit for TestingBot"
    • Changedswitch_frame1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
    • Changedswitch_tab1 field changed
      • addedInput schema / properties / session
        Added value: +{
        +  "description": "Target session: map name or sessionId. Omit to use the default session.",
        +  "type": "string"
        +}
  2. 36 tool updatesv4.0.1
    • Removedattach_session
    • Changedclick_element3 fields changed
      • removedInput schema / properties / scrollToView
        Removed value: -{
        -  "description": "Whether to scroll the element into view before clicking",
        -  "type": "boolean"
        -}
      • changedInput schema / properties / selector / description
        Previous value: -"Value for the selector, in the form of css selector or xpath (\"button.my-class\" or \"//button[@class='my-class']\" or \"button=Exact text with spaces\" or \"a*=Link containing text\")"New value: +"Ref from snapshot (e12) or selector: CSS, XPath, \"button=Exact text\", \"a*=Partial text\""
      • removedInput schema / properties / timeout
        Removed value: -{
        -  "description": "Maximum time to wait for element in milliseconds",
        -  "type": "number"
        -}
    • Changedclose_session1 field changed
      • removedInput schema / properties / detach / description
        Removed value: -"If true, disconnect without terminating; if false, terminate. When omitted, externally managed and auto-detach sessions are preserved while other sessions are terminated."
    • Removeddelete_cookies
    • Removeddrag_and_drop
    • Removedemulate_device
    • Addedenable_tools
    • Removedexecute_electron_script
    • Changedexecute_script2 fields changed
      • changedInput schema / properties / args / description
        Previous value: -"Arguments to pass to the script. For browser: element selectors or values. For mobile commands: command-specific parameters as objects."New value: +"Script arguments, or the mobile command's parameters"
      • changedInput schema / properties / script / description
        Previous value: -"JavaScript code (browser) or mobile command string like \"mobile: pressKey\" (Appium)"New value: +"JavaScript, or \"mobile: <command>\" on Appium"
    • Removedget_accessibility_tree
    • Removedget_app_state
    • Removedget_contexts
    • Removedget_cookies
    • Removedget_elements
    • Removedget_mock_calls
    • Removedhide_keyboard
    • Removedlaunch_chrome
    • Removedlist_apps
    • Removedmanage_mock
    • Removedmock
    • Removedopen_web_extension
    • Addedperform_actions
    • Addedpress_key
    • Removedrotate_device
    • Addedselect_option
    • Removedset_cookie
    • Removedset_geolocation
    • Changedset_value3 fields changed
      • removedInput schema / properties / scrollToView
        Removed value: -{
        -  "description": "Whether to scroll the element into view before typing",
        -  "type": "boolean"
        -}
      • changedInput schema / properties / selector / description
        Previous value: -"Value for the selector, in the form of css selector or xpath (\"button.my-class\" or \"//button[@class='my-class']\")"New value: +"Ref from snapshot (e12) or selector: CSS, XPath, \"button=Exact text\", \"a*=Partial text\""
      • removedInput schema / properties / timeout
        Removed value: -{
        -  "description": "Maximum time to wait for element in milliseconds",
        -  "type": "number"
        -}
    • Addedsnapshot
    • Changedstart_session41 fields changed
      • changedInput schema / properties / app / description
        Previous value: -"App URL (bs://... for BrowserStack, storage:filename= for Sauce Labs, lt://... for TestMu, tb://... for TestingBot, cloud:<package-or-bundle> for Digital.ai mobile sessions)"New value: +"Cloud app URL from upload_app (bs://, storage:filename=, lt://, tb://, cloud:<id>)"
      • changedInput schema / properties / appPath / description
        Previous value: -"Path to app file (.app/.apk/.ipa)"New value: +"Mobile: local .app/.apk/.ipa"
      • changedInput schema / properties / appWaitActivity / description
        Previous value: -"Activity to wait for on Android launch"New value: +"Android launch activity to wait for"
      • changedInput schema / properties / appiumConfig / description
        Previous value: -"Appium server connection (local provider only)"New value: +"Local Appium server"
      • changedInput schema / properties / attach / description
        Previous value: -"Attach to existing Chrome instead of launching"New value: +"Attach to a running Chrome (attachConfig, default localhost:9222)"
      • removedInput schema / properties / attachConfig / description
        Removed value: -"Chrome remote debugging connection (attach mode only, defaults: port 9222, host localhost)"
      • changedInput schema / properties / autoAcceptAlerts / description
        Previous value: -"Auto-accept alerts (default: true)"New value: +"Mobile, default true"
      • removedInput schema / properties / autoDismissAlerts / description
        Removed value: -"Auto-dismiss alerts (default: false)"
      • changedInput schema / properties / autoGrantPermissions / description
        Previous value: -"Auto-grant app permissions (default: true)"New value: +"Mobile, default true"
      • removedInput schema / properties / automationName / description
        Removed value: -"Automation driver"
      • changedInput schema / properties / browser / description
        Previous value: -"Browser to launch (required for browser platform)"New value: +"Required for platform browser"
      • changedInput schema / properties / browserVersion / description
        Previous value: -"Browser version (cloud providers only, default: latest)"New value: +"Cloud only"
      • changedInput schema / properties / browserstackLocal / description
        Previous value: -"Deprecated: use \"tunnel\" instead. Enable BrowserStack Local tunnel routing."New value: +"Deprecated: tunnel"
      • changedInput schema / properties / capabilities / description
        Previous value: -"Additional capabilities to merge. For Electron, configure the official service under \"wdio:electronServiceOptions\" (for example appBinaryPath, appEntryPoint, appArgs, logDir, or captureRendererLogs)."New value: +"Extra capabilities to merge, e.g. \"wdio:electronServiceOptions\""
      • changedInput schema / properties / deviceName / description
        Previous value: -"Mobile device/emulator/simulator name (required for ios/android)"New value: +"Mobile: device, emulator or simulator name (required)"
      • changedInput schema / properties / deviceQuery / description
        Previous value: -"Digital.ai device selection query for dynamic allocation, e.g. \"@os='android' and @version='14' and @name='.*Pixel.*'\". Only used with provider: \"digitalai\" mobile sessions; if omitted, one is built from deviceName/platformVersion."New value: +"Digital.ai mobile device query"
      • changedInput schema / properties / electronDeeplinkScheme / description
        Previous value: -"URI scheme allowed by trigger_electron_deeplink, without \":\" (for example, \"myapp\"). Electron-only and optional unless triggering deeplinks."New value: +"Electron: URI scheme (no \":\") allowed for trigger_electron_deeplink"
      • changedInput schema / properties / electronRootDir / description
        Previous value: -"Project root used by the Electron standalone service for Electron Builder/Electron Forge discovery. Electron-only."New value: +"Electron: project root for Builder/Forge discovery"
      • removedInput schema / properties / fullReset / description
        Removed value: -"Uninstall app before/after session"
      • removedInput schema / properties / headless / description
        Removed value: -"Run browser in headless mode (default: true)"
      • changedInput schema / properties / navigationUrl / description
        Previous value: -"URL to navigate to after starting"New value: +"URL to open after starting"
      • changedInput schema / properties / newCommandTimeout / description
        Previous value: -"Appium command timeout in seconds"New value: +"Appium, seconds"
      • removedInput schema / properties / noReset / description
        Removed value: -"Preserve app data between sessions"
      • changedInput schema / properties / os / description
        Previous value: -"Operating system for cloud provider browser sessions (e.g. \"Windows\", \"Mac\", \"macOS\", \"Linux\"). BrowserStack: sets bstack:options.os separately. TestMu/Sauce Labs/TestingBot: combined with osVersion into W3C platformName. Digital.ai: combined with osVersion into the digitalai:osName capability (e.g. \"Mac OS Sequoia\", \"Windows 10\") — required for the grid to match a node. Browser platform only."New value: +"Cloud browser OS, e.g. \"Windows\", \"macOS\""
      • changedInput schema / properties / osVersion / description
        Previous value: -"OS version for cloud provider browser sessions (e.g. \"11\", \"15\", \"Monterey\"). BrowserStack: sets bstack:options.osVersion separately. TestMu/Sauce Labs/TestingBot: combined with os into W3C platformName. Digital.ai: combined with os into digitalai:osName. Browser platform only."New value: +"Cloud browser OS version, e.g. \"11\", \"Sequoia\""
      • removedInput schema / properties / platform / description
        Removed value: -"Session platform type"
      • changedInput schema / properties / platformVersion / description
        Previous value: -"OS version for mobile sessions (e.g., \"17.0\", \"14\"). Mobile (ios/android) only."New value: +"Mobile OS version, e.g. \"17.0\""
      • changedInput schema / properties / provider / description
        Previous value: -"Session provider (default: local). Use \"external\" to connect to an externally managed W3C WebDriver endpoint. \"digitalai\" requires DIGITALAI_CLOUD_URL + DIGITALAI_ACCESS_KEY env vars."New value: +"Default local. Cloud providers read credentials from env. external: a W3C WebDriver endpoint (webdriverConfig)."
      • changedInput schema / properties / region / description
        Previous value: -"Sauce Labs region (default: eu-central-1). Only used with provider: \"saucelabs\"."New value: +"Sauce Labs only"
      • changedInput schema / properties / reporting / description
        Previous value: -"Cloud provider reporting labels (project, build, session)"New value: +"Cloud reporting labels"
      • changedInput schema / properties / saucelabsLocal / description
        Previous value: -"Deprecated: use \"tunnel\" instead. Enable Sauce Connect tunnel routing."New value: +"Deprecated: tunnel"
      • changedInput schema / properties / testmuLocal / description
        Previous value: -"Deprecated: use \"tunnel\" instead. Enable TestMu Tunnel routing."New value: +"Deprecated: tunnel"
      • changedInput schema / properties / trace / description
        Previous value: -"Enable trace recording — produces a Playwright-compatible zip saved to .trace/ on close_session, playable at player.vibium.dev."New value: +"Save a Playwright-compatible trace zip to .trace/ on close_session"
      • changedInput schema / properties / tunnel / description
        Previous value: -"Enable local tunnel routing (cloud providers only, default: false). true = auto-start tunnel before session and stop on close. \"external\" = tunnel already running externally."New value: +"Cloud: true starts a tunnel, \"external\" uses a running one"
      • removedInput schema / properties / tunnelName / description
        Removed value: -"Tunnel identifier name. With tunnel: \"external\" this must match the running tunnel. With tunnel: true a unique name is auto-generated if not provided."
      • changedInput schema / properties / udid / description
        Previous value: -"Unique Device Identifier for iOS real device"New value: +"iOS real device UDID"
      • changedInput schema / properties / webdriverConfig / description
        Previous value: -"Existing W3C WebDriver endpoint connection (provider: \"external\" only). Defaults to 127.0.0.1:4445/."New value: +"provider external only"
      • changedInput schema / properties / windowHeight / default
        Previous value: -1080New value: +800
      • removedInput schema / properties / windowHeight / description
        Removed value: -"Browser window height"
      • changedInput schema / properties / windowWidth / default
        Previous value: -1920New value: +1280
      • removedInput schema / properties / windowWidth / description
        Removed value: -"Browser window width"
    • Removedswipe
    • Removedswitch_context
    • Changedswitch_frame1 field changed
      • changedInput schema / properties / selector / description
        Previous value: -"CSS/XPath selector for the iframe element. Omit to switch back to the top-level frame."New value: +"Ref or selector of the iframe; omit for the top page"
    • Removedtap_element
    • Removedtrigger_electron_deeplink
    • Removedupload_app
  3. 4 tool updatesv3.14.0
    • Changedget_mock_calls3 fields changed
      • addedInput schema / properties / method
        Added value: +{
        +  "description": "Optional for mockType browser: request method filter, such as get.",
        +  "type": "string"
        +}
      • changedInput schema / properties / mockType / description
        Previous value: -"Mock type: electron or browser. Defaults to browser in WebDriver sessions; required in Electron sessions. Browser mocking is not implemented yet. Appium sessions are unsupported."New value: +"Mock type: electron or browser. Defaults to browser in WebDriver sessions; required in Electron sessions. Browser mocks intercept network requests by url glob and require a BiDi-enabled session (start_session with capabilities: { webSocketUrl: true }); in Electron sessions they additionally require the session to have negotiated BiDi. Electron mocks require apiName and funcName. Appium sessions are unsupported."
      • addedInput schema / properties / url
        Added value: +{
        +  "description": "Required for mockType browser: URL glob to intercept, such as **/api/todos.",
        +  "minLength": 1,
        +  "type": "string"
        +}
    • Changedmanage_mock3 fields changed
      • addedInput schema / properties / method
        Added value: +{
        +  "description": "Optional for mockType browser: request method filter, such as get.",
        +  "type": "string"
        +}
      • changedInput schema / properties / mockType / description
        Previous value: -"Mock type: electron or browser. Defaults to browser in WebDriver sessions; required in Electron sessions. Browser mocking is not implemented yet. Appium sessions are unsupported."New value: +"Mock type: electron or browser. Defaults to browser in WebDriver sessions; required in Electron sessions. Browser mocks intercept network requests by url glob and require a BiDi-enabled session (start_session with capabilities: { webSocketUrl: true }); in Electron sessions they additionally require the session to have negotiated BiDi. Electron mocks require apiName and funcName. Appium sessions are unsupported."
      • addedInput schema / properties / url
        Added value: +{
        +  "description": "Required for mockType browser: URL glob to intercept, such as **/api/todos.",
        +  "minLength": 1,
        +  "type": "string"
        +}
    • Changedmock8 fields changed
      • changedInput schema / properties / behavior / description
        Previous value: -"Default: mockReturnValue. Once behaviors queue a value for the next call."New value: +"Default: mockReturnValue for electron mocks; omit for browser mocks to passively record matching requests without altering them. Once behaviors apply to the next request only."
      • changedInput schema / properties / behavior / enum
        Previous value: -[
        -  "mockReturnValue",
        -  "mockReturnValueOnce",
        -  "mockResolvedValue",
        -  "mockResolvedValueOnce",
        -  "mockRejectedValue",
        -  "mockRejectedValueOnce"
        -]New value: +[
        +  "mockReturnValue",
        +  "mockReturnValueOnce",
        +  "mockResolvedValue",
        +  "mockResolvedValueOnce",
        +  "mockRejectedValue",
        +  "mockRejectedValueOnce",
        +  "respond",
        +  "respondOnce",
        +  "abort",
        +  "abortOnce",
        +  "redirect",
        +  "redirectOnce"
        +]
      • addedInput schema / properties / headers
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "description": "Browser respond behaviors: response header overrides.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / method
        Added value: +{
        +  "description": "Optional for mockType browser: request method filter, such as get.",
        +  "type": "string"
        +}
      • changedInput schema / properties / mockType / description
        Previous value: -"Mock type: electron or browser. Defaults to browser in WebDriver sessions; required in Electron sessions. Browser mocking is not implemented yet. Appium sessions are unsupported."New value: +"Mock type: electron or browser. Defaults to browser in WebDriver sessions; required in Electron sessions. Browser mocks intercept network requests by url glob and require a BiDi-enabled session (start_session with capabilities: { webSocketUrl: true }); in Electron sessions they additionally require the session to have negotiated BiDi. Electron mocks require apiName and funcName. Appium sessions are unsupported."
      • addedInput schema / properties / statusCode
        Added value: +{
        +  "description": "Browser respond behaviors: response status code override.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedInput schema / properties / url
        Added value: +{
        +  "description": "Required for mockType browser: URL glob to intercept, such as **/api/todos.",
        +  "minLength": 1,
        +  "type": "string"
        +}
      • changedInput schema / properties / value / description
        Previous value: -"JSON value to return, resolve, or reject with. Omit for undefined."New value: +"JSON value to return, resolve, or reject with. Browser respond behaviors use it as the required response body, redirect behaviors as the target URL string; omit it for abort or observing."
    • Addedquery_docs
  4. 3 tool updatesv3.13.0
    • Addedget_mock_calls
    • Addedmanage_mock
    • Addedmock
  5. 14 tool updatesv3.12.0
    • Changedattach_session1 field changed
      • changedInput schema / properties / platform / description
        Previous value: -"Existing session platform type"New value: +"Existing session platform type (browser, ios, or android; Electron attachment is unsupported)."
    • Addedclick_element
    • Addedexecute_electron_script
    • Addedget_app_state
    • Addedget_screenshot
    • Addedhide_keyboard
    • Addedlist_apps
    • Addedrotate_device
    • Addedset_cookie
    • Addedset_geolocation
    • Changedstart_session4 fields changed
      • changedInput schema / properties / capabilities / description
        Previous value: -"Additional capabilities to merge"New value: +"Additional capabilities to merge. For Electron, configure the official service under \"wdio:electronServiceOptions\" (for example appBinaryPath, appEntryPoint, appArgs, logDir, or captureRendererLogs)."
      • addedInput schema / properties / electronDeeplinkScheme
        Added value: +{
        +  "description": "URI scheme allowed by trigger_electron_deeplink, without \":\" (for example, \"myapp\"). Electron-only and optional unless triggering deeplinks.",
        +  "pattern": "^[A-Za-z][A-Za-z0-9+.-]*$",
        +  "type": "string"
        +}
      • addedInput schema / properties / electronRootDir
        Added value: +{
        +  "description": "Project root used by the Electron standalone service for Electron Builder/Electron Forge discovery. Electron-only.",
        +  "minLength": 1,
        +  "type": "string"
        +}
      • changedInput schema / properties / platform / enum
        Previous value: -[
        -  "browser",
        -  "ios",
        -  "android"
        -]New value: +[
        +  "browser",
        +  "electron",
        +  "ios",
        +  "android"
        +]
    • Addedswipe
    • Addedtap_element
    • Addedtrigger_electron_deeplink
  6. 22 tool updatesv3.11.1
    • Addedattach_session
    • Addedclose_session
    • Addeddelete_cookies
    • Addeddrag_and_drop
    • Addedemulate_device
    • Addedexecute_script
    • Addedget_accessibility_tree
    • Addedget_contexts
    • Addedget_cookies
    • Addedget_elements
    • Addedget_tabs
    • Addedlaunch_chrome
    • Addednavigate
    • Addedopen_web_extension
    • Addedscroll
    • Removedset_cookie
    • Addedset_value
    • Addedstart_session
    • Addedswitch_context
    • Addedswitch_frame
    • Addedswitch_tab
    • Addedupload_app
  7. 29 tool updatesv3.11.0
    • Removedclick_element
    • Removedclose_session
    • Removeddelete_cookies
    • Removeddrag_and_drop
    • Removedemulate_device
    • Removedexecute_script
    • Removedget_accessibility_tree
    • Removedget_app_state
    • Removedget_contexts
    • Removedget_cookies
    • Removedget_elements
    • Removedget_screenshot
    • Removedget_tabs
    • Removedhide_keyboard
    • Removedlaunch_chrome
    • Removedlist_apps
    • Removednavigate
    • Removedopen_web_extension
    • Removedrotate_device
    • Removedscroll
    • Removedset_geolocation
    • Removedset_value
    • Removedstart_session
    • Removedswipe
    • Removedswitch_context
    • Removedswitch_frame
    • Removedswitch_tab
    • Removedtap_element
    • Removedupload_app
  8. 1 tool updatev3.10.1
    • Changedstart_session3 fields changed
      • changedInput schema / properties / provider / description
        Previous value: -"Session provider (default: local). \"digitalai\" requires DIGITALAI_CLOUD_URL + DIGITALAI_ACCESS_KEY env vars."New value: +"Session provider (default: local). Use \"external\" to connect to an externally managed W3C WebDriver endpoint. \"digitalai\" requires DIGITALAI_CLOUD_URL + DIGITALAI_ACCESS_KEY env vars."
      • changedInput schema / properties / provider / enum
        Previous value: -[
        -  "local",
        -  "browserstack",
        -  "saucelabs",
        -  "testmu",
        -  "testingbot",
        -  "digitalai"
        -]New value: +[
        +  "local",
        +  "browserstack",
        +  "saucelabs",
        +  "testmu",
        +  "testingbot",
        +  "digitalai",
        +  "external"
        +]
      • addedInput schema / properties / webdriverConfig
        Added value: +{
        +  "description": "Existing W3C WebDriver endpoint connection (provider: \"external\" only). Defaults to 127.0.0.1:4445/.",
        +  "properties": {
        +    "hostname": {
        +      "default": "127.0.0.1",
        +      "type": "string"
        +    },
        +    "path": {
        +      "default": "/",
        +      "type": "string"
        +    },
        +    "port": {
        +      "default": 4445,
        +      "type": "number"
        +    },
        +    "protocol": {
        +      "default": "http",
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
  9. 4 tool updatesv3.9.0
    • Changedlist_apps1 field changed
      • changedInput schema / properties / provider / enum
        Previous value: -[
        -  "browserstack",
        -  "saucelabs",
        -  "testmu",
        -  "testingbot"
        -]New value: +[
        +  "browserstack",
        +  "saucelabs",
        +  "testmu",
        +  "testingbot",
        +  "digitalai"
        +]
    • Addedopen_web_extension
    • Changedstart_session6 fields changed
      • changedInput schema / properties / app / description
        Previous value: -"App URL (bs://... for BrowserStack, storage:filename= for Sauce Labs, lt://... for TestMu, tb://... for TestingBot mobile sessions)"New value: +"App URL (bs://... for BrowserStack, storage:filename= for Sauce Labs, lt://... for TestMu, tb://... for TestingBot, cloud:<package-or-bundle> for Digital.ai mobile sessions)"
      • addedInput schema / properties / deviceQuery
        Added value: +{
        +  "description": "Digital.ai device selection query for dynamic allocation, e.g. \"@os='android' and @version='14' and @name='.*Pixel.*'\". Only used with provider: \"digitalai\" mobile sessions; if omitted, one is built from deviceName/platformVersion.",
        +  "type": "string"
        +}
      • changedInput schema / properties / os / description
        Previous value: -"Operating system for cloud provider browser sessions (e.g. \"Windows\", \"Mac\", \"macOS\", \"Linux\"). BrowserStack: sets bstack:options.os separately. TestMu/Sauce Labs/TestingBot: combined with osVersion into W3C platformName. Browser platform only."New value: +"Operating system for cloud provider browser sessions (e.g. \"Windows\", \"Mac\", \"macOS\", \"Linux\"). BrowserStack: sets bstack:options.os separately. TestMu/Sauce Labs/TestingBot: combined with osVersion into W3C platformName. Digital.ai: combined with osVersion into the digitalai:osName capability (e.g. \"Mac OS Sequoia\", \"Windows 10\") — required for the grid to match a node. Browser platform only."
      • changedInput schema / properties / osVersion / description
        Previous value: -"OS version for cloud provider browser sessions (e.g. \"11\", \"15\", \"Monterey\"). BrowserStack: sets bstack:options.osVersion separately. TestMu/Sauce Labs/TestingBot: combined with os into W3C platformName. Browser platform only."New value: +"OS version for cloud provider browser sessions (e.g. \"11\", \"15\", \"Monterey\"). BrowserStack: sets bstack:options.osVersion separately. TestMu/Sauce Labs/TestingBot: combined with os into W3C platformName. Digital.ai: combined with os into digitalai:osName. Browser platform only."
      • changedInput schema / properties / provider / description
        Previous value: -"Session provider (default: local)"New value: +"Session provider (default: local). \"digitalai\" requires DIGITALAI_CLOUD_URL + DIGITALAI_ACCESS_KEY env vars."
      • changedInput schema / properties / provider / enum
        Previous value: -[
        -  "local",
        -  "browserstack",
        -  "saucelabs",
        -  "testmu",
        -  "testingbot"
        -]New value: +[
        +  "local",
        +  "browserstack",
        +  "saucelabs",
        +  "testmu",
        +  "testingbot",
        +  "digitalai"
        +]
    • Changedupload_app1 field changed
      • changedInput schema / properties / provider / enum
        Previous value: -[
        -  "browserstack",
        -  "saucelabs",
        -  "testmu",
        -  "testingbot"
        -]New value: +[
        +  "browserstack",
        +  "saucelabs",
        +  "testmu",
        +  "testingbot",
        +  "digitalai"
        +]
  10. 3 tool updatesv3.7.0
    • Changedlist_apps1 field changed
      • changedInput schema / properties / provider / enum
        Previous value: -[
        -  "browserstack",
        -  "saucelabs",
        -  "testmu"
        -]New value: +[
        +  "browserstack",
        +  "saucelabs",
        +  "testmu",
        +  "testingbot"
        +]
    • Changedstart_session4 fields changed
      • changedInput schema / properties / app / description
        Previous value: -"App URL (bs://... for BrowserStack, storage:filename= for Sauce Labs, lt://... for TestMu mobile sessions)"New value: +"App URL (bs://... for BrowserStack, storage:filename= for Sauce Labs, lt://... for TestMu, tb://... for TestingBot mobile sessions)"
      • changedInput schema / properties / os / description
        Previous value: -"Operating system for cloud provider browser sessions (e.g. \"Windows\", \"Mac\", \"macOS\", \"Linux\"). BrowserStack: sets bstack:options.os separately. TestMu/Sauce Labs: combined with osVersion into W3C platformName. Browser platform only."New value: +"Operating system for cloud provider browser sessions (e.g. \"Windows\", \"Mac\", \"macOS\", \"Linux\"). BrowserStack: sets bstack:options.os separately. TestMu/Sauce Labs/TestingBot: combined with osVersion into W3C platformName. Browser platform only."
      • changedInput schema / properties / osVersion / description
        Previous value: -"OS version for cloud provider browser sessions (e.g. \"11\", \"15\", \"Monterey\"). BrowserStack: sets bstack:options.osVersion separately. TestMu/Sauce Labs: combined with os into W3C platformName. Browser platform only."New value: +"OS version for cloud provider browser sessions (e.g. \"11\", \"15\", \"Monterey\"). BrowserStack: sets bstack:options.osVersion separately. TestMu/Sauce Labs/TestingBot: combined with os into W3C platformName. Browser platform only."
      • changedInput schema / properties / provider / enum
        Previous value: -[
        -  "local",
        -  "browserstack",
        -  "saucelabs",
        -  "testmu"
        -]New value: +[
        +  "local",
        +  "browserstack",
        +  "saucelabs",
        +  "testmu",
        +  "testingbot"
        +]
    • Changedupload_app1 field changed
      • changedInput schema / properties / provider / enum
        Previous value: -[
        -  "browserstack",
        -  "saucelabs",
        -  "testmu"
        -]New value: +[
        +  "browserstack",
        +  "saucelabs",
        +  "testmu",
        +  "testingbot"
        +]
  11. 3 tool updatesv3.6.0
    • Changedlist_apps4 fields changed
      • changedInput schema / properties / organizationWide / description
        Previous value: -"List apps uploaded by all users in the organization (uses recent_group_apps endpoint). Defaults to false (own uploads only)."New value: +"(BrowserStack only) List apps uploaded by all users in the organization. Defaults to false (own uploads only)."
      • addedInput schema / properties / provider
        Added value: +{
        +  "description": "Cloud provider",
        +  "enum": [
        +    "browserstack",
        +    "saucelabs",
        +    "testmu"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / region
        Added value: +{
        +  "default": "eu-central-1",
        +  "description": "Sauce Labs region (default: eu-central-1)",
        +  "enum": [
        +    "us-west-1",
        +    "eu-central-1",
        +    "apac-southeast-1"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / required
        Added value: +[
        +  "provider"
        +]
    • Changedstart_session14 fields changed
      • changedInput schema / properties / app / description
        Previous value: -"BrowserStack app URL (bs://...) or custom_id for mobile sessions"New value: +"App URL (bs://... for BrowserStack, storage:filename= for Sauce Labs, lt://... for TestMu mobile sessions)"
      • changedInput schema / properties / browserVersion / description
        Previous value: -"Browser version (BrowserStack only, default: latest)"New value: +"Browser version (cloud providers only, default: latest)"
      • changedInput schema / properties / browserstackLocal / anyOf
        Previous value: -[
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "const": "external",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "const": "external",
        +    "type": "string"
        +  },
        +  {
        +    "type": "boolean"
        +  }
        +]
      • changedInput schema / properties / browserstackLocal / description
        Previous value: -"Enable BrowserStack Local tunnel routing (BrowserStack only, default: false). true = auto-start tunnel before session and stop on close. \"external\" = tunnel already running externally, set local: true in capabilities only."New value: +"Deprecated: use \"tunnel\" instead. Enable BrowserStack Local tunnel routing."
      • changedInput schema / properties / os / description
        Previous value: -"Operating system (BrowserStack browser only, e.g. \"Windows\", \"OS X\")"New value: +"Operating system for cloud provider browser sessions (e.g. \"Windows\", \"Mac\", \"macOS\", \"Linux\"). BrowserStack: sets bstack:options.os separately. TestMu/Sauce Labs: combined with osVersion into W3C platformName. Browser platform only."
      • changedInput schema / properties / osVersion / description
        Previous value: -"OS version (BrowserStack browser only, e.g. \"11\", \"Sequoia\")"New value: +"OS version for cloud provider browser sessions (e.g. \"11\", \"15\", \"Monterey\"). BrowserStack: sets bstack:options.osVersion separately. TestMu/Sauce Labs: combined with os into W3C platformName. Browser platform only."
      • changedInput schema / properties / platformVersion / description
        Previous value: -"OS version (e.g., \"17.0\", \"14\")"New value: +"OS version for mobile sessions (e.g., \"17.0\", \"14\"). Mobile (ios/android) only."
      • changedInput schema / properties / provider / enum
        Previous value: -[
        -  "local",
        -  "browserstack"
        -]New value: +[
        +  "local",
        +  "browserstack",
        +  "saucelabs",
        +  "testmu"
        +]
      • addedInput schema / properties / region
        Added value: +{
        +  "default": "eu-central-1",
        +  "description": "Sauce Labs region (default: eu-central-1). Only used with provider: \"saucelabs\".",
        +  "enum": [
        +    "us-west-1",
        +    "eu-central-1",
        +    "apac-southeast-1"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / reporting / description
        Previous value: -"BrowserStack reporting labels (project, build, session)"New value: +"Cloud provider reporting labels (project, build, session)"
      • addedInput schema / properties / saucelabsLocal
        Added value: +{
        +  "anyOf": [
        +    {
        +      "const": "external",
        +      "type": "string"
        +    },
        +    {
        +      "type": "boolean"
        +    }
        +  ],
        +  "description": "Deprecated: use \"tunnel\" instead. Enable Sauce Connect tunnel routing."
        +}
      • addedInput schema / properties / testmuLocal
        Added value: +{
        +  "anyOf": [
        +    {
        +      "const": "external",
        +      "type": "string"
        +    },
        +    {
        +      "type": "boolean"
        +    }
        +  ],
        +  "description": "Deprecated: use \"tunnel\" instead. Enable TestMu Tunnel routing."
        +}
      • addedInput schema / properties / tunnel
        Added value: +{
        +  "anyOf": [
        +    {
        +      "const": "external",
        +      "type": "string"
        +    },
        +    {
        +      "type": "boolean"
        +    }
        +  ],
        +  "description": "Enable local tunnel routing (cloud providers only, default: false). true = auto-start tunnel before session and stop on close. \"external\" = tunnel already running externally."
        +}
      • addedInput schema / properties / tunnelName
        Added value: +{
        +  "description": "Tunnel identifier name. With tunnel: \"external\" this must match the running tunnel. With tunnel: true a unique name is auto-generated if not provided.",
        +  "type": "string"
        +}
    • Changedupload_app3 fields changed
      • addedInput schema / properties / provider
        Added value: +{
        +  "description": "Cloud provider",
        +  "enum": [
        +    "browserstack",
        +    "saucelabs",
        +    "testmu"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / region
        Added value: +{
        +  "default": "eu-central-1",
        +  "description": "Sauce Labs region (default: eu-central-1)",
        +  "enum": [
        +    "us-west-1",
        +    "eu-central-1",
        +    "apac-southeast-1"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "path"
        -]New value: +[
        +  "provider",
        +  "path"
        +]
  12. 29 tool updates
    • Addedclick_element
    • Addedclose_session
    • Addeddelete_cookies
    • Addeddrag_and_drop
    • Addedemulate_device
    • Addedexecute_script
    • Addedget_accessibility_tree
    • Addedget_app_state
    • Addedget_contexts
    • Addedget_cookies
    • Addedget_elements
    • Addedget_screenshot
    • Addedget_tabs
    • Addedhide_keyboard
    • Addedlaunch_chrome
    • Addedlist_apps
    • Addednavigate
    • Addedrotate_device
    • Addedscroll
    • Addedset_cookie
    • Addedset_geolocation
    • Addedset_value
    • Addedstart_session
    • Addedswipe
    • Addedswitch_context
    • Addedswitch_frame
    • Addedswitch_tab
    • Addedtap_element
    • Addedupload_app
  13. 29 tool updatesv3.5.1
    • Removedclick_element
    • Removedclose_session
    • Removeddelete_cookies
    • Removeddrag_and_drop
    • Removedemulate_device
    • Removedexecute_script
    • Removedget_accessibility_tree
    • Removedget_app_state
    • Removedget_contexts
    • Removedget_cookies
    • Removedget_elements
    • Removedget_screenshot
    • Removedget_tabs
    • Removedhide_keyboard
    • Removedlaunch_chrome
    • Removedlist_apps
    • Removednavigate
    • Removedrotate_device
    • Removedscroll
    • Removedset_cookie
    • Removedset_geolocation
    • Removedset_value
    • Removedstart_session
    • Removedswipe
    • Removedswitch_context
    • Removedswitch_frame
    • Removedswitch_tab
    • Removedtap_element
    • Removedupload_app
  14. 29 tool updatesv3.4.4
    • Addedclick_element
    • Addedclose_session
    • Addeddelete_cookies
    • Addeddrag_and_drop
    • Addedemulate_device
    • Addedexecute_script
    • Addedget_accessibility_tree
    • Addedget_app_state
    • Addedget_contexts
    • Addedget_cookies
    • Addedget_elements
    • Addedget_screenshot
    • Addedget_tabs
    • Addedhide_keyboard
    • Addedlaunch_chrome
    • Addedlist_apps
    • Addednavigate
    • Addedrotate_device
    • Addedscroll
    • Addedset_cookie
    • Addedset_geolocation
    • Addedset_value
    • Addedstart_session
    • Addedswipe
    • Addedswitch_context
    • Addedswitch_frame
    • Addedswitch_tab
    • Addedtap_element
    • Addedupload_app
  15. 29 tool updatesv3.4.1
    • Removedclick_element
    • Removedclose_session
    • Removeddelete_cookies
    • Removeddrag_and_drop
    • Removedemulate_device
    • Removedexecute_script
    • Removedget_accessibility_tree
    • Removedget_app_state
    • Removedget_contexts
    • Removedget_cookies
    • Removedget_elements
    • Removedget_screenshot
    • Removedget_tabs
    • Removedhide_keyboard
    • Removedlaunch_chrome
    • Removedlist_apps
    • Removednavigate
    • Removedrotate_device
    • Removedscroll
    • Removedset_cookie
    • Removedset_geolocation
    • Removedset_value
    • Removedstart_session
    • Removedswipe
    • Removedswitch_context
    • Removedswitch_frame
    • Removedswitch_tab
    • Removedtap_element
    • Removedupload_app
  16. 2 tool updatesv3.4.0
    • Changedstart_session1 field changed
      • addedInput schema / properties / appiumConfig / properties / protocol
        Added value: +{
        +  "type": "string"
        +}
    • Addedswitch_frame
  17. 6 tool updatesv3.3.0
    • Addedget_accessibility_tree
    • Addedget_app_state
    • Addedget_contexts
    • Addedget_cookies
    • Addedget_screenshot
    • Addedget_tabs

TDQS

A4/5.0

Scored across 17 tools

Disambiguation5/5

Each tool targets a distinct browser or mobile automation concern, and the descriptions explicitly clarify overlap cases such as perform_actions versus single-action tools. Navigation, session lifecycle, observation, and documentation tools are clearly separated.

Naming Consistency4/5

Tool names are consistently snake_case and mostly follow an action_object pattern, such as start_session, click_element, and get_screenshot. A few bare verb or noun names like navigate, scroll, and snapshot are minor deviations but remain readable.

Tool Count4/5

Seventeen tools is slightly above the ideal compact range, but each tool covers a meaningful part of browser and mobile automation. The enable_tools meta-tool keeps the default surface from becoming even larger.

Completeness4/5

The set covers core session, navigation, interaction, inspection, scripting, screenshot, and documentation workflows. Some advanced interactions such as mobile swipe, hover, or drag-and-drop are not directly exposed, though scripting and enabled tool groups provide workarounds.

Maintenance

ActivityNo data
ResponsivenessOutdated data

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Enables AI assistants to automate mobile app testing and development for iOS and Android through natural language interactions. Supports intelligent element identification, session management, automated test generation, and comprehensive device interactions including clicks, swipes, screenshots, and app management.
    32
    16,435 npm
    518
    Apache 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to automate browser interactions using Selenium WebDriver, supporting multiple browsers and tools for navigation, clicking, typing, screenshots, and more.
    1,095 npm
    MIT