Complete reference for configuring and running the ControlFloor Provider.
The ControlFloor Provider runs on each Mac that has iOS devices physically connected. It manages device detection, agent launching, video streaming relay, and command forwarding between the Server and on-device agents.
The Provider is configured via ~/cf/provider/config.json.
| Field | Type | Description |
|---|---|---|
| controlfloor.host | string | Server hostname and port (e.g., "localhost:8080") |
| controlfloor.https | bool | Use HTTPS to connect to the server |
| controlfloor.selfSigned | bool | Allow self-signed TLS certificates |
| licenseKeys | array | List of license key strings |
| name | string | Provider name (set during registration) |
| password | string | Provider authentication password (set during registration) |
| portRange | object | Port range for device communication (e.g., {"start": 9300, "end": 9400}) |
| videoPortRange | object | Port range for video streaming (e.g., {"start": 9400, "end": 9500}) |
| rsdMethod | string | RSD tunnel method for iOS 17+ ("internal", "pmd3", "tunneld", "none") |
| alerts | string | Path to custom alert rules file |
| logLevel | string | Logging verbosity ("debug", "info", "warn", "error") |
{
"controlfloor": {
"host": "controlfloor.internal:8080",
"https": true,
"selfSigned": false
},
"licenseKeys": ["CF-XXXX-XXXX-XXXX-XXXX"],
"name": "provider1",
"password": "auto-generated-password",
"portRange": { "start": 9300, "end": 9400 },
"videoPortRange": { "start": 9400, "end": 9500 },
"rsdMethod": "internal",
"logLevel": "info"
}Run the Provider for a single specific device:
$ ./cfprovider run --udid 00008030-001A2B3C4D5E6F70Useful for development, debugging, or when you need to manage a specific device independently.
Automatically manage all connected devices:
$ ./cfprovider runnerRunner mode continuously monitors for device connections and disconnections. It automatically launches agents on new devices, handles reconnections, and keeps everything running. This is the recommended mode for production.
iOS 17 replaced the traditional usbmuxd communication with Remote Service Discovery (RSD).
Configure the tunnel method in config.json via the
rsdMethod field.
"rsdMethod": "internal"
ControlFloor's own QUIC tunnel implementation using remotedtool
and utunuds helper binaries. These must be set to suid root.
Locking is handled internally, and sudo is not required at runtime. This is the default
and recommended method.
Note: The internal method does not support a short range of early iOS 17
firmware versions where CoreDevice tunnels were not yet available. For those devices,
use the pmd3 method instead.
"rsdMethod": "pmd3"Uses pymobiledevice3 to create individual QUIC tunnels per device. Requires Python 3 and pymobiledevice3 to be installed. A file lock prevents race conditions when multiple tunnels are created simultaneously. Tunnel creation takes approximately 5 seconds per device.
"rsdMethod": "tunneld"
Uses pymobiledevice3's tunneld daemon process to manage
tunnels. Unlike the pmd3 method which creates individual
tunnels, this runs a single long-lived daemon that manages all device tunnels. You must
launch the daemon separately before starting the Provider:
$ sudo python3 -m pymobiledevice3 remote tunneld
When using this method, commands are issued with --tunnel [UDID]
instead of --rsd address/port options. This can be more
stable for large device farms but adds an external dependency.
"rsdMethod": "none"Disables RSD tunnel creation. Use this if you only have iOS 16 or earlier devices, or if you are managing tunnels externally and passing in RSD address/port manually.
License keys are added to the licenseKeys array in
config.json. Each key authorizes automation for one
device. Multiple keys can be listed for multi-device deployments.
"licenseKeys": [
"CF-AAAA-BBBB-CCCC-DDDD",
"CF-EEEE-FFFF-GGGG-HHHH"
]The Provider uses TCP ports for communicating with on-device agents. Ensure the configured port ranges are available and not blocked by firewalls.
portRange — TCP ports for agent commands (need one port per device)videoPortRange — TCP ports for video streaming (need one port per device)ControlFloor can automatically handle iOS system alerts (permission prompts, notification dialogs, etc.) using configurable rules.
Alert rules are defined in alerts.json (shipped with ControlFloor)
and can be extended with custom.alerts.json for app-specific dialogs.
// custom.alerts.json example
[
{
"title": "Allow Notifications",
"action": "Allow"
},
{
"title": "Location Access",
"action": "Allow While Using App"
}
]The Provider binary supports the following commands:
| Command | Description |
|---|---|
| run --udid <id> | Run for a single device |
| runner | Run for all connected devices (auto-detect) |
| register | Register this provider with the server |
| list-devices | List connected USB devices |
| device-info --udid <id> | Show detailed device information |
| version | Show provider version |
| help | Show help and all available commands |
For larger deployments, multiple Providers can connect to a single Server. Each Provider runs on a separate Mac with its own set of USB-connected devices.
./cfprovider registerEnsure each Provider uses non-overlapping port ranges if they share a network.