RemotePower
Sign in
Access your device control panel
Invalid username or password
Demo mode — this is a read-only sandbox with fake data. Browse anything. Nothing here can be modified. Run your own →
RemotePower RemotePower
Live
Main
Help
Fleet at a glance
Everything that needs your attention, in one screen.

Needs attention

Recent activity

Fleet roster · 7-day status

Device Control
Manage and remotely control enrolled devices
0
Total devices
0
Online
0
Offline
Enrolled Devices
0 selected
Monitor
Ping, TCP, and HTTP checks run from the server
Targets
LabelTypeTargetStatusDetailChecked
No monitors configured.
Device metrics
Device Alert Memory Swap CPU load Disks
Scripts
—
Running on
—
Failing
—
All OK
—
Script Device Group Status Last output Last run Duration
Click Refresh to load results.
Admin Users
Manage who can access this dashboard
Accounts
UsernameCreatedRole
Settings
Server configuration

Server identity

Display name shown in the page title, push notification subject lines, and webhook payloads. Helps tell instances apart when you have more than one.

Default poll interval

How often newly-enrolled agents heartbeat back to the server. Existing devices are not affected — change theirs from the device detail page.

10–3600 (default 60)

Online TTL

A device is considered offline if no heartbeat is received within this window. Should be at least 2 × poll_interval to avoid false offline alerts during a single missed poll.

90–7200 (default 180)

Monitor check interval

How often monitors auto-check when the Monitor page is open. Also controls server-side offline/patch check frequency.

60–3600 (default 300)

CVE details cache

How long OSV.dev vulnerability details are cached before being re-fetched. Higher = fewer external requests, lower = newer descriptions on existing CVEs.

1–90 (default 7)

Wake-on-LAN

Magic packets are sent via UDP broadcast from the server. Adjust if your network uses a directed broadcast address.

Webhook URL

POST a JSON payload to this URL on events. Compatible with Ntfy, Gotify, Slack, Discord, Pushover, and any webhook receiver. Push-friendly headers (X-Title, X-Priority, X-Tags) are included automatically.

✓ Webhook is currently configured

Per-event toggles

Enable or disable each event type. Disabled events are recorded as "disabled" in the webhook log so you can see what was suppressed.

Email notifications (SMTP)

Send the same events via email as a sibling channel to webhooks. Both channels respect maintenance windows. Email is opt-in per event in the table above.

Comma-, semicolon- or whitespace-separated list. All listed addresses receive every enabled event.

Webhook log

Recent deliveries
TimeEventStatusDetail
No webhook deliveries yet.

Two-Factor Authentication (2FA)

Protect your account with an authenticator app (Google Authenticator, Authy, etc.).

Session length

How long a session lasts. Short by default; "remember me" extends to long.

SSH preferences

Your default SSH username. Used by the quick-SSH link on the Devices page so you don't retype it each time. Stored per-user, not shared.

LDAP / LDAPS authentication

External authentication source. Local users in users.json are tried first — emergency access never depends on LDAP being reachable. Users authenticated via LDAP are auto-provisioned with the role determined by group membership.

ldaps:// for TLS, ldap:// for plain (don't).
AD: (sAMAccountName={u}) · OpenLDAP: (uid={u}) · FreeIPA: (uid={u})

Backup & export

Download a ZIP of all server data files (devices, config, history, audit log, etc.). Useful for disaster recovery and migrations.

Status endpoint

A machine-readable fleet summary at /api/status for external dashboards — Uptime Kuma, Homepage, Grafana. It needs a status token (not a login), so a monitoring tool can poll it, but it is not public. Generate a token to enable it.

Proxmox VE connection

Connect a single Proxmox VE node. The RemotePower server calls the Proxmox API directly to list QEMU VMs (Virtualization page) and LXC containers (Containers page), and to start / shut them down. Authentication uses a Proxmox API token — create one under Datacenter → Permissions → API Tokens.

Note: the API token secret is stored in the server's config.json (file mode 600). It is not encrypted at rest. Use an API token scoped to only the permissions it needs (VM.PowerMgmt, VM.Audit), not a full-access token.

More secure option: set the token secret in the environment variable RP_PROXMOX_TOKEN_SECRET (in the systemd unit or container env) instead of here. When that variable is set it takes precedence, the secret stays out of config.json, and it is not included in the backup export.

✓ The token secret is currently being read from the RP_PROXMOX_TOKEN_SECRET environment variable. The field below is ignored.

Proxmox ships a self-signed certificate by default — if you haven't installed a trusted cert, set Verify TLS to Off. Prefer installing a real certificate.

Mailbox monitor

Count messages in a mailbox without IMAP/SMTP. Pick a device, give it one or more directory paths, and the agent counts the regular files in each (a Maildir new folder holds one file per unread message). Tick "Show on dashboard" to surface a device's count as a tile on the Home dashboard.

When any watched mailbox reaches this many messages, RemotePower fires a webhook alert. Leave blank to disable.

AI provider

Wire in an LLM for the ✨ buttons on the command output, journal, scripts, CVE findings, devices, and notifications. Disabled by default. Cloud providers send the content of the request to a third party; pick a local provider (Ollama or LocalAI) if you don't want data to leave the building.

Leave blank to keep the saved key. Type __clear__ to remove it. Not used for Ollama or LocalAI.

Privacy — what gets sent to the provider

By default, hostnames and IP addresses are stripped from every request before it leaves the building. Long hex strings, bearer tokens, and AWS access keys are always redacted regardless of these toggles. Cleartext journal content and command output are sent only when you explicitly opt in.

Context awareness (v2.1.7)

A small block of background ("you are an assistant inside RemotePower; the agent polls every 60s…") plus a one-line-per-device fleet snapshot is prepended to every AI request. The model stops giving generic Linux advice and starts giving advice that references your devices and your conventions. Project context is non-sensitive. Fleet context contains hostnames and group names by design — if you're on a cloud provider and don't want hostnames egressing, turn the fleet toggle off (project context will stay on).

Limits

Bounds to keep cloud-provider costs predictable. The token limit is per response. The daily request cap is per user — set to 0 to disable.

