> ## Documentation Index
> Fetch the complete documentation index at: https://ancplua.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# iMessage (legacy: imsg)

# iMessage (legacy: imsg)

<Warning>
  For new iMessage deployments, use BlueBubbles.

  The `imsg` integration is legacy and may be removed in a future release.
</Warning>

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

## Quick setup

<Tabs>
  <Tab title="Local Mac (fast path)">
    <Steps>
      <Step title="Install and verify imsg">
        ```bash theme={null}
        brew install steipete/tap/imsg
        imsg rpc --help
        ```
      </Step>

      <Step title="Configure Datzi">
        ```json5 theme={null}
        {
          channels: {
            imessage: {
              enabled: true,
              cliPath: "/usr/local/bin/imsg",
              dbPath: "/Users/<you>/Library/Messages/chat.db",
            },
          },
        }
        ```
      </Step>

      <Step title="Start gateway">
        ```bash theme={null}
        datzi gateway
        ```
      </Step>

      <Step title="Approve first DM pairing (default dmPolicy)">
        ```bash theme={null}
        datzi pairing list imessage
        datzi pairing approve imessage <CODE>
        ```

        Pairing requests expire after 1 hour.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Remote Mac over SSH">
    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`.

    ```bash theme={null}
    #!/usr/bin/env bash
    exec ssh -T gateway-host imsg "$@"
    ```

    Recommended config when attachments are enabled:

    ```json5 theme={null}
    {
      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`.
  </Tab>
</Tabs>

## 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:

```json5 theme={null}
{
  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'
    }
  }
}
```

```bash theme={null}
#!/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:

```json5 theme={null}
{
  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

* [Configuration reference - iMessage](/datzi/gateway/configuration-reference#imessage)
* [Gateway configuration](/datzi/gateway/configuration)
* [Pairing](/datzi/channels/pairing)
* BlueBubbles (see the channels overview for details)
