mirror of
https://github.com/anthropics/claude-plugins-official.git
synced 2026-03-19 23:23:07 +00:00
Add imessage channel plugin
iMessage bridge for Claude Code. Reads ~/Library/Messages/chat.db directly for history and new-message polling; sends via AppleScript to Messages.app. macOS only. Built-in access control: inbound messages are gated by an allowlist (default: self-chat only), outbound sends are scoped to the same allowlist. The /imessage:access skill manages allowlists and policy. Requires Full Disk Access and Automation TCC grants — both prompted by macOS on first use. Ships full source — server.ts runs locally via bun, started by the .mcp.json command.
This commit is contained in:
75
external_plugins/imessage/README.md
Normal file
75
external_plugins/imessage/README.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# iMessage
|
||||
|
||||
Connect iMessage to your Claude Code assistant. Reads `~/Library/Messages/chat.db` directly for history, search, and new-message detection; sends via AppleScript to Messages.app. No external server, no background process to keep alive.
|
||||
|
||||
macOS only.
|
||||
|
||||
## Quick setup
|
||||
> Default: text yourself. Other senders are dropped silently (no auto-reply) until you allowlist them. See [ACCESS.md](./ACCESS.md) for groups and multi-user setups.
|
||||
|
||||
**1. Grant Full Disk Access.**
|
||||
|
||||
`chat.db` is protected by macOS TCC. The first time the server reads it, macOS pops a prompt asking if your terminal can access Messages — click **Allow**. The prompt names whatever app launched bun (Terminal.app, iTerm, Ghostty, your IDE).
|
||||
|
||||
If you click Don't Allow, or the prompt never appears, grant it manually: **System Settings → Privacy & Security → Full Disk Access** → add your terminal. Without this the server exits immediately with `authorization denied`.
|
||||
|
||||
**2. Install the plugin.**
|
||||
|
||||
These are Claude Code commands — run `claude` to start a session first.
|
||||
|
||||
Install the plugin. No env vars needed.
|
||||
```
|
||||
/plugin install imessage@claude-plugins-official
|
||||
```
|
||||
|
||||
**3. Relaunch with the channel flag.**
|
||||
|
||||
The server won't connect without this — exit your session and start a new one:
|
||||
|
||||
```sh
|
||||
claude --channels plugin:imessage@claude-plugins-official
|
||||
```
|
||||
|
||||
Check that `/imessage:configure` tab-completes.
|
||||
|
||||
**4. Text yourself.**
|
||||
|
||||
iMessage yourself from any device. It reaches the assistant immediately — self-chat bypasses access control.
|
||||
|
||||
> The first outbound reply triggers an **Automation** permission prompt ("Terminal wants to control Messages"). Click OK.
|
||||
|
||||
**5. Decide who else gets in.**
|
||||
|
||||
Nobody else's texts reach the assistant until you add their handle:
|
||||
|
||||
```
|
||||
/imessage:access allow +15551234567
|
||||
```
|
||||
|
||||
Handles are phone numbers (`+15551234567`) or Apple ID emails (`them@icloud.com`). If you're not sure what you want, ask Claude to review your setup.
|
||||
|
||||
## How it works
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| **Inbound** | Polls `chat.db` once a second for `ROWID > watermark`. Watermark initializes to `MAX(ROWID)` at boot — old messages aren't replayed on restart. |
|
||||
| **Outbound** | `osascript` with `tell application "Messages" to send …`. Text and chat GUID pass through argv so there's no escaping footgun. |
|
||||
| **History & search** | Direct SQLite queries against `chat.db`. Full history — not just messages since the server started. |
|
||||
| **Attachments** | `chat.db` stores absolute filesystem paths. The first inbound image per message is surfaced to the assistant as a local path it can `Read`. Outbound attachments send as separate messages after the text. |
|
||||
|
||||
## Access control
|
||||
|
||||
See **[ACCESS.md](./ACCESS.md)** for DM policies, groups, self-chat, delivery config, skill commands, and the `access.json` schema.
|
||||
|
||||
Quick reference: IDs are **handle addresses** (`+15551234567` or `someone@icloud.com`). Default policy is `allowlist` — this reads your personal `chat.db`. Self-chat always bypasses the gate.
|
||||
|
||||
## Tools exposed to the assistant
|
||||
|
||||
| Tool | Purpose |
|
||||
| --- | --- |
|
||||
| `reply` | Send to a chat. `chat_id` + `text`, optional `files` (absolute paths). Auto-chunks text; files send as separate messages. |
|
||||
| `chat_messages` | Fetch recent history from a chat (oldest-first). Reads `chat.db` directly — full native history. Scoped to allowlisted chats. |
|
||||
|
||||
## What you don't get
|
||||
|
||||
AppleScript can send messages but not tapback, edit, or thread — those require Apple's private API. If you need them, look at [BlueBubbles](https://bluebubbles.app) (requires disabling SIP).
|
||||
Reference in New Issue
Block a user