Super Farm
On this page

Command reference

For anyone who runs the farm from a terminal or a script. Every command of sf, with its usage, options and an example. sf <command> --help prints the same text for one command.

Conventions#

sf has two kinds of commands. Local commands (doctor, host, config, token, serve, service, version, completion) work on the machine and need no daemon. All others talk to the daemon over HTTP, so the daemon must be running (sf serve or sf service start).

A selector picks Androids. It is one of all, running, stopped, tag:NAME, a number such as 5, or a range such as 1-10. Join selectors with commas and exclude with !, for example 1-10,tag:eu,!tag:spare.

Exit codes: 0 success, 1 the operation failed, 2 wrong usage, 130 interrupted with Ctrl-C. sf doctor exits 1 when a check fails, and sf service status exits 3 when the service is not active.

The global options below are accepted before and after the command name (sf --json ls and sf ls --json are the same).

OptionDescription
--home DIRfarm home to work on (default: $SUPERFARM_HOME or ~/.local/share/superfarm)
--jsonprint the result as JSON (for scripts)
--wait, --no-waitfollow a started task to its end and show per-device results (default: yes on a terminal, no in a script)
-q, --quietno progress line and no hints, only the result

Commands#

CommandWhat it does
sf ls (list)list the Androids and their state
sf createadd Androids (they are created stopped)
sf startstart Androids
sf restartrestart Androids
sf recreaterebuild the containers of Androids (data is kept)
sf stopstop Androids
sf rm (delete)delete Androids (asks first)
sf setchange settings of Androids (applied at their next restart)
sf infoshow one Android in detail
sf logsshow the container logs of one Android
sf gpuGPUs and the rendering mode of Androids
sf imageAndroid images, one per Android version
sf taskslist background tasks, or show, follow and cancel one
sf toplive load of the host, the GPUs and every running Android
sf openprint the panel's address and how to log in
sf shellrun a command inside Androids
sf screenshotsave a screenshot of one Android
sf appsthe app library: APK / XAPK / APKS / APKM files kept by the farm
sf appapps on the Androids: install, launch, stop, clear, compare versions
sf pushcopy a local file onto Androids
sf pullcopy a file from one Android to this machine
sf galleryadd a picture or video to the gallery of Androids
sf inputsend the same touch or key to many Androids at once
sf windownative device windows (scrcpy) on the desktop the daemon runs on
sf vpnVPN profiles, logins and tunnel status
sf gatewayshared VPN gateways: one tunnel for many Androids
sf camerafeed a video or live stream into the camera and microphone of Androids
sf listenhear one Android on the speakers of the machine the daemon runs on
sf autoautomation: train recordings into programs and run programs or flows
sf backupback up and restore Androids and the farm's settings
sf mcplet MCP-enabled AI assistants see and operate the farm
sf approvalsanswer AI assistants that ask to change the farm
sf askask the built-in Assistant to look at or operate the farm
sf aithe in-farm AI: model profiles, the Assistant, the Pilot
sf doctorcheck that this machine can run Androids, with the fix for each problem
sf hostprepare and inspect this machine (kernel modules, limits, GPUs)
sf configread and change the farm's settings (config.yaml)
sf tokenprint the API token the panel and scripts log in with
sf serverun the daemon (panel + API) in the foreground
sf servicerun the daemon as a systemd user service
sf versionprint the version
sf completionprint a shell completion script

sf ls#

Alias: sf list.

List the Androids and their state.

sf ls [-w] [--interval SECONDS]
OptionDefaultDescription
-w, --watchkeep the list on screen and refresh it
--interval SECONDS2.0refresh interval for -w (default: 2)

Example:

sf ls
sf ls -w

sf create#

Add one or more Androids. Anything not given follows the farm's settings (sf config show) and keeps following them when they change.

sf create [-n COUNT] [--name NAME] [--android VERSION]
          [--gpu {auto,software,igpu,dgpu,intel,amd,nvidia}]
          [--net {direct,vpn,gateway,proxy,none}] [--vpn PROFILE] [--gateway NAME] [--cpus CPUS]
          [--memory MIB] [--width WIDTH] [--height HEIGHT] [--dpi DPI] [--fps FPS] [--tag TAG]
          [--data-volume VOLUME] [--image IMAGE]
OptionDefaultDescription
-n, --count COUNT1how many (default: 1)
--name NAMEdisplay name (numbered when several are created)
--android VERSIONAndroid version, e.g. 13 (default: android.default_version)
--gpu {auto,software,igpu,dgpu,intel,amd,nvidia}rendering: CPU only (software), integrated or discrete GPU, a vendor, or auto
--net {direct,vpn,gateway,proxy,none}network mode
--vpn PROFILEpin this VPN profile (implies --net vpn)
--gateway NAMEshared VPN gateway to use (implies --net gateway)
--cpus CPUSCPU cores each may use
--memory MIBRAM limit each, in MiB
--width WIDTHscreen width in pixels
--height HEIGHTscreen height in pixels
--dpi DPIscreen density
--fps FPSframes per second
--tag TAGtag for selectors (repeatable)
--data-volume VOLUMEadopt an existing Docker volume as /data (one Android only)
--image IMAGErun this exact image instead of the one for the Android version

Example:

sf create -n 5 --android 13 --gpu igpu --tag eu
sf create --name shop --net vpn --vpn nl-ams.ovpn

sf start#

Start Androids.

sf start [--force] selector
ArgumentDescription
selectorwhich Androids
OptionDefaultDescription
--forcestart even when the farm is over its capacity estimate