Test connection

Round-trip a one-word "say hi" request against the configured provider. Saves a settings round-trip before you start using the ✨ buttons in anger.

Command History
Log of all commands sent to devices
Recent commands
TimeActorDeviceCommand
Scheduled Commands
Queue shutdown or reboot at a specific time
Pending jobs
DeviceCommandScheduled forBy
No scheduled jobs.
Documentation
How to use RemotePower — quick reference for the common tasks
Enrolling devices — get a host into RemotePower

Quick (interactive): Click "Enroll device" in the dashboard. You get a 6-digit PIN, valid for 10 minutes. On the target machine: sudo remotepower-agent enroll, paste the PIN.

Automated (Ansible / cloud-init): Use the API to mint a one-time-use enrollment token (Settings → API or POST /api/enrollment-tokens), pass it via $REMOTEPOWER_ENROLL_TOKEN or /etc/remotepower/enroll-token, then run remotepower-agent enroll-token --server https://<host>. Token is consumed atomically — same one can't enroll twice. Default expiry 24h, max 7 days.

The token resolution order is: --token arg → environment variable → on-disk file (mode 600, auto-deleted on success).

Metric alerts — disk / memory / CPU thresholds

RemotePower fires metric_warning, metric_critical, and metric_recovered webhooks when a device's resource crosses its configured threshold. Defaults:

MetricWarningCritical
Disk usage (per mount)80%90%
Memory85%95%
Swap20%50%
CPU load ratio (loadavg / cpu_count)1.5×3.0×

Per-device overrides: Devices page → ⋯ menu → "Metric thresholds". The modal shows current sysinfo values for context, then warn/crit fields per metric (empty = use default). Per-mount disk overrides go in the bottom section — useful when /var fills with logs or /backup is meant to fill.

Hysteresis: a metric must drop 5 points below its warn threshold before "recovered" fires. Without this, oscillation around 80% would generate webhook spam every 60s.

Trends over time: Monitor page → Device metrics row → "Trend" button. Same chart as the per-device sysinfo modal.

Web terminal — open SSH from the browser

Click "Web terminal" on a device. Modal asks for SSH user, port, password, plus your RemotePower admin password (re-prompted every time, by design).

Architecture: a separate remotepower-webterm daemon handles the WebSocket+SSH bits because RemotePower's CGI can't hold persistent connections. nginx proxies /api/webterm/connect to it. SSH credentials live only in memory for the duration of the session — never persisted.

Setup (one-time): sudo bash packaging/install-webterm.sh. Auto-detects the CGI user (www-data, nginx, http, etc.), installs Python deps, generates the daemon ↔ CGI shared secret, prints the nginx snippet you need to add. Run with --dry-run first if you want a preview.

