# Configuration

This page documents all configuration options for the WebdriverIO MCP server.

## MCP Server Configuration[​](#mcp-server-configuration "Direct link to MCP Server Configuration")

The MCP server is configured through the configuration files or commands.

### Basic Configuration[​](#basic-configuration "Direct link to Basic Configuration")

Edit your MCP configuration file (e.g. `./.mcp.json`) and add the following:

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

***

## Session Options[​](#session-options "Direct link to Session Options")

All session options are passed to the `start_session` tool. There is a single unified tool for browser and mobile sessions; the `platform` parameter determines the session type.

### Common Options[​](#common-options "Direct link to Common Options")

#### `platform`[​](#platform "Direct link to platform")

* **Type:** `"browser" | "ios" | "android"`
* **Mandatory:** Yes

The platform to automate.

#### `provider`[​](#provider "Direct link to provider")

* **Type:** `"local" | "browserstack" | "saucelabs" | "testmu" | "testingbot"`
* **Mandatory:** No
* **Default:** `"local"`

Where the session runs. Use a cloud provider name for remote devices; each requires its own environment variables. See [Cloud Providers](/docs/mcp/cloud-providers.md) for details.

***

## Browser Session Options[​](#browser-session-options "Direct link to Browser Session Options")

Options for `platform: "browser"` sessions.

### `browser`[​](#browser "Direct link to browser")

* **Type:** `"chrome" | "firefox" | "edge" | "safari"`
* **Mandatory:** Yes (for browser platform)

Browser to launch.

### `browserVersion`[​](#browserversion "Direct link to browserversion")

* **Type:** `string`
* **Mandatory:** No
* **Default:** `"latest"`

Browser version. Cloud providers only (default: latest).

### `os` / `osVersion`[​](#os--osversion "Direct link to os--osversion")

* **Type:** `string`
* **Mandatory:** No

Operating system for cloud provider browser sessions. Examples: `os: "Windows"`, `osVersion: "11"` or `os: "OS X"`, `osVersion: "Sequoia"`.

### `headless`[​](#headless "Direct link to headless")

* **Type:** `boolean`
* **Mandatory:** No
* **Default:** `true`

Run browser in headless mode (no visible window). Set to `false` to see the browser.

### `windowWidth`[​](#windowwidth "Direct link to windowwidth")

* **Type:** `number`
* **Mandatory:** No
* **Default:** `1920`
* **Range:** `400` - `3840`

Initial browser window width in pixels.

### `windowHeight`[​](#windowheight "Direct link to windowheight")

* **Type:** `number`
* **Mandatory:** No
* **Default:** `1080`
* **Range:** `400` - `2160`

Initial browser window height in pixels.

### `navigationUrl`[​](#navigationurl "Direct link to navigationurl")

* **Type:** `string`
* **Mandatory:** No

URL to navigate to immediately after starting the browser. More efficient than calling `start_session` followed by `navigate` separately.

### `attach`[​](#attach "Direct link to attach")

* **Type:** `boolean`
* **Mandatory:** No
* **Default:** `false`

Attach to an existing Chrome instance instead of launching a new one. Use after `launch_chrome` to connect via CDP.

### `attachConfig`[​](#attachconfig "Direct link to attachconfig")

* **Type:** `{ port?: number; host?: string }`
* **Mandatory:** No
* **Default:** `{ port: 9222, host: "localhost" }`

Chrome remote debugging connection config. Only applies when `attach: true`.

***

## Mobile Session Options[​](#mobile-session-options "Direct link to Mobile Session Options")

Options for `platform: "ios"` or `platform: "android"` sessions.

### `deviceName`[​](#devicename "Direct link to devicename")

* **Type:** `string`
* **Mandatory:** Yes (for mobile platforms)

Name of the device, simulator, or emulator.

**Examples:**

* iOS Simulator: `"iPhone 16"`, `"iPad Air (5th generation)"`
* Android Emulator: `"Pixel 7"`, `"Nexus 5X"`
* Real Device: The device name as shown in your system

### `platformVersion`[​](#platformversion "Direct link to platformversion")

* **Type:** `string`
* **Mandatory:** No

OS version of the device/simulator/emulator (e.g., `"18.0"` for iOS, `"14"` for Android).

### `automationName`[​](#automationname "Direct link to automationname")

* **Type:** `"XCUITest" | "UiAutomator2"`
* **Mandatory:** No

Automation driver. Defaults to `XCUITest` for iOS and `UiAutomator2` for Android.

### `udid`[​](#udid "Direct link to udid")

* **Type:** `string`
* **Mandatory:** No (Required for real iOS devices)

Unique Device Identifier. Required for real iOS devices (40-character identifier).

