Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
GITEA_URLNoOptional Gitea URL
MIA_REPOSNoLocal checkouts for `repo_script` / runbook `local` steps
BESZEL_URLNoOptional Beszel URL
GITEA_TOKENNoOptional Gitea token
BESZEL_TOKENNoOptional Beszel token
MIA_READONLYNo`true` = no applies. Makes every write tool refuse to apply.
MIA_INVENTORYNoPath of fleet.yaml~/.config/mia/fleet.yaml
MIA_SSH_REUSENossh behaviour
MIA_STATE_DIRNoJournal, snapshots, oversized outputs~/.local/state/mia
MIA_GIT_AUTHORNoLocal checkouts for `repo_script` / runbook `local` steps
MIA_PROBE_FROMNo`ru_probe` vantage host
MIA_CONCURRENCYNossh behaviour
MIA_SSH_OPTIONSNossh behaviour
JELLYFIN_API_KEYNoOptional Jellyfin API key used by the home media integrations
MIA_PROBE_IFACESNo`ru_probe` ISP interfaces (e.g. `wan0=ISP-A,wan1=ISP-B`)
MIA_PROBE_CONTROLNo`ru_probe` datacenter control host
MIA_REMNAWAVE_MCPNoCommand that starts mcp-remnawave for panel steps of runbooks
TAILSCALE_API_KEYNoOptional Tailscale API key
REMNAWAVE_BASE_URLNoRemnawave panel base URL, read-only use
MIA_EDGE_SCRIPT_URLNoURL of the public install script used by `node_bootstrap`, pinned to a reviewed commit
REMNAWAVE_API_TOKENNoRemnawave panel API token, read-only use
CLOUDFLARE_API_TOKENNoOptional Cloudflare API token (DNS records)
MIA_TUNING_SCRIPT_URLNoURL of the public install script used by `tuning_apply`, pinned to a reviewed commit

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
prompts
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
fleet_hostsA

The inventory (fleet.yaml): hosts with address, roles, tags, groups, services. No host is contacted. Start here to learn the names used by every other tool.

fleet_discoverA

Cross-check the inventory with the tailnet (local tailscale status) and the Remnawave panel: nodes/peers missing from fleet.yaml (with ready YAML), inventory hosts that are offline or unknown to both, panel nodes and their state.

fleet_statusA

One-screen health of the fleet: every host probed over ssh in parallel — uptime, load, memory, disk, pending updates/reboot, remnanode container, certificate days, Tailscale, panel state and users online — plus the codes of open issues (details: fleet_audit). With target all it also lists every tailnet device that is not in fleet.yaml: Linux machines are probed with the default ssh user, others shown with their online state.

fleet_auditC

Audit hosts against the fleet baseline (as the nodes run now: vps-edge-run.sh bootstrap + ufw-blacklist.sh ipsets, MGMT-PORTS chain, beszel-agent, security updates automatic with manual reboots) and general health: firewall (ufw off, management ports public, other public ports listed), Tailscale, sshd hardening, fail2ban jails, node_exporter, beszel-agent, MGMT-PORTS, ipset blacklists, auto-updates, tuning (bbr/fq, conntrack), remnanode container/compose/SECRET_KEY, certificate expiry, geo updater, disks, memory, temperatures, pending security updates, reboot, failed units, NTP, inventory services, panel node state. Findings have stable codes (policy.skip in fleet.yaml mutes them).

host_inspectB

Everything about one host in one call: system, pending updates, systemd units, listening sockets, firewall, Tailscale, docker, remnanode (compose, certificate, geo files), inventory services, tuning — plus audit findings and the matching panel node.

host_logsA

Tail logs on a host. source: a service name (container stdout / systemd journal of the unit — e.g. remnanode, fail2ban, tailscaled), a log file name (remnanode.log = xray logs in /var/log/remnanode, auth, syslog, apt, install-*), or explicit unit:, container:, file:, journal (whole journal).

host_portsB

What is reachable on a host and from where: every listening socket classified as local / tailnet-only / public-allowed / blocked by ufw / PUBLIC because ufw is off, with the process name. Plus the public UFW allows.

host_firewallB

