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 saucelabsstatusSauce Labs service status (operational flag, wait time)
toil saucelabsconcurrencyConcurrency allowed and in use for your organization and team (also verifies credentials)
toil saucelabsplatform listSupported OS/browser/device platforms
toil saucelabsappium-version listAppium versions available for real-device sessions, with end-of-life dates
toil saucelabsuser listLook up users in your organization
toil saucelabsjob listList your recent jobs
toil saucelabsjob getGet one job: status, platform, timings, and log/video URLs
toil saucelabsjob updatewriteUpdate a job's name, build, tags, result, or visibility
toil saucelabsjob stopwriteStop a running job
toil saucelabsjob deletewriteCLI onlyDelete a job and all of its assets
toil saucelabsjob assetsList the asset files a job produced (logs, video, screenshots) — names only, no download
toil saucelabsrdc-job listList real-device jobs
toil saucelabsrdc-job getGet one real-device job: device, result, timings, and log URLs
toil saucelabsrdc-job updatewriteUpdate a real-device job's name, build, tags, or result
toil saucelabsrdc-job stopwriteStop a running real-device job
toil saucelabsrdc-job deletewriteCLI onlyDelete a real-device job (owner, team admin, or org admin only)
toil saucelabsbuild listList builds
toil saucelabsbuild getGet one build with its job counts
toil saucelabsbuild jobsList the jobs in a build
toil saucelabsjob buildGet the build a job belongs to
toil saucelabsdevice listList real devices your account can use
toil saucelabsdevice getGet one device's full descriptor (hardware, OS, screen)
toil saucelabsdevice statusLive availability of real devices (AVAILABLE, IN_USE, CLEANING, ...)
toil saucelabssession listList your device sessions
toil saucelabssession createwriteReserve a real device. Returns immediately in PENDING state unless --wait is passed
toil saucelabssession getGet a session: state, device, expiry, Appium URL, and live-view link
toil saucelabssession deletewriteCLI onlyClose a session and release the device
toil saucelabssession open-urlwriteOpen a URL on the device (Chrome on Android; Safari or a deep link on iOS)
toil saucelabssession shellwriteRun an ADB shell command on an Android device (public devices allow only a safe subset)
toil saucelabssession install-appwriteInstall an app from Sauce app storage onto the device (runs in the background)
toil saucelabssession installationsList app installations on the device and their status
toil saucelabssession launch-appwriteLaunch an installed app
toil saucelabssession uninstall-appwriteUninstall an app
toil saucelabssession settingswriteChange device settings: orientation (both), locale and animations (Android only)
toil saucelabssession start-testwriteStart recording a test (a job) inside the session
toil saucelabssession end-testwriteEnd the active test in the session, optionally recording its result
toil saucelabssession testsList the tests recorded in a session, with links to each job
toil saucelabssession network-profilesList the network throttling profiles available to a session
toil saucelabssession networkwriteThrottle the device network with a named profile or explicit conditions, or --reset to clear
toil saucelabssession appiumwriteGet the session's Appium server URL, or --start one
toil saucelabstunnel listList your tunnels with full details
toil saucelabstunnel getGet one tunnel
toil saucelabstunnel jobsNumber of jobs currently running through a tunnel
toil saucelabstunnel stopwriteCLI onlyShut down a tunnel
toil saucelabsstorage filesList uploaded app files
toil saucelabsstorage groupsList app groups (all versions of one app)
toil saucelabsteam listList teams
toil saucelabsteam getGet one team and its settings
toil saucelabsteam membersList a team's members