Tutorial

OpenClaw iMessage node setup: verify the first message safely

May 5, 202613 min readUpdated September 13, 2026By OpenClawBlog Team

Getting iMessage to answer once is easy to mistake for a complete setup. A healthy channel probe can coexist with missing macOS permissions, an unapproved sender, or a Gateway running on the wrong machine. The useful first check has to prove each boundary separately.

There is also a naming trap. In OpenClaw, the Mac that runs Messages.app and imsg is the iMessage host. It is not automatically an OpenClaw node in the device-pairing sense. The current iMessage setup documentation uses the Gateway plus imsg on a signed-in Mac. If the Gateway is elsewhere, it uses an SSH wrapper. A separately paired OpenClaw node is optional, and is mainly for running node commands on another machine.

What the setup actually contains

PartWhere it runsWhat it proves
iMessage pluginGateway hostOpenClaw has the channel integration that can start and supervise the bridge.
imsgMac signed in to MessagesThe process can read the local Messages database and ask Messages.app to send.
Channel policyOpenClaw configurationDirect messages and groups have an explicit admission rule.
Optional OpenClaw nodeAny paired device or node hostThe Gateway may invoke an approved node command. This is separate from iMessage transport.

The current migration note matters if you are following an older tutorial: the supported path no longer uses a BlueBubbles server, webhook, REST password, or channel port. It uses the official @openclaw/imessage plugin and imsg over JSON-RPC on standard input and output. Do not build the first test around an old BlueBubbles configuration.

Prerequisites and boundaries

  • A working OpenClaw Gateway on the machine where you will install the plugin.
  • A Mac with Messages.app signed in to the Apple account that should send and receive the bot's messages.
  • imsg installed on that Mac. Its repository lists macOS 14 or newer as a requirement and documents a Homebrew installation.
  • Full Disk Access for the process context that reads ~/Library/Messages/chat.db, and Automation permission for the process that sends through Messages.app. Permissions granted to a different Terminal, shell, or service context may not help the Gateway.
  • A separate phone number or Apple account you control for the first inbound test. Do not start with a group conversation or with a sender you cannot identify.

Basic text and media send and receive do not require disabling System Integrity Protection. The OpenClaw documentation reserves that step for the private API bridge used by advanced actions such as reactions, edits, effects, polls, and group operations. It is not part of a safe first-message check.

Build the local Mac path first

1. Install the channel plugin on the Gateway

On the Gateway host, run the documented plugin installation:

openclaw plugins install @openclaw/imessage

Inspect the installation result before continuing. If the Gateway is already managed as a service, use the normal restart procedure after the plugin is installed. The point of this step is to make the channel available on the Gateway; it does not install imsg on the Messages Mac.

2. Install and inspect imsg on the Messages Mac

The small, read first check is more useful than sending a test message immediately:

brew install steipete/tap/imsg
imsg --version
imsg chats --limit 3
imsg rpc --help

The imsg repository describes the roles clearly: the CLI reads the local Messages database, watches for new messages, and sends through Messages.app automation. If imsg chats cannot list conversations, fix the Mac-side database access before changing OpenClaw routing.

For a headless Gateway or LaunchAgent, trigger the permission prompts in the same user and GUI context that will run the bridge. The setup guide suggests an interactive imsg chats --limit 1 or a controlled send for this reason. A probe run from your personal Terminal does not prove that a service launched under another user has the same permissions.

3. Start with a narrow channel policy

This is a proposed test baseline, not a list of mandatory fields:

{
  channels: {
    imessage: {
      enabled: true,
      cliPath: "/absolute/path/from-command-v-imsg",
      dbPath: "/Users/bot/Library/Messages/chat.db",
      dmPolicy: "pairing",
      groupPolicy: "disabled",
      includeAttachments: false,
      configWrites: false
    }
  }
}

Use the path returned by command -v imsg in cliPath. On a local Mac, dbPath points to that Mac's Messages database. The default DM policy is pairing, which means an unknown sender receives a short code and is not processed until an operator approves the request. Keeping groups disabled and attachments off removes two variables from the first test. Disabling channel-initiated configuration writes also keeps a message from changing the configuration while you are still validating it.

The iMessage access-control reference treats DM access and group access as separate decisions. An approved DM sender is not automatically authorized in a group. That distinction is worth keeping even if you plan to enable a group later.

4. Start the Gateway and check the channel

openclaw gateway
openclaw channels status --probe --channel imessage

A successful probe is transport evidence. It is not yet proof that a phone-sent message will reach the agent or that the agent can reply. The troubleshooting documentation explicitly separates those cases, so keep the probe result as one checkpoint in the record rather than calling the whole integration done.

When the Gateway is not on the Messages Mac

The supported remote pattern is a transparent SSH wrapper. Install and update imsg on the Mac that runs Messages, not on the Linux or Windows Gateway. On the Gateway host, save an executable wrapper such as:

#!/usr/bin/env bash
exec ssh -T messages-mac imsg "$@"

Then point the channel at the absolute path of that wrapper:

{
  channels: {
    imessage: {
      enabled: true,
      cliPath: "/home/openclaw/.openclaw/scripts/imsg-ssh",
      remoteHost: "user@messages-mac",
      dbPath: "/Users/bot/Library/Messages/chat.db",
      dmPolicy: "pairing",
      groupPolicy: "disabled",
      includeAttachments: false
    }
  }
}

Here, cliPath is a path on the Gateway host. remoteHost and dbPath describe the Messages Mac. Use non-interactive SSH keys and establish the Mac's host key in the Gateway user's known_hosts before starting the channel.

The wrapper must behave like a live standard-input and standard-output pipe. Forward small JSON-RPC frames promptly, preserve newlines, and keep diagnostics on standard error. A wrapper that buffers input can make a healthy imsg process look broken with RPC timeouts. The deployment guide also warns that a remote setup adds attachment path and SSH/SCP requirements, so leave attachments disabled until text works.

Remote permissions are the awkward part. The Mac may be able to read chats while outbound sends fail with AppleEvents error -1743. OpenClaw attributes that failure to the macOS TCC context that needs Automation permission. Grant permissions to the user and service context that actually runs imsg, or run the bridge in that user's logged-in session. Test the exact SSH path before blaming the Gateway.

Do you need to pair the Mac as an OpenClaw node?

Only if you want the Gateway to run approved node commands on that Mac. An iMessage channel can use the SSH wrapper without turning the Messages Mac into a general-purpose OpenClaw node.

If you do need both, keep the approval concepts separate. OpenClaw's node flow creates a device pairing request and then a command-surface request. The documented CLI checks look like this:

openclaw devices list
openclaw devices approve <deviceRequestId>
openclaw nodes pending
openclaw nodes approve <nodeRequestId>
openclaw nodes describe --node <idOrNameOrIp>

The node-host documentation describes the same separation: the Gateway routes the model's work, while the node host executes an approved command such as system.run. Device admission alone is not command approval, and pairing a node does not grant Messages database access or macOS Automation permission. Give the Mac node only the command surface the workflow needs.

Verify the first message in layers

Layer 1: prove that Messages has the conversation

On the Messages Mac, identify the test conversation without sending anything:

imsg chats --limit 10 --json
imsg history --chat-id <chat-id> --limit 10

Record the numeric chat ID for the conversation you intend to use. If the history command cannot read it, stop there. The OpenClaw channel cannot repair a Mac that is not exposing the local chat data.

Layer 2: prove that a fresh inbound event arrives locally

From the separate phone or account you control, send a neutral text such as OPENCLAW CHECK. Do not include a shell command, a request to open a browser, a file path, or an attachment. Watch the same chat while the message arrives:

imsg watch --chat-id <chat-id> --json

This is a proposed verification test, not a claim that the command was run here. Its job is to distinguish an Apple Messages delivery problem from an OpenClaw dispatch problem. The official troubleshooting page recommends checking for a new chat.db row or an imsg watch event before changing OpenClaw settings.