Firewall detail of a host: ufw status numbered, fail2ban jails with the banned IP lists, ipset blacklists (ufw-blacklist.sh) with entry counts, and the MGMT-PORTS iptables chain.

host_dockerC

Docker on a host: containers (state, image, restarts), compose projects, disk usage of images/volumes/build cache.

host_file_readA

Read a file on a host (as root when sudo is configured) or list a directory. Secrets (SECRET_KEY, private keys, tokens, passwords) are masked.

host_connectionsA

Established TCP connections per host on a local port (default 443), total and by remote address family — to watch traffic move from an old ingress to a new one, or drain before removing a node.

host_net_checkA

Network checks run FROM hosts (in parallel): tcp connect, tls (TLS1.3 + h2 — what a REALITY dest needs), http timings, dns, ping, trace. Use to pick/verify a REALITY dest, check a node reaches the panel, or see if a destination is filtered from a location.

host_services_discoverA

What runs on a host that the inventory does not know yet: docker compose projects (with their files), standalone containers, non-stock systemd services, and known apps with an API (Jellyfin, Tdarr) — returned as ready services: / apps: YAML for fleet.yaml. Read-only; use it to describe a home server once.

tuning_statusB

Kernel/network tuning state from the owner's vps-network-tuning-script (initial.sh status): profile, BBR/fq, conntrack, NOFILE, swap, journald — plus available rollback backups.

ru_probeA

Is an address reachable from Russia (or any censored network): a TLS handshake from a vantage host through EVERY local ISP interface (MIA_PROBE_FROM, MIA_PROBE_IFACES) with the address forced (--resolve, not DNS), plus a control from a datacenter host (MIA_PROBE_CONTROL). Verdict per target: ok | partial (one ISP) | blocked-ru (both ISPs fail, datacenter passes = DPI (TSPU) blocks address:port — roll the DNS back first) | down. Read-only, one handshake per pair; the gate before and after any address switch (ingress, new node).

fleet_scheduleA

Everything that runs on a schedule, Cronicle-style: systemd timers and cron jobs on every host — schedule, last run (when, result, duration), next run, failures first. cron does not log results, so for cron only the last start (journal/syslog) is known. Stock OS jobs (apt-daily, fstrim, logrotate …) are hidden unless all=true or they fail.

schedule_toggleA

