Run APX on a server
The core runs fine on its own. Put it on a small VPS or a computer that is always on, and your agents keep working (routines, channels, tasks) while your laptop sleeps. The desktop app and your phone connect to it.
Nothing here needs root, and the server doesn’t need Node installed: the bundle brings its own.
1. Install
Section titled “1. Install”Run it on the server itself (it installs where it runs), over SSH:
curl -fsSL https://agentprojectcontext.github.io/apx/v2/install.sh | bashOr from your own computer in one line, PowerShell on Windows included:
ssh user@server 'curl -fsSL https://agentprojectcontext.github.io/apx/v2/install.sh | bash'Options: --file <bundle> (a bundle you already have, no download), --version <x.y.z>, --feed <owner/repo>,
--no-service, --uninstall. Through the pipe they go after bash -s --, for example
curl -fsSL https://agentprojectcontext.github.io/apx/v2/install.sh | bash -s -- --no-service.
bash install.sh --file apx-core-<version>-linux-x64.tar.gzIn PowerShell:
irm https://agentprojectcontext.github.io/apx/v2/install.ps1 | iexParameters: -File <bundle>, -Version <x.y.z>, -Feed <owner/repo>, -NoService, -Uninstall.
You don’t need to open a terminal on the server. In the desktop app’s first run (or APX menu › Change connection):
-
Choose Client, then SSH, and type
user@server. It uses your ownsshand keys. -
If APX isn’t on that server yet, the app says so and offers Install it for me (or Install it myself, which shows the command to run). It sends the same
install.shover SSH and installs the app’s own version. It works on Linux and macOS servers; on Windows, install by hand. -
On Linux it then asks to keep APX running when you disconnect, a step that needs the server’s administrator: Do it for me asks for the sudo password (sent straight to
sudoover SSH and not kept), or I’ll do it myself shows the command. Then it connects and goes on to set up your crew.
What the script does:
- Downloads the newest APX bundle for your system and checks it against its
.sha256. - Unpacks it into
~/.apx/v2/app/versions/<version>/and points~/.apx/v2/app/currentat it. The version that ran before stays until the next update. - Writes the
apxcommand to~/.local/bin(and adds that folder to your shell’s startup file if it wasn’t on yourPATH). - If APX v1 is installed, stops its daemon and removes its
apxcommand. Its files in~/.apxstay, so you can import them. - Starts the core as a service, unless you passed
--no-service.
Your data lives in ~/.apx/v2, apart from the app itself.
2. Set it up
Section titled “2. Set it up”One command takes the server the rest of the way:
apx setup --headless --expose tailscale # or --expose lanAdd --import (with --keys, --skills, --services if you want them) to bring the projects and agents of an APX
v1 on the same machine.
It runs, in order, the steps you could also run by hand:
-
Run the core as a service.
apx service installwrites a systemd user unit (Linux), a launchd agent (macOS) or a login entry (Windows), starts the core, and waits until it answers. It starts again at login and whenever it dies. -
Import APX v1 (only with
--import). Same asapx import-v1. It only reads v1’s files. -
Expose the core (only with
--expose). Same asapx expose tailscaleorapx expose lan, followed byapx service restart, because the core reads its settings when it starts. -
Pair a device. Same as
apx pair: prints a one-time code, the addresses and anapx://pairlink.
Check it any time:
❯ apx service status service systemd: active core answers on http://127.0.0.1:7440
On Linux the core’s log is in the journal: journalctl --user -u apx -f. On macOS and Windows it’s
~/.apx/v2/logs/core.log.
3. Choose who can reach it
Section titled “3. Choose who can reach it”By default the core only answers its own machine. apx expose changes that:
| Command | What it does |
|---|---|
apx expose tailscale | Keeps the core on 127.0.0.1 and publishes it with tailscale serve at https://<machine>.<tailnet>.ts.net, reachable only from your tailnet. |
apx expose lan | Makes the core listen on every address (APX_HOST=0.0.0.0), for example http://192.168.1.20:7440. |
apx expose off | Back to this computer only. The token stays. |
apx expose status | What is in effect, the port, whether there’s a token, and where the settings file is. |
Both tailscale and lan create a token for the core if it has none, and print it once. Restart the core afterwards
(apx service restart) so it reads the change.
apx tailscale status, apx tailscale connect and apx tailscale off do the same for Tailscale through the running
core, the way the panel does in Settings › Connections › Devices.
core.env and the token
Section titled “core.env and the token”apx expose writes <home>/core.env (~/.apx/v2/core.env unless APX_HOME says otherwise), readable only by you
(mode 600). It may set only these keys: APX_HOST, APX_PORT, APX_TOKEN, APX_PUBLIC_URL, APX_ALLOWED_ORIGINS.
After apx expose tailscale it looks like this:
# APX core settings (KEY=VALUE). Written by `apx expose`; the process environment wins over this file.APX_TOKEN=<64 hex characters>APX_PUBLIC_URL=https://<machine>.<tailnet>.ts.netThe process environment wins over the file. The apx command and the desktop app on the same machine read the token
from here on their own, so you don’t need to copy it anywhere. Other devices never get it: they pair.
4. Connect your devices
Section titled “4. Connect your devices”Run apx pair on the server whenever you need a code (it works once, for 10 minutes).
❯ apx pair Pairing code: ABCD2345 Expires at 10:40:00 (in about 10 min) Addresses a device may reach this core on: https://<machine>.<tailnet>.ts.net In the APX app, open Pair and paste the link, or enter an address and the code: apx://pair?c=ABCD2345&u=https%3A%2F%2F<machine>.<tailnet>.ts.net
- Desktop app: on its first run choose Client, then either Address (the Tailscale or LAN address; the
panel asks for the code) or SSH (
user@server). SSH uses your own keys and forwards the core to your computer, so it works even when the server is exposed to nobody. Details in Desktop app. - Phone: scan the QR from the panel, paste the
apx://pairlink in the APX app, or open the address in the phone’s browser and type the code. See Your phone. - A browser on another computer: open the core’s address (the Tailscale one, or the LAN one such as
http://192.168.1.20:7440). The panel asks to Pair this device: type a code fromapx pair(or from Settings › Connections › Devices › Pair a device on a device already paired), and that browser keeps its own key. Nothing to install on that computer.
Every device gets its own key. Revoke one with apx devices revoke <id> or in Settings › Connections › Devices.
Updates
Section titled “Updates”A bundle install updates itself. Every 6 hours (the first time a minute after it starts) the core asks the GitHub
Releases of agentprojectcontext/apx whether there is a newer APX. The panel shows it in the top bar, whether you
opened it on the server or from a desktop app connected to it, and Update now downloads the new bundle, checks its
.sha256, unpacks it beside the running one, moves current and restarts the core.
From the terminal:
apx upgrade --check # is there a newer APX?apx upgrade # apply itRunning the install script again also installs the newest version. APX_UPDATES=off stops the checks;
APX_RELEASES=<owner/repo> points them at another feed (off also stops them).
Uninstall
Section titled “Uninstall”curl -fsSL https://agentprojectcontext.github.io/apx/v2/install.sh | bash -s -- --uninstallIt stops the service and removes ~/.apx/v2/app and the apx command; your data in ~/.apx/v2 stays. On Windows,
save install.ps1 and run it with -Uninstall (Uninstall).
From a checkout instead
Section titled “From a checkout instead”On a machine where you work on APX itself:
pnpm installalias apx="node $PWD/apps/terminal/src/main.ts"apx service installWhere to next
Section titled “Where to next”- Desktop app and Your phone
- Configuration: every environment variable
- Troubleshooting
