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
Local Mac (fast path)
Remote Mac over SSH
Install and verify imsg
brew install steipete/tap/imsg
imsg rpc --help
Configure Datzi
{
channels: {
imessage: {
enabled: true,
cliPath: "/usr/local/bin/imsg",
dbPath: "/Users/<you>/Library/Messages/chat.db",
},
},
}
Approve first DM pairing (default dmPolicy)
datzi pairing list imessage
datzi pairing approve imessage <CODE>
Pairing requests expire after 1 hour.Datzi only requires a stdio-compatible cliPath, so you can point cliPath at a wrapper script that SSHes to a remote Mac and runs imsg.#!/usr/bin/env bash
exec ssh -T gateway-host imsg "$@"
Recommended config when attachments are enabled:{
channels: {
imessage: {
enabled: true,
cliPath: "~/.datzi/scripts/imsg-ssh",
remoteHost: "user@gateway-host", // used for SCP attachment fetches
includeAttachments: true,
attachmentRoots: ["/Users/*/Library/Messages/Attachments"],
remoteAttachmentRoots: ["/Users/*/Library/Messages/Attachments"],
},
},
}
If remoteHost is not set, Datzi attempts to auto-detect it by parsing the SSH wrapper script.
remoteHost must be host or user@host (no spaces or SSH options).
Datzi uses strict host-key checking for SCP, so the relay host key must already exist in ~/.ssh/known_hosts.
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:
- Create/sign in a dedicated macOS user.
- Sign into Messages with the bot Apple ID in that user.
- Install
imsg in that user.
- Create SSH wrapper so Datzi can run
imsg in that user context.
- 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 "$@"
- 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