Example:

sf start 1-10

sf restart#

Restart Androids.

sf restart [--force] selector
ArgumentDescription
selectorwhich Androids
OptionDefaultDescription
--forcestart even when the farm is over its capacity estimate

Example:

sf restart tag:eu

sf recreate#

Rebuild the containers of Androids (data is kept).

sf recreate [--force] selector
ArgumentDescription
selectorwhich Androids
OptionDefaultDescription
--forcestart even when the farm is over its capacity estimate

Example:

sf recreate 3

sf stop#

Stop Androids.

sf stop selector
ArgumentDescription
selectorwhich Androids

Example:

sf stop all

sf rm#

Alias: sf delete.

Delete Androids and, unless --keep-data, their data. With backup.auto_before_risky (the default) a backup is taken first.

sf rm [--keep-data] [--force] [-y] selector
ArgumentDescription
selectorwhich Androids
OptionDefaultDescription
--keep-datakeep the /data volume (it can be adopted again later)
--forcedelete even if the safety backup cannot be taken
-y, --yesdo not ask for confirmation

Example:

sf rm 7
sf rm tag:test --keep-data --yes

sf set#

Change per-Android settings. Keys are InstanceSpec fields, nested ones with a dot (network.mode, resources.cpus, device.locale). Lists are comma separated. default puts an optional setting back to following the farm's value.

sf set [--force] selector key=value [key=value ...]
ArgumentDescription
selectorwhich Androids
key=valueone or more settings
OptionDefaultDescription
--forceallow a change that can lose data (another Android version on existing data)

Example:

sf set 1-5 fps=30 network.mode=vpn tags=eu,shop
sf set 3 gpu_mode=default

sf info#

Show one Android in detail.

sf info [--device] id
ArgumentDescription
idAndroid id
OptionDefaultDescription
--devicealso ask the running Android about itself (model, build, battery)

Example:

sf info 3

sf logs#

Show the container logs of one Android.

sf logs [-n LINES] [--logcat] id
ArgumentDescription
idAndroid id
OptionDefaultDescription
-n, --lines LINES200lines to show (default: 200)
--logcatAndroid's own log (logcat) instead of the containers' output

Example:

sf logs 3 -n 50
sf logs 3 --logcat

sf gpu#

GPUs and the rendering mode of Androids.

CommandWhat it does
sf gpu lslist GPUs and the rendering choices on this machine
sf gpu setchoose how Androids draw (applied at their next restart)

sf gpu ls#

List GPUs and the rendering choices on this machine.

sf gpu ls

Example:

sf gpu ls

sf gpu set#

Choose how Androids draw (applied at their next restart).

sf gpu set [--node DEVICE] selector {auto,software,igpu,dgpu,intel,amd,nvidia,default}
ArgumentDescription
selectorwhich Androids
{auto,software,igpu,dgpu,intel,amd,nvidia,default}default follows the farm's gpu.mode again
OptionDefaultDescription
--node DEVICEpin one card, e.g. /dev/dri/renderD129 (empty string: unpin)

Example:

sf gpu set 1-8 igpu
sf gpu set 9 nvidia --node /dev/dri/renderD129

sf image#

Android images, one per Android version.

CommandWhat it does
sf image lslist the image of every configured Android version
sf image pulldownload and prepare the image of one Android version
sf image buildrebuild an image with its overlays (camera, GPU runtime)

sf image ls#

List the image of every configured Android version.

sf image ls

Example:

sf image ls

sf image pull#

Download and prepare the image of one Android version.

sf image pull version
ArgumentDescription
versionAndroid version, e.g. 13

Example:

sf image pull 13

sf image build#

Rebuild an image with its overlays (camera, GPU runtime).

sf image build version
ArgumentDescription
versionAndroid version, e.g. 13

Example:

sf image build 13

sf tasks#

List background tasks, or show, follow and cancel one.

sf tasks [--active] [--cancel] [id]
ArgumentDescription
idtask id, e.g. t12
OptionDefaultDescription
--activeonly tasks still running
--cancelask the task to stop

Example:

sf tasks
sf tasks t12 --wait
sf tasks t12 --cancel

sf top#

Live load of the host, the GPUs and every running Android.

sf top [--interval SECONDS] [--once]
OptionDefaultDescription
--interval SECONDS3.0refresh interval (default: 3)
--onceprint one snapshot and exit

Example:

sf top

sf open#

Print the panel's address and how to log in.

sf open

Example:

sf open

sf shell#

Run one command on every selected Android and show each one's output. The words after -- are the command, passed as separate arguments (no shell on this machine ever sees them). Obviously destructive commands are refused unless --force.

sf shell [--root] [--timeout SECONDS] [--force] selector
ArgumentDescription
selectorwhich Androids
OptionDefaultDescription
--rootrun as root inside the Android
--timeout SECONDStime limit per Android (default: control.shell_timeout)
--forcerun a command the safety denylist would refuse

Example:

sf shell all -- getprop ro.build.version.release
sf shell 3 --root -- ls /data/app

sf screenshot#

Save a screenshot of one Android.

sf screenshot [-o FILE] id
ArgumentDescription
idAndroid id
OptionDefaultDescription
-o, --output FILEwhere to save (default: android-<id>.png)

Example:

sf screenshot 3 -o shot.png

sf apps#

The app library: APK / XAPK / APKS / APKM files kept by the farm.

CommandWhat it does
sf apps lslist the apps in the library
sf apps addupload an app file into the library
sf apps rmremove an app from the library