Switch a scheduled job off / on, or run a timer now (the «Расписание» buttons): a systemd timer — disable --now / enable --now (+ reset-failed of its service), run = start its service; a cron job — the exact line in /etc/crontab, /etc/cron.d/* or a user crontab is commented out with «#mia-off » (enable removes the marker; a copy of the file goes to /root/mia-backup first). Reversible.

cron_loggingA

Make every cron job write its output to a log and rotate those logs. A line that already appends to a file keeps it and the file joins rotation unless another logrotate config covers it; output to /dev/null or nowhere → >> /var/log/cron/.log 2>&1; a pipe into logger stays in syslog. Rotation: /etc/logrotate.d/cron-jobs (weekly, 8 copies, compress, copytruncate). Every line also runs through /usr/local/sbin/mia-cronrun, which records start, end and exit code so fleet_schedule shows a result for cron jobs (the command itself is unchanged). Stock OS cron files are left alone; copies of touched files go to /root/mia-backup; a logrotate error after the change rolls the rotation file back. Roll out a few hosts at a time and look at fleet_schedule in between.

fleet_snapshotA

Record the configuration state of hosts (packages, enabled units, containers/images, ufw rules, listening ports, sshd, users/sudo/authorized keys, crontabs, sysctl, certificates, tracked config files …) to the local state dir, and report what changed since the previous snapshot. Run it on a schedule (e.g. daily cron mia call fleet_snapshot) to keep a change history.

fleet_changesA

What changed on hosts: diff of recorded snapshots (latest vs previous, or vs the first one after since), or of the latest snapshot vs the live host (live:true, catches changes made by hand since). Next to the diff: actions this server ran on those hosts in the same window (journal), so changes made outside mia stand out.

snapshots_listC

Recorded snapshots of a host (newest first), or the hosts that have any.

journal_listB

What this server did to hosts: every action with time, host, outcome and planHash (newest first).

job_statusA

State of a detached remote job (node_bootstrap): running or finished with exit code, the log tail, a Tailscale login URL if the node waits for authorization. Tries the host over Tailscale (inventory address) first, then the public bootstrap address. Without jobId: lists known jobs.

service_actionA

restart / start / stop / update (compose pull + up -d) / recreate a service on hosts — a compose project, systemd unit or container from the inventory (remnanode, certbot, remnawave, tailscaled, fail2ban, node_exporter, docker … or your own). Rolling by default (batch 1 for disruptive actions), verified: the service must be up again.

remnanode_updateA

Update remnanode (remnawave/node image) on nodes: compares the running image with Docker Hub, then per node docker compose pull && up -d, waits for the container and (if the panel is configured) for the panel to see the node connected before moving on. Rolling, batch 1 by default; stops at the first node that does not come back.

cert_renewA

Renew the remnanode TLS certificate with the docker certbot from vps-edge-run.sh (cd /opt/certbot && docker compose run --rm certbot renew). Skips certificates with more than minDays left unless force. Port 80 must be publicly open (it is in the baseline). Optionally restarts remnanode so xray loads the new certificate.

geo_updateB

Run the roscomvpn geoip/geosite updater now (update-roscomvpn-geo.service from vps-edge-run.sh) and check it succeeded.

blacklist_updateB

Refresh the ipset blacklists now with the fleet script /usr/local/bin/ufw-blacklist.sh (normally run by /etc/cron.d/ufw-blacklist every 2 h) and show the entry counts of the sets afterwards.

updates_policyA

Bring hosts to the fleet update policy: security updates install automatically (unattended-upgrades, stock security-only origins), NO automatic reboots — reboots stay manual (host_reboot). Writes /etc/apt/apt.conf.d/20auto-upgrades and 99zz-mia-policy, enables apt-daily timers. apt-based hosts only.

fail2ban_unbanA

Unban an IP in fail2ban (all jails, or one) on hosts — e.g. after locking yourself out or a false positive.

ufw_ruleA

Add or delete a UFW rule on hosts, e.g. open a new public port for an inbound (allow 8443/tcp on the internet interface) or close one. Public exposure of 22/2222/5443/5444/9100 is blocked unless allowDangerous. The rule list before the change is shown in the dry run.

apt_upgradeA

Install pending apt updates on hosts (noninteractive, keeps existing config files). Shows what will be upgraded; warns when docker/containerd are in the list (remnanode restarts). Optional reboot afterwards when the kernel asks for it. Rolling, batch 1 by default.

host_rebootA

Reboot hosts (shutdown -r +delay) and wait for each to come back over ssh with remnanode running before the next one (rolling, batch 1). The dry run shows users online per node (panel) and whether a reboot is pending anyway.

host_execA

Run an arbitrary shell command on hosts (bash, through sudo when configured). For anything the dedicated tools do not cover. Output tail per host; the journal keeps the command. Parallel by default (batch 10).

tuning_applyA

Apply or roll back the kernel/network tuning of vps-network-tuning-script (initial.sh apply|rollback): BBR+fq, conntrack, NOFILE, swap, journald limits. apply creates a backup in /root/edge-tuning-backup-*; rollback restores the latest (or backupDir).

disk_cleanupA

Free disk space on hosts: apt cache, journald vacuum to a size, unused docker images and build cache (never volumes), rotated logs. The dry run shows what takes space now.

node_bootstrapA

Turn a fresh Ubuntu server into a node with vps-edge-run.sh (github.com/akadorkin/remnanode-install-script): user + sudo, Tailscale (--ssh, exit node), Docker, hardening (ssh, fail2ban, UFW tailscale-only), tuning, node_exporter, geo updater, certbot certificate for the domain, remnanode with the panel's SECRET_KEY. That is only the start of the current baseline: afterwards ops-scripts fleet-node-seal.sh (ipset blocklists, MGMT-PORTS, node_exporter, beszel-agent, log-upload) — the node_add runbook (scenario_start) runs the whole sequence; fleet_audit shows what is missing. Runs detached on the server over its public IP (the firewall reset cuts public ssh); poll with job_status. The server reboots 3 min after success. Needs the domain's A record pointing at the server.

jellyfin_statusA

Jellyfin on a host: version and pending restart, libraries (type, folders — with their host paths — and scan state), who is watching what right now (direct play vs transcode), item counts, scheduled tasks that failed last time or are running.

tdarr_statusB

Tdarr on a host: server version/uptime, nodes (paused, workers), libraries (folder, cache, output, watching, processing), global pause, overall statistics.

jellyfin_library_add_pathA

Add a folder to an existing Jellyfin library. The folder may be given as a host path (translated through the Jellyfin container mounts) or as the path inside the container; it must exist on both sides. Optionally scans the library afterwards.

jellyfin_library_createC

Create a Jellyfin library with folders. Library options (metadata language, savers, fetchers …) can be copied from an existing library of your choice; otherwise Jellyfin defaults apply.

jellyfin_scanC

Scan Jellyfin for new/changed files: one library (metadata/images for new items only) or all libraries.

jellyfin_task_runC

Start a Jellyfin scheduled task by name or key (e.g. "Scan Media Library", "Extract Chapter Images", "Clean Cache", RefreshLibrary).

tdarr_library_addA

Add folders to Tdarr: one new library per folder, cloned from an existing library (same flow/plugin stack, transcode/health-check settings, cache and output unless given), with counters reset. Folders may be host paths (translated through the Tdarr container mounts). The dry run shows every library object that will be inserted. Optionally starts a "find new" scan of each.

tdarr_scanA

Scan a Tdarr library: scanFindNew (only new files, default) or scanFresh (re-scan everything).

tdarr_pauseA

Pause or resume all Tdarr nodes (global setting), e.g. while the server is busy streaming.

repo_scriptA

Run one of your own fleet scripts from a local repo checkout (MIA_REPOS, e.g. ops=~/src/ops-scripts) on hosts: deploy/migrate-blacklist.sh, lock-mgmt-ports-apply.sh, install-beszel.sh … The script (plus files listed in with, same relative paths) is sent over ssh, run as root from a temp dir, then removed. Exactly the checked-out version runs: the plan shows the commit, uncommitted changes and a hash of the files. Secrets go by env var name (envFrom): the value is read from mia's own environment and never shown.

host_copyA

Copy files or directories from one host to others through this machine (certificates, /opt/remnanode/docker-compose.yml with the node key, /etc/log-upload/secrets.env, haproxy.cfg …): what the owner did by hand when moving an ingress or cloning a node. Contents are never shown: the plan lists size and sha256 on the source and on each target. Existing target paths are archived to /root/mia-backup-.tgz first. For one env-style file, set changes KEY=value lines on the way (e.g. LOG_NODE_NAME).

tailnet_devicesA

Every device of the tailnet (Tailscale API with TAILSCALE_API_KEY, else this machine's tailscale status): online / last seen, OS and client version, update available, node key expiry, tags — and which inventory host and panel node it is.

tailnet_device_removeA

Remove a machine from the tailnet (Tailscale API, needs TAILSCALE_API_KEY): the last step of taking a server out of service. The dry run shows the device, when it was last seen and whether it is still in fleet.yaml; an online device or one still in the inventory is refused unless force.

tailnet_joinA

Join a server to the tailnet over its public address (hosts..bootstrap in fleet.yaml): for a machine that is already set up but logged out of Tailscale or never joined. The key is a fresh one-time key from the Tailscale API (TAILSCALE_API_KEY), made only on apply and passed through the environment — never in the plan or journal; without the API it falls back to TAILSCALE_AUTH_KEY. Runs tailscale up --reset --ssh --hostname node-<name> (+ exit node like the fleet), then verifies the node shows up online.

dns_recordsB

DNS records in Cloudflare (CLOUDFLARE_API_TOKEN): by name, or every record that points at an IP across all zones — e.g. everything still on an old ingress address.

dns_changeA

Change A records in Cloudflare with a dry run: set (name → IP, created or updated; one A record per name), move (every A record on one IP to another — an ingress switch), remove (records by name, or every A record on an IP). The plan shows each record before and after; after apply every record is read back.

gitea_runnersB

Gitea Actions runners (GITEA_URL + GITEA_TOKEN): name, online/offline, busy, labels — to spot stale registrations and runners that announce another node's label.

gitea_runner_removeA

Delete a runner registration in Gitea (a node taken out of service). Dry run shows the runner; a busy runner is refused.

gitea_runner_registerA

Register the Gitea Actions runner on a node with a runner bootstrap script from your own repo checkout (MIA_REPOS; default ops:deploy/bootstrap-node-runner.sh ): a fresh registration token comes from the Gitea API at run time and reaches the script through an environment variable, never the plan or journal. Verified afterwards: act_runner active and the label is exactly node-:host (copied configs announced other nodes' labels before).

beszel_systemsC

Systems (cards) in the Beszel hub: name, host, status — to find duplicates a new agent created and cards of removed nodes.

beszel_system_editA

Rename or delete a Beszel card, found by exact name or host (tailnet name / IP). Delete only after the agent on that machine is stopped, or it recreates the card.

host_file_editA

Edit one of the fleet's registry files on a host the way it is done by hand: clone the entry of a template node for a new node (Prometheus overrides, log-collector inventory, reboot-reminder lists, IP lists) or remove the entries of a removed node (e.g. node_servers.keep.txt). Works on plain lines (an IP inside a one-line list is edited in place), JSON and YAML (comments kept). The dry run shows the diff; the file is backed up (.bak-mia-), written in place (owner and mode kept), optionally a unit is reloaded.

fleet_host_editA

Edit a host in fleet.yaml (this machine's inventory, not the server): add, change fields, move between groups, switch off/on (disabled), remove. The dry run shows the diff of fleet.yaml (layout and comments kept) and refuses a result mia could not load; apply writes it with a backup in the state directory and refuses if the file changed since the plan.

scenario_listB

Runbooks for whole operations (add a node and bring it to the fleet standard, switch the ingress, remove a node, change xray rules): their parameters, and the runs started so far. With run: the step log of that run.

scenario_startA

Start a runbook. Read-only checks run on their own; the first step that changes something comes back with its exact plan (dry run) and waits. Show that plan to the owner and continue with scenario_step only after the owner said yes to that step.

scenario_stepA

Answer the step a run is waiting on: apply (run the plan shown — only with the owner's explicit yes for this step), done (a manual step the owner has finished), skip, or retry (re-check / re-plan). Returns what happened and the next step that needs an answer. Runs are saved: resume any time with decision retry.

Prompts

Interactive templates invoked by user choice

NameDescription
morning_checkDaily look at the fleet: health, audit, what changed overnight
node_downIncident: a node is down / disconnected in the panel / users complain about a location
rolling_updateUpdate remnanode on all nodes one by one, then OS updates
onboard_nodeBring a fresh VPS into the fleet as a remnanode
security_reviewSecurity posture of the fleet: exposure, access, drift
weekly_maintenanceWeekly: certificates, geo/blacklist freshness, disks, updates, drift
home_checkHome servers: containers, temperatures, disks, Jellyfin and Tdarr state
media_add_folderAdd a folder with new media to Jellyfin and Tdarr on a home server

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

B3.4/5.0

Scored across 63 tools

Disambiguation4/5

Tools are organized by clear domain prefixes (fleet_, host_, jellyfin_, tdarr_, dns_, gitea_, tailnet_, scenario_) and each names a distinct resource+action. A few boundaries blur where a fleet-wide tool overlaps host-level ones (fleet_status vs fleet_audit vs host_inspect; fleet_changes vs fleet_snapshot vs snapshots_list; host_firewall vs host_ports), but descriptions clarify the split.

Naming Consistency4/5

Uniform snake_case with predictable domain prefixes throughout. Minor deviations exist in verb placement (gitea_runner_remove/gitea_runner_register vs gitea_runners; jellyfin_library_add_path vs jellyfin_library_create), but the convention remains readable and largely consistent.

Tool Count2/5

63 tools is far beyond the 25+ heavy threshold, and the surface spans many unrelated subsystems (fleet ops, Jellyfin, Tdarr, DNS, Gitea, Tailscale, runbooks). Even with broad legitimate scope, the sheer count risks overwhelming an agent and makes selection costly.

Completeness5/5

Near-exhaustive lifecycle coverage: reads, writes, edits, dry-run/plan modalitities, backups, verification, and orchestration runbooks. CRUD plus ops (reboot, service actions, cert renewal, disk cleanup, snapshots, journal) is present across every domain, with no obvious dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues