Managing OpenClaw From My Mac Without Running It Locally
On this page5 sections ▾
I manage OpenClaw from my Mac while it runs on my homebox server. The Mac holds a clone of the scripts and configuration; SSH runs commands against the server, where the services, runtime state, and network access already exist.
The server reads automation secrets from the openclaw-secrets 1Password vault through a service account. That lets it use the credentials it needs without copying them into my local checkout or committing them to git.
#What lives on each machine
The server workspace is:
/home/oak/.openclaw/workspaceOpenClaw runs there, writes its runtime state, and talks to services on my UniFi network. Docker and the 1Password CLI are installed on the server. I keep its firewall rules limited to the connections those jobs need.
My local clone contains the portable parts: scripts, routine definitions, infrastructure configuration, test fixtures, and workspace documentation. I can edit and test those on the Mac without maintaining a second OpenClaw installation with a different set of services and credentials.
Mac:
edit and test portable code
commit changes
inspect the server and trigger commands over SSH
Server:
run OpenClaw and hold runtime state
read secrets from 1Password
talk to local services
execute side effects
push signed backup commits#Run server commands through a wrapper
A raw SSH command works:
ssh pokedex 'cd /home/oak/.openclaw/workspace && git status --short'I added bin/box to my OpenClaw-homebox repo so I don't have to repeat the host and workspace path. A shell alias makes it available from any directory:
alias openclaw-box="$HOME/Developer/github/gordonbeeming/OpenClaw-homebox/bin/box"The wrapper defaults to the pokedex SSH alias and /home/oak/.openclaw/workspace. Local overrides go in .openclaw/box.env.
openclaw-box doctor
openclaw-box status
openclaw-box remote 'git status --short'
openclaw-box deploy-caddy
openclaw-box caddy-logsdoctor checks that the Mac can reach the server, the workspace exists, and Docker and the 1Password CLI are available. It checks those prerequisites; the status and logs for a particular routine still need their own review.
#Keep runtime state separate from portable changes
The repo ignores machine-local directories:
.openclaw/
state/
That keeps runtime state, logs, and setup markers out of the portable checkout. The tracked content includes AGENTS.md, SOUL.md, USER.md, routines, Caddy configuration, operational scripts, and memory files that I intentionally back up.
The server has its own git identity and signs its nightly backup commits with its own key. My Mac doesn't need that signing key to edit the portable code.
#Add a routine locally, then test it on the server
For example, if I were adding a routine to summarise Gmail messages, I'd start with fixtures on the Mac:
openclaw-box dry-run ./routines/gmail-summary --fixture fixtures/gmail/sample.jsonThe wrapper supplies the local dry-run environment:
OPENCLAW_DRY_RUN=1
OPENCLAW_TARGET=local
OPENCLAW_WORKSPACE=<this repo>The routine must honour that mode. An environment variable alone doesn't prevent writes or outgoing messages, so I'd test its parsing and decisions against fixtures before giving it access to the live service.
Once the portable changes were committed, I'd push them and update the server checkout:
git push
openclaw-box pullReal credentials would stay in 1Password. I'd check that the server's service account could read the required items, then run the routine there in dry-run mode:
openclaw-box remote './routines/gmail-summary --dry-run'This would check the routine against the server's network and services. It should report intended actions without sending email, archiving messages, or changing remote state. After reviewing that output, I'd reload the relevant service and check its status and logs.
#Give common changes their own commands
Caddy already has a deploy command:
openclaw-box deploy-caddyIt pulls the latest repo state on the server, runs the Caddy deploy script, and prints the container status afterwards.
At the time of this setup, I still wanted a named openclaw-box restart-gateway command for the OpenClaw runtime. That command wasn't implemented yet. The aim was to keep the correct service-manager invocation in the repo rather than reconstructing it for each restart.
The existing wrapper gives me the workflow I need for editing locally, checking the real server, and deploying Caddy. New routines still need their own tested dry-run behaviour and an explicit reload step for the service that runs them.