sf apps ls#

List the apps in the library.

sf apps ls

Example:

sf apps ls

sf apps add#

Upload an app file into the library.

sf apps add FILE [FILE ...]
ArgumentDescription
FILEAPK, XAPK, APKS or APKM file

Example:

sf apps add ~/Downloads/shop-4.2.apk

sf apps rm#

Remove an app from the library.

sf apps rm app_id
ArgumentDescription
app_idapp id as shown by sf apps ls

Example:

sf apps rm com.example.shop-42

sf app#

Apps on the Androids: install, launch, stop, clear, compare versions.

CommandWhat it does
sf app installinstall an app from the library
sf app ensureinstall an app only where it is missing or older
sf app uninstallremove an app
sf app launchopen an app
sf app stopforce-stop an app
sf app clearerase an app's data (as after a fresh install)
sf app matrixwhich version of which app is installed where

sf app install#

Install an app from the library.

sf app install [--no-grant] [--downgrade] selector app
ArgumentDescription
selectorwhich Androids
appapp id from sf apps ls, or a package name (its newest version is used)
OptionDefaultDescription
--no-grantdo not grant the app's runtime permissions
--downgradeallow replacing a newer installed version

Example:

sf app install 1-10 com.example.shop

sf app ensure#

Install an app only where it is missing or older.

sf app ensure [--no-grant] selector app
ArgumentDescription
selectorwhich Androids
appapp id from sf apps ls, or a package name (its newest version is used)
OptionDefaultDescription
--no-grantdo not grant the app's runtime permissions

Example:

sf app ensure all com.example.shop

sf app uninstall#

Remove an app.

sf app uninstall [--keep-data] selector package
ArgumentDescription
selectorwhich Androids
packagepackage name, e.g. com.example.shop
OptionDefaultDescription
--keep-datakeep the app's data and cache

Example:

sf app uninstall tag:test com.example.shop

sf app launch#

Open an app.

sf app launch selector package
ArgumentDescription
selectorwhich Androids
packagepackage name, e.g. com.example.shop

Example:

sf app launch all com.example.shop

sf app stop#

Force-stop an app.

sf app stop selector package
ArgumentDescription
selectorwhich Androids
packagepackage name, e.g. com.example.shop

Example:

sf app stop all com.example.shop

sf app clear#

Erase an app's data (as after a fresh install).

sf app clear selector package
ArgumentDescription
selectorwhich Androids
packagepackage name, e.g. com.example.shop

Example:

sf app clear 3 com.example.shop

sf app matrix#

Which version of which app is installed where.

sf app matrix [selector]
ArgumentDescription
selectorwhich Androids (default: all)

Example:

sf app matrix running

sf push#

Copy a local file onto Androids.

sf push selector local [remote]
ArgumentDescription
selectorwhich Androids
localfile on this machine
remotefolder (ending in /) or full path on the Android (default: /sdcard/Download/)

Example:

sf push all notes.txt /sdcard/Download/

sf pull#

Copy a file from one Android to this machine.