**Finding UDID:**

* **iOS:** Connect device, open Finder, click on device → Serial Number (click to reveal UDID)
* **Android:** Run `adb devices` in terminal

### `appPath`[​](#apppath "Direct link to apppath")

* **Type:** `string`
* **Mandatory:** No

Path to the application file to install and launch.

**Supported formats:**

* iOS Simulator: `.app` directory
* iOS Real Device: `.ipa` file
* Android: `.apk` file

Either `appPath` must be provided, or `noReset: true` to connect to an already-running app.

### `app`[​](#app "Direct link to app")

* **Type:** `string`
* **Mandatory:** No

Cloud provider app URL (`bs://...` for BrowserStack, `storage:filename=` for Sauce Labs, `lt://...` for TestMu, TestingBot app\_url) or `customId`. Used instead of `appPath` for cloud mobile sessions.

### `appWaitActivity`[​](#appwaitactivity "Direct link to appwaitactivity")

* **Type:** `string`
* **Mandatory:** No (Android only)

Activity to wait for on app launch. If not specified, the app's main/launcher activity is used.

**Example:** `"com.example.app.MainActivity"`

### Session State Options[​](#session-state-options "Direct link to Session State Options")

#### `noReset`[​](#noreset "Direct link to noreset")

* **Type:** `boolean`
* **Mandatory:** No

Preserve the app state between sessions. When `true`:

* App data is preserved (login state, preferences, etc.)
* Session will **detach** instead of close (keeps app running)
* Can be used without `appPath` to connect to an already-running app

#### `fullReset`[​](#fullreset "Direct link to fullreset")

* **Type:** `boolean`
* **Mandatory:** No

Completely reset the app before the session:

* iOS: Uninstalls and reinstalls the app
* Android: Clears app data and cache

Set `fullReset: false` with `noReset: true` to preserve app state completely.

### Session Timeout[​](#session-timeout "Direct link to Session Timeout")

#### `newCommandTimeout`[​](#newcommandtimeout "Direct link to newcommandtimeout")

* **Type:** `number`
* **Mandatory:** No
* **Default:** `300`

How long (in seconds) Appium will wait for a new command before ending the session. Increase for longer debugging sessions.

### Automatic Handling[​](#automatic-handling "Direct link to Automatic Handling")

#### `autoGrantPermissions`[​](#autograntpermissions "Direct link to autograntpermissions")

* **Type:** `boolean`
* **Mandatory:** No
* **Default:** `true`

Automatically grant app permissions on install/launch (camera, microphone, location, etc.).

Android Only

This option primarily affects Android. iOS permissions must be handled differently due to system restrictions.

#### `autoAcceptAlerts`[​](#autoacceptalerts "Direct link to autoacceptalerts")

* **Type:** `boolean`
* **Mandatory:** No
* **Default:** `true`

Automatically accept system alerts (dialogs) during automation ("Allow notifications?", etc.).

#### `autoDismissAlerts`[​](#autodismissalerts "Direct link to autodismissalerts")

* **Type:** `boolean`
* **Mandatory:** No
* **Default:** `false`

Dismiss system alerts instead of accepting them. Takes precedence over `autoAcceptAlerts` when `true`.

### Appium Server Connection[​](#appium-server-connection "Direct link to Appium Server Connection")

Override the Appium server connection on a per-session basis using `appiumConfig`:

```
start_session({
  platform: "ios",
  deviceName: "iPhone 16",
  appPath: "/path/to/app.app",
  appiumConfig: { host: "192.168.1.100", port: 4724, path: "/wd/hub" }
})
```

#### `appiumConfig`[​](#appiumconfig "Direct link to appiumconfig")

* **Type:** `{ host?: string; port?: number; path?: string }`
* **Mandatory:** No

Appium server connection. Defaults to `{ host: "127.0.0.1", port: 4723, path: "/" }`.

***

## Cloud Provider Options[​](#cloud-provider-options "Direct link to Cloud Provider Options")

### Credentials[​](#credentials "Direct link to Credentials")

Each cloud provider requires its own environment variables:

| Provider     | Username Variable       | Access Key Variable       |
| ------------ | ----------------------- | ------------------------- |
| BrowserStack | `BROWSERSTACK_USERNAME` | `BROWSERSTACK_ACCESS_KEY` |
| Sauce Labs   | `SAUCE_USERNAME`        | `SAUCE_ACCESS_KEY`        |
| TestMu       | `TESTMU_USERNAME`       | `TESTMU_ACCESS_KEY`       |
| TestingBot   | `TESTINGBOT_KEY`        | `TESTINGBOT_SECRET`       |