Layer 3: verify the sender gate before approving it

With dmPolicy: "pairing", the first response may be a pairing code rather than an agent answer. List pending requests on the Gateway:

openclaw pairing list imessage

Compare the displayed sender handle with the phone or account you meant to test. Approve only that request:

openclaw pairing approve imessage <CODE>

The pairing documentation says that approval grants direct-message access only. It does not open group access. It also notes that a first CLI approval can bootstrap commands.ownerAllowFrom when no command owner exists. If you do not want the test sender to become the first command owner, establish the operator identity separately or use the Control UI's explicit choice instead of approving blindly from the shell.

Layer 4: send one bounded request

After approval, send a second neutral message from the same test account: Reply with exactly READY. Do not run tools or change files. Keep the request deliberately boring. Follow the Gateway logs if you need timing information, and record whether the reply came back to the expected iMessage conversation, from the expected bot identity, and only once.

That last step is a proposed end-to-end check. It proves one controlled route on one conversation. It does not prove that groups, attachments, node commands, private API actions, or future sessions will behave the same way.

What counts as a useful pass

CheckEvidenceWhat it does not prove
Local readimsg chats and imsg history show the intended conversation.Outbound Automation permission.
Transportopenclaw channels status --probe --channel imessage completes successfully.Inbound routing or sender approval.
AdmissionThe pairing request names the expected sender and is approved deliberately.Group access or command-owner intent.
End to endOne controlled DM produces one expected reply.Reliability under restarts, attachments, or multiple senders.

This record keeps documented observations separate from the editorial test. It also gives you a clean stopping point. Do not turn on groups, attachments, private API actions, or node execution until the smaller path is understandable.

Failure paths worth checking first

imsg is missing or RPC is unsupported

Run imsg rpc --help, imsg status --json, and the channel probe on the machine that actually runs the bridge. If the Gateway is remote, update the Mac-side installation and check the SSH wrapper rather than installing a second copy on the Gateway. The troubleshooting guide identifies an SSH wrapper as the route for non-macOS Gateways.

Messages sends, but inbound text never arrives

Check whether a fresh phone-sent message creates a new local database row or an imsg watch event. If it does not, repair the Mac's Messages and Apple Push state before changing OpenClaw policies. If the row exists, inspect pairing, allowlists, and the channel probe. The source guidance warns against turning imsg launch and Gateway restarts into a periodic loop, because repeated restarts can interrupt active deliveries.

The DM is ignored

Check dmPolicy, allowFrom, and openclaw pairing list imessage. An allowlist and pairing approval are not the same store or the same decision. If the message is in a group, also check groupPolicy, groupAllowFrom, the configured group registry, and mention gating. A successful DM test says nothing about an unconfigured group.

Remote sends fail with AppleEvents -1743

Recheck Automation permission in the exact macOS user and process context behind SSH or a LaunchAgent. A local interactive Terminal may have permission while the SSH server-side process does not. If the wrapper cannot perform one controlled outbound send, keep the deployment local until that process boundary is fixed.

Where to stop

For a Gateway on the same Mac as Messages, the setup is short: install the plugin, install imsg, grant permissions, configure pairing, probe the channel, and approve one known sender. For a remote Gateway, the added work is SSH transparency, host-key verification, remote paths, and macOS service permissions. For a true OpenClaw node, add device and command-surface approvals as a separate project.

Do not disable System Integrity Protection for the first text. Do not open DM policy to everyone to make a test pass. Do not treat a connected probe as proof of delivery. The first message is verified safely when you can name the Mac that read it, the policy that admitted it, and the one reply that returned to the intended conversation.

Sources

Reference Trail

Sources and further reading

  1. iMessage setup documentationdocs.openclaw.ai
  2. current migration notedocs.openclaw.ai
  3. imsg repositorygithub.com
  4. iMessage access-control referencedocs.openclaw.ai
  5. deployment guidedocs.openclaw.ai
Back to ArchiveMore: TutorialsNext: OpenClaw v2026.5.4: Plugins/migration, recovery notes