Clients
Web, mobile, desktop, terminal and CLI all open one server URL.
Every client talks to a single Harmony Chat server URL. None of them talk to a worker port or to the database.
| Client | Form | Server URL comes from |
|---|---|---|
| Web | Static SPA | Same origin, or VITE_HARMONY_API at build |
| Mobile | Capacitor shell | Runtime "Change server" |
| Desktop | Electron shell | Runtime "Change server" |
| Terminal | Chat in this terminal | Local config under $HARMONY_HOME |
| CLI | harmony | Local config under $HARMONY_HOME |
Web
For development, run the Vite dev server and point it at the API:
bun run dev:web # http://127.0.0.1:5173For deployment, build the static bundle and serve it — behind a CDN, or same-origin on the main server so one HTTPS origin serves both page and API:
bun run --cwd apps/web build # emits apps/web/distSame-origin is the least to operate: one host, one TLS certificate, no CORS.
Mobile and desktop
Both are shells around the same UI, so the server URL is a runtime setting rather than a build constant. Point them at the address from Self-host.
Terminal
harmony tui draws the same rooms, DMs, threads and reactions in a text terminal: no browser, no DOM.
It reads the session file the CLI wrote, so signing in once is enough for both, and it needs a terminal
on stdin and stdout — piped, it refuses with one line on stderr and exit 1.
bun run harmony -- tui
bun run harmony -- --api http://127.0.0.1:8080/api/v1 tuiF1 lists the chords in place, and $HARMONY_HOME/tui-keys.json rebinds any of them. The client owns
no chat state: it shares the request path, the session file and the realtime socket with the others. Do
not confuse it with a harness terminal, which is a coding agent's own screen projected into chat.
CLI
bun run harmony -- health
./apps/cli/bin/harmony --helpSee CLI for the command grammar.