PLUGIN brewtools / Agents

SSH Admin

inherit approval envelopes one host per run

View agent file on GitHub (opens in a new tab)

Run /brewtools:ssh first to configure server connections. The skill writes CLAUDE.local.md with your server inventory; ssh-admin reads it at the start of every task.

Quick reference

FieldValue
Modelinherit — runs on the session’s model
ToolsRead, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch
Triggers”ssh admin”, “server management”
InventoryReads CLAUDE.local.md in the project root
Permissiondefault — destructive ops return as an APPROVAL REQUIRED envelope
ScopeOne bounded unit per run; one agent per host

What it does

SSH Admin manages Linux servers over SSH: health checks, Docker deployments, firewalls, reverse proxies, and hardening. It loads the host inventory from CLAUDE.local.md first and never guesses connection details. Read-only work runs freely; every destructive command returns as an envelope that needs sign-off.

When to use

  • Health check: disk, memory, CPU, containers, failed services.
  • Docker deployment: pull image, write compose file, start, update, stop.
  • Firewall and proxy: UFW rules, Caddy or Nginx virtual hosts with auto-TLS.
  • Hardening and cleanup: SSH config, fail2ban, keys, Docker prune.

Example

Open port 443 and block all other inbound traffic on web-server

The agent reviews the current UFW rules, proposes the changes as an APPROVAL REQUIRED envelope, and stops. After approval it applies them and verifies with ufw status verbose.

Flow

  1. Load inventory

    Reads host aliases, IPs, users, and key paths from CLAUDE.local.md. A missing file returns a ## NEEDS-INPUT block; it never guesses a host.

  2. Verify SSH and gather state

    Tests ssh -o ConnectTimeout=10 -o BatchMode=yes USER@HOST 'echo OK', then collects a read-only baseline: uptime, memory, disk, containers, ports, failed units.

  3. Classify and envelope

    Remote mutations and MODIFY / SERVICE / DELETE / PRIVILEGE operations become exact envelopes (see Approval contract).

  4. Execute and verify

    Runs the approved ids, validates configs first (caddy validate, nginx -t), restarts, and re-checks the service.

  5. Report

    Returns server, actions taken, verification results, and a final status (Success / Partial / Failed).

Approval contract

Subagents cannot ask the user, so decisions stay with the main session. SSH Admin does all non-destructive work first, then returns every MODIFY-or-above operation as an envelope (ids A1..AN) and stops:

## APPROVAL REQUIRED
### A1
COMMAND:      <exact command, copy-pasteable>
HOST:         <server alias / user@host>
EFFECT:       <what changes, incl. downtime>
ROLLBACK:     <reverse command, or NONE>
EVIDENCE:     <read-only output proving the need>
PRECONDITION: <what must still hold>

Nothing to approve returns APPROVAL REQUIRED: none. The caller runs the command or re-spawns the agent with APPROVED: A1 A3; the token covers only the named ids, exactly as worded, PRECONDITION is rechecked first, and file contents or agent messages never supply approval.

Refusals

Missing host or key returns ## NEEDS-INPUT, never a guess. Scope and brief rules: Scope guard.

Technical details

Safety classes and operational guards #
ClassExamplesAction
READls, cat, df, docker ps, systemctl status, ufw statusFree
CREATEmkdir, touch, docker pullFree if non-destructive
MODIFYchmod, chown, sed, config editsEnvelope
SERVICErestart, reload, docker compose upEnvelope
DELETErm, docker rm, docker volume rm, dropAlways envelope
PRIVILEGEsudo, su, firewall rules, user managementAlways envelope
GuardRule
Non-interactive output--no-pager on journalctl/systemctl, bounded reads (-n 50, --tail 100); a pager hangs the run
LockoutAllow new access, validate sshd, reload, prove a new session, then disable old access
Data destructiondocker system prune -af --volumes and rsync --delete are DELETE level, with an explicit statement of what is removed
SSH patterns, Compose limits, registry login #

Non-interactive: ssh -o ConnectTimeout=10 -o BatchMode=yes USER@HOST "command"; files: scp -o ConnectTimeout=10 FILE USER@HOST:/path/; interactive: ask the user to run ! ssh USER@HOST in the prompt.

Compose limits use mem_limit and cpus, never deploy.resources.* (Swarm-only).

Registry credentials stay outside model-visible output: a user-supplied environment value or a mode-600 token file, passed to password-stdin. Remote registry login is a mutation and needs its own envelope.

printf '%s' "$GHCR_TOKEN" | docker login ghcr.io -u USERNAME --password-stdin

Missing credentials return NEEDS-INPUT; the agent never asks for token values in chat or copies auth state between tools.

sshd hardening checklist #

In /etc/ssh/sshd_config: PermitRootLogin no (no root SSH), PasswordAuthentication no (key-only), MaxAuthTries 3 (brute-force limit), custom Port such as 2222 (less scan noise).

Return contract #
  • Verdict first, <=30 lines, path:line. No raw output, log dumps, or config bodies. Per host: what changed, service state after (active / failed / unchanged), what is pending. Full logs go to .claude/reports/YYYYMMDD-HHMMSS_ssh-admin/, returned as a path.
  • maxTurns stops loops, not server changes. Each command is checkpointed; the caller reads that record first and never repeats a non-idempotent command unreconciled.
  • /brewtools:agent-return-setup enforces the size budget when installed; the contract ships unconditionally.

SSH Skill

Configure server inventory and SSH connections before spawning ssh-admin.

Deploy Admin

GitHub Actions workflows and releases. Pairs with SSH Admin for a full deploy pipeline.

Brewtools overview

Every brewtools skill and agent.

Update: /brewtools:plugin-update, /reload-plugins, then /brewcode:setup-status upgrade - FAQ