Skip to content

iMessage

Status: legacy external CLI integration. Gateway spawns imsg rpc and communicates over JSON-RPC on stdio (no separate daemon/port).

BlueBubbles (recommended)

Preferred iMessage path for new setups.

Pairing

iMessage DMs default to pairing mode.

Configuration reference

Full iMessage field reference.

  1. Install and verify imsg

    Terminal window
    brew install steipete/tap/imsg
    imsg rpc --help
  2. Configure OpenClaw

    {
    channels: {
    imessage: {
    enabled: true,
    cliPath: "/usr/local/bin/imsg",
    dbPath: "/Users/

    /Library/Messages/chat.db”, }, }, }

  3. Start gateway

    Terminal window
    openclaw gateway
  4. Approve first DM pairing (default dmPolicy)

    Terminal window
    openclaw pairing list imessage
    openclaw pairing approve imessage
    Pairing requests expire after 1 hour.
  • Messages must be signed in on the Mac running imsg.
  • Full Disk Access is required for the process context running OpenClaw/imsg (Messages DB access).
  • Automation permission is required to send messages through Messages.app.

channels.imessage.dmPolicy controls direct messages:

  • pairing (default)
  • allowlist
  • open (requires allowFrom to include "*")
  • disabled

Allowlist field: channels.imessage.allowFrom.

Allowlist entries can be handles or chat targets (chat_id:*, chat_guid:*, chat_identifier:*).

Legacy iMessage chats can also be bound to ACP sessions.

Fast operator flow:

  • Run /acp spawn codex --bind here inside the DM or allowed group chat.
  • Future messages in that same iMessage conversation route to the spawned ACP session.
  • /new and /reset reset the same bound ACP session in place.
  • /acp close closes the ACP session and removes the binding.

Configured persistent bindings are supported through top-level bindings[] entries with type: "acp" and match.channel: "imessage".

match.peer.id can use:

` (recommended for stable group bindings)

  • `chat_guid:

`

  • `chat_identifier:

`

Example:

{
agents: {
list: [
{
id: "codex",
runtime: {
type: "acp",
acp: { agent: "codex", backend: "acpx", mode: "persistent" },
},
},
],
},
bindings: [
{
type: "acp",
agentId: "codex",
match: {
channel: "imessage",
accountId: "default",
peer: { kind: "group", id: "chat_id:123" },
},
acp: { label: "codex-group" },
},
],
}

See ACP Agents for shared ACP binding behavior.

Dedicated bot macOS user (separate iMessage identity)

Use a dedicated Apple ID and macOS user so bot traffic is isolated from your personal Messages profile.

Typical flow:

  1. Create/sign in a dedicated macOS user.
  2. Sign into Messages with the bot Apple ID in that user.
  3. Install imsg in that user.
  4. Create SSH wrapper so OpenClaw can run imsg in that user context.
  5. Point `channels.imessage.accounts.

.cliPathand.dbPath` to that user profile.

First run may require GUI approvals (Automation + Full Disk Access) in that bot user session.
Remote Mac over Tailscale (example)
Common topology:
- gateway runs on Linux/VM
- iMessage + `imsg` runs on a Mac in your tailnet
- `cliPath` wrapper uses SSH to run `imsg`
- `remoteHost` enables SCP attachment fetches
Example:
{
channels: {
imessage: {
enabled: true,
cliPath: "~/.openclaw/scripts/imsg-ssh",
remoteHost: "[email protected]",
includeAttachments: true,
dbPath: "/Users/bot/Library/Messages/chat.db",
},
},
}
#!/usr/bin/env bash
exec ssh -T [email protected] imsg "$@"
Use SSH keys so both SSH and SCP are non-interactive.
Ensure the host key is trusted first (for example `ssh [email protected]`) so `known_hosts` is populated.
Multi-account pattern

iMessage supports per-account config under channels.imessage.accounts.

Each account can override fields such as cliPath, dbPath, allowFrom, groupPolicy, mediaMaxMb, history settings, and attachment root allowlists.

Attachments and media
  • inbound attachment ingestion is optional: channels.imessage.includeAttachments
  • remote attachment paths can be fetched via SCP when remoteHost is set
  • attachment paths must match allowed roots:
    • channels.imessage.attachmentRoots (local)
    • channels.imessage.remoteAttachmentRoots (remote SCP mode)
    • default root pattern: /Users/*/Library/Messages/Attachments
  • SCP uses strict host-key checking (StrictHostKeyChecking=yes)
  • outbound media size uses channels.imessage.mediaMaxMb (default 16 MB)
Outbound chunking
  • text chunk limit: channels.imessage.textChunkLimit (default 4000)
  • chunk mode: channels.imessage.chunkMode
    • length (default)
    • newline (paragraph-first splitting)
Addressing formats
Preferred explicit targets:
- `chat_id:123` (recommended for stable routing)
- `chat_guid:...`
- `chat_identifier:...`
Handle targets are also supported:
- `imessage:+1555...`
- `sms:+1555...`
Terminal window
imsg chats --limit 20

iMessage allows channel-initiated config writes by default (for /config set|unset when commands.config: true).

Disable:

{
channels: {
imessage: {
configWrites: false,
},
},
}
imsg not found or RPC unsupported
Validate the binary and RPC support:
Terminal window
imsg rpc --help
openclaw channels status --probe
If probe reports RPC unsupported, update `imsg`.
DMs are ignored

Check:

  • channels.imessage.dmPolicy
  • channels.imessage.allowFrom
  • pairing approvals (openclaw pairing list imessage)
Group messages are ignored

Check:

  • channels.imessage.groupPolicy
  • channels.imessage.groupAllowFrom
  • channels.imessage.groups allowlist behavior
  • mention pattern configuration (agents.list[].groupChat.mentionPatterns)
Remote attachments fail

Check:

  • channels.imessage.remoteHost
  • channels.imessage.remoteAttachmentRoots
  • SSH/SCP key auth from the gateway host
  • host key exists in ~/.ssh/known_hosts on the gateway host
  • remote path readability on the Mac running Messages
macOS permission prompts were missed
Re-run in an interactive GUI terminal in the same user/session context and approve prompts:
Terminal window
imsg chats --limit 1
imsg send

“test”

Confirm Full Disk Access + Automation are granted for the process context that runs OpenClaw/`imsg`.