PLUGIN brewtools / Agents
On this page
SSH Admin
inherit approval envelopes one host per runView 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
| Field | Value |
|---|---|
| Model | inherit — runs on the session’s model |
| Tools | Read, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch |
| Triggers | ”ssh admin”, “server management” |
| Inventory | Reads CLAUDE.local.md in the project root |
| Permission | default — destructive ops return as an APPROVAL REQUIRED envelope |
| Scope | One 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
- Load inventory
Reads host aliases, IPs, users, and key paths from
CLAUDE.local.md. A missing file returns a## NEEDS-INPUTblock; it never guesses a host. - 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. - Classify and envelope
Remote mutations and MODIFY / SERVICE / DELETE / PRIVILEGE operations become exact envelopes (see Approval contract).
- Execute and verify
Runs the approved ids, validates configs first (
caddy validate,nginx -t), restarts, and re-checks the service. - 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 #
| Class | Examples | Action |
|---|---|---|
| READ | ls, cat, df, docker ps, systemctl status, ufw status | Free |
| CREATE | mkdir, touch, docker pull | Free if non-destructive |
| MODIFY | chmod, chown, sed, config edits | Envelope |
| SERVICE | restart, reload, docker compose up | Envelope |
| DELETE | rm, docker rm, docker volume rm, drop | Always envelope |
| PRIVILEGE | sudo, su, firewall rules, user management | Always envelope |
| Guard | Rule |
|---|---|
| Non-interactive output | --no-pager on journalctl/systemctl, bounded reads (-n 50, --tail 100); a pager hangs the run |
| Lockout | Allow new access, validate sshd, reload, prove a new session, then disable old access |
| Data destruction | docker 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-stdinMissing 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. maxTurnsstops 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-setupenforces the size budget when installed; the contract ships unconditionally.
Related
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