HORUSdocs
Docs menu
horus CLI

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.

CommandIn short
horus devicesList connected phones and their state
horus pairTrust this computer (asks for the Horus password)
horus sshOpen a shell, or run one command
horus execRun a command on one or every paired phone
horus cpCopy files, like scp
horus syncMirror a folder with rsync
horus forwardReach a server on the phone at localhost
horus configSet up plain ssh and VS Code
horus statusBattery, temperature and server state
horus stopTurn remote access off on the phone
horus unpairRemove this computer's key from the phone
horus tuneLift 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.

your computer
horus devices
you'll see something like
NAME     SERIAL          MODEL      BATTERY  STATUS
pixel    1A2B3C4D5E6F7G  Pixel 8    84%+     paired, server running
-        R58N12ABCDE     Galaxy S21 61%      not paired (run `horus pair`)
STATUS saysMeaning
Horus is not set up yetOpen Horus on the phone and finish setup.
not paired (run `horus pair`)This computer isn't trusted yet.
paired, remote access offPaired, 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.

your computer
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.

your computer
# 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.

your computer
horus exec --all -- uname -m
horus exec --all -- git -C /workspace/projects/app pull
you'll see something like
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.

your computer
# 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.

your computer
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.

your computer
# phone port 3000 at localhost:3000
horus forward 3000
# phone port 3000 at localhost:8080 instead
horus forward pixel 3000 8080
you'll see something like
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.

your computer
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.

your computer
horus status
you'll see something like
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:

you'll see something like
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

VariableWhat it's for
HORUS_HOMEWhere horus keeps keys and pairings. Default ~/.horus.
ADBPath to adb, if it isn't on your PATH.
HORUS_PASSWORDThe Horus password, for pairing from a script without typing it.
HORUS_APP_IDThe 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.