# iMessage — Access & Delivery This channel reads your Messages database (`~/Library/Messages/chat.db`) directly. Every text to this Mac — from any contact, in any chat — reaches the gate. Access control selects which conversations the assistant should see. Texting yourself always works. **Self-chat bypasses the gate** with no setup: the server learns your own addresses at boot and lets them through unconditionally. For other senders, the default policy is **`allowlist`**: nothing passes until you add the handle with `/imessage:access allow
`. All state lives in `~/.claude/channels/imessage/access.json`. The `/imessage:access` skill commands edit this file; the server re-reads it on every inbound message, so changes take effect without a restart. Set `IMESSAGE_ACCESS_MODE=static` to pin config to what was on disk at boot. ## At a glance | | | | --- | --- | | Default policy | `allowlist` | | Self-chat | Bypasses the gate; no config needed | | Sender ID | Handle address: `+15551234567` or `someone@icloud.com` | | Group key | Chat GUID: `iMessage;+;chat…` | | Mention quirk | Regex only; iMessage has no structured @mentions | | Config file | `~/.claude/channels/imessage/access.json` | ## Self-chat Open Messages on any device signed into your Apple ID, start a conversation with yourself, and text. It reaches the assistant. The server identifies your addresses at boot by reading `message.account` and `chat.last_addressed_handle` from `chat.db`. Messages from those addresses skip the gate entirely. To distinguish your input from its own replies — both appear in `chat.db` as from-me — it maintains a 15-second window of recently sent text and matches against it. ## DM policies `dmPolicy` controls how texts from senders other than you, not on the allowlist, are handled. | Policy | Behavior | | --- | --- | | `allowlist` (default) | Drop silently. Safe default for a personal account. | | `pairing` | Reply with a pairing code, drop the message. Every contact who texts this Mac will receive one; only use this if very few people have the number. | | `disabled` | Drop everything except self-chat, which always bypasses. | ``` /imessage:access policy pairing ``` ## Handle addresses iMessage identifies senders by **handle addresses**: either a phone number in `+country` format or the Apple ID email. The form matches what appears at the top of the conversation in Messages.app. | Contact shown as | Handle address | | --- | --- | | Phone number | `+15551234567` (keep the `+`, no spaces or dashes) | | Email | `someone@icloud.com` | If the exact form is unclear, check the `chat_messages` tool output or (under `pairing` policy) the pending entry in `access.json`. ``` /imessage:access allow +15551234567 /imessage:access allow friend@icloud.com /imessage:access remove +15551234567 ``` ## Groups Groups are off by default. Opt each one in individually, keyed on the chat GUID. Chat GUIDs look like `iMessage;+;chat123456789012345678`. They're not exposed in Messages.app; get them from the `chat_id` field in `chat_messages` tool output or from the server's stderr log when it drops a group message. ``` /imessage:access group add "iMessage;+;chat123456789012345678" ``` Quote the GUID; the semicolons are shell metacharacters. iMessage has **no structured @mentions**. The `@Name` highlight in group chats is presentational styling — nothing in `chat.db` marks it as a mention. With the default `requireMention: true`, the only trigger is a `mentionPatterns` regex match. Set at least one pattern before opting a group in, or no message will ever match. ``` /imessage:access set mentionPatterns '["^claude\\b", "@assistant"]' ``` Pass `--no-mention` to process every message in the group, or `--allow addr1,addr2` to restrict which members can trigger it. ``` /imessage:access group add "iMessage;+;chat123456789012345678" --no-mention /imessage:access group add "iMessage;+;chat123456789012345678" --allow +15551234567,friend@icloud.com /imessage:access group rm "iMessage;+;chat123456789012345678" ``` ## Delivery AppleScript can send messages but cannot tapback, edit, or thread-reply; those require private API. Delivery config is correspondingly limited. Set with `/imessage:access set