Test jobs on virtual devices and desktop browsers, real-device jobs, builds, the
real-device catalog, Real Device Access sessions (reserve a device, open URLs,
install apps, run ADB shell commands, record tests, throttle the network, start
Appium), Sauce Connect tunnels, app storage metadata and teams, on Sauce Labs.
Verification level: unit.
Supported versions: The oldest Sauce Labs version toil supports hasn’t been established. Sauce Labs is
SaaS only, so there is no server release to pin. toil calls the REST v1 and v1.2,
Real Device Access v2, Builds v2, Team Management v1 and Storage v1 APIs on the
data-center host in baseUrl. Nothing has been verified against a live account yet.
Credential
Your Sauce Labs username and access key: in Sauce Labs, User settings → Access
key. toil sends them as Authorization: Basic base64(username:accessKey), and puts
the username in most /rest/v1/<username>/... paths. There is no token exchange,
password or browser login. toil saucelabs concurrency is the cheapest check that
the two belong together: Sauce has no “current user” endpoint, and that one is
scoped to the username.
Configuration
| Key | Env var | Required | Meaning |
|---|---|---|---|
baseUrl | TOIL_SAUCELABS_BASE_URL | yes | Your account’s data-center API endpoint, e.g. https://api.us-west-1.saucelabs.com (https://api.eu-central-1.saucelabs.com in the EU). There’s no default |
username | TOIL_SAUCELABS_USERNAME, then SAUCE_USERNAME | yes | Sauce Labs username |
accessKey | TOIL_SAUCELABS_ACCESS_KEY, then SAUCE_ACCESS_KEY | yes | Access key |
CI fallbacks: when TOIL_SAUCELABS_USERNAME or TOIL_SAUCELABS_ACCESS_KEY isn’t
set, the default connection takes the value from SAUCE_USERNAME or
SAUCE_ACCESS_KEY, the variables saucectl, Sauce Connect and Sauce’s own CI docs
read. Each sits directly below its TOIL_ variable and above the config file.
There’s no fallback for the base URL.
Environment variables (CI, or a one-off shell):
export TOIL_SAUCELABS_BASE_URL=https://api.us-west-1.saucelabs.com
export TOIL_SAUCELABS_USERNAME=<your username>
export TOIL_SAUCELABS_ACCESS_KEY=<your access key>
Or ~/.toil/config.json:
{
"version": 2,
"connections": {
"sauce": { "area": "saucelabs", "baseUrl": "https://api.us-west-1.saucelabs.com", "username": "imagile" }
},
"defaults": { "saucelabs": { "connection": "sauce" } }
}
The access key never goes in this file; a plaintext one there is refused with
CONFIG_INVALID. Run toil connections add sauce --area saucelabs (or
toil connections login sauce for an existing connection) to keep it in the OS
credential store, or set TOIL_SAUCELABS_ACCESS_KEY.
Commands
Ids are positional arguments: <job-id>, <build-id>, <device-id>,
<session-id>, <tunnel-id>, <team-id>. Over MCP they’re fields (jobId,
sessionId, …). Enum values are matched ignoring case. Integer flags take whole
numbers 0 or more. Time flags (--from, --to, --start, --end) take Unix
seconds or an ISO 8601 date; give the date-time an offset (2026-09-01T00:00:00Z),
because one without is read in the machine’s local time zone.
Account and platform:
status: Sauce Labs service status (operational flag, wait time)concurrency: Concurrency allowed and in use for your organization and team (also verifies credentials)platform list: Supported OS/browser/device platforms (--api all|appium|webdriver, defaultall);datais{ api, count, platforms }appium-version list: Appium versions available for real-device sessions, with end-of-life datesuser list: Look up users in your organization (--username,--phrase,--limit(default 20, max 100),--offset)
Jobs on virtual devices and desktop browsers, under your username:
job list: List your recent jobs (--limit,--offset,--from,--to);datais{ count, jobs }job get: Get one job: status, platform, timings, and log/video URLsjob update: Update a job’s name, build, tags, result, or visibility (--name,--build,--tags(repeatable or comma-separated; replaces the existing tags),--passedor--failed,--public public|public restricted|share|team|private). At least one is required, checked before any requestjob stop: Stop a running jobjob delete: Delete a job and all of its assets;datais{ jobId, deleted: true }job assets: List the asset files a job produced (logs, video, screenshots) — names only, no download;datais{ jobId, assets }
Real-device jobs:
rdc-job list: List real-device jobs (--limit,--offset,--livefor manual tests only)rdc-job get: Get one real-device job: device, result, timings, and log URLsrdc-job update: Update a real-device job’s name, build, tags, or result (--name,--build,--tags,--passedor--failed)rdc-job stop: Stop a running real-device job;datais{ jobId, stopped: true }rdc-job delete: Delete a real-device job (owner, team admin, or org admin only);datais{ jobId, deleted: true }
Builds (--source vdc|rdc, default vdc):
build list: List builds (--statusrepeatable or comma-separated, each sent as its ownstatus=parameter: running, error, failed, complete, success;--name,--start,--end,--limit,--offset,--sort asc|desc);datais{ source, count, builds }build get: Get one build with its job countsbuild jobs: List the jobs in a build (--failed,--errored,--passed,--running,--queued,--completed,--finished,--faulty,--modified-since, which is sent as typed);datais{ buildId, source, count, jobs }job build <job-id>: Get the build a job belongs to
Real devices:
device list: List real devices your account can use (--nameregex,--os android|ios,--os-version,--type phone|tablet);datais{ count, devices }device get: Get one device’s full descriptor (hardware, OS, screen)device status: Live availability of real devices (AVAILABLE, IN_USE, CLEANING, …) (--state,--name,--private-only)
Real-device sessions (Real Device Access API):
session list: List your device sessions (--state,--device-name);datais{ count, sessions }session create: Reserve a real device. Returns immediately in PENDING state unless —wait is passed (--device-name,--os android|ios,--tunnel-name,--tunnel-owner(needs--tunnel-name),--durationas ISO 8601, e.g.PT30M).--waitpolls every 5 s until the session is ACTIVE, and fails if it closes or errors, or when it’s still starting after--timeoutseconds (default 300). It gives up when the next poll would land past the timeout, so up to 5 s early; the session keeps starting in the background. The command’s time limit is an hour (TOIL_TIMEOUT_MSoverrides it)session get: Get a session: state, device, expiry, Appium URL, and live-view linksession delete: Close a session and release the device (--reboot, private devices only)session open-url: Open a URL on the device (Chrome on Android; Safari or a deep link on iOS):session open-url <session-id> <url>session shell: Run an ADB shell command on an Android device (public devices allow only a safe subset):session shell <session-id> <command>;datais{ sessionId, command, stdout }. It waits up to 120 s for the devicesession install-app: Install an app from Sauce app storage onto the device (runs in the background):session install-app <session-id> <app>, where<app>isstorage:<file-id>orstorage:filename=<name>(--launch,--no-instrumentation)session installations: List app installations on the device and their statussession launch-app: Launch an installed app (exactly one of--bundle-idor--package-name;--activityneeds--package-name)session uninstall-app: Uninstall an app (exactly one of--bundle-idor--package-name)session settings: Change device settings: orientation (both), locale and animations (Android only) (--orientation portrait|landscape,--locale,--animations on|off);datais{ sessionId, applied }session start-test: Start recording a test (a job) inside the session (--name,--build,--tags,--video,--device-logs,--network-capture,--screenshots,--appium-logs)session end-test: End the active test in the session, optionally recording its result (--passedor--failed)session tests: List the tests recorded in a session, with links to each jobsession network-profiles: List the network throttling profiles available to a sessionsession network: Throttle the device network with a named profile or explicit conditions, or —reset to clear (exactly one mode:--profile,--reset, or any of--downloadand--upload(0-50000 kbps),--latency(0-3000 ms) and--loss(0-100 %))session appium: Get the session’s Appium server URL, or —start one (--appium-versionneeds--start)
Sauce Connect tunnels, under your username:
tunnel list: List your tunnels with full details (--alladds tunnels shared with you). With--allSauce may answer with an object keyed by owner, in which casedata.tunnelsis that object andcountis absenttunnel get: Get one tunneltunnel jobs: Number of jobs currently running through a tunneltunnel stop: Shut down a tunnel
App storage (metadata only; no upload or download):
storage files: List uploaded app files (--query,--kind android|ios,--page(starts at 1),--page-size(max 100))storage groups: List app groups (all versions of one app), with the same flags
Teams:
team list: List teams (--nameprefix)team get: Get one team and its settingsteam members: List a team’s members
Lists are one request each, with the paging parameters passed straight through;
count is the length of the list Sauce returned, and is absent when the answer
isn’t a list. Sauce’s error bodies ({ "detail": "..." }) become the error message.
Writes
job update, stop and delete; rdc-job update, stop and delete; tunnel stop; and every session command that acts on a device (create, delete,
open-url, shell, install-app, launch-app, uninstall-app, settings,
start-test, end-test, network, appium) change something in Sauce Labs. Each
needs writes: true on the connection and --allow-write on the call. session appium needs both even to read the URL, because the same command can start a server.
job delete, rdc-job delete, session delete and tunnel stop delete something, so
they run on the CLI only and are never MCP tools.
toil saucelabs concurrency
toil saucelabs job list --limit 20 --from 2026-09-01T00:00:00Z
toil saucelabs build list --source rdc --status failed,error
toil saucelabs session create --device-name "iPhone 15.*" --os ios --wait --allow-write
toil saucelabs session shell <session-id> "getprop ro.build.version.release" --allow-write Settings at a glance
-
baseUrlrequiredData-center API endpoint, e.g. https://api.us-west-1.saucelabs.com
TOIL_SAUCELABS_BASE_URL -
usernamerequiredSauce Labs username; most API paths are scoped to it
TOIL_SAUCELABS_USERNAMEorSAUCE_USERNAME -
accessKeyrequired secretSauce Labs access key
TOIL_SAUCELABS_ACCESS_KEYorSAUCE_ACCESS_KEY
Commands at a glance
toil saucelabs statusSauce Labs service status (operational flag, wait time)
toil saucelabs concurrencyConcurrency allowed and in use for your organization and team (also verifies credentials)
toil saucelabs platform listSupported OS/browser/device platforms
toil saucelabs appium-version listAppium versions available for real-device sessions, with end-of-life dates
toil saucelabs user listLook up users in your organization
toil saucelabs job listList your recent jobs
toil saucelabs job getGet one job: status, platform, timings, and log/video URLs
toil saucelabs job updatewriteUpdate a job's name, build, tags, result, or visibility
toil saucelabs job stopwriteStop a running job
toil saucelabs job deletewriteCLI onlyDelete a job and all of its assets
toil saucelabs job assetsList the asset files a job produced (logs, video, screenshots) — names only, no download
toil saucelabs rdc-job listList real-device jobs
toil saucelabs rdc-job getGet one real-device job: device, result, timings, and log URLs
toil saucelabs rdc-job updatewriteUpdate a real-device job's name, build, tags, or result
toil saucelabs rdc-job stopwriteStop a running real-device job
toil saucelabs rdc-job deletewriteCLI onlyDelete a real-device job (owner, team admin, or org admin only)
toil saucelabs build listList builds
toil saucelabs build getGet one build with its job counts
toil saucelabs build jobsList the jobs in a build
toil saucelabs job buildGet the build a job belongs to
toil saucelabs device listList real devices your account can use
toil saucelabs device getGet one device's full descriptor (hardware, OS, screen)
toil saucelabs device statusLive availability of real devices (AVAILABLE, IN_USE, CLEANING, ...)
toil saucelabs session listList your device sessions
toil saucelabs session createwriteReserve a real device. Returns immediately in PENDING state unless --wait is passed
toil saucelabs session getGet a session: state, device, expiry, Appium URL, and live-view link
toil saucelabs session deletewriteCLI onlyClose a session and release the device
toil saucelabs session open-urlwriteOpen a URL on the device (Chrome on Android; Safari or a deep link on iOS)
toil saucelabs session shellwriteRun an ADB shell command on an Android device (public devices allow only a safe subset)
toil saucelabs session install-appwriteInstall an app from Sauce app storage onto the device (runs in the background)
toil saucelabs session installationsList app installations on the device and their status
toil saucelabs session launch-appwriteLaunch an installed app
toil saucelabs session uninstall-appwriteUninstall an app
toil saucelabs session settingswriteChange device settings: orientation (both), locale and animations (Android only)
toil saucelabs session start-testwriteStart recording a test (a job) inside the session
toil saucelabs session end-testwriteEnd the active test in the session, optionally recording its result
toil saucelabs session testsList the tests recorded in a session, with links to each job
toil saucelabs session network-profilesList the network throttling profiles available to a session
toil saucelabs session networkwriteThrottle the device network with a named profile or explicit conditions, or --reset to clear
toil saucelabs session appiumwriteGet the session's Appium server URL, or --start one
toil saucelabs tunnel listList your tunnels with full details
toil saucelabs tunnel getGet one tunnel
toil saucelabs tunnel jobsNumber of jobs currently running through a tunnel
toil saucelabs tunnel stopwriteCLI onlyShut down a tunnel
toil saucelabs storage filesList uploaded app files
toil saucelabs storage groupsList app groups (all versions of one app)
toil saucelabs team listList teams
toil saucelabs team getGet one team and its settings
toil saucelabs team membersList a team's members