Terminal over the Mesh
Open a real terminal on one of your machines from another, with no remote-desktop session.
Open an interactive terminal on another of your machines, the way ssh does, without a remote-desktop session: from the GaiaDesk app (Terminal next to a device) or from the command line (gaiadesk-cli shell). Keystrokes, Ctrl-C, arrow keys and window resizing all go to the remote shell, and full-screen programs such as vim, htop and less work.
The target's screen is never shared or even read: a terminal session carries the shell and nothing else. The person at the target is still told that someone opened a terminal on it.
It works wherever you are. GaiaDesk tries the lightest route first:
GaiaDesk Mesh, if both machines are on it;
your local network, if the target is paired with this device;
the GaiaDesk server, as the account you're signed in with — the route for a machine on another network, or signed into a different account.
Mesh and a shared network are optional; being signed in is enough. The target can be a Mac, a Windows PC or a Linux machine.
Before you start
GaiaDesk is running on the target machine.
You have its 9-digit address (the desk ID) and its unattended password (see Unattended access). The 6-digit one-time code works too, but then someone at the target has to click Allow (the prompt says it's a terminal).
The target runs a GaiaDesk recent enough for terminal-only sessions. An older one is refused with a message saying so, rather than sharing its screen: update it, or connect normally and open the terminal from the session toolbar.
The shell is authenticated like any other connection: the same password check, allow-list and approval prompt, whichever route it takes. Nobody can open a shell on your machine by being on the same network or mesh.
From the app
In Devices, press Terminal next to a device (with a saved password it opens straight away). Or on Home, type the address and password and press Terminal beside Connect. The terminal opens as a tab of the session window. The line above it says how it's connected (LAN, Mesh or the GaiaDesk server) and the machine's name. Copy with Ctrl+Shift+C and paste with Ctrl+Shift+V (⌘C / ⌘V on a Mac). Closing the tab ends the shell.
From the command line
gaiadesk-cli shell does the same in your own terminal. When you leave, your terminal is put back as it was, even if the connection drops. Its first line says which route it took.
The connection stays open for 10 minutes after you leave, so the next shell or exec to the same machine starts at once (--persist 0 turns that off; gaiadesk-cli disconnect --desk-id <id> closes it now). See connection reuse.
Put the command on your PATH (once)
macOS: open GaiaDesk → Settings → Terminal over the Mesh → Add the gaiadesk command. macOS asks for your password once. It adds gaiadesk and gaiadesk-cli to /usr/local/bin, pointing into the app, so app updates update the command too.
Windows: the installer adds GaiaDesk's folder to your PATH. Open a new terminal window (PowerShell, Command Prompt or Windows Terminal) after installing or updating.
Linux (.deb / .rpm): nothing to do. The package installs /usr/bin/gaiadesk-cli.
Linux (AppImage): an AppImage's files only exist while it runs, so it can't put a command on your PATH. Install the .deb or .rpm instead, or unpack the AppImage once and run the tool from the unpacked folder:
./GaiaDesk_*.AppImage --appimage-extract >/dev/null
LD_LIBRARY_PATH="$PWD/squashfs-root/usr/lib" ./squashfs-root/usr/bin/gaiadesk-cli shell --desk-id 123456789Open a terminal
From a Mac:
gaiadesk shell --desk-id 123456789From Windows (PowerShell, Command Prompt or Windows Terminal):
gaiadesk-cli shell --desk-id 123456789From Linux:
gaiadesk-cli shell --desk-id 123456789You're asked for the target's password, which isn't echoed. After that you're at a prompt on the other machine. To leave, type exit. On a Mac or Linux target, Ctrl-D also works.
What you land in depends on the target:
Target | Shell |
|---|---|
macOS | your login shell (usually zsh), in your home folder |
Linux | your login shell ( |
Windows | Command Prompt ( |
The password without typing it
For scripts, set GAIADESK_CODE in the environment instead of typing the password:
# macOS / Linux
GAIADESK_CODE='your-password' gaiadesk-cli shell --desk-id 123456789# Windows PowerShell
$env:GAIADESK_CODE = 'your-password'
gaiadesk-cli shell --desk-id 123456789Every command (shell, exec, cp, …) refuses --code <password> on the command line, because every user on your machine can read a command line (with ps or Task Manager). If you accept that, add --allow-code-in-argv. For a program, a scoped agent token is better than the password: see agent tokens.
One command, no session
To run a single command and get its exit code back, use exec:
gaiadesk-cli exec --desk-id 123456789 -- df -hexec works like ssh host cmd: no terminal is involved, so the command's stdout and stderr come back separately and unaltered, its stdin is closed (-i forwards yours), and it is stopped after --timeout (30 minutes by default). --json, --shell cmd|pwsh|sh|none and everything else for scripts and agents is in The CLI for scripts and AI agents.
Exit codes
Code | Meaning |
|---|---|
0–255 | the remote shell's (or command's) own exit code (253–255 can also mean the rows below) |
124 |
|
130 | interrupted with Ctrl-C; the command was stopped |
253 |
|
254 | the target refused (wrong password, allow-list, no control, a token without |
255 | could not connect: desk offline or not found, unreachable, timed out ( |
shell always prints the reason on stderr, and never exits 0 unless the remote shell did. Not on a terminal — shell -- <command>, or a script piped in — it runs like exec (plain pipes, the remote exit code, --json); see The CLI for scripts and AI agents.
Troubleshooting
"could not reach desk …": no route reached the target. The message lists what each route said, one line per address tried, for example:
"isn't paired with this device": the target answered on your network but was never paired with this device (it may be signed into another account). GaiaDesk tries the server next, and that needs you signed in.
"no answer on that UDP port": GaiaDesk isn't running on the target, or a firewall (Windows Defender Firewall, for example) is blocking it.
"not signed in to GaiaDesk on this machine": the server route needs the account. Sign in to the GaiaDesk app on this machine, or set
GAIADESK_TOKEN_FILE.
"desk … is offline (last seen …)": one of your account's or team's machines isn't connected. Wake it, or check GaiaDesk is running there.
"no desk … is online, and none by that id belongs to your account or team": check the ID.
"desk … refused the connection: …": the target said no. Check the password and the target's allow-list.
"… older GaiaDesk that can't open a terminal without sharing its screen": update GaiaDesk on the target.
"the desk closed the terminal" / "this session may not run commands": the session was admitted without control permission (view-only), so no shell or command is allowed.
A Windows target that never answers
exec: a Windows terminal asks where its cursor is before it starts, and older versions left that unanswered.execno longer uses a terminal at all; update GaiaDesk on both machines.