Recordings: Every session recorded to /var/lib/remotepower/webterm-sessions/<id>.cast in asciinema v2 format. Output-only by default (set RECORD_INPUT=1 in daemon env to capture keystrokes too — only do this if you've thought about who can read the recordings dir). Replay with asciinema play <file>.

Commands — run shell, shutdown, reboot, upgrade

Per-device dropdown menu has the common actions: shutdown, reboot, Wake-on-LAN (if device has a known MAC), agent self-update, upgrade packages, custom command.

Commands queue in cmds.json. The agent picks them up on its next heartbeat (default 60s, configurable per-device). Output comes back on the heartbeat after execution finishes — for apt upgrade that can be a few minutes.

Batch mode: tick checkboxes on multiple devices, the batch bar at the bottom of the page lets you run any of those actions across all selected devices at once.

Custom commands: "Custom command" in the menu, or save reusable ones to the Library (Admin → Library) and pick from a dropdown when you run them.

Webhooks — get notified when things happen

Settings → Webhooks. RemotePower auto-detects the format from your URL: Discord webhook URLs get embed-style messages; ntfy URLs get priority + emoji tags; everything else gets generic JSON.

Events you can subscribe to: device_offline / device_online, monitor_down / monitor_up, service_down / service_up, patch_alert, cve_found, log_alert, container_stopped / container_restarting, metric_warning / metric_critical / metric_recovered, command_queued / command_executed.

Each event can be toggled independently. The "Send test event" button fires a sample payload so you can verify your endpoint works before relying on it.

External monitors — ping/TCP/HTTP probes

Monitor page → "Add target". The server runs these probes itself, not the agents — useful for checking your ISP gateway is up, a web service is responding, or an SSH port is open.

Probes run on a schedule (monitor_interval, default 300s, minimum 60s). The schedule piggybacks on incoming CGI requests, so as long as any agent is heartbeating or anyone's browsing, monitors run on time. State transitions fire monitor_down / monitor_up webhooks.

Proxmox virtualization — managing QEMU VMs

RemotePower can connect to one Proxmox VE node and manage its guests. Configure it under Settings → Proxmox: the node's host, the node name, and a Proxmox API token (created in Proxmox under Datacenter → Permissions → API Tokens). Use a scoped token — VM.Audit and VM.PowerMgmt are enough — not a full-access token. There's a "Test connection" button to verify the setup.

Once configured, the Virtualization page lists the node's QEMU virtual machines: status, CPU and memory while running, uptime. Each guest has Start and graceful Shutdown actions. The connection is server-to-API — the RemotePower server talks to the Proxmox REST API directly; no agent runs on the Proxmox node.

This is a single-node integration. The Virtualization nav entry is always visible; if Proxmox isn't configured the page simply tells you so.

Proxmox LXC containers

LXC containers on the Proxmox node appear on the Containers page, in a section below the agent-reported Docker/Podman containers. They carry the same Start and Shutdown actions as QEMU VMs.

The LXC section only appears once Proxmox is configured (Settings → Proxmox). Like the VM list, it's fetched live from the Proxmox API each time you open the page.

Snapshots & rollback — point-in-time guest states

Each Proxmox guest — QEMU on the Virtualization page, LXC on the Containers page — has a Snapshots button. It opens a panel listing the guest's snapshots and lets you create, roll back, and delete them.

Create — give the snapshot a name (a letter followed by letters, digits or underscores) and an optional description. Snapshots are disk-only — the VM's RAM state is not captured. A typical workflow: take a snapshot named before_upgrade immediately before a risky change.

Rollback — returns the guest to a snapshot's state. This is destructive: every change made since the snapshot was taken is discarded. Because of that, RemotePower asks you to type the guest's name to confirm — a deliberate speed bump, not just an OK button. After a rollback the guest is at a crash-consistent disk state (no live memory, since snapshots are disk-only).

Delete — removes a snapshot. Irreversible, but it does not affect the running guest — only the saved point-in-time state is gone.

Snapshot operations run asynchronously on Proxmox. RemotePower sends the request and refreshes the list shortly after; a slow operation may not show on the first refresh — reopen the panel. Every snapshot action is recorded in the fleet event log.

Quick SSH from the Devices page

Set a default SSH username under Settings → Security → SSH preferences. It's stored per-user.

On the Devices page, a small SSH icon appears next to each device's hostname. Clicking it builds an ssh:// link to that device — using the device's IP if known, otherwise its hostname — with your default username, and also copies the plain ssh user@host command to your clipboard.

Whether the ssh:// link opens a terminal depends on your own machine having an ssh:// handler registered (the OS, PuTTY, a terminal emulator). If it doesn't, the copied command is the reliable path — paste it into any terminal.

Mailbox monitor — unread-message counts

A lightweight way to see a mailbox's message count without any IMAP/SMTP setup. Configure it under Settings → Mailbox monitor: pick a device, enter one or more absolute directory paths, and Save. The agent counts the regular files directly inside each directory and reports the numbers in its heartbeat — for a Maildir new/ folder that file count is the unread-message count.

Tick "Show this device's mailbox count on the dashboard" to add an "Unread mail" tile to the Home dashboard, alongside the devices / updates / drift / CVE tiles.

Counts refresh on the agent's schedule — roughly every five minutes, not instantly. The agent needs read access to the directory; if it doesn't have it, the count shows the reason (e.g. "permission denied") rather than a number. No email content is ever read — only files counted.

Scan packages now — on-demand inventory

The agent submits its full package inventory (used for CVE scanning) and the patch/upgradable count only every few hours. Right after you patch a host, use the "Scan packages now" item in the device action menu to get a fresh report sooner.

It sets a one-shot request; the device sends a fresh package list and patch count within a heartbeat or two — typically a minute or two, not instantly. The agent must be running 2.4.5 or newer to act on it.

Status endpoint — for external dashboards

RemotePower can expose a small machine-readable fleet summary at /api/status for external dashboard tools — Uptime Kuma, Homepage, a Grafana panel.

Generate a status token under Settings → Advanced → Status endpoint. The endpoint then answers at /api/status?token=YOUR_TOKEN — reachable by a polling tool, but not public. It returns a rolled-up health word (ok / warning / critical), device online/offline counts, and attention counts by severity. Rotate or disable the token any time from the same place.

Two-factor authentication (TOTP)

Settings → Security → "Enable two-factor". Scan the QR with any authenticator app (1Password, Authy, Google Authenticator, etc.). After enabling, every login asks for a 6-digit code in addition to your password.

To disable, you need to authenticate with a current TOTP code first — prevents someone with stolen session cookies from removing your second factor.

Tables: filter, sort, density

Every fleet table — Devices, Services, CVE Findings, Containers, Monitor, TLS, Patches, Audit Log, Command History, Schedule, Maintenance, plus admin tables — has a substring filter and clickable column headers.

First click sorts ascending, second descending, third clears. Hold Shift to add a secondary sort key (small superscript shows the priority).

The Devices grid has four density modes: Minimal (table layout, multi-select via checkboxes), Compact, Comfortable, Spacious. All preferences (filter, sort, density) sync per-user across browsers.

Backup & restore

All state lives in /var/lib/remotepower/ as JSON files. To back up:

sudo tar czf rp-backup-$(date +%F).tar.gz /var/lib/remotepower/

To restore: stop nginx briefly so no writes interleave, untar, restart.

v1.12.1+ keeps a rolling .bak next to each file. If a file ever ends up corrupted, load() automatically falls back to the .bak with a warning to the nginx error log. The dashboard keeps working with last-known-good data.

Troubleshooting common issues

Devices show "Offline" but agent is running: agent token doesn't match server. Check journalctl -u remotepower-agent for "Credentials rejected" — re-enroll on the device with sudo remotepower-agent enroll.

Web terminal fails with 404: nginx routes /api/webterm/connect to fcgiwrap instead of the daemon. The exact-match location = /api/webterm/connect block must come BEFORE any location ^~ /api/ in the same server block.

Web terminal fails with 502: nginx is correctly trying the daemon but the daemon isn't running. sudo systemctl status remotepower-webterm and journalctl -u remotepower-webterm.

Per-mount disk thresholds aren't taking effect: Agent must be v1.11.10+ to report per-mount data. Push an agent self-update from the toolbar.

Update history is empty for old agents: Pre-v1.11.7 had a bug where command output never reached the server. Push agent self-updates; the next upgrade will populate history.

Full reference: Manual.html.

API access — automation and integrations

Every dashboard action has an underlying API endpoint. Browse the full schema at /swagger.html (also linked from the sidebar as "API Reference").

Auth: two methods. Session tokens (login flow, time-limited) for short-lived scripts. Named API keys (Admin → API Keys → "New key") for CI / cron / Ansible — these don't expire. Pass via X-Token: <token> header.

Common patterns:

# List devices
curl -H "X-Token: $T" https://remote.example.com/api/devices | jq

# Reboot a specific device
curl -X POST -H "X-Token: $T" -H "Content-Type: application/json" \
  -d '{"device_id":"abc123"}' \
  https://remote.example.com/api/reboot

# Set per-device thresholds
curl -X PATCH -H "X-Token: $T" -H "Content-Type: application/json" \
  -d '{"mem_warn_percent": 70, "disk_per_mount": {"/var": {"warn":70,"crit":85}}}' \
  https://remote.example.com/api/devices/abc123/metric-thresholds
Page reference
Devices page — your fleet, at a glance

Home page. Every enrolled device shown as a card or table row, depending on density. Each card shows: status (online/offline), name, OS icon, last-seen time, group badge, tag pills, key sysinfo (CPU/RAM/disk sparklines if metrics are flowing), pending updates count, open CVEs count.

Density modes: top-right toggle. Minimal = table, one row per device, sortable, multi-select. Compact = small cards. Comfortable = default. Spacious = roomy cards with bigger metric blocks.

Per-device dropdown (⋯ button) covers the common actions: reboot, shutdown, custom command, agent update, upgrade packages, web terminal, metrics chart, metric thresholds, edit notes, edit tags, change group, delete.

Batch actions: tick checkboxes on multiple devices, the batch bar at the bottom lets you run any of the above across the selection.

Filter & sort: top-bar substring filter matches name, hostname, group, tags, IP, OS. Click any column header (in minimal mode) to sort; Shift-click for secondary sort. Filter and sort persist per user.

CMDB page — asset metadata + credentials vault

Per-device structured metadata that the agent doesn't auto-discover: asset ID, server function (web / db / nas / firewall…), hypervisor URL, SSH port, free-form Markdown documents.

Multiple documents per asset (v2.0): attach as many titled Markdown docs as you want — runbook, hardware spec, change log, vendor contacts. Each doc has its own title, body, and timestamp. Docs render as expandable cards in the asset view.

Credentials vault: store SSH passwords, BMC credentials, vendor portal logins encrypted at rest. Encryption is AES-GCM with PBKDF2-SHA256-derived keys; the passphrase is shared across admins (set once at vault setup). Reveal events are audit-logged. Each credential row exposes an ssh:// link button if the asset has an SSH user/port set.

Server functions list: editable in Settings, used as autocomplete suggestions when filling the function field on an asset.

Containers page — what's running where

All containers across your fleet, in one table. Auto-detected from each agent: Docker (via socket), Podman (rootless or root), Kubernetes pods (via kubelet, where applicable). Read-only — RemotePower doesn't manipulate containers, just observes them.

Per-row info: device, container name, image, status, restart count, ports, namespace (k8s). Filter by name, image, device, or namespace.

Alerts: three webhook events fire automatically — container_stopped (unexpected stop), container_restarting (restart count climbed), containers_stale (device hasn't reported container info recently — usually means the agent's container detection isn't working).

Network page — topology graph

Manual topology map drawn from each device's connected_to field. RemotePower doesn't auto-discover topology — set the upstream switch / router for each device, and the graph renders.

Switches, APs, and other agentless devices live as full-fledged records in the device list (with their own CMDB / vault / SSH-link as agented devices). Use Devices → Add agentless device.

The graph is positional — drag nodes around, the layout persists. Useful for finding the "who's downstream of this switch" answer at a glance.

Monitor page — external probes + live device metrics

Top section: external probes. ICMP ping, TCP port, HTTP HEAD checks that the server runs against any target (your ISP gateway, an external website, a remote SSH port). Add via "Add target". Probes run on schedule (default 300s, min 60s); state transitions fire monitor_down / monitor_up webhooks. Each row shows current state, last check, response detail.

Bottom section: live device metrics (v1.12.0). Every enrolled device's current memory / swap / CPU / per-mount disk values, color-coded by alert level. Filter by name, group, tag, or mount path. Sort by any column.

Trend button (v2.0): next to the per-device thresholds button, opens the time-series chart modal — same chart you'd get from the Devices page metrics action, just one click away from the fleet view.

TLS / DNS page — certificate & record watchlist

Server-side probes that warn before things expire. Add a hostname (or hostname:port for non-443) and the type — TLS for cert expiry, DNS for record-set health. Probes run on schedule alongside the monitor probes.

TLS: connects, fetches the leaf cert, reports expiry days remaining + issuer + SAN list. Alerts at <30 days, critical at <7. Self-signed and otherwise-invalid certs flagged with reason.

DNS: resolves A/AAAA/MX/TXT (whichever exist), reports the TTL of the soonest-expiring record. Useful for catching domain registrar issues before the domain itself lapses.

Both fire alerts via the existing webhook system — no separate config needed.

Patches page — pending updates across the fleet

Aggregates pending-update counts from every agent. Linux agents run apt list --upgradable / dnf check-update / pacman -Qu / apk list --upgradable on a schedule (default every 3 hours) and report the count + package list back.

Per-device row: total upgradable, security-only count (where the package manager exposes that), oldest pending update age. Click into a device for the full list.

Patch alert webhook: Settings → Webhooks → Patch alert. Configurable threshold; fires patch_alert when a device has more than N pending updates.

Run upgrade: per-device dropdown → "Upgrade packages" runs the appropriate package manager non-interactively and returns the output as Update history. Batch select to upgrade many at once.

Custom Scripts — your own bash health checks on devices

Define arbitrary bash scripts server-side and assign them to any set of enrolled devices. The agent runs each assigned script every 5 minutes with a 30-second timeout. Exit code 0 = OK; anything else = FAIL.

Create a script: Custom Scripts → New script. Paste a body directly, or type a description and click ✨ Generate to have the AI draft one. Assign the script to one or more devices using the device picker. Save.

Results: The Custom Scripts page shows a fleet-wide table — script name, device, status badge, last output snippet, when it last ran, and how long it took. Click any output snippet to see the full stdout/stderr.

Alerts: Status changes fire webhooks — custom_script_fail when a script flips from OK to FAIL (includes the first line of output), custom_script_recover when it returns to OK. Both are edge-triggered: they fire once on the transition, not on every failing run.

Script execution: Scripts run as the agent user (root on most setups), with stdout and stderr merged, capped at 4 KB. The script body is written to a private temp file (chmod 700), executed by /bin/bash, then deleted. Scripts are pushed from the server — no SSH needed.

Examples: check a web endpoint returns 200, verify a backup file was recently modified, test a database port is accepting connections, confirm a cron job's sentinel file exists.

CVEs page — known vulnerabilities in installed packages

Cross-references each agent's installed-package list against OSV.dev on a schedule (default daily). Findings are severity-ranked and grouped by device.

Each finding shows: CVE ID, severity (CRITICAL / HIGH / MEDIUM / LOW), affected package + installed version, fixed version (if any), summary, references. Click for the full OSV record.

Ignore list: known false positives or accepted risk can be ignored per CVE-ID + per-package combo. Ignored findings disappear from the active view but stay in audit history. The "Show ignored" toggle reveals them.

cve_found webhook: fires when new CVEs appear that aren't on the ignore list. Useful for plugging into the team's incident channel.

Services page — systemd unit health matrix

Per-device watched-services view. Define which units to watch in Settings → Service watch (or via API), and the agent reports their state on every heartbeat: active, inactive, failed, activating, etc.

Matrix view: rows are devices, columns are services; cell color reflects state. Filter by service name, device, or group; sort by failure count.

Webhooks: service_down when a watched unit transitions to inactive/failed; service_up on recovery. Maintenance windows suppress these without losing the audit trail.

Logs page — log tail across the fleet with pattern matching

Per-device journalctl output for watched units. Agents submit log lines on every heartbeat; server keeps a rolling 6-hour buffer.

Search: regex over the buffered logs. Filter by device, unit, time range. Useful for "did this error happen anywhere in the last hour?"

Pattern alerts: Settings → Log rules. Define regex patterns; matches fire log_alert webhook with the matched line, device, and unit. Useful for kernel oops, OOM kills, fail2ban bans, anything you want a notification on.

Per-device or fleet-global rules: rules can be scoped to a device (only matches there fire) or fleet-global (matches on any device fire).

Schedule page — one-shot & recurring commands

Schedule reboots, shutdowns, package upgrades, or arbitrary commands. Two modes:

One-shot: pick a date+time, RemotePower fires the command then. Useful for "reboot tonight at 2 AM".

Recurring: standard 5-field cron expression (min hour dom mon dow). Useful for "reboot every Sunday at 3 AM" or "run cleanup every weekday at midnight".

Per-device, per-group, or fleet-global. Combine with maintenance windows to suppress alerts during the planned action.

Calendar page — visual timeline of scheduled events

Calendar view of upcoming scheduled commands and maintenance windows. Useful for "what's planned this week?" and avoiding accidentally double-booking maintenance.

Read-only here — to add events, use the Schedule page (for scheduled commands) or Maintenance page (for maintenance windows).

Tasks page — operational checklist

Free-form per-fleet task list. Write down what you need to do, check items off, leave notes. Doesn't drive any automation — just a place to keep track of "rebuild X next maintenance window" or "investigate why Y is restarting".

Tasks have title, description, optional due date, status (open / in-progress / done). Filter by status; sort by due date.

Maintenance page — alert-suppression windows

Schedule windows during which webhook alerts are suppressed for specific devices, groups, or the whole fleet. Useful for planned downtime where you don't want to be paged for an expected outage.

Two modes: one-shot (start time + end time) or recurring (cron pattern + duration). Scope: device, group, or all.

Suppressed alerts are still logged — you can see exactly what would have fired during the window via the audit log. So if something unexpected happens during maintenance, you can find it after the fact.

History page — command execution log

Every command run via RemotePower, with actor (which user), target device, command, exit code, output preview, timestamp.

Used together with the Audit log (which covers admin actions like creating users, changing settings) to reconstruct what happened during an incident.

Rolling buffer of last 200 commands. For longer-term retention, configure log forwarding to your central logging system.

Settings page — server-wide configuration

Tabs:

  • Account — change password, enable/disable TOTP 2FA, view active sessions, revoke sessions.
  • Webhooks — add destination URLs (Discord, ntfy, Slack, generic JSON), per-event toggles, "send test event" buttons.
  • SMTP — outbound email settings for the digest endpoint and password resets.
  • LDAP — bind URL, search base, attribute mappings; "Test connection" button.
  • Service watch — list of systemd units the agents should monitor, applied to all devices unless overridden.
  • Log rules — regex patterns for log_alert events.
  • Server functions — autocomplete list for CMDB asset function field.
  • Backup — one-click ZIP download of all state JSON files.
Users page (Admin) — local accounts

Manage local user accounts. Each user has a username, bcrypt password, role (admin or viewer), optional TOTP secret, optional email for password reset.

Roles: admin can do everything. Viewer is read-only — can browse all pages but every write endpoint returns 403.

LDAP users auto-create on first successful bind; their role defaults to viewer until an admin promotes them.

API Keys page (Admin) — non-expiring tokens for automation

Named API keys that don't expire (unlike session tokens). Use for CI scripts, cron jobs, Ansible, Grafana scraping /api/metrics.

Keys are bound to a user account — when you create a key, it inherits your role. To make a "ci-bot" key with limited access, create a viewer-role user first and create the key while logged in as that user.

Pass via X-Token: <key> header (same as session tokens). Keys can be revoked instantly from this page; revoked keys 401 immediately.

Library page (Admin) — saved command snippets

Reusable shell-command bookmarks. Save common diagnostics ("show disk usage by mount"), restart routines ("kick the failing service"), or chained operations as named entries.

When running a custom command on a device, the modal has a dropdown that auto-populates from this library — no need to remember the exact find incantation.

Audit page (Admin) — admin event log

Every administrative action: user created/modified/deleted, password changed, settings changed, API key minted/revoked, enrollment token created, vault unlocked, credentials revealed.

Each entry: timestamp, actor (user), action, detail string, source IP. Filter by actor, action, or substring; sort by any column.

For command execution, see the History page (separate). The Audit log is for "who changed what configuration" rather than "who ran what command".

Links page — external bookmark grid

Per-fleet bookmark grid. Add URLs for the things you reach for during operations: your monitoring stack, your wiki, your status page, your IPMI portal, your DNS provider's dashboard.

Group links by category. Each link gets a name, URL, and optional icon. Display-only — RemotePower doesn't proxy or check these.

Scripts — the multi-line script library (v2.1+)

Like the command library but for full bash scripts — multi-line, with `set -euo pipefail`, error handling, the works. Stored in scripts.json; created and edited via the Scripts page.

Save flow: paste a script → editor runs bash -n (syntax check) and a regex-based dangerous-pattern detector (rm -rf /, fork bomb, dd if=/dev/zero of=/dev/sda, curl|bash, chmod 777 /, etc.). Both must pass before save.

Run on a device: Devices page → ⋯ menu → "Run script…", pick from the library, confirm. Output comes back on the next heartbeat after execution finishes.

Batch run: tick checkboxes on multiple devices, batch bar → "Run script", pick from the library. The batch tracker shows per-device progress; output collects under the batch job ID for ~1h.

Tagged runs: instead of ticking devices, target a tag or group via the API: POST /api/exec/batch with tag, group, or device_ids.

Full reference: docs/scripts.md.

AI assistant — five providers, ✨ buttons across the dashboard (v2.1.3+)

Disabled by default. Enable in Settings → AI assistant. Five providers: Anthropic (Claude), OpenAI (ChatGPT), DeepSeek, Ollama (local), LocalAI (local). Pure stdlib — no extra pip deps. Pick a local provider (Ollama / LocalAI) if you don't want data leaving the building.

Where the ✨ buttons appear:

  • Device dropdown (⋯ menu) → Investigate, Generate runbook.
  • Device detail modal → Explain on each command output, Find the problem on the journal panel.
  • Services page → service detail → Diagnose on failed/inactive units.
  • TLS page → table row → Triage on warning/critical/error certs.
  • Patches page → table row → Prioritise on devices with pending updates.
  • CVE Findings → row → Triage.
  • Scripts editor → Generate from prompt / Explain / Audit for risks.
  • Notifications → webhook log row → Explain.
  • Help → AI Assistant → standalone chat with model picker and Ollama server stats.

Privacy: hostnames and IPs are redacted before leaving the building unless you toggle "Send hostnames" / "Send IP addresses" in Settings. Bearer tokens, AWS keys, and long hex strings are always redacted regardless. AI-generated scripts go through the same dry-run + dangerous-pattern detection as anything else — no AI-trusted bypass.

Slow local models (smallthinker, qwq, deepseek-r1) routinely take 60–180 s per response. The HTTP timeout is 5 min on the Python side, but nginx's fastcgi_read_timeout defaults to 60 s and will cut you off first — add a location /api/ai/ block with fastcgi_read_timeout 300s;. See docs/ai.md for the snippet and the full reference.

Rate limits: per-user per-day cap in Settings (default 100; 0 = unlimited). Per-button max_tokens tuned client-side so a short Explain doesn't sit waiting for 4000 tokens to generate.

Device runbooks — AI-generated, per device (v2.1.7)

What it is: a structured operations document for each device, generated by the AI from the device's current state (sysinfo, watched services, containers, recent commands, journal, CVE findings, patch status). Saved per-device; regenerable any time.

How to generate: Devices page → ⋯ menu → Inspect → ✨ Generate runbook. The AI gets the live snapshot of the device plus the fleet context (so it can say "this is your mail server" rather than just "this is a Linux box"). Takes 15–90 s depending on provider and model.

What's in it: sections for purpose / role, installed stack, running services, listening ports, scheduled jobs, recent activity, "things to know," and known risks. Format is Markdown — rendered inline on the device detail modal under a Runbook section.

When it's worth re-running: after a major change to the device, before handover, when documenting a system for a colleague, after the OS upgrade. The data is current as of when it ran — the timestamp is shown alongside the runbook.

Privacy: runbooks contain hostnames and IPs by design (a redacted runbook is useless). The redaction toggles in Settings → AI assistant apply, but you'll want "Send hostnames" + "Send IP addresses" on for runbook generation specifically. Storing hostnames in a runbook that lives in your own JSON file isn't a privacy concern; what matters is whether they cross over to a cloud provider on generate.

Configuration drift detection — per-device file integrity monitoring (v2.2.0)

What it is: the agent computes SHA-256 hashes of a list of watched config files every few heartbeats and ships them in the heartbeat payload. The server stores baselines (first-seen hash per file per device) and fires a drift_detected webhook when a current hash diverges from the baseline.

Hash-only by design. The contents of /etc/sudoers, /etc/ssh/sshd_config, etc. never cross the wire on routine polling. To see what actually changed, an operator action queues a cat command through the existing exec mechanism (subject to the usual audit + permission checks).

Where to find it: sidebar → Security → Drift. Fleet-wide table shows devices sorted with drifted ones at the top; click Detail for per-file status, drift count, history of the last 20 changes, and the Accept as baseline button.

Default watched list: /etc/ssh/sshd_config, /etc/sudoers, /etc/fstab, /etc/crontab, /etc/hosts, /etc/resolv.conf, /etc/nsswitch.conf, /etc/pam.d/sshd. Customisable globally (cfg['drift']['default_watched_files']) and per-device (device.watched_files).

Webhook: drift_detected fires once per change (debounced — not on every poll that reports the same new hash). Route it to a channel you check, especially for after-hours alerts.

Compliance: covers configuration management controls in SOC 2 (CC6.1, CC6.6), ISO 27001 (A.12.4.3, A.14.2.4), HIPAA (164.312(c)), PCI DSS (11.5), FedRAMP. Baseline-acceptance audit-log entries are designed to be readable as evidence.

Agent version: requires v2.2.0+ for the agent-side hash reporting. Older agents work normally otherwise but show "no drift data" on the Drift page.

Full reference: docs/drift.md.

MCP server — natural-language fleet queries from Claude Desktop, Cursor, VS Code (v2.2.0)

What it is: RemotePower ships an MCP (Model Context Protocol) server at mcp/remotepower-mcp.py. Connect it to an MCP-compatible AI host and you can ask things like "Which devices have pending security updates?" or "Show me the journal for pmg01 from the last hour" in plain English.

Architecture: the MCP server runs on the operator's laptop, not on the RemotePower server. The AI host (Claude Desktop, Cursor, etc.) spawns it as a stdio subprocess. The MCP server makes HTTPS calls to RemotePower's REST API on behalf of the AI using an API token you provision. Credentials live in the host's config file and never reach the AI provider.

Read-only, by design. 12 tools: list_devices, get_device, get_journal, get_services, get_containers, get_cves, get_drift, get_recent_commands, get_runbook, get_patches, get_tls, search_devices. No write tools. No run_command, no run_script, no reboot_device. The test suite asserts no write-shaped names slipped in. Write tools land in a future release once a server-side allow-list, per-MCP-token role, and confirmation flags are in place — not before.

Setup (Claude Desktop):

  1. Settings → API keys → Generate a viewer token; copy the rpk_... value.
  2. Copy remotepower-mcp.py to your laptop (scp works).
  3. Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows) — add an mcpServers.remotepower entry with the command, args, and env (URL + token).
  4. Restart Claude Desktop. The 🔨 tool indicator should show remotepower.

Device-name resolution: exact → prefix → substring → ambiguity error. You can pass web01 and the server finds tviweb01.tvipper.com automatically (as long as there's exactly one match).

Pure stdlib Python. No pip install. Single 470-line file.

Full reference: docs/mcp.md.

Notification setup — getting alerts to land where you'll see them

RemotePower has webhook (Discord / Slack / ntfy / generic JSON) and SMTP email channels. Pick whichever you actually check.

Recommended baseline (most operators want):

  1. One webhook for page-me-now events: device_offline, service_down, monitor_down, metric_critical, cve_found. Point at ntfy / Pushover / your phone.
  2. One webhook for FYI-during-business-hours events: metric_warning, patch_alert, log_alert, container_stopped. Point at a Discord/Slack channel.
  3. Email digest for the slow stuff (weekly CVE summary, patches pending) once cron_email_digest is enabled.

Per-event toggles: each webhook URL has independent toggles for every event type. The "Send test event" button fires a sample payload so you can verify the integration works before relying on it.

Maintenance windows suppress alerts during planned downtime. Suppressed alerts are still logged — you can see what would have fired in the audit log. So if something unexpected happens during maintenance, you can find it after.

✨ Explain on alerts: each webhook log row has a ✨ Explain button that asks the AI to rewrite the raw alert into a single short paragraph ("postfix on pmg01 stopped at 14:32 after matching connection refused 3 times — likely upstream MX is unreachable; check DNS and try a manual delivery"). Useful during on-call when you're seeing a wall of cryptic alerts at 3am.

AI Assistant
Free-form chat against the configured provider. Local-model stats when running Ollama or LocalAI.
AI is disabled
Enable it in Settings → AI assistant first.
Provider
—
—
Status
—
Version
—
Loaded models
—
No messages yet — type a prompt below.
Conversation history is kept in your browser (localStorage) — not on the server. Clearing the conversation clears only your view.
Each request is audited. Privacy redaction follows the toggles in Settings → AI assistant.
About
RemotePower — self-hosted device management
RemotePower
RemotePower
Server version: —
Agent version—
GitHubgithub.com/tyxak/remotepower
LicenseMIT
Latest releasechecking…

Self-hosted remote device management — shutdown, reboot, Wake-on-LAN, monitoring, scheduled commands, and agent self-update.

No inbound firewall rules on clients. Agents poll the server over HTTPS. Flat JSON storage, Nginx + Python CGI. No Docker, no Node.js.

API Keys
Named non-expiring keys for scripts and CI pipelines
Keys
NameRoleUserCreated
Patch Report
Overview of pending system updates across all devices — percentage only counts online devices with data
Export (filtered):
—
Total
—
Fully Patched
—
With Patches
—
Total Pending
—
Patch Rate
DeviceGroupOSStatusPkg ManagerPendingPatch StatusRecent Patch Cmds
Click Refresh to load patch report.
CVE Findings
Package vulnerabilities per device, via OSV.dev — scan checks installed packages against known CVEs.
0
Critical
0
High
0
Medium
0
Low
0
Devices Scanned
DeviceGroupEcosystemCriticalHighMediumLowLast scan
Click Refresh to load findings.
Services 🔧 0 maintenance window(s) active
systemd units watched per device. Click a row to see history, logs, and configuration.
0
Services Up
0
Services Down
0
Devices Reporting
0
Units Watched
DeviceGroupWatchedUpDownLast report
Click Refresh to load.
Logs
6-hour rolling buffer across the fleet. Search, tail live, or manage alert rules.
0
Lines in buffer
0
Devices reporting
—
Last line
0
Alert rules
Live tail — auto-refreshing every 30s
Alert rules
Regex match on incoming log lines fires a log_alert webhook.
DeviceGroupUnitPatternThreshold
No per-device rules configured.
Fleet-wide rules apply to every device that submits logs for the named unit. Use * for the unit to match any unit on any device.
UnitPatternThresholdCreated
Maintenance Windows
Scheduled windows suppress webhook alerts for specific devices, groups, or the whole fleet.
ReasonScopeTargetWhenEventsStatus
Click Refresh.
Recent Suppressions
WhenEventDeviceWindowReason
Calendar
Shared events across all users — backups, deploys, renewals, anything you want to remember.
—
Mon
Tue
Wed
Thu
Fri
Sat
Sun
Tasks
Shared kanban board. Drag cards between columns. Optionally link a task to a device.
● Upcoming 0
● Ongoing 0
● Pending 0
● Closed 0
CMDB
Configuration Management Database — asset metadata, documentation, and encrypted credentials per enrolled device.
🔒 Checking vault status…
Name Asset ID Function OS IP Hypervisor Docs Creds
Containers
Docker / Podman / Kubernetes pods reported by enrolled agents. Read-only — RemotePower shows what's running, doesn't manage it.
DeviceOSTotalRunningStoppedRestarting (≥5)RuntimesReported
Proxmox LXC containers
LXC containers on the Proxmox node. Actions hit the Proxmox API directly.
Virtualization
QEMU virtual machines on the Proxmox node. Start / shutdown actions call the Proxmox VE API directly from the RemotePower server.
Network map
Topology view from manually-set connected_to links and tunnels (peer links). Drag nodes to reposition — positions persist across refresh. Add agentless devices on the Devices page.
Configuration drift
Watched config files across the fleet. Agent hashes each file every few heartbeats; server alerts when a hash diverges from the stored baseline. Hash-only — no file content crosses the wire. Documentation.
DeviceGroupFiles watched DriftMissingLast check
TLS / DNS expiry
Server-side cert and DNS watchlist. Probes run from the RemotePower server. Defaults: warn at 14 days, critical at 3 days.
StatusHostPortDays leftExpiresIssuerLast check
Links
Shared bookmark dashboard. Card grid grouped by category. Click any card to open the link in a new tab. Internal links (LAN-only, behind VPN, etc.) are amber-bordered; external links are accent-bordered.
Audit Log
Security audit trail — logins, commands, session revocations
TimeActorActionDetailSource IP
Command Library
Saved shell command snippets — pick from the exec modal
Snippets
NameCommandDescription
No snippets yet.
Scripts
Multi-line bash scripts. Lint with bash -n + dangerous-command detection before they go anywhere. Run on a single device from the device dropdown, or on a batch via the multi-select bar.
Saved scripts
Name Description Size Updated Flags
Test LDAP user login
Enter credentials to verify the full authentication path. No session is created — this is purely a test.
Enroll a device
Run the client installer on the target machine and enter this PIN when prompted. Expires after 10 minutes.
Enrollment PIN
------
Expires in 10:00
Shut down device?
Are you sure you want to shut down ? This will power off the machine immediately.
Reboot device?
Reboot ? The machine will restart and come back online within a minute.
Device details
Loading…
Edit tags
Comma-separated. Use tags like: servers, homelab, workstations
Add monitor target
Add admin user
Change password
Schedule command
5 fields: min hour dom mon dow — leave blank for one-shot
Run command
Command runs as root on the client machine. Output returned on next heartbeat (~60s).
Metric thresholds
When a metric crosses a threshold, RemotePower fires the corresponding webhook event. Hysteresis: a metric must drop 5 points below "warn" before "recovered" fires.
Metric
Warning
Critical
Per-mount disk overrides
Different thresholds for specific mount points. Useful when /var fills with logs (lower threshold) or /backup is meant to fill (higher threshold).
Open web terminal
SSH directly to the device. Credentials are not stored — you'll need to enter them again next session.
Required every time you open a terminal.
connecting…
Monitor history
Loading…
Device notes
Device group
Assign a namespace like dc1/prod, homelab, office. Devices sort and group by this field.
Adjust poll interval
How often the agent checks in. 60s is the default. Lower values increase responsiveness but raise server load.
Command allowlist
If non-empty, only these exact shell commands can be run on this device via exec. One per line. Leave empty to allow any command.
Create API key
Named, non-expiring keys for scripts and CI. The key is shown once — save it now.
API Key (save this — shown once)
Add command snippet
New script
Bash script. Runs as root on the target device. bash -n syntax-checked + scanned for dangerous patterns before save.
Output is reviewed + dry-run before save — same path as a human-written script.
Run script
Pick a script to queue.
Batch script run
Polling for results…
docker compose
Choose a project, then an action. Output appears below.
Queue an action — output arrives on the next heartbeat (~60s).
Metrics
Loading…
Patch Report
Loading…
CVE Findings
Loading…
Ignore CVE
Mark as an accepted risk. It stays recorded but stops counting as a finding or raising attention.
Services
Loading…
Configure watched services
One systemd unit per line (e.g. nginx.service, postgresql.service). Agent reports their state on every heartbeat.
Set up CMDB vault
Choose a passphrase that will encrypt every credential stored in the CMDB. This passphrase is never stored on the server — losing it permanently destroys access to the credentials. All admins share this passphrase.
Unlock CMDB vault
The derived key is held only in this browser tab and cleared on logout or page reload.
Rotate CMDB vault passphrase
All stored credentials will be re-encrypted under the new passphrase.
Asset
Default 22. Used by the SSH link buttons on credentials.
Hostname: —
OS: —
IP: —
MAC: —
Group: —
Documents
No documents yet. Click "Add document" to attach one.
🔒 Vault is locked. Unlock from the CMDB page header to add or reveal credentials.
Credentials
No credentials yet.
Add document
Add credential
Update history
Last 10 package-upgrade runs from this device. Output is captured by the agent and sent on the next heartbeat after the run completes.
Loading…
Revealed credential
This reveal has been recorded in the audit log. The values below are not stored in the page after this modal closes.
—
—
—
—
Add TLS / DNS watch target
The server will probe this host periodically (cron) and on demand. Empty cert / connection errors show as red regardless of expiry.
Override DNS resolution. Useful when probing a local cert by IP — the hostname above is still sent as SNI in the handshake.
Auto-detect maps well-known ports to their STARTTLS protocol. Pick a specific protocol if you're running a service on a non-standard port.
Looks up _PORT._tcp.HOSTNAME for TLSA records, validates DNSSEC, and compares the cert against them. Without DNSSEC the check refuses to trust the records (status: insecure).
Certificate detail
Add agentless device
For devices that can't run the agent — switches, APs, printers, IPMI, cameras, smart plugs. They appear in the device list, get CMDB metadata + vault credentials, and show on the Network map. Status is whatever you set it to.
Edit network links
Set connected_to for each device — what it plugs into upstream (typically a switch or AP). Leave blank for devices with no parent (the internet gateway, root switch, etc.).
Add link
Pick an existing category or type a new one. Empty = "Uncategorised".
Tunnels
Peer links between devices, drawn as dashed amber lines on the map. Use these for VPN tunnels, site-to-site links, or anything else that isn't physical wiring.
Containers
New event
New task
Add per-device log alert rule
Matching log lines fire a log_alert webhook when the threshold is reached within a single agent submission (~5 min window).
Fleet-wide rule: applies to every device that submits logs for this unit. Use * to match any unit on any device (useful for patterns like OOMkilled).
New maintenance window
Set device icon
Pick an emoji to represent this device, or clear to use the default.
New custom script
Exit 0 = OK · non-zero = FAIL · runs as root · 30 s timeout · stdout captured
Loading devices…
Script output