--- name: mac-server-setup description: > Set up and harden a remote Mac as an always-on headless server for running openclaw agents. Use when provisioning a new Mac (Mac Mini, Mac Studio, etc.) for server duty via SSH. Covers dev environment (Homebrew, nvim, tmux, node, bun, starship, gh), nvim config, server hardening (power mgmt, firewall, consumer service cleanup, Spotlight, SMB, hostname), SSH key auth, git repos, local SSH config, Signet agent platform (install, launchd, tailnet binding), and OpenClaw agent runtime (auth profiles, gateway config). Generates an idempotent setup script on the remote machine. Triggers: "set up mac server", "harden mac", "provision remote mac", "new client server setup", "mac server hardening", "openclaw server setup". --- # Mac Server Setup Provision a remote Mac as a reliable headless server with dev tools and security hardening. Outputs an idempotent bash script on the target machine. ## Workflow ### 0. SSH MCP Server Setup Before anything else, configure an SSH MCP server so Claude Code can execute commands on the remote Mac. Add to `~/.mcp.json` on the operator's local machine: ```json { "mcpServers": { "ssh-": { "command": "npm", "args": [ "exec", "ssh-mcp", "--", "--host=", "--port=22", "--user=", "--password=" ] } } } ``` For key-based auth (after SSH hardening), replace `--password` with: ```json "--privateKeyPath", "/home//.ssh/id_ed25519" ``` Then enable in `~/.claude/settings.local.json`: ```json { "enableAllProjectMcpServers": true } ``` The `ssh-mcp` package is from npm (`npm exec ssh-mcp`). It provides `exec` and `sudo-exec` tools. Note: `sudo-exec` requires either passwordless sudo on the remote machine or won't work. To enable passwordless sudo on the Mac (needed for hardening): ``` sudo visudo -f /etc/sudoers.d/ ``` Add: ` ALL=(ALL) NOPASSWD: ALL` **Important**: the MCP server has a ~1000 char command length limit. Write long scripts in chunks using `cat >>` with heredocs. ### 1. Recon Gather remote machine state before writing anything. Run all commands in [references/recon-commands.md](references/recon-commands.md) and report findings to inform decisions. ### 2. Elicit Configuration Ask the user: - **Hostname** — what to name the machine - **Wi-Fi** — keep or disable? - **File sharing** — remove SMB or keep with auth only? - **SSH** — password-only? Set up key auth? - **Nvim config** — clone from Gitea? Custom repo URL? - **Git repos** — GitHub org/account for ~/.agents, ~/., ~/.config/nvim? - **Extra packages** — beyond standard set? ### 3. Generate Setup Script A reference script is bundled at [scripts/setup-and-harden.sh](scripts/setup-and-harden.sh). Copy it to the remote machine and customize hostname, paths, and SMB share name before running. The script is idempotent — safe to re-run. Structure: **Part 1 — Dev environment** (details: [references/dev-setup.md](references/dev-setup.md)) - Homebrew PATH in `.zprofile` (idempotent) - Packages: neovim, tmux, git, starship, gh, node (brew), bun (curl) - Git identity (`git config --global`) + gh credential helper - Nvim config clone + config.json + dotfile symlinks - Nvim plugin sync via `nvim --headless "+Lazy! sync" +qa` - Shell aliases + starship init in .zshrc (idempotent) **Part 2 — Server hardening** (details: [references/hardening.md](references/hardening.md)) - FileVault: disable (blocks unattended boot) - Auto-login: enable for server user (kcpassword + loginwindow pref) - Power: no sleep, auto-restart on power loss - App firewall: on, allow signed, stealth mode - SMB: disable guest access - Consumer services: disable 18+ via `launchctl disable gui/$UID/