Docs / Contact / devices/remote-console
Remote Command Console
The Files and terminal tools drive a board that's plugged into your USB port. The remote command console does the opposite: it reaches a device that's already deployed and online over the network, with no cable in sight. It's the surface the Device tab shows when the entity is connected to Contact over MQTT but isn't sitting on your desk.
It is deliberately not a REPL. There is no arbitrary code over the network, only a small, fixed set of allow-listed commands (filesystem operations, a memory check, and reboot). A command is published to the device, the device runs exactly that operation and replies, and you see the result.
Local terminal vs. remote console
The Device tab shows one of two workspaces depending on how it can reach the board, and it picks automatically:
| Local terminal | Remote command console | |
|---|---|---|
| How it reaches the board | USB serial (WebSerial) | MQTT, through Contact's servers |
| Shows up when | A board is connected over USB | No USB session, but the entity is online |
| What you can run | The full REPL: arbitrary code, plus the file editor, camera, and vision tools | A bounded set of commands only |
| Where it happens | Entirely local; nothing passes through Contact | Contact relays each command to the device and back |
| Needs the device online? | No, just a cable | Yes, the device must be reporting in |
Plug a board in and you get the full local workbench. Unplug it (or open the tab for a device you'll never physically touch) and, as long as the device is checking in, the workspace becomes the command console instead. The console's header says so: "Remote commands, bounded, no arbitrary code. Type help."
Every command here rides the MQTT command channel to the device and waits for a reply. If the entity is offline, the console isn't shown, and a reboot has nothing to deliver to. "Online" means the device has an active connection and is reporting heartbeats, the same signal the status badge uses.
The commands
Type help to print the list. Everything except help and clear (which are handled in the browser) is sent to the device.
| Command | What it does |
|---|---|
ls [path] |
List a directory. Defaults to /. Folders are shown with a trailing /. |
cat <file> |
Print a file's contents. |
rm <file> |
Delete a file. |
mkdir <dir> |
Create a directory. |
rmdir <dir> |
Remove an empty directory. |
mv <src> <dst> |
Move or rename. |
cp <src> <dst> |
Copy a file (streamed in chunks, so it's safe on large files). |
free |
Run a garbage collection, then report free heap and free filesystem space. |
reboot |
Restart the device. See Per-entity reboot below. |
help |
Print this list (browser-side; nothing is sent to the device). |
clear |
Clear the console (browser-side). |
There's no cd; commands take absolute paths (or paths relative to /). An unknown verb is rejected locally with a hint to type help, so a typo never reaches the device.
The filesystem commands map to a single allow-listed endpoint (POST /api/entities/:id/filesystem), and the allow-list is enforced twice: once on Contact's server and again on the device itself. Nothing outside the list runs, by construction.
Permissions
The console gates each action on its own RBAC permission, and hides or refuses what you can't do:
entity:FileSystemAccess: required for the filesystem commands (ls,cat,rm,mkdir,rmdir,mv,cp,free). Without it, those commands come back with a permission error.entity:Reboot: required forreboot.
Both live in the Remote commands permission group in the policy editor (alongside DeployCode for remote deployments), so you can grant device operators the ability to run commands and reboot without giving them account, billing, or IAM access. The built-in FleetOperator role already includes them. Every filesystem command and every reboot is written to the audit log with the entity, the command, its arguments, and the caller's IP.
Per-entity reboot
Reboot is available two ways, and both do the same thing: publish a fire-and-forget reset to the device:
- Type
rebootin the console. - Use the Reboot button in the Remote actions card on the Device tab (it asks for confirmation first).
Because a device that's resetting can't acknowledge, a successful reboot means "the reboot command was published," not "the device is back up." The device drops its connection, calls machine.reset(), and comes back on its own, reconnecting, re-running its boot code, and reporting in again a moment later. Watch the status badge to confirm it returned.
When a board is connected locally over USB instead, the same Reboot control performs a hardware reset over the serial line rather than sending a network command, so the button does the right thing whichever way the tab is reaching the device.
The Remote actions card also hosts Deploy code for pushing an application update over the air; that flow is covered in Remote Deployments.
Tendrl