Skip to main content

iMessage (legacy: imsg)

For new iMessage deployments, use BlueBubbles.The imsg integration is legacy and may be removed in a future release.
Status: legacy external CLI integration. Gateway spawns imsg rpc and communicates over JSON-RPC on stdio (no separate daemon/port).

Quick setup

1

Install and verify imsg

brew install steipete/tap/imsg
imsg rpc --help
2

Configure Datzi

{
  channels: {
    imessage: {
      enabled: true,
      cliPath: "/usr/local/bin/imsg",
      dbPath: "/Users/<you>/Library/Messages/chat.db",
    },
  },
}
3

Start gateway

datzi gateway
4

Approve first DM pairing (default dmPolicy)

datzi pairing list imessage
datzi pairing approve imessage <CODE>
Pairing requests expire after 1 hour.

Requirements and permissions (macOS)

  • Messages must be signed in on the Mac running imsg.
  • Full Disk Access is required for the process context running Datzi/imsg (Messages DB access).
  • Automation permission is required to send messages through Messages.app.

Access control and routing

channels.imessage.dmPolicy controls direct messages:
  • pairing (default)
  • allowlist
  • open (requires allowFrom to include "*")
  • disabled
Allowlist field: channels.imessage.allowFrom. channels.imessage.groupPolicy controls group handling:
  • allowlist (default when configured)
  • open
  • disabled
Group sender allowlist: channels.imessage.groupAllowFrom. Sessions:
  • DMs use direct routing; groups use group routing.
  • With default session.dmScope=main, iMessage DMs collapse into the agent main session.
  • Group sessions are isolated (agent:<agentId>:imessage:group:<chat_id>).

Deployment patterns

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 Datzi can run imsg in that user context.
  5. Point channels.imessage.accounts.<id>.cliPath and .dbPath to that user profile.

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: '~/.datzi/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 "$@"

Media, chunking, and delivery targets

  • 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
  • outbound media size uses channels.imessage.mediaMaxMb (default 16 MB)
  • text chunk limit: channels.imessage.textChunkLimit (default 4000)
Preferred explicit targets:
  • chat_id:123 (recommended for stable routing)
  • chat_guid:...
  • chat_identifier:...

Config writes

iMessage allows channel-initiated config writes by default (for /config set|unset when commands.config: true). Disable:
{
  channels: {
    imessage: {
      configWrites: false
    }
  }
}

Troubleshooting

  • imsg not found or RPC unsupported: validate the binary and RPC support with imsg rpc --help and datzi channels status --probe.
  • DMs are ignored: check channels.imessage.dmPolicy, channels.imessage.allowFrom, and pairing approvals.
  • Group messages are ignored: check channels.imessage.groupPolicy, channels.imessage.groupAllowFrom, and mention pattern configuration.
  • Remote attachments fail: verify remoteHost, key auth, and known_hosts.
  • macOS permission prompts were missed: re-run imsg chats --limit 1 in an interactive GUI terminal in the same user/session context.

Configuration reference pointers