Skip to content

revka gateway, daemon & service

Run the gateway, the full daemon, or an OS-managed service; manage pairing codes and bind hosts/ports.

These commands run the Revka HTTP runtime: revka gateway for the dashboard and API alone, revka daemon for the full autonomous runtime, and revka service to keep either alive as an OS-managed background service. This page is the reference for all three, plus the pairing-code workflow and the bind-host restrictions that gate network exposure.

Reach for revka gateway for local dashboard work, revka daemon for production (channels, heartbeat, and cron together), and revka service once you want Revka to start on login or boot and survive crashes. For a first-time, click-through walkthrough see Run the dashboard; for OS-by-OS service detail see Run as a background service.

revka gateway starts just the HTTP/WebSocket gateway: the embedded React dashboard at /, the REST API under /api/*, the Server-Sent Events stream at /api/events, and the WebSocket endpoints (/ws/chat, /ws/canvas/{id}, /ws/nodes). It does not start channels, the heartbeat, or the cron scheduler — use revka daemon for those.

Terminal window
revka gateway # start on config defaults
revka gateway start # explicit start
revka gateway start -p 8080 # custom port
revka gateway start --host 0.0.0.0 # bind all interfaces (see bind restrictions)
revka gateway start -p 0 # bind a random available port
revka gateway restart # graceful restart
revka gateway restart -p 9090
revka gateway get-paircode # show the current pairing code
revka gateway get-paircode --new # rotate to a fresh pairing code
SubcommandFlagsPurpose
start-p / --port <u16> (0 = random), --host <STRING>Start the gateway. Bare revka gateway is equivalent to revka gateway start.
restart-p / --port <u16>, --host <STRING>Graceful restart with the same flags as start.
get-paircode--newPrint the current pairing code, or rotate to a fresh one with --new.

The default bind is 127.0.0.1:42617. The listen port is read from [gateway].port in your config (schema default 42617), and --port/--host override the config per invocation. The process prints its URL on startup.

revka daemon launches the complete Revka runtime as a single foreground process: the gateway server, every configured channel supervisor (Telegram, Discord, Slack, and so on), the heartbeat monitor, and the cron scheduler. This is the recommended production entrypoint — register it with revka service so the OS keeps it alive.

Terminal window
revka daemon # use config defaults
revka daemon -p 9090 # gateway on port 9090
revka daemon --host 127.0.0.1 # localhost only
revka daemon --host 0.0.0.0 # all interfaces (requires allow_public_bind)
FlagDefaultMeaning
-p / --port <u16>[gateway].portGateway listen port. 0 binds a random available port.
--host <STRING>[gateway].hostBind address. Non-loopback addresses are gated — see bind restrictions.
--config-dir <PATH>~/.revkaGlobal flag; must precede the subcommand. Also sets REVKA_CONFIG_DIR for the process.

The daemon terminates cleanly on SIGINT or SIGTERM. SIGHUP is explicitly ignored, so the process survives an SSH or terminal disconnect. A warning is logged if the binary is running from a user home directory instead of a system install location such as /usr/local/bin.

Each of the four daemon components — gateway, channels, heartbeat, scheduler — runs in its own task wrapped by a supervisor. On crash or exit, the supervisor waits channel_initial_backoff_secs (default 2), then doubles the delay on each subsequent failure up to channel_max_backoff_secs (default 60) before restarting. The restart count and last error are recorded in the health snapshot.

[reliability]
channel_initial_backoff_secs = 2 # initial retry delay (minimum 1)
channel_max_backoff_secs = 60 # exponential cap; must be >= initial
KeyTypeDefaultMeaning
reliability.channel_initial_backoff_secsinteger2Initial retry delay in seconds. Minimum 1.
reliability.channel_max_backoff_secsinteger60Exponential backoff cap. Must be greater than or equal to the initial value.

While running, the daemon writes daemon_state.json alongside config.toml (<config_dir>/daemon_state.json) every 5 seconds. The file contains a health snapshot of every component and a written_at timestamp.

  • Liveness monitoring — a state file older than 45 seconds means the daemon has died. External monitors can poll this file directly.
  • Windowsrevka service start reads this file to detect whether a direct-daemon fallback is already running, because the Windows Task Scheduler cannot be queried reliably.

Every /api/* request carries Authorization: Bearer <token>, and that token is minted by exchanging a one-time pairing code. Pairing is what stops an unknown client on your network from driving your agent.

Terminal window
revka gateway get-paircode # show the current code
revka gateway get-paircode --new # rotate to a fresh code

These call the localhost-only admin endpoints GET /admin/paircode and POST /admin/paircode/new. Codes are single-use: once a client pairs with a code it is consumed, and you must rotate to issue another.

Exchange a code for a token (revka pair token)

Section titled “Exchange a code for a token (revka pair token)”

revka pair token exchanges a pairing code for a bearer token from the command line — useful for pairing a headless device or a script.

Terminal window
revka pair token --code 123456
revka pair token --code 123456 --name "Field phone" --device-type mobile --hardware "Pixel 8 / Android"
revka pair token --url http://revka.local:8080 --code 123456 --json
revka pair token --code 123456 --host 192.168.1.10 --port 8080
FlagRequiredMeaning
--code <STRING>yesThe one-time pairing code.
--url <URL>noFull gateway base URL, e.g. http://127.0.0.1:8080.
--host <STRING>noGateway host, used when --url is omitted.
-p / --port <u16>noGateway port, used when --url is omitted.
--name <STRING>noDevice name shown on the dashboard Pairing page.
--device-type <STRING>noDevice type label. Default: cli.
--hardware <STRING>noHardware / platform label, e.g. Pixel 8 / Android.
--jsonnoPrint machine-readable JSON instead of human text.

Under the hood this posts the code to the gateway and returns the bearer token:

POST /api/pair
Content-Type: application/json
{
"code": "123456",
"device_name": "Field phone",
"device_type": "mobile",
"hardware": "Pixel 8 / Android"
}
{
"token": "<bearer-token>",
"persisted": true,
"message": "Pairing successful"
}

For the dashboard-side flow, QR-based device pairing, and device revocation, see Pairing & authentication and Secrets, pairing & device auth.

The gateway can bind to 127.0.0.1 (localhost only — the default), 0.0.0.0 (all IPv4 interfaces), or [::] (all IPv6 interfaces). Binding to any non-loopback address without allow_public_bind = true (and no active tunnel) logs a warning but still binds. This is a deliberate safety default — 0.0.0.0 exposes the gateway to every connected network.

[gateway]
host = "0.0.0.0"
port = 42617
allow_public_bind = true
Terminal window
revka daemon --host 127.0.0.1 # localhost only (default)
revka daemon --host 0.0.0.0 # LAN access — needs allow_public_bind = true
KeyTypeDefaultMeaning
gateway.hoststring127.0.0.1Bind address. Inside Docker containers the default is [::].
gateway.portinteger42617Listen port. 0 binds a random available port.
gateway.allow_public_bindbooleanfalseMust be true to bind any non-loopback address.

Both keys have environment overrides for containers and CI: REVKA_GATEWAY_HOST / HOST, REVKA_GATEWAY_PORT / PORT, and REVKA_ALLOW_PUBLIC_BIND.

Terminal window
REVKA_ALLOW_PUBLIC_BIND=true revka gateway start --host 0.0.0.0

revka service runs revka daemon as a persistent, OS-managed background service so it starts automatically and is restarted on failure. The init system is auto-detected per platform:

  • macOS — a launchd agent at ~/Library/LaunchAgents/com.revka.daemon.plist (RunAtLoad and KeepAlive enabled).
  • Linux — a systemd user unit at ~/.config/systemd/user/revka.service (no root required), or an OpenRC init script at /etc/init.d/revka.
  • Windows — a Scheduled Task named Revka Daemon that runs at logon, with a direct background-spawn fallback if the scheduler is unavailable.
Terminal window
revka service install
revka service start
revka service stop
revka service restart
revka service status
revka service logs -n 100 --follow
revka service logs
revka service uninstall
# Override the init system (Linux only)
revka service --service-init systemd install
revka service --service-init openrc install
SubcommandPurpose
installGenerate and register the service unit / plist / scheduled task.
startStart the service. Rotates daemon logs first if they exceed 20 MB.
stopStop the running service.
restartStop then start.
statusReport whether the daemon is running. Also checks the 45-second-fresh daemon state file as a fallback.
logsTail the daemon logs. -n / --lines <N> sets the line count (default 50); -f / --follow streams new output like tail -f.
uninstallRemove the service unit / plist / scheduled task.
FlagValuesDefaultMeaning
--service-initauto, systemd, openrcautoForce a specific init system on Linux. Applies to all subcommands.

revka service auto-detects the right init system, but on Linux you can force one with --service-init. Pass it before the subcommand:

  • auto (default) — detect systemd, OpenRC, launchd, or Windows Task Scheduler automatically.
  • systemd — install a systemd user unit. Runs systemctl --user enable revka.service so it starts on login. For start-on-boot without an active session, enable lingering with loginctl enable-linger $USER.
  • openrc — install an OpenRC init script. System-wide and root-only; see the Linux tab below.

The launchd agent runs revka daemon with RunAtLoad and KeepAlive. Homebrew installs are detected automatically: the service then uses <brew_prefix>/var/revka/logs/ for logs and carries REVKA_CONFIG_DIR as an environment key in the plist, so config and workspace data survive brew upgrade. The plist raises the file-descriptor limit (SoftResourceLimits/HardResourceLimits for NumberOfFiles, 4096 soft / 8192 hard) to avoid “Too many open files” when many MCP servers run at once.

brew services start revka uses the same plist.

Terminal window
revka service install
revka service start

Before revka service start, daemon logs are rotated if they exceed 20 MB. Up to 5 rotated copies are kept (daemon.stdout.log.1 through .5); the oldest is deleted before renaming. Logs live in the Homebrew var/revka/logs/ directory or <config_dir>/logs/.

  1. Install the service. The init system is auto-detected.

    Terminal window
    revka service install
  2. Start it.

    Terminal window
    revka service start
  3. Confirm it is healthy. Check the service state and the public health endpoint.

    Terminal window
    revka service status
    curl http://127.0.0.1:42617/health
  4. Pair a client. Read the pairing code and exchange it for a token.

    Terminal window
    revka gateway get-paircode
    revka pair token --code 123456
  • Liveness. GET /health returns 200 with pairing status and a component snapshot and needs no auth — ideal for load balancers. revka status --format exit-code exits 0 when healthy and 1 otherwise (the canonical Docker HEALTHCHECK). Run revka doctor for structured diagnostics.
  • Service won’t start (Windows). revka service status also consults the daemon state file; a state file fresher than 45 seconds means a daemon is already running.
  • Restart loops in the logs. A component keeps failing and the supervisor keeps restarting it with growing backoff. Check the recorded last error and tune reliability.channel_max_backoff_secs.
  • Can’t reach the gateway from another machine. The default bind is loopback-only. Set allow_public_bind = true or front it with a tunnel.
  • Pairing input rejects your code. Codes are single-use. Rotate with revka gateway get-paircode --new and try again.