Skip to main content

Running Anyy as a Resident Service

Anyy is a resident, local-first personal assistant. You can run it straight from your terminal, but to receive messages and run scheduled work while no terminal is open, you keep it always-on as a background service. This page is the canonical reference for running Anyy as a persistent service and for managing the gateway lifecycle.

If you have not installed Anyy yet, start with Installation.

Foreground vs Resident

Anyy has two ways to run:

  • Foreground — you run anyy in a terminal. The TUI may start a temporary in-process gateway for that session only. When you close the terminal, the gateway stops, so inbound messages and scheduled jobs are no longer handled. This is perfect for trying things out and for one-off work.
  • Resident — a small background service keeps the gateway running across reboots and logouts. This is what you want once you connect messaging channels or rely on reminders, cron, and heartbeat. Your assistant stays online and reachable even when no terminal is open.

Installing Anyy never starts a background service on its own, and a plain anyy command never installs one without asking. Going resident is an explicit choice you make with anyy gateway start (or by accepting the prompt during anyy setup).

Features that need the resident gateway:

  • receiving channel messages (for example Weixin) while no terminal is open
  • gateway-owned cron, reminders, heartbeat, and background jobs
  • any client that expects a continuously available runtime

The Gateway Lifecycle

The gateway is the long-running runtime that hosts channels, background jobs, and the local RPC surface other Anyy commands talk to. Anyy manages it for you through one small command group — you do not call systemctl, launchctl, or the init script directly:

anyy gateway start [--home PATH]
anyy gateway restart [--home PATH]
anyy gateway status [--home PATH]
anyy gateway stop [--home PATH]

What each subcommand does:

  • start — ensures the background service is installed for the resolved home, then starts it. If the service is already running it is a no-op that reports success. It waits for the gateway to become reachable before reporting Gateway: running.
  • restart — refreshes and restarts the service. If no service exists yet, it installs and starts one instead of failing.
  • stop — stops the running service (the service definition stays installed, so the next boot or start brings it back).
  • status — reports the service and runtime state with no side effects. It never installs, starts, or restarts anything.

These commands manage only the Anyy service for the resolved home. They are not a general-purpose service manager.

The service definition always launches the same supervised entrypoint, with the resolved home passed explicitly:

<home>/bin/anyy __gateway --home <home>

__gateway is the internal supervised runtime entrypoint used by the service. You do not run it by hand — use anyy gateway start.

Which home is used

The resolved home directory is, in order of precedence:

  1. the --home PATH flag
  2. the ANYY_HOME environment variable
  3. the default — ~/.anyy for a normal-user install, /root/.anyy when running as root (/root/.anyy is the built-in fallback used when no home is otherwise resolved)

All service definitions, the runtime socket, sessions, state, and Anyy's own logs live under this home.

Run as a Service

anyy gateway start picks the right host service manager automatically:

HostService managerGenerated definition
macOSlaunchd user agent~/Library/LaunchAgents/com.anyy.anyy.plist
Linux with systemctlsystemd user unit~/.config/systemd/user/anyy.service
OpenWrt (/etc/openwrt_release present)procd init script/etc/init.d/anyy

On any other host you get actionable guidance instead of a silent failure:

Background service is not supported on this host yet.
Use anyy gateway start on macOS, systemd user Linux, or procd hosts.

The recommended path on every platform is anyy gateway start — it writes the correct definition, enables it, starts it, and verifies the gateway is reachable. The platform sections below show the exact definitions Anyy generates (and the shipped reference templates for system-wide installs) so you know what lands on disk.

Linux (systemd)

On a Linux host with systemctl, anyy gateway start installs and enables a systemd user unit at ~/.config/systemd/user/anyy.service. This is the default and needs no root. The generated unit is:

~/.config/systemd/user/anyy.service (generated by anyy gateway start)
[Unit]
Description=Anyy Gateway service
After=network-online.target

[Service]
Type=simple
ExecStart="/home/you/.anyy/bin/anyy" "__gateway" "--home" "/home/you/.anyy"
WorkingDirectory=/home/you/.anyy
Restart=on-failure

[Install]
WantedBy=default.target

Manage it through Anyy:

anyy gateway start
anyy gateway status
anyy gateway stop

System-wide (root) unit

For a host where the assistant should run as a system service under root (for example an always-on home server), the repository ships a reference system unit. Reproduced verbatim from deploy/linux/anyy.service:

deploy/linux/anyy.service
[Unit]
Description=Anyy Gateway native Linux resident
Documentation=https://github.com/Mai8304/Anyy
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
Environment=ANYY_HOME=/root/.anyy
WorkingDirectory=/root/.anyy
ExecStart=/root/.anyy/bin/anyy __gateway --home /root/.anyy
ExecReload=/bin/kill -USR1 $MAINPID
Restart=always
RestartSec=3
TimeoutStopSec=60
KillSignal=SIGTERM
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
warning

Installing a system unit requires root. Copy the file to /etc/systemd/system/anyy.service, then run as root:

sudo systemctl daemon-reload
sudo systemctl enable --now anyy.service

This unit expects an install rooted at /root/.anyy. The install layout it assumes is documented in deploy/linux/README.md. anyy gateway commands manage the per-user service, not this system unit — use systemctl for the system unit.

macOS (launchd)

On macOS, anyy gateway start installs a launchd user agent. There is no shipped static plist in the repository — the generated user agent is the only macOS service artifact, and anyy gateway start is the supported way to install it. The generated definition at ~/Library/LaunchAgents/com.anyy.anyy.plist is:

~/Library/LaunchAgents/com.anyy.anyy.plist (generated by anyy gateway start)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.anyy.anyy</string>
<key>ProgramArguments</key>
<array>
<string>/Users/you/.anyy/bin/anyy</string>
<string>__gateway</string>
<string>--home</string>
<string>/Users/you/.anyy</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>WorkingDirectory</key>
<string>/Users/you/.anyy</string>
</dict>
</plist>

RunAtLoad starts it at login and KeepAlive restarts it if it exits. Manage it through Anyy — you do not need to touch launchctl:

anyy gateway start
anyy gateway status
anyy gateway stop
note

This is a per-user LaunchAgent, so it runs while you are logged in. The repository does not ship a system-wide LaunchDaemon. If you need the assistant to run before login, write your own LaunchDaemon wrapper around anyy gateway start (a manual, user-provided example, not a shipped artifact):

Manual example — not shipped; you author this yourself
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.anyy.boot</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/anyy</string>
<string>gateway</string>
<string>start</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

Installing a LaunchDaemon under /Library/LaunchDaemons requires root.

OpenWrt

OpenWrt is a supported Linux host, not a separate router product. Anyy detects it via /etc/openwrt_release and anyy gateway start installs a procd init script at /etc/init.d/anyy. The generated script is:

/etc/init.d/anyy (generated by anyy gateway start)
#!/bin/sh /etc/rc.common
START=95
USE_PROCD=1

start_service() {
procd_open_instance
procd_set_param command '/root/.anyy/bin/anyy' '__gateway' '--home' '/root/.anyy'
procd_set_param respawn
procd_close_instance
}

The repository also ships a slightly fuller reference init script with explicit respawn limits and logging. Reproduced verbatim from deploy/openwrt/etc/init.d/anyy:

deploy/openwrt/etc/init.d/anyy
#!/bin/sh /etc/rc.common

START=95
STOP=10
USE_PROCD=1

ANYY_HOME="${ANYY_HOME:-/root/.anyy}"

start_service() {
procd_open_instance
procd_set_param env ANYY_HOME="$ANYY_HOME"
procd_set_param command /root/.anyy/bin/anyy __gateway --home /root/.anyy
procd_set_param respawn 3600 5 5
procd_set_param stdout 1
procd_set_param stderr 1
procd_close_instance
}

reload_service() {
procd_send_signal anyy
}
warning

OpenWrt services run as root. Manage the service through Anyy (anyy gateway start / stop / status). If you install the shipped reference script manually, copy it to /etc/init.d/anyy, make it executable, then /etc/init.d/anyy enable and /etc/init.d/anyy start.

Autostart & Liveness

Each host keeps the gateway alive automatically once installed:

  • macOS (launchd user agent)RunAtLoad starts it at login; KeepAlive relaunches it if it exits.
  • Linux (systemd user unit)WantedBy=default.target and Restart=on-failure restart it if it crashes. To keep a user service running after you log out, enable lingering once: sudo loginctl enable-linger $USER.
  • OpenWrt (procd)procd_set_param respawn restarts the process; the shipped reference uses respawn 3600 5 5 (give up only after 5 crashes inside an hour).
  • Linux system unit (deploy/linux/anyy.service) — Restart=always with RestartSec=3 and WantedBy=multi-user.target start it at boot and keep it up.

The gateway also runs a heartbeat that records its own liveness. Check it with:

anyy heartbeat status
anyy heartbeat status --json

Logs & Status

The fastest health check is anyy status, which summarizes the gateway and its subsystems:

◆ Anyy status
Gateway stopped
Profile default
...

◆ Subsystems
Gateway listener —
Cron unavailable
Heartbeat unavailable
...

For the service-and-runtime view specifically, use anyy gateway status:

◆ Gateway
Status not installed
Service launchd user service
Home /Users/you/.anyy
Socket /Users/you/.anyy/anyy.sock

The Status line distinguishes the cases you care about: running, running manually (a foreground gateway with no installed service), not running, not installed, and (when the command binary is newer than the running process) running an older Anyy — for which the next step is anyy gateway restart.

Where logs go, per host. Two streams are distinct: Anyy's runtime writes its own application logs under <home>/logs/ on every host, while the service manager captures the process stdout/stderr separately — the generated user services do not redirect that output into <home>/logs/.

  • macOS / launchd — Anyy writes its own logs under <home>/logs/. The launchd user agent captures the process stdout/stderr to launchd's own log destination, not to <home>/logs/.
  • Linux / systemd user — Anyy writes its own logs under <home>/logs/. The systemd user unit's stdout/stderr is captured by journald (journalctl --user -u anyy). The systemd reference system unit sets StandardOutput=journal / StandardError=journal, so its process output goes to the system journal (journalctl -u anyy).
  • OpenWrt / procd — Anyy writes its own logs under <home>/logs/. The shipped reference script sets stdout 1 / stderr 1, so procd routes the process output to syslog (logread).

Updating a Resident Install

Update the program with anyy update (see Updating for the full flow). When a resident service is involved, update is gateway-aware:

  • if an Anyy service is installed and running, update restarts it and verifies the gateway reports the new version
  • if the service is installed but stopped, it reports Gateway: not running
  • if a gateway is running manually without a service, it reports Gateway: running manually and does not fail
  • if no gateway or service exists, it reports Gateway: not installed

anyy update never installs a service — that stays an explicit choice. If you ever see a version mismatch in anyy gateway status (the running process is older than the command), restart the gateway to adopt the new build:

anyy gateway restart

Uninstalling the Service

To stop and remove the resident service plus the program while keeping all your data (config, secrets, sessions, logs, state, memory, skills, channel data):

anyy uninstall --keep-data --yes

To remove everything, including the home directory and all data:

anyy uninstall --full --yes

Running anyy uninstall with no mode flag prompts interactively; the --yes / -y flag skips confirmation and requires --keep-data or --full.

Both modes remove the Anyy-owned service definition (the launchd plist, systemd user unit, or procd init script) before touching program files, so no orphaned service is left behind. To stop the service without uninstalling anything, use anyy gateway stop instead.

warning

If you installed the shipped system unit (deploy/linux/anyy.service) or a manual LaunchDaemon, anyy uninstall does not manage it — that one was installed with root outside Anyy. Disable it yourself, for example: sudo systemctl disable --now anyy.service.