← all posts

Managing OpenClaw From My Mac Without Running It Locally

Gordon Beeming
Gordon Beeming
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:

Server workspace
/home/oak/.openclaw/workspace

OpenClaw 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.

Operating model
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:

Inspect the remote workspace
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:

~/.zshrc
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 control commands
openclaw-box doctor
openclaw-box status
openclaw-box remote 'git status --short'
openclaw-box deploy-caddy
openclaw-box caddy-logs

doctor 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:

gitignore
.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:

Local development example
openclaw-box dry-run ./routines/gmail-summary --fixture fixtures/gmail/sample.json

The wrapper supplies the local dry-run environment:

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:

Sync portable changes
git push
openclaw-box pull

Real 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:

Server-side dry-run example
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:

Deploy Caddy on the server
openclaw-box deploy-caddy

It 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.

Gordon Beeming
Gordon Beeming

Father • Husband • Triathlete • SSW Solution Architect

Related posts