Needs attention
Recent activity
Fleet roster · 7-day status
| Label | Type | Target | Status | Detail | Checked | |
|---|---|---|---|---|---|---|
| No monitors configured. | ||||||
| Device | Alert | Memory | Swap | CPU load | Disks | |
|---|---|---|---|---|---|---|
| Script | Device | Group | Status | Last output | Last run | Duration | |
|---|---|---|---|---|---|---|---|
| Click Refresh to load results. | |||||||
| Username | Created | Role | |
|---|---|---|---|
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.
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.
Monitor check interval
How often monitors auto-check when the Monitor page is open. Also controls server-side offline/patch check frequency.
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.
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.
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.
Webhook log
| Time | Event | Status | Detail | |
|---|---|---|---|---|
| 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).(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.
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.
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.
__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.
| Time | Actor | Device | Command |
|---|---|---|---|
| Device | Command | Scheduled for | By | |
|---|---|---|---|---|
| No scheduled jobs. | ||||
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:
| Metric | Warning | Critical |
|---|---|---|
| Disk usage (per mount) | 80% | 90% |
| Memory | 85% | 95% |
| Swap | 20% | 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
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):
- Settings → API keys → Generate a viewer token; copy the
rpk_...value. - Copy
remotepower-mcp.pyto your laptop (scpworks). - Edit
~/Library/Application Support/Claude/claude_desktop_config.json(macOS) or%APPDATA%\Claude\claude_desktop_config.json(Windows) — add anmcpServers.remotepowerentry with the command, args, and env (URL + token). - 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):
- One webhook for page-me-now events:
device_offline,service_down,monitor_down,metric_critical,cve_found. Point at ntfy / Pushover / your phone. - One webhook for FYI-during-business-hours events:
metric_warning,patch_alert,log_alert,container_stopped. Point at a Discord/Slack channel. - Email digest for the slow stuff (weekly CVE summary, patches pending) once
cron_email_digestis 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.

| Agent version | — |
| GitHub | github.com/tyxak/remotepower |
| License | MIT |
| Latest release | checking… |
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.
| Name | Role | User | Created | |
|---|---|---|---|---|
| Device | Group | OS | Status | Pkg Manager | Pending | Patch Status | Recent Patch Cmds | |
|---|---|---|---|---|---|---|---|---|
| Click Refresh to load patch report. | ||||||||
| Device | Group | Ecosystem | Critical | High | Medium | Low | Last scan | |
|---|---|---|---|---|---|---|---|---|
| Click Refresh to load findings. | ||||||||
| Device | Group | Watched | Up | Down | Last report | |
|---|---|---|---|---|---|---|
| Click Refresh to load. | ||||||
log_alert webhook.| Device | Group | Unit | Pattern | Threshold | |
|---|---|---|---|---|---|
| No per-device rules configured. | |||||
| Reason | Scope | Target | When | Events | Status | |
|---|---|---|---|---|---|---|
| Click Refresh. | ||||||
| Name | Asset ID | Function | OS | IP | Hypervisor | Docs | Creds | |
|---|---|---|---|---|---|---|---|---|
| Device | OS | Total | Running | Stopped | Restarting (≥5) | Runtimes | Reported | |
|---|---|---|---|---|---|---|---|---|
connected_to links and tunnels (peer links). Drag nodes to reposition — positions persist across refresh. Add agentless devices on the Devices page.| Device | Group | Files watched | Drift | Missing | Last check | |
|---|---|---|---|---|---|---|
| Status | Host | Port | Days left | Expires | Issuer | Last check | |
|---|---|---|---|---|---|---|---|
| Time | Actor | Action | Detail | Source IP |
|---|---|---|---|---|
| Name | Command | Description | |
|---|---|---|---|
| No snippets yet. | |||
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.| Name | Description | Size | Updated | Flags | |
|---|---|---|---|---|---|