iMessage Deployment Patterns for imsg and Messages
Covers dedicated bot macOS users, remote Macs over Tailscale, multi-account setups, and DM history patterns. For operators running imsg alongside an already signed-in Messages account.
Read this when
- Choosing where to run the Gateway and imsg
- Isolating bot traffic from a personal iMessage identity
- Running more than one iMessage account
Ways to run imsg alongside a Messages account that is already signed in, plus the configuration each approach requires.
Deployment patterns
Dedicated bot macOS user (separate iMessage identity)
Isolate bot traffic from your personal Messages profile by using a separate Apple ID and a separate macOS user.
The usual sequence:
- Create a dedicated macOS user, or sign in as one.
- In that user, sign into Messages with the bot Apple ID.
- Install
imsgunder that user. - Set up an SSH wrapper so OpenClaw can run
imsgwithin that user's context. - Configure
channels.imessage.accounts.<id>.cliPathand.dbPathto reference that user profile.
GUI approvals (Automation and Full Disk Access) may be needed in the bot user's session on first run.
Remote Mac over Tailscale (example)
A frequent setup:
- the gateway lives on Linux or a VM
- iMessage and
imsgrun on a Mac inside your tailnet - the
cliPathwrapper reachesimsgover SSH remoteHosthandles inbound fetches and owner-only outbound staging via SSH/SCP
Sample:
{
channels: {
imessage: {
enabled: true,
cliPath: "/home/openclaw/.openclaw/scripts/imsg-ssh",
remoteHost: "bot@mac-mini.tailnet-1234.ts.net",
includeAttachments: true,
dbPath: "/Users/bot/Library/Messages/chat.db",
},
},
}
#!/usr/bin/env bash
exec ssh -T bot@mac-mini.tailnet-1234.ts.net imsg "$@"
cliPath must be an absolute wrapper path local to the Gateway. remoteHost and dbPath point at the Messages Mac, so the remote database path must not be rewritten with the Gateway user's home directory.
Configure SSH keys so that both SSH and SCP run without prompts.
Add the host key to known hosts first (with ssh bot@mac-mini.tailnet-1234.ts.net, for instance) so that known_hosts gets populated.
Multi-account pattern
Per-account configuration is available for iMessage under channels.imessage.accounts.
Fields such as cliPath, dbPath, allowFrom, dmPolicy, groupPolicy, mediaMaxMb, history settings, and attachment root allowlists can be overridden by each account. Policies left out of an account inherit from the channel root, while policies set explicitly on the account take precedence. When neither scope defines them, pairing applies to DMs and allowlist applies to groups.
Direct-message history
New direct-message sessions get seeded with recent decoded imsg history for that conversation when channels.imessage.dmHistoryLimit is set. Per-sender overrides go in channels.imessage.dms["<sender>"].historyLimit, which includes 0 for turning history off for a given sender.
DM history for iMessage is retrieved on demand from imsg. With dmHistoryLimit left unset, global DM history seeding is off, yet a positive per-sender channels.imessage.dms["<sender>"].historyLimit still turns seeding on for that sender.