rk ecp
The rk ecp command sends External Control Protocol (ECP) commands for querying and controlling Roku devices. ECP is a RESTful API running on port 8060 that enables external control, debugging, and inspection of Roku apps.
See the generated command reference for more information about arguments, options, and defaults.
Requirements
Your setup must meet the following requirements:
- You must enable developer mode on the target Roku device by going to Settings > System > Advanced system settings > Developer options.
- You must have a Roku on your network (reachable by IP address or hostname) or a running Roku Cloud Emulator (RCE) device named with
--device rce:<name>. - The ECP API must be reachable on port 8060, which is its default port.
Synopsis
The following syntax shows how to run the command:
rk ecp <subcommand> [options]See rk logs for more information about server-backed log collection and search.
See the generated rk ecp reference for more information about every option, including device selection and the output and screenshot format.
On an RCE device, every subcommand works while the device is running. The keypress, input, query/app-ui, and capture-screen subcommands need developer mode on and ECP not limited. The query/device-info subcommand answers in either case and reports both states. The capture-screen subcommand goes through the device's installer and needs your sideloaded app in the foreground. See Screenshots for more information. Before developer mode is on, rk device input sends keys through RCE instead.
Migrating to the renamed command
The following changes apply to the renamed command:
- The primary command is
query/app-ui. - The
query-uialias is deprecated and emits a warning.
Commands
See the generated rk ecp reference for more information about the syntax of the query, keypress, input, and capture-screen commands.
Understanding device info output
The device info XML contains detailed hardware and software information:
- model-number: Device model (for example, "3941X" for Roku Express+)
- vendor-name: Manufacturer name (typically "Roku")
- serial-number: Unique device serial number
- software-version: Current firmware version
- software-build: Firmware build number
- device-id: Unique device identifier
- advertising-id: Advertising tracking identifier
- wifi-mac: Wi-Fi MAC address
- ethernet-mac: Ethernet MAC address (if applicable)
- network-type: Connection type ("wifi" or "ethernet")
- user-device-name: Custom device name that the user sets
- supports-ethernet: Whether the device has an Ethernet port
- supports-hdmi-5v: Whether the device supports HDMI 5V power
- ui-resolution: Current UI resolution (for example, "1080p")
- can-use-wifi-extender: Wi-Fi extender capability
Example XML output:
<device-info>
<model-number>3941X</model-number>
<vendor-name>Roku</vendor-name>
<software-version>12.5.0</software-version>
<user-device-name>Living Room</user-device-name>
<network-type>wifi</network-type>
<ui-resolution>1080p</ui-resolution>
</device-info>The following example shows the --json output, which is a key-value object:
{
"model-number": "3941X",
"vendor-name": "Roku",
"software-version": "12.5.0",
"user-device-name": "Living Room",
"network-type": "wifi",
"ui-resolution": "1080p"
}The following example shows the --pretty output, which is human-readable text:
model-number: 3941X
vendor-name: Roku
software-version: 12.5.0
user-device-name: Living Room
network-type: wifi
ui-resolution: 1080pUnderstanding UI query output
The XML output represents the SceneGraph node hierarchy at the moment of the query. Common attributes include:
- id: Node identifier (if set in your code)
- type: SceneGraph component type (for example, Group, Label, Rectangle, Button)
- focusable: Whether the node can receive focus (
trueorfalse) - focused: Whether the node currently has focus (
trueorfalse) - visible: Whether the node is visible (
trueorfalse) - translation: Node position
[x, y] - width/height: Node dimensions
- Component-specific fields: Varies by node type (for example,
textfor Label,urifor Poster)
Example output structure:
<app-ui>
<node id="root" type="Group" focusable="false" focused="false">
<node id="mainScene" type="Scene" focusable="true" focused="true">
<node id="button1" type="Button" focusable="true" text="Click Me" translation="[100, 50]"/>
<node id="label1" type="Label" text="Hello World" translation="[100, 150]"/>
</node>
</node>
</app-ui>The following example shows the same structure with --json:
{
"app-ui": {
"node": {
"id": "root",
"type": "Group",
"focusable": "false",
"focused": "false",
"node": {
"id": "mainScene",
"type": "Scene",
"focusable": "true",
"focused": "true",
"node": [
{
"id": "button1",
"type": "Button",
"focusable": "true",
"text": "Click Me",
"translation": "[100, 50]"
},
{
"id": "label1",
"type": "Label",
"text": "Hello World",
"translation": "[100, 150]"
}
]
}
}
}
}Use cases
The following examples show how to use rk ecp in common scenarios.
Device identification
The following command checks the device model and firmware version:
npx rk ecp query/device-info --jsonMulti-device testing
The following script collects device info for all test devices:
for device in device-1 device-2 device-3; do
npx rk ecp query/device-info --device $device --json --output devices/$device.json
doneDebugging layout issues
The following command captures the current UI state so that you can inspect it in an editor:
npx rk ecp query/app-ui --output current-layout.xmlAutomated UI testing
The following commands navigate through the UI and capture the resulting UI state:
npx rk ecp keypress Home
sleep 1
npx rk ecp keypress Down
npx rk ecp keypress Down
npx rk ecp keypress Select
sleep 2
npx rk ecp query/app-ui --json --output test-result.jsonRemote control automation
The following script launches and navigates to specific content:
npx rk ecp keypress Home
sleep 1
npx rk ecp keypress Down
npx rk ecp keypress Select
sleep 2
npx rk ecp keypress PlayText input automation
The following script enters a search query one character at a time:
search_term="Breaking Bad"
for ((i=0; i<${#search_term}; i++)); do
char="${search_term:$i:1}"
npx rk ecp keypress "Lit_$char"
sleep 0.1
done
npx rk ecp keypress EnterIntegration testing
The following commands test a complete user flow:
npx rk ecp keypress Home
sleep 1
# Navigate to app
npx rk ecp keypress Down
npx rk ecp keypress Right
npx rk ecp keypress Select
sleep 3
# Verify UI state
npx rk ecp query/app-ui --json | node validate-ui-structure.jsCI/CD integration
The following command saves a UI snapshot for regression testing:
npx rk ecp query/app-ui --device ci-roku --json --output snapshots/ui-$(date +%s).jsonFocus debugging
The following command shows which component has focus:
npx rk ecp query/app-ui --json | jq '.['"'"app-ui'"'"'].node | .. | select(.focused == "true")?'Additional ECP resources
The ECP API provides capabilities that rk ecp does not implement:
- App launch and install: Launches apps and installs them from a package URL
- Media playback control: Plays and pauses media, seeks, and queries playback state
- App queries: Lists installed apps and queries the active app
See the Roku External Control Protocol Guide and the Roku Input Interface for more information about ECP.
The rk ecp command provides the following capabilities:
- UI inspection (
query/app-ui) - Device info (
query/device-info) - Keypress simulation (
keypress) - Launch parameters (
input) - Screenshot capture (
capture-screen)
Troubleshooting
"Developer mode is not enabled on device"
Enable developer mode on your Roku device:
- Go to Settings > System > Advanced system settings.
- Select Developer options.
- Enable Developer mode.
- Restart your Roku device if prompted.
"Cannot connect to device"
Try the following steps:
- Verify that the device is powered on and connected to the network.
- Confirm the device IP address by running
npx rk device ls. - Check that the device is on the same local network as the development machine.
- Check that the firewall is not blocking port 8060.
- Try opening
http://<device-ip>:8060in a browser.
"Request timed out"
A timeout can have the following causes and fixes:
- The device may be slow to respond or busy.
- The network may be congested, or the device load may be high.
- Try again after the device completes its current operation.
- You cannot increase the timeout.
"Device not found"
Try the following steps:
- List the available devices by running
npx rk device ls. - If the device is missing, add it by running
npx rk device add <ip> --name "My Device". - Set the active device by running
npx rk device set-active <id|ip|name>.
Related documentation
- rk device — Describes how to manage device configurations.
- Roku External Control Protocol Guide: Describes the ECP API.
- Roku Input Interface: Describes the Roku Input interface.
- SceneGraph XML Reference: Describes the SceneGraph XML elements.
Updated about 5 hours ago