Set these before starting the MCP server.

### `region`[​](#region "Direct link to region")

* **Type:** `"us-west-1" | "eu-central-1" | "apac-southeast-1"`
* **Mandatory:** No
* **Default:** `"eu-central-1"`

Sauce Labs data center region. Ignored for other providers.

### `tunnel`[​](#tunnel "Direct link to tunnel")

* **Type:** `boolean | "external"`
* **Mandatory:** No
* **Default:** `false`

Enable local tunnel routing for cloud provider sessions (accessing localhost, staging environments, internal services).

* `true` — Auto-start the tunnel before the session and stop it on close
* `"external"` — Tunnel already running externally; sets provider-appropriate flags only

Before using `true`, read the provider's local-binary resource (`wdio://browserstack/local-binary`, `wdio://saucelabs/local-binary`, `wdio://testmu/local-binary`, or `wdio://testingbot/local-binary`) for setup instructions specific to your OS and architecture.

### `tunnelName`[​](#tunnelname "Direct link to tunnelname")

* **Type:** `string`
* **Mandatory:** No

Tunnel identifier name. Required when `tunnel: "external"` to match the running tunnel. When `tunnel: true`, a unique name is auto-generated if not provided.

### `reporting`[​](#reporting "Direct link to reporting")

* **Type:** `{ project?: string; build?: string; session?: string }`
* **Mandatory:** No

Cloud provider session labels visible in the provider's dashboard. Works identically across BrowserStack, Sauce Labs, TestMu, and TestingBot.

### `trace`[​](#trace "Direct link to trace")

* **Type:** `boolean`
* **Mandatory:** No
* **Default:** `false`

