Command reference
Every horus command, with examples.
Every command below takes an optional phone: its name from pairing, or its adb serial. If only one phone is plugged in you can leave it out, and horus picks that one.
On the phone side of a copy, write phone:path, for example pixel:/workspace/projects. Anything after -- is the command to run on the phone.
| Command | In short |
|---|---|
| horus devices | List connected phones and their state |
| horus pair | Trust this computer (asks for the Horus password) |
| horus ssh | Open a shell, or run one command |
| horus exec | Run a command on one or every paired phone |
| horus cp | Copy files, like scp |
| horus sync | Mirror a folder with rsync |
| horus forward | Reach a server on the phone at localhost |
| horus config | Set up plain ssh and VS Code |
| horus status | Battery, temperature and server state |
| horus stop | Turn remote access off on the phone |
| horus unpair | Remove this computer's key from the phone |
| horus tune | Lift Android's background process limit |
horus devices
Lists every phone connected over USB and what state it's in. Run this first when anything seems off.
horus devices
NAME SERIAL MODEL BATTERY STATUS pixel 1A2B3C4D5E6F7G Pixel 8 84%+ paired, server running - R58N12ABCDE Galaxy S21 61% not paired (run `horus pair`)
| STATUS says | Meaning |
|---|---|
| Horus is not set up yet | Open Horus on the phone and finish setup. |
| not paired (run `horus pair`) | This computer isn't trusted yet. |
| paired, remote access off | Paired, but switched off. Run horus pair or turn it on in Settings. |
| paired, server … | Ready. The SSH server's current state follows. |
horus pair [phone] [--name NAME]
Makes this computer trusted by the phone. Asks for the Horus password, installs the phone's SSH server the first time, and turns remote access on. Full walkthrough: Pair a phone.
horus pair horus pair --name pixel horus pair R58N12ABCDE --name galaxy
Running horus pair again is safe. It re-trusts a phone whose identity changed because Horus was reinstalled or its data cleared.
horus ssh [phone] [-- command…]
With no command, opens an interactive zsh on the phone. Type exit or press Ctrl-D to leave. With a command after --, runs just that and prints the result.
# a shell on the only connected phone horus ssh # a shell on a specific phone horus ssh pixel # run one command horus ssh pixel -- ls /workspace/projects horus ssh pixel -- make test
The first time you run claude, codex or opencode over SSH, it installs that agent into your home folder on the phone (needs internet, a minute or two), then starts it.
horus exec <phone | --all> -- command
Runs a command on one phone, or on every paired phone that's plugged in with --all. With several phones, they all run at the same time and every output line starts with the phone's name.
horus exec --all -- uname -m horus exec --all -- git -C /workspace/projects/app pull
galaxy | aarch64 pixel | aarch64
If any phone fails, horus exits with that failure's code, which is handy in scripts.
horus cp [-r] SRC… DST
Copies files, like scp. Exactly one side is on the phone, written phone:path. Add -r to copy folders. Symbolic links are followed, so their targets get copied.
# a folder from your computer into the phone's projects horus cp -r ./app pixel:/workspace/projects/ # a file from the phone to the current folder on your computer horus cp pixel:/workspace/out.log . # several files at once horus cp notes.md todo.md pixel:/workspace/projects/app/
horus sync SRC DST [--delete]
Makes one folder match another using rsync. Only changed files are sent, so running it again is quick. Symbolic links are kept as links.
horus sync ./site/ pixel:/workspace/site/ horus sync pixel:/workspace/projects/app/ ./app-backup/
horus forward [phone] PORT [LOCAL]
Makes a server running on the phone reachable from your computer. For example, a dev server on the phone's port 3000 opens at http://localhost:3000 in your laptop's browser.
# phone port 3000 at localhost:3000 horus forward 3000 # phone port 3000 at localhost:8080 instead horus forward pixel 3000 8080
http://localhost:3000 → pixel port 3000 (until the phone is unplugged)
The forward lasts until you unplug the phone. To remove it sooner, run adb forward --remove tcp:3000 (use your local port number).
horus config [--install]
Writes ~/.horus/ssh_config with an entry for every paired phone, so plain ssh pixel and VS Code Remote-SSH work. With --install, it also adds an Include line to the top of your ~/.ssh/config. Run it again after pairing a new phone. Full guide.
horus config --install
horus status [phone] [--log]
Shows the phone's details and health. Add --log to print the SSH server's log when something isn't working.
horus status
Phone Pixel 8 (1A2B3C4D5E6F7G), Android SDK 35 Name pixel Horus 1.0.1 Paired yes Remote access on, server running Paired computers 1 Battery 84%, charging Temperature none
Temperature is Android's heat warning level: none, light, moderate, severe, critical, emergency or shutdown. At moderate and above, Android slows the phone down. Give it a break or take the case off. If the battery line ends in optimized by Android, allow Horus unrestricted battery use.
horus stop [phone]
Turns remote access off on the phone. The pairing is kept. Turn it back on in Horus → Settings, or with horus pair.
horus unpair [phone]
Removes this computer's key from the phone, so it can no longer log in. You can also revoke computers on the phone under SETTINGS → Remote access.
horus tune [phone]
Android 12 and newer stop apps from starting more than a small number of background processes, shared by all apps. Builds and agents start many, so long tasks can be cut off. horus tune lifts that limit for the whole phone by running Android's documented developer commands over adb. It prints each one:
Lifting Android's background process limit on pixel (affects every app on the phone): adb shell device_config set_sync_disabled_for_tests persistent adb shell device_config put activity_manager max_phantom_processes 2147483647 adb shell settings put global settings_enable_monitor_phantom_procs false Done. It lasts until a factory reset; undo with `device_config set_sync_disabled_for_tests none`.
The last settings line only runs on Android 14 and newer. On Android 11 and older there's no limit, and horus says so and does nothing.
Environment variables
| Variable | What it's for |
|---|---|
HORUS_HOME | Where horus keeps keys and pairings. Default ~/.horus. |
ADB | Path to adb, if it isn't on your PATH. |
HORUS_PASSWORD | The Horus password, for pairing from a script without typing it. |
HORUS_APP_ID | The app's package name, for custom builds of Horus. |
What's in ~/.horus: this computer's SSH key, the list of paired phones and their names, each phone's known host key, and the generated ssh_config. Uninstalling horus doesn't delete it.