sf pull [-o PATH] id remote
ArgumentDescription
idAndroid id
remotefile path on the Android
OptionDefaultDescription
-o, --output PATHlocal file or folder (default: the file's name, here)

Example:

sf pull 3 /sdcard/Download/report.pdf

Add a picture or video to the gallery of Androids.

sf gallery selector local
ArgumentDescription
selectorwhich Androids
localpicture or video on this machine

Example:

sf gallery 1-5 photo.jpg

sf input#

Send the same touch or key to many Androids at once.

CommandWhat it does
sf input taptap a point of the screen
sf input texttype text into the focused field
sf input keypress a key

sf input tap#

Tap one point on every selected Android. Coordinates are fractions of the screen (0.5 0.9 = centre, near the bottom), so one command fits every resolution.

sf input tap [--pixels] selector x y
ArgumentDescription
selectorwhich Androids
x0 (left) to 1 (right)
y0 (top) to 1 (bottom)
OptionDefaultDescription
--pixelsx and y are pixels, not fractions

Example:

sf input tap 1-10 0.5 0.9

sf input text#

Type text into the focused field.

sf input text selector text
ArgumentDescription
selectorwhich Androids
texttext to type (it appears in this machine's process list; never type secrets this way)

Example:

sf input text 3 'hello world'

sf input key#

Press a key.

sf input key selector key
ArgumentDescription
selectorwhich Androids
keykey name (HOME, BACK, ENTER, APP_SWITCH, ...) or an Android key code

Example:

sf input key all HOME

sf window#

Native device windows (scrcpy) on the desktop the daemon runs on.

CommandWhat it does
sf window openopen a window for each selected Android
sf window gridopen windows tiled to fill the screen
sf window closeclose device windows

sf window open#

Open a window for each selected Android.

sf window open selector
ArgumentDescription
selectorwhich Androids

Example:

sf window open 3

sf window grid#

Open windows tiled to fill the screen.

sf window grid selector
ArgumentDescription
selectorwhich Androids

Example:

sf window grid 1-12

sf window close#

Close device windows.

sf window close selector
ArgumentDescription
selectorwhich Androids (all closes every window, also of deleted Androids)

Example:

sf window close all

sf vpn#

VPN profiles, logins and tunnel status.

CommandWhat it does
sf vpn profileslist the imported VPN profiles
sf vpn importimport OpenVPN (.ovpn) or WireGuard (.conf) profiles
sf vpn rmremove a VPN profile
sf vpn credentialsstore the username and password a VPN profile logs in with
sf vpn statustunnel state, public address and kill switch of Androids

sf vpn profiles#

List the imported VPN profiles.

sf vpn profiles

Example:

sf vpn profiles

sf vpn import#

Import OpenVPN (.ovpn) or WireGuard (.conf) profiles.

sf vpn import FILE [FILE ...]
ArgumentDescription
FILE

Example:

sf vpn import ~/vpn/nl-ams.ovpn ~/vpn/de-fra.ovpn

sf vpn rm#

Remove a VPN profile.

sf vpn rm name
ArgumentDescription
nameprofile name as shown by sf vpn profiles

Example:

sf vpn rm nl-ams.ovpn

sf vpn credentials#

Store a VPN login under a name (network.vpn.credentials says which name profiles use; default unless changed). The password is asked for without echo, or read from stdin with --password-stdin; it is never taken from the command line. Stored logins cannot be read back, only replaced or deleted. Without a name: list the names that exist.

sf vpn credentials [--username USERNAME] [--password-stdin] [--delete] [name]
ArgumentDescription
namecredentials name, e.g. default
OptionDefaultDescription
--username USERNAMEVPN account name (asked for when omitted)
--password-stdinread the password from stdin (one line)
--deletedelete the stored login

Example:

sf vpn credentials default
printf '%s' "$VPN_PASSWORD" | sf vpn credentials default --username myaccount --password-stdin

sf vpn status#

Tunnel state, public address and kill switch of Androids.

sf vpn status [--refresh] [selector]
ArgumentDescription
selectorwhich Androids (default: running)
OptionDefaultDescription
--refreshask the public address again from inside each Android's network (a few seconds each)

Example:

sf vpn status running
sf vpn status 3 --refresh

sf gateway#

Shared VPN gateways: one tunnel for many Androids.

CommandWhat it does
sf gateway lslist gateways and their state
sf gateway adddefine a gateway (or change an existing one)
sf gateway rmremove a gateway (asks first)
sf gateway upstart a gateway and wait for its tunnel
sf gateway downstop a gateway

sf gateway ls#

List gateways and their state.

sf gateway ls

Example:

sf gateway ls

sf gateway add#

Define a gateway (or change an existing one).

sf gateway add --profile PROFILE [--provider {openvpn,wireguard}] [--credentials CREDENTIALS]
               [--subnet SUBNET]
               name
ArgumentDescription
namegateway name, e.g. eu
OptionDefaultDescription
--profile PROFILEVPN profile the gateway connects with
--provider {openvpn,wireguard}openvpn
--credentials CREDENTIALSdefaultcredentials name (default: default)
--subnet SUBNETprivate /24 for its Androids (default: next free one from docker.subnet_pool)

Example:

sf gateway add eu --profile nl-ams.ovpn

sf gateway rm#

Remove a gateway (asks first).

sf gateway rm [--force] [-y] name
ArgumentDescription
name
OptionDefaultDescription
--forceremove it even while Androids are attached
-y, --yesdo not ask for confirmation

Example:

sf gateway rm eu

sf gateway up#

Start a gateway and wait for its tunnel.

sf gateway up name
ArgumentDescription
name

Example:

sf gateway up eu

sf gateway down#

Stop a gateway.

sf gateway down [--force] name
ArgumentDescription
name
OptionDefaultDescription
--forcestop it even while Androids are attached

Example:

sf gateway down eu

sf camera#

Feed a video or live stream into the camera and microphone of Androids.

CommandWhat it does
sf camera statusshow whether the virtual camera is ready, what plays where, and the sources
sf camera playplay a media file (or the live RTMP ingest) as the camera of Androids
sf camera stopstop the camera feed
sf camera micmute, unmute or solo the microphone of Androids

sf camera status#

Show whether the virtual camera is ready, what plays where, and the sources.

sf camera status

Example:

sf camera status

sf camera play#

Play a media file (or the live RTMP ingest) as the camera of Androids.

sf camera play [--sound SOUND] selector source
ArgumentDescription
selectorwhich Androids
sourcea file from the media library (see sf camera status), or rtmp for the live ingest
OptionDefaultDescription
--sound SOUNDsourcemicrophone sound: source (the video's own, default), none, or another library file

Example:

sf camera play 1-5 intro.mp4
sf camera play 3 rtmp --sound none

sf camera stop#

Stop the camera feed.

sf camera stop [selector]
ArgumentDescription
selectorwhich Androids (default: every Android)

Example:

sf camera stop 1-5

sf camera mic#

Mute, unmute or solo the microphone of Androids.

sf camera mic selector {mute,unmute,solo}
ArgumentDescription
selectorwhich Androids
{mute,unmute,solo}solo: unmute these and mute every other

Example:

sf camera mic 3 solo

sf listen#

Hear one Android on the speakers of the machine the daemon runs on.

sf listen [ID|off]
ArgumentDescription
`IDoff`

Example:

sf listen 3
sf listen off

sf auto#

Automation. Record a task a few times in the panel, train the recordings into a program (sf auto train), then run it on any selection of Androids (sf auto run). Flows are hand-written YAML scripts run the same way.

CommandWhat it does
sf auto datasetslist datasets (groups of recordings of one task)
sf auto trainturn a dataset's recordings into one program
sf auto programslist trained programs
sf auto flowshand-written YAML flows (bare: list them)
sf auto runrun a program or a flow on Androids
sf auto runslist runs, or show one run device by device
sf auto resolvelet a device that waits for attention continue, skip the step or stop
sf auto valuesvalues that runs type in: shared, per Android, and pools (bare: list them)
sf auto schedulerecurring runs (bare: list them)

sf auto datasets#

List datasets (groups of recordings of one task).

sf auto datasets

Example:

sf auto datasets

sf auto train#

Turn a dataset's recordings into one program.

sf auto train dataset
ArgumentDescription
datasetdataset id as shown by sf auto datasets

Example:

sf auto train open-settings

sf auto programs#

List trained programs.

sf auto programs

Example:

sf auto programs

sf auto flows#

Hand-written YAML flows (bare: list them).

CommandWhat it does
sf auto flows lslist flows, including the shipped examples
sf auto flows showprint a flow's YAML
sf auto flows validatecheck a YAML file without saving it
sf auto flows savesave a YAML file as a flow (validated first)
sf auto flows rmdelete a flow

sf auto flows ls#

List flows, including the shipped examples.

sf auto flows ls

Example:

sf auto flows ls

sf auto flows show#

Print a flow's YAML.

sf auto flows show name
ArgumentDescription
name

Example:

sf auto flows show examples/open-app

sf auto flows validate#

Check a YAML file without saving it.

sf auto flows validate file
ArgumentDescription
fileYAML file, or - for stdin

Example:

sf auto flows validate login.yaml

sf auto flows save#

Save a YAML file as a flow (validated first).

sf auto flows save name file
ArgumentDescription
nameflow name
fileYAML file, or - for stdin

Example:

sf auto flows save login login.yaml

sf auto flows rm#

Delete a flow.

sf auto flows rm name
ArgumentDescription
name

Example:

sf auto flows rm login

sf auto run#

Run a trained program or a flow on every selected Android, each on its own. A device that meets a screen no rule covers stops and waits (see sf auto runs <task> and sf auto resolve); the others carry on.

sf auto run [--var NAME=VALUE] [--secret NAME] [--dry-run] {program,flow} name selector
ArgumentDescription
{program,flow}
nameprogram or flow name
selectorwhich Androids
OptionDefaultDescription
--var NAME=VALUEa value for this run (repeatable)
--secret NAMEa value for this run that is asked for without echo, or read from stdin (repeatable)
--dry-runfind every element but do not tap or type

Example:

sf auto run flow examples/open-app 1-10 --var package=com.android.settings
sf auto run program sign-in tag:eu --var user=demo --secret password

sf auto runs#

List runs, or show one run device by device.

sf auto runs [--active] [task]
ArgumentDescription
tasktask id of a run
OptionDefaultDescription
--activeonly runs still going

Example:

sf auto runs
sf auto runs t12

sf auto resolve#

Let a device that waits for attention continue, skip the step or stop.

sf auto resolve task id [{resume,skip,abort}]
ArgumentDescription
tasktask id of the run
idAndroid id
{resume,skip,abort}resume: you fixed the screen, carry on (default). skip: skip this step. abort: stop this device

Example:

sf auto resolve t12 4 resume

sf auto values#

Values that runs type in: shared, per Android, and pools (bare: list them).

CommandWhat it does
sf auto values lslist stored values and pools
sf auto values setstore a value
sf auto values rmremove a value
sf auto values pool-addadd lines to a pool (each line is handed out once)
sf auto values pool-rmdelete a pool

sf auto values ls#

List stored values and pools.

sf auto values ls [--instance ID]
OptionDefaultDescription
--instance IDthe values of one Android instead of the shared ones

Example:

sf auto values ls
sf auto values ls --instance 3

sf auto values set#

Store a value under a name; flows and programs use it as {name}. Leave the value out to be asked for it without echo (or to pipe it in), so it never appears in the process list or in shell history. Names that look like secrets (password, pin, otp, ...) are refused by the farm: pass those per run with sf auto run --secret.

sf auto values set [--instance ID] name [value]
ArgumentDescription
name
valuethe value; omit to type it hidden or read it from stdin
OptionDefaultDescription
--instance IDstore it for one Android only

Example:

sf auto values set city Berlin
sf auto values set invite-code        (asked for, not shown)

sf auto values rm#

Remove a value.

sf auto values rm [--instance ID] name
ArgumentDescription
name
OptionDefaultDescription
--instance IDremove the value of one Android

Example:

sf auto values rm city

sf auto values pool-add#

Add lines to a pool (each line is handed out once).

sf auto values pool-add name file
ArgumentDescription
namepool name
filetext file with one value per line, or - for stdin

Example:

sf auto values pool-add codes codes.txt

sf auto values pool-rm#

Delete a pool.

sf auto values pool-rm name
ArgumentDescription
name

Example:

sf auto values pool-rm codes

sf auto schedule#

Recurring runs (bare: list them).

CommandWhat it does
sf auto schedule lslist schedules
sf auto schedule addrun a program or flow on a timetable
sf auto schedule rmdelete a schedule
sf auto schedule enableswitch a schedule on
sf auto schedule disableswitch a schedule off without deleting it

sf auto schedule ls#

List schedules.

sf auto schedule ls

Example:

sf auto schedule ls

sf auto schedule add#

Run a program or flow on a timetable.

sf auto schedule add [--every SECONDS] [--cron LINE] [--var NAME=VALUE] [--dry-run]
                     name {program,flow} target selector
ArgumentDescription
namea name for the schedule
{program,flow}
targetprogram or flow name
selectorwhich Androids
OptionDefaultDescription
--every SECONDSrun every so many seconds
--cron LINEcron line: minute hour day-of-month month day-of-week
--var NAME=VALUEa value for this run (repeatable)
--dry-runfind every element but do not tap or type

Example:

sf auto schedule add nightly flow examples/open-app all --cron '0 3 * * *' --var package=com.android.settings

sf auto schedule rm#

Delete a schedule.

sf auto schedule rm id
ArgumentDescription
id

Example:

sf auto schedule rm s3

sf auto schedule enable#

Switch a schedule on.

sf auto schedule enable id
ArgumentDescription
id

Example:

sf auto schedule enable s3

sf auto schedule disable#

Switch a schedule off without deleting it.

sf auto schedule disable id
ArgumentDescription
id

Example:

sf auto schedule disable s3

sf backup#

Back up and restore Androids and the farm's settings.

CommandWhat it does
sf backup createback up the data of Androids
sf backup listlist the backups
sf backup verifycheck a backup against its recorded checksums
sf backup restorerestore a backup as a new Android, or over an existing one
sf backup prunedelete old backups, keeping the newest backup.keep of each Android
sf backup farmback up the farm itself: settings, Android definitions, automation

sf backup create#

Back up /data of every selected Android (tar + manifest with checksums). A running Android is stopped for the copy and started again when backup.stop_for_backup is on.

sf backup create selector
ArgumentDescription
selectorwhich Androids

Example:

sf backup create 1-5

sf backup list#

Alias: sf backup ls.

List the backups.

sf backup list [--kind {android,farm,all}]
OptionDefaultDescription
--kind {android,farm,all}allwhich backups (default: all)

Example:

sf backup list

sf backup verify#

Check a backup against its recorded checksums.

sf backup verify [--deep] archive
ArgumentDescription
archivebackup name as shown by sf backup list
OptionDefaultDescription
--deepalso read the whole archive to check it can be unpacked

Example:

sf backup verify android-3/20250101-040000

sf backup restore#

Without --over the backup becomes a NEW Android and nothing existing is touched. With --over ID that Android's data is replaced: it must be stopped, and you are asked first. A farm backup (farm/<time>) merges settings into this farm and never overwrites what exists. One this farm made itself is restored in full; from any other, only what cannot decide what runs on this machine is taken unless you say so with the flags below.

sf backup restore [--over ID] [--keep-network] [-y] [--trust] [--restore-config]
                  [--restore-secrets]
                  archive
ArgumentDescription
archivebackup name as shown by sf backup list
OptionDefaultDescription
--over IDreplace the data of this existing Android (asks first)
--keep-networkrestoring as new: keep the network on even though the original Android still exists
-y, --yesdo not ask for confirmation
--trustfarm backup from elsewhere: keep the Androids exactly as saved (custom image, data volume, boot arguments, autostart) and the schedules. Only for a backup you made yourself: it decides what runs on this machine with full privileges
--restore-configfarm backup from elsewhere: also take its config.yaml (never implied by --trust)
--restore-secretsfarm backup from elsewhere: also take its VPN profiles, logins and tokens

Example:

sf backup restore android-3/20250101-040000
sf backup restore android-3/20250101-040000 --over 3
sf backup restore farm/20250101-050000

sf backup prune#

Delete old backups, keeping the newest backup.keep of each Android.

sf backup prune

Example:

sf backup prune

sf backup farm#

Back up the farm itself: settings, Android definitions, automation.

sf backup farm [--include-secrets]
OptionDefaultDescription
--include-secretsalso store VPN logins and tokens (the archive is then owner-only; keep it private)

Example:

sf backup farm

sf mcp#

Run the farm's MCP server. Alone, sf mcp speaks MCP over stdin/stdout: this is what a desktop assistant or IDE agent launches (see sf mcp config). With --http it serves Streamable HTTP on this machine only. Actions that change the farm follow ai.policy and wait for your Yes or No (sf approvals). Details: docs/MCP.md.

CommandWhat it does
sf mcp configprint the configuration snippet for an MCP client
sf mcp toolslist the tools an assistant gets, with their class and what the policy does

sf mcp config#

Print the mcpServers entry an MCP client needs to start this farm's server, with the absolute paths of this install. It never contains the API token.

sf mcp config [--http] [--port PORT]
OptionDefaultDescription
--httpthe snippet for the HTTP endpoint instead of stdio
--port PORTport of the HTTP endpoint (default: ai.mcp.http_port)

Example:

sf mcp config
sf mcp config --http

sf mcp tools#

List the tools an assistant gets, with their class and what the policy does.

sf mcp tools [--markdown]
OptionDefaultDescription
--markdownprint the tool reference as Markdown (docs/MCP.md is built from it)

Example:

sf mcp tools
sf mcp tools --markdown

sf approvals#

An AI assistant that wants to change the farm waits for your Yes or No. Alone, sf approvals lists the requests.

CommandWhat it does
sf approvals lslist approval requests, newest first
sf approvals approvesay yes to a request: the action runs
sf approvals denysay no to a request: nothing runs and the assistant is told
sf approvals watchanswer requests in the terminal as they arrive

sf approvals ls#

List approval requests, newest first.

sf approvals ls [--state {pending,approved,denied,expired}] [-n LIMIT]
OptionDefaultDescription
--state {pending,approved,denied,expired}only requests in this state
-n, --limit LIMIT30how many (default: 30)

Example:

sf approvals ls
sf approvals ls --state pending

sf approvals approve#

Say yes to a request: the action runs.

sf approvals approve [--remember] id
ArgumentDescription
idrequest id as shown by sf approvals ls
OptionDefaultDescription
--rememberalso approve the same tool on the same Androids for the rest of that assistant session (not for destructive actions)

Example:

sf approvals approve 3f9a1c2e

sf approvals deny#

Say no to a request: nothing runs and the assistant is told.

sf approvals deny [--reason REASON] id
ArgumentDescription
idrequest id as shown by sf approvals ls
OptionDefaultDescription
--reason REASON``shown to the assistant

Example:

sf approvals deny 3f9a1c2e --reason 'not during business hours'

sf approvals watch#

Wait for approval requests and ask yes or no for each, until Ctrl-C.

sf approvals watch

Example:

sf approvals watch

sf ask#

Send one request to the farm's built-in Assistant and print its steps and its answer. Actions that change the farm follow ai.policy: under ask each one is shown and waits for y or n here (or in the panel). The last line is the farm's own record of what ran.

sf ask [--model MODEL] [--keep] request [request ...]
ArgumentDescription
requestwhat you want, in plain words (quote it)
OptionDefaultDescription
--model MODELmodel profile to use (default: ai.default_model)
--keepkeep the conversation afterwards (see: sf ai conversations)

Example:

sf ask "how many Androids are running, and how many can this machine run?"
sf ask --model local "start every Android tagged eu"

sf ai#

Model profiles (which model, where), the built-in Assistant, and the AI Pilot, which turns a model operating an app into a program that replays without one. See docs/AI.md.

CommandWhat it does
sf ai chattalk with the built-in Assistant
sf ai conversationslist the Assistant's conversations
sf ai modelsmodel profiles: where a model lives and what it can do
sf ai pilotteach the farm a task: a model operates the app, the runs become a program

sf ai chat#

Talk with the built-in Assistant.

sf ai chat [--model MODEL]
OptionDefaultDescription
--model MODELmodel profile to use (default: ai.default_model)

Example:

sf ai chat
sf ai chat --model local

sf ai conversations#

List the Assistant's conversations.

sf ai conversations

Example:

sf ai conversations

sf ai models#

Model profiles: where a model lives and what it can do.

CommandWhat it does
sf ai models lslist the configured profiles
sf ai models testreally test a profile: server, model, a reply, a tool call
sf ai models addadd or replace a profile
sf ai models keystore a profile's API key (typed here, kept in secrets, never shown)
sf ai models rmremove a profile

sf ai models ls#

List the configured profiles.

sf ai models ls

Example:

sf ai models ls

sf ai models test#

Really test a profile: server, model, a reply, a tool call.

sf ai models test name
ArgumentDescription
nameprofile name

Example:

sf ai models test local

sf ai models add#

Add or replace a profile.

sf ai models add --provider {ollama,openai} [--base-url BASE_URL] [--model MODEL]
                 [--key-name KEY_NAME] [--vision] [--no-tools] [--timeout TIMEOUT] [--default]
                 name
ArgumentDescription
nameprofile name: lower-case letters, digits, - and _
OptionDefaultDescription
--provider {ollama,openai}wire format: an Ollama server, or any OpenAI-compatible chat-completions API
--base-url BASE_URLserver address (default: http://127.0.0.1:11434)
--model MODELmodel name on that server (default: the first it lists)
--key-name KEY_NAMENAME of the secret that will hold the API key (then: sf ai models key)
--visionthe model reads pictures
--no-toolsthe model cannot call tools
--timeout TIMEOUTseconds to wait for one answer (default: 120)
--defaultmake this the default profile

Example:

sf ai models add local --provider ollama --model <name> --default
sf ai models add hosted --provider openai --base-url https://api.example.com --model <name> --key-name hosted-key

sf ai models key#

Store a profile's API key (typed here, kept in secrets, never shown).

sf ai models key name
ArgumentDescription
nameprofile name

Example:

sf ai models key hosted

sf ai models rm#

Remove a profile.

sf ai models rm name
ArgumentDescription
nameprofile name

Example:

sf ai models rm hosted

sf ai pilot#

With a goal: start a Pilot session on the selected Androids. A model operates the app one action at a time and every action is recorded; a run counts only when the success check really holds. Train the recordings (--train, or sf ai pilot train) into a program that replays with no model: sf auto run program <dataset> <selector>.

With a word: sessions | show <session> | cancel <session> | resolve <session> <android> resume|skip|abort | confirm <session> <android> | train <dataset>.

sf ai pilot [--app PACKAGE] [--success CHECK] [--runs RUNS] [--model MODEL]
            [--max-steps MAX_STEPS] [--dataset DATASET] [--value NAME=VALUE] [--ask-value NAME]
            [--train] [--steps]
            GOAL SELECTOR | WORD ... [GOAL SELECTOR | WORD ... ...]
ArgumentDescription
`GOAL SELECTORWORD ...`
OptionDefaultDescription
--app PACKAGEthe app to operate, e.g. com.android.settings
--success CHECKwhat must be on screen when the goal is reached: text:..., id:..., desc:..., package:... or activity:... (without it a run can only be checked by the model's own evidence)
--runs RUNS1runs per Android (default: 1; three or more give a real consensus)
--model MODELmodel profile to use (default: ai.default_model)
--max-steps MAX_STEPSactions per run (default: ai.pilot.max_steps)
--dataset DATASETdataset to record into (default: named after the goal)
--value NAME=VALUEa value the Pilot may type by name (kept in memory for this session only)
--ask-value NAMElike --value, but the value is asked for here without being shown (use it for secrets)
--traintrain the dataset when the session ends with verified runs
--stepswith show: list every action and the model's reason for it

Example:

sf ai pilot "open the date and time settings" 1 --app com.android.settings --success "text:Set time automatically" --runs 3 --train
sf ai pilot sessions
sf ai pilot show t12 --steps
sf ai pilot resolve t12 3 resume
sf ai pilot confirm t12 3
sf ai pilot train open-the-date-and-time-settings

sf doctor#

Check that this machine can run Androids, with the fix for each problem.

sf doctor

Example:

sf doctor

sf host#

Prepare and inspect this machine (kernel modules, limits, GPUs).

CommandWhat it does
sf host planshow every command host setup would run, changing nothing
sf host applycarry out host setup (re-runs itself under sudo)
sf host capacityestimate how many Androids this machine can run at once
sf host gpuslist the GPUs found and the rendering modes they allow
sf host sign-modulesign a self-built kernel module for Secure Boot (virtual camera)

sf host plan#

Show every command host setup would run, changing nothing.

sf host plan [--boot]
OptionDefaultDescription
--bootonly what must be redone after every reboot

Example:

sf host plan

sf host apply#

Install packages, load kernel modules, raise kernel limits, create runtime folders and install the systemd units. Needs root: started as a normal user it continues under sudo, keeping your farm home. Safe to repeat.

sf host apply [--dry-run] [--boot]
OptionDefaultDescription
--dry-runprint every command and file, change nothing
--bootonly what must be redone after every reboot

Example:

sf host apply
sf host apply --dry-run

sf host capacity#

Estimate how many Androids this machine can run at once.

sf host capacity [--workload {video,light}]
OptionDefaultDescription
--workload {video,light}videovideo: apps playing video, the heaviest case measured (default). light: mostly idle screens

Example:

sf host capacity

sf host gpus#

List the GPUs found and the rendering modes they allow.

sf host gpus

Example:

sf host gpus

sf host sign-module#

Run scripts/host/sign-module.sh. Without arguments it reports the Secure Boot state and the signing key in use. Arguments after -- go to the script (see its --help); anything but a status report runs under sudo.

sf host sign-module

Example:

sf host sign-module                              (status report)
sf host sign-module -- --create-key --enroll v4l2loopback

sf config#

Read and change the farm's settings (config.yaml).

CommandWhat it does
sf config getprint one setting
sf config setchange one setting (validated before it is saved)
sf config unsetput one setting back to its default
sf config showprint all settings in effect
sf config pathprint where config.yaml is
sf config docsrender the settings reference (docs/CONFIGURATION.md)

sf config get#

Print one setting.

sf config get key
ArgumentDescription
keydotted key, e.g. network.vpn.selection

Example:

sf config get android.fps

sf config set#

Change one setting (validated before it is saved).

sf config set key value
ArgumentDescription
keydotted key, e.g. android.fps
valuenew value; lists are comma separated

Example:

sf config set android.fps 25
sf config set network.dns 1.1.1.1,9.9.9.9

sf config unset#

Put one setting back to its default.

sf config unset key
ArgumentDescription
keydotted key

Example:

sf config unset android.fps

sf config show#

Print all settings in effect.

sf config show [--changed]
OptionDefaultDescription
--changedonly what differs from the defaults (the file's content)

Example:

sf config show --changed

sf config path#

Print where config.yaml is.

sf config path

Example:

sf config path

sf config docs#

Render the settings reference (docs/CONFIGURATION.md).

sf config docs [-o FILE] [--check FILE]
OptionDefaultDescription
-o, --output FILEwrite to FILE instead of printing
--check FILEexit 1 when FILE differs from what would be generated (for CI)

Example:

sf config docs -o docs/CONFIGURATION.md
sf config docs --check docs/CONFIGURATION.md

sf token#

Print the API token the panel and scripts log in with.

sf token [--rotate]
OptionDefaultDescription
--rotatereplace the token; the old one stops working at once

Example:

sf token
sf token --rotate

sf serve#

Run the daemon in the foreground until Ctrl-C. Androids keep running when it stops.

sf serve [--host HOST] [--port PORT]
OptionDefaultDescription
--host HOSTlisten address (default: server.host, 127.0.0.1)
--port PORTlisten port (default: server.port, 7700)

Example:

sf serve
sf serve --port 7701

sf service#

Run the daemon as a systemd user service.

CommandWhat it does
sf service installwrite and enable the user service
sf service startstart the daemon in the background
sf service stopstop the daemon (Androids keep running)
sf service statusshow whether the daemon runs
sf service logsshow the daemon's log

sf service install#

Write and enable the user service.

sf service install

Example:

sf service install

sf service start#

Start the daemon in the background.

sf service start

Example:

sf service start

sf service stop#

Stop the daemon (Androids keep running).

sf service stop

Example:

sf service stop

sf service status#

Show whether the daemon runs.

sf service status

Example:

sf service status

sf service logs#

Show the daemon's log.

sf service logs [-n LINES] [-f]
OptionDefaultDescription
-n, --lines LINES100lines to show (default: 100)
-f, --followkeep printing new lines

Example:

sf service logs -f

sf version#

Print the version.

sf version

Example:

sf version

sf completion#

Print a shell completion script.

sf completion {bash,zsh}
ArgumentDescription
{bash,zsh}

Example:

sf completion bash > ~/.local/share/bash-completion/completions/sf
sf completion zsh > ~/.zfunc/_sf

Next#

This page is docs/CLI.md in the repository.