A Machine That Never Sleeps
Wolffish is a desktop app first — private, local, on your machine — and that remains the primary way to run it. But an agent that answers Telegram at 3 AM, runs the nightly reflection, and fires automations on schedule wants a machine that is never asleep, never on battery, never in a bag. Since v1.0.239 the same app runs headless on a server: the whole agent — channels, automations, memory, MCP, the works — with no window and no tray, driven by the terminal CLI and, day to day, by your phone. The whole route — install, headless boot, the systemd service, the CLI attaching — is verified end to end on a pristine Ubuntu 24.04 VPS. No display server required, no Docker, no Node.Install
One command, as root or with sudo:.deb on apt systems, .rpm on dnf/zypper/yum — and falls back to the portable AppImage anywhere else, entirely under $HOME, no root needed. Downloads are verified against the release manifest’s sha512 before anything is installed.
It is also deliberately hard to lie to. The installer asks the package manager whether the package is actually installed and configured rather than trusting exit codes — apt’s way of “fixing” an unsatisfiable dependency is to remove the package it just unpacked and report success. It refreshes stale package lists and retries before concluding anything (a fresh VPS image is often one apt-get update away from working), never lets the package manager remove things to make an install succeed, cleans up after itself instead of leaving a half-unpacked package that breaks every later apt run, and when it genuinely cannot proceed it names the libraries that are missing.
On a .deb/.rpm install, the wolffish command is shipped by the package at /usr/bin/wolffish — it exists the moment the install finishes: no first launch, no PATH line, no new shell, the same command for every account on the machine. On the AppImage route the installer writes the PATH line into your shell profile for you (once, ever — --no-modify-path if you’d rather it kept its hands off your dotfiles).
Two names, on purpose:
wolffish is the terminal client, wolffish-app is the app binary. Two different programs answering to one name, resolved by PATH order, is a coin flip nobody can debug.First Contact
Make It Survive a Reboot
The daemon the CLI starts lives until the machine restarts. To make Wolffish come back on its own:--headless it registers a login item instead — starts when you log in, opens the window — which is the right mode for a laptop and the wrong one for a server. Because a background service is registered to stay running (quit, and the system restarts it within seconds), choosing it asks first.
There is no
start to remember: the daemon starts on demand — any wolffish command brings it up — and the service brings it up at boot. wolffish service stop is the deliberate way down.Your Phone Is the Interface
This is the recommended shape for a server install. The CLI is how you administer the box; the mobile app is how you live with it. Pair once and your phone carries the day-to-day surface of the server: the chat feed with its tool cards and files, every conversation streaming live, projects, procedures and automations — editable from the phone, against the server’s own files — the three customization documents, capabilities, variables, the usage ledger, diagnostics, and push notifications when a run finishes, fails, or needs you. A headless server with a paired phone is not a degraded Wolffish; it is the desktop experience with the desk removed. Pairing from a terminal is built for a box with no screen:K7M9-2QXR, case and dashes forgiven) expires in about three minutes; generate another whenever. The tunnel that results is the same one the desktop uses: end-to-end encrypted, outbound only, through the blind relay.
Self-hosting the relay too? The typed code carries only the secret — type your relay’s address into the Relay card on the phone’s pairing screen as well. The QR carries the address for you.
wolffish pair telegram takes the bot token typed hidden, and wolffish pair whatsapp --number +… links by phone number with an eight-character code, because a WhatsApp QR can never fit an SSH window.
What a Server Can and Can’t Do
Everything that is the agent works headless: chat on every channel, automations and procedures on schedule, the full memory system, MCP servers, video generation, file work, the phone tunnel, notifications. The agent’s own channel roster is kept honest too — on a headless box, in-app chat is reported unavailable, so the model never believes a window is open with someone there to answer in. What needs a desktop stays on the desktop: the browser extension (there is no browser to load it into), computer use (nothing to screenshot), and opening files with the OS —/open prints the path instead. Every such refusal names the terminal’s own way to do the same thing.
The Shape of the Attack Surface
A Wolffish server exposes nothing to the network. There is no web UI, no API port, no inbound anything:- The CLI talks to the daemon over a Unix domain socket at
~/.wolffish/cli.sock, created with owner-only permissions — deliberately not an HTTP server, so a VPS install can’t grow a listening port by accident. - The phone tunnel is outbound WebSocket to the relay. No firewall rule, no port forward, nothing reachable from outside.
- Telegram and WhatsApp are outbound connections to their own services.
wolffish status --json and wolffish view redact credential-shaped values unless you pass --raw, and provider keys are typed hidden, never in shell history.
Data, Updates, Uninstall
Everything lives in~/.wolffish/ — workspace, conversations, config, logs, the daemon socket. Back up that folder and you’ve backed up the agent; wolffish service logs reads ~/.wolffish/workspace/logs/.
Updating depends on the route in: an AppImage updates itself; a .deb/.rpm can’t (a package manager isn’t something an app should drive), so updating is re-running the install command — settings and workspace untouched. wolffish settings updates shows the version, checks, and prints what’s new, rendered.
Uninstall is three honest steps:
The Terminal CLI
Everything the command can do — sessions, one-shots, the settings browser, approvals, editors, and the reference tables.