Vibium on Sauce Labs
Community Supported Desktop Browsers Only
Vibium is an open-source browser automation tool built for coding agents. A single binary speaks WebDriver BiDi to the browser and exposes that control as a command-line interface, a Model Context Protocol (MCP) server, and JavaScript and Python client libraries. Vibium can attach to a browser session that already exists, and every Sauce Labs desktop browser session can hand out a WebDriver BiDi URL, so you can drive Chrome, Edge, and Firefox on Sauce Labs Windows, macOS, and Linux virtual machines from Vibium with no Sauce Labs specific code.
This framework is built and maintained by its open-source project, not by Sauce Labs. Sauce Labs supports the cloud side: devices, browsers, endpoints, and test artifacts. Report framework issues to the project's issue tracker. Validated with the version noted below; later versions may differ.
Sauce Labs validated this guide with Vibium 26.8.21 in September 2026.
Vibium depends on Sauce Labs CDP / BiDi support, which is in Beta. The limitations of that feature apply to Vibium as well.
How It Works with Sauce Labs
Sauce Labs does not host Vibium. You create an ordinary W3C WebDriver session on Sauce Labs with the webSocketUrl
capability set to true, Sauce Labs returns a WebDriver BiDi WebSocket URL for that session, and Vibium connects to
that URL.
+-----------------------------+ 1. POST /session (webSocketUrl: true) +-----------------------------+
| Your machine, CI job, | ------------------------------------------------> | Sauce Labs |
| or coding agent | <------------------------------------------------ | ondemand.<dc>.saucelabs |
| | 2. webSocketUrl: wss://.../se/bidi | .com/wd/hub |
| vibium start <url> | | |
| browser.start(url) | 3. WebDriver BiDi over the returned URL | Chrome, Edge, or Firefox |
| VIBIUM_CONNECT_URL=<url> | <===============================================> | on a Windows, macOS, or |
| | | Linux virtual machine |
| | 4. PUT /jobs/<id> {"passed": true} | |
| | 5. DELETE /session/<id> | |
+-----------------------------+ ------------------------------------------------> +-----------------------------+
- Create a Sauce Labs session with any W3C WebDriver client or a plain HTTP request. Set
webSocketUrl: truenext to your usual browser, platform, andsauce:optionscapabilities. - Read
webSocketUrlfrom the response. It has the formwss://<host>.saucelabs.com/selenium/session/<sessionId>/se/bidi. - Hand that URL to Vibium:
vibium start <url>for the CLI,browser.start(url)in the JavaScript or Python client, or theVIBIUM_CONNECT_URLenvironment variable for the MCP server. Vibium detects the existing session and attaches to it instead of launching a browser. - Drive the browser with Vibium. Navigation, element lookups, screenshots, and JavaScript evaluation all run against the Sauce Labs browser.
- When you are done, set the job's pass or fail status through the Sauce Labs REST API and end the session with a
WebDriver
DELETE. Vibium detaches from a session it did not create, but it never ends one.
What You'll Need
- A Sauce Labs account (Log in or sign up for a free trial license).
- Your Sauce Labs Username and Access Key.
- Node.js for the CLI, the MCP server, and the JavaScript client, or Python 3 for the Python client.
- A way to create the Sauce Labs session:
curl, Node.jsfetch, Pythonrequests, or any Selenium or WebDriver client you already use.
Step 1: Install Vibium
- Node.js
- Python
npm install vibium
npx vibium --version
vibium CLI, the MCP server, and the JavaScript client.pip install vibium requests
requests is used below to create the Sauce Labs session; any HTTP client works.Installing Vibium downloads the Vibium binary. Vibium downloads a local browser only the first time you launch one locally, so a CI job that only attaches to Sauce Labs never needs a browser download.
Step 2: Link Your Sauce Labs Account
Set your SAUCE_USERNAME and SAUCE_ACCESS_KEY as environment variables.
echo $SAUCE_USERNAME
echo $SAUCE_ACCESS_KEY
If nothing is returned, set them:
export SAUCE_USERNAME="your Sauce username"
export SAUCE_ACCESS_KEY="your Sauce access key"
Step 3: Create a Sauce Labs Session with a BiDi URL
Create a normal desktop browser session and add webSocketUrl: true.
Every other sauce:options value you already use, such as build,
tags, tunnelName,
screenResolution, and
maxDuration, applies unchanged. Do not set
extendedDebugging; it cannot be combined with webSocketUrl.
- Node.js
- Python
- curl
const region = process.env.SAUCE_REGION ?? 'us-west-1';
const hub = `https://ondemand.${region}.saucelabs.com/wd/hub`;
const auth = 'Basic ' + Buffer.from(
`${process.env.SAUCE_USERNAME}:${process.env.SAUCE_ACCESS_KEY}`).toString('base64');
const res = await fetch(`${hub}/session`, {
method: 'POST',
headers: { Authorization: auth, 'Content-Type': 'application/json' },
body: JSON.stringify({
capabilities: {
alwaysMatch: {
browserName: 'chrome',
browserVersion: 'latest',
platformName: 'Windows 11',
webSocketUrl: true,
'sauce:options': { name: 'Vibium on Sauce Labs', build: 'vibium-quickstart' },
},
},
}),
});
const { value } = await res.json();
const sessionId = value.sessionId;
const bidiUrl = value.capabilities.webSocketUrl;
console.log(`Sauce Labs job: https://app.saucelabs.com/tests/${sessionId}`);
import os, requests
region = os.environ.get("SAUCE_REGION", "us-west-1")
hub = f"https://ondemand.{region}.saucelabs.com/wd/hub"
auth = (os.environ["SAUCE_USERNAME"], os.environ["SAUCE_ACCESS_KEY"])
caps = {"capabilities": {"alwaysMatch": {
"browserName": "chrome",
"browserVersion": "latest",
"platformName": "Windows 11",
"webSocketUrl": True,
"sauce:options": {"name": "Vibium on Sauce Labs", "build": "vibium-quickstart"},
}}}
value = requests.post(f"{hub}/session", auth=auth, json=caps, timeout=300).json()["value"]
session_id = value["sessionId"]
bidi_url = value["capabilities"]["webSocketUrl"]
print(f"Sauce Labs job: https://app.saucelabs.com/tests/{session_id}")
curl -s -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" \
-H 'Content-Type: application/json' \
-d '{"capabilities":{"alwaysMatch":{
"browserName":"chrome","browserVersion":"latest","platformName":"Windows 11",
"webSocketUrl":true,
"sauce:options":{"name":"Vibium on Sauce Labs","build":"vibium-quickstart"}}}}' \
https://ondemand.us-west-1.saucelabs.com/wd/hub/session
value.sessionId and value.capabilities.webSocketUrl. Keep both; you need the session ID in
Step 5.For the EU Central or US East data centers, replace us-west-1 with eu-central-1 or us-east-4 in both the
ondemand and api host names. See Data Center Endpoints.
Step 4: Attach Vibium and Drive the Browser
Copy the webSocketUrl from the response exactly as returned. No additional authentication header is needed.
- CLI
- Node.js
- Python
- MCP server
export BIDI_URL="wss://<host>.saucelabs.com/selenium/session/<sessionId>/se/bidi"
npx vibium start "$BIDI_URL"
npx vibium go https://www.saucedemo.com
npx vibium title
npx vibium screenshot -o saucedemo.png
npx vibium stop
vibium stop disconnects Vibium. The Sauce Labs session keeps running until you end it in Step 5. If you drive more
than one Sauce Labs browser from the same machine, add --session <name> to every command to keep the daemons apart.import { browser } from 'vibium';
let passed = false;
try {
const bro = await browser.start(bidiUrl); // attaches to the Sauce Labs session
const page = await bro.page();
await page.go('https://www.saucedemo.com');
await (await page.find('#user-name')).type('standard_user');
await (await page.find('#password')).type('secret_sauce');
await (await page.find('#login-button')).click();
const heading = await (await page.find('.title')).text();
passed = heading === 'Products';
await bro.stop(); // detaches; does not end the Sauce Labs session
} finally {
// Step 5: report the result and end the session (see below)
}
from vibium import browser
passed = False
try:
bro = browser.start(bidi_url) # attaches to the Sauce Labs session
page = bro.page()
page.go("https://www.saucedemo.com")
page.find("#user-name").type("standard_user")
page.find("#password").type("secret_sauce")
page.find("#login-button").click()
passed = page.find(".title").text() == "Products"
bro.stop() # detaches; does not end the Sauce Labs session
finally:
pass # Step 5: report the result and end the session (see below)
VIBIUM_CONNECT_URL in the MCP server's environment and Vibium's browser tools operate on the Sauce Labs
browser instead of launching a local one.{
"mcpServers": {
"vibium-sauce": {
"command": "npx",
"args": ["vibium", "mcp"],
"env": {
"VIBIUM_CONNECT_URL": "wss://<host>.saucelabs.com/selenium/session/<sessionId>/se/bidi"
}
}
}
}
VIBIUM_CONNECT_URL="$BIDI_URL" npx vibium mcp
browser_navigate, browser_get_title, browser_find, and browser_screenshot then run on the Sauce
Labs browser. The session URL is only valid for the life of that Sauce Labs session, so treat the configuration as
temporary.Step 5: Report the Result and End the Session
Vibium never ends a session it did not create, so you must do both of the following yourself, ideally in a finally
block so they run even when the test fails.
curl -s -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" -X PUT -H 'Content-Type: application/json' \
-d '{"passed": true}' \
"https://api.us-west-1.saucelabs.com/rest/v1/$SAUCE_USERNAME/jobs/<sessionId>"
curl -s -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" -X DELETE \
"https://ondemand.us-west-1.saucelabs.com/wd/hub/session/<sessionId>"
The first call is the Update a Job API. Without it the job shows as complete with no pass or fail status. Without the second call the session runs until it hits the Sauce Labs idle or maximum duration timeout and continues to consume concurrency.
Step 6: View Your Results
Open the job under Automated > Test Results. You get the full video
of the browser, the name and build you set, and the pass or fail status you reported. The Commands tab lists the
WebDriver HTTP calls you made (typically the session creation and deletion); WebDriver BiDi traffic from Vibium is not
itemised there.
Supported Browsers and Platforms
Verified by Sauce Labs in September 2026 with Vibium 26.8.21.
| Sauce Labs target | Result |
|---|---|
| Chrome on Windows 11 | ✔️ CLI, JavaScript client, Python client, and MCP server all validated end to end |
| Firefox on Windows 11 | ✔️ JavaScript client validated end to end |
| Microsoft Edge on Windows; Chrome on macOS and Linux | ✔️ Sauce Labs returns a BiDi URL; same attach mechanism |
| Safari on macOS | ❌ Session creation fails when webSocketUrl is set; Safari cannot be used with Vibium |
| Chrome and Safari on Android emulators and iOS simulators | ❌ webSocketUrl returns true instead of a URL; nothing to attach to |
| Browsers on Android and iOS real devices | ❌ The returned URL is internal to the Sauce Labs network and not reachable |
| Java client | Not validated by Sauce Labs |
Limitations
- Desktop browsers only. Safari and all mobile targets are not available, as shown above.
- Extended debugging is not available in the same session as
webSocketUrl. - You own the session lifecycle. Vibium detaches but never deletes the Sauce Labs session; always send the
DELETEin Step 5. - No automatic pass or fail. Set it with the Jobs API as shown in Step 5.
- BiDi commands are not listed in the job. The video shows everything Vibium did; the command list shows only WebDriver HTTP calls.
- Sauce Labs session limits apply. The
idleTimeoutandmaxDurationvalues of the session govern how long Vibium can stay attached.
Security Considerations
Sauce Labs does not require an additional authentication header on the BiDi WebSocket. Anyone who has the
webSocketUrl can drive that browser until the session ends. Do not print it in CI logs, do not commit it to source
control, and remove it from MCP configuration files when the session is over.
Keep SAUCE_USERNAME and SAUCE_ACCESS_KEY in environment variables or your CI secret store; they are only needed to
create and end the session.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
| HTTP 500 when creating a Safari session | Safari does not accept webSocketUrl. Use Chrome, Edge, or Firefox. |
webSocketUrl in the response is true, not a URL | The session is on a mobile emulator or simulator. Use a desktop browser. |
The URL starts with ws://172. and Vibium cannot connect | The session is on a real device. Use a desktop browser. |
The Sauce Labs job keeps running after vibium stop | Expected. End the session with the WebDriver DELETE in Step 5. |
| The job shows Complete with no pass or fail | Send the PUT in Step 5 with {"passed": true} or {"passed": false}. |
| The session ends during a long pause | The session hit idleTimeout. Keep commands flowing or raise the timeout when you create the session. |
More Information
- Vibium on GitHub, the Vibium CLI reference, and the Vibium client libraries documentation
- CDP / BiDi on Sauce Labs for how Sauce Labs exposes WebDriver BiDi
- Test Configuration Options for every capability you can set on the session
- Jobs API for setting job status and reading job details
- Community Frameworks for the support model that applies to this guide