Enable trace recording. Produces a Playwright-compatible `.trace` zip file saved to `.trace/` on `close_session`. View traces at [player.vibium.dev](https://player.vibium.dev).

***

## Element Detection Options[​](#element-detection-options "Direct link to Element Detection Options")

Options for the `get_elements` tool.

### `inViewportOnly`[​](#inviewportonly "Direct link to inviewportonly")

* **Type:** `boolean`
* **Mandatory:** No
* **Default:** `false`

Only return elements visible in the current viewport. Set to `true` to reduce results on long pages.

### `includeContainers`[​](#includecontainers "Direct link to includecontainers")

* **Type:** `boolean`
* **Mandatory:** No
* **Default:** `false`

Include container/layout elements in the results:

**Android containers:** `ViewGroup`, `FrameLayout`, `LinearLayout`, `RelativeLayout`, `ConstraintLayout`, `ScrollView`, `RecyclerView`

**iOS containers:** `View`, `StackView`, `CollectionView`, `ScrollView`, `TableView`

### `includeBounds`[​](#includebounds "Direct link to includebounds")

* **Type:** `boolean`
* **Mandatory:** No
* **Default:** `false`

Include element bounding box coordinates (x, y, width, height) in the response.

### Pagination[​](#pagination "Direct link to Pagination")

#### `limit`[​](#limit "Direct link to limit")

* **Type:** `number`
* **Mandatory:** No
* **Default:** `0` (unlimited)

Maximum number of elements to return.

#### `offset`[​](#offset "Direct link to offset")

* **Type:** `number`
* **Mandatory:** No
* **Default:** `0`

Number of elements to skip before returning results.

**Example:** Get elements 21–40:

```
Get elements with limit 20 and offset 20
```

***

## Accessibility Tree Options[​](#accessibility-tree-options "Direct link to Accessibility Tree Options")

Options for the `get_accessibility_tree` tool (browser-only).

### `limit`[​](#limit-1 "Direct link to limit-1")

* **Type:** `number`
* **Mandatory:** No
* **Default:** `0` (unlimited)

Maximum number of nodes to return.

### `offset`[​](#offset-1 "Direct link to offset-1")

* **Type:** `number`
* **Mandatory:** No
* **Default:** `0`

Number of nodes to skip for pagination.

### `roles`[​](#roles "Direct link to roles")

* **Type:** `string[]`
* **Mandatory:** No
* **Default:** All roles

Filter to specific accessibility roles.

**Common roles:** `button`, `link`, `textbox`, `checkbox`, `radio`, `heading`, `img`, `listitem`

**Example:** Get only buttons and links:

```
Get accessibility tree filtered to button and link roles
```

***

## Screenshot[​](#screenshot "Direct link to Screenshot")

The `get_screenshot` tool takes no parameters. Screenshots are automatically processed:

| Optimization  | Value    | Description                                       |
| ------------- | -------- | ------------------------------------------------- |
| Max dimension | 2000px   | Images larger than 2000px are scaled down         |
| Max file size | 1MB      | Images are compressed to stay under 1MB           |
| Format        | PNG/JPEG | PNG with max compression; JPEG if needed for size |

***

## Session Behavior[​](#session-behavior "Direct link to Session Behavior")

### Session Types[​](#session-types "Direct link to Session Types")

| Type      | Description         | Auto-Detach                              |
| --------- | ------------------- | ---------------------------------------- |
| `browser` | Browser session     | No                                       |
| `ios`     | iOS app session     | Yes (if `noReset: true` or no `appPath`) |
| `android` | Android app session | Yes (if `noReset: true` or no `appPath`) |

### Single-Session Model[​](#single-session-model "Direct link to Single-Session Model")

The MCP server operates with a **single-session model**:

* Only one browser OR app session can be active at a time
* Starting a new session will close/detach the current session
* Session state is maintained globally across tool calls

### Detach vs Close[​](#detach-vs-close "Direct link to Detach vs Close")

| Action     | `detach: false` (Close)      | `detach: true` (Detach)                      |
| ---------- | ---------------------------- | -------------------------------------------- |
| Browser    | Closes browser completely    | Keeps browser running, disconnects WebDriver |
| Mobile App | Terminates app               | Keeps app running in current state           |
| Use Case   | Clean slate for next session | Preserve state, manual inspection            |

***

## Performance Considerations[​](#performance-considerations "Direct link to Performance Considerations")

### Browser Automation[​](#browser-automation "Direct link to Browser Automation")

* **Headless mode** is faster but doesn't render visual elements
* **Smaller window sizes** reduce screenshot capture time
* **Element detection** is optimized with a single script execution
* **Screenshot optimization** keeps images under 1MB for efficient processing

### Mobile Automation[​](#mobile-automation "Direct link to Mobile Automation")

* **XML page source parsing** uses only 2 HTTP calls (vs 600+ for traditional element queries)
* **Accessibility ID selectors** are fastest and most reliable
* **XPath selectors** are slowest; use only as a last resort
* **Pagination** (`limit` and `offset`) reduces token usage for screens with many elements

### Token Usage Tips[​](#token-usage-tips "Direct link to Token Usage Tips")

| Setting                    | Impact                                              |
| -------------------------- | --------------------------------------------------- |
| `inViewportOnly: true`     | Filters off-screen elements, reducing response size |
| `includeContainers: false` | Excludes layout elements (ViewGroup, etc.)          |
| `includeBounds: false`     | Omits x/y/width/height data                         |
| `limit` with pagination    | Process elements in batches instead of all at once  |

***

## Appium Server Setup[​](#appium-server-setup "Direct link to Appium Server Setup")

Before using mobile automation, ensure Appium is properly configured.

### Basic Setup[​](#basic-setup "Direct link to Basic Setup")

```
# Install Appium globally
npm install -g appium

# Install drivers
appium driver install xcuitest    # iOS
appium driver install uiautomator2  # Android

# Start the server
appium
```

### Custom Server Configuration[​](#custom-server-configuration "Direct link to Custom Server Configuration")

```
# Start with custom host and port
appium --address 0.0.0.0 --port 4724

# Start with logging
appium --log-level debug

# Start with specific base path
appium --base-path /wd/hub
```

### Verify Installation[​](#verify-installation "Direct link to Verify Installation")

```
# Check installed drivers
appium driver list --installed

# Check Appium version
appium --version

# Test connection
curl http://localhost:4723/status
```

***

## Troubleshooting Configuration[​](#troubleshooting-configuration "Direct link to Troubleshooting Configuration")

### MCP Server Not Starting[​](#mcp-server-not-starting "Direct link to MCP Server Not Starting")

1. Verify npm/npx is installed: `npm --version`
2. Try running manually: `npx @wdio/mcp`
3. Check your harness' logs for errors

### Appium Connection Issues[​](#appium-connection-issues "Direct link to Appium Connection Issues")

1. Verify Appium is running: `curl http://localhost:4723/status`
2. Check `appiumConfig` in `start_session` matches the Appium server settings
3. Ensure firewall allows connections on the Appium port

### Session Won't Start[​](#session-wont-start "Direct link to Session Won't Start")

1. **Browser:** Ensure the target browser is installed
2. **iOS:** Verify Xcode and simulators are available
3. **Android:** Check `ANDROID_HOME` and emulator is running
4. Review Appium server logs for detailed error messages

### Session Timeouts[​](#session-timeouts "Direct link to Session Timeouts")

If sessions are timing out during debugging:

1. Increase `newCommandTimeout` when starting the session
2. Use `noReset: true` to preserve state between sessions
3. Use `detach: true` when closing to keep the app running
