@photon-ai/imessage-kit is an MIT-licensed, macOS-only SDK that talks directly to the local Messages database and AppleScript bridge. Use it when you want to read, send, and automate iMessage on a Mac you control — automation tools, AI agents, chat-first apps.
This SDK is for talking to iMessage locally on a Mac you control. If you
want remote/hosted iMessage delivery, threaded replies, tapbacks, edits /
unsends, and live typing indicators, use
Spectrum for a unified API across platforms,
or
@photon-ai/advanced-imessage
when you need low-level iMessage control.Requirements
- OS: macOS only (reads the Messages SQLite database directly).
- Runtime: Node.js ≥ 20 or Bun ≥ 1.0.
- Permission: the process must have Full Disk Access granted. Open System Settings → Privacy & Security → Full Disk Access and add your terminal or IDE (Terminal, iTerm2, Warp, VS Code, Cursor…).
Install
better-sqlite3 as an optional peer dependency.
Quick start
IMessageConfig
SDK main configuration interface
IMessageConfig
SDK main configuration interface
Sending
sdk.send(to, content) auto-detects whether to is a recipient (phone number / email) or a chatId (group or DM).
Text
Images and files
Groups
GroupchatIds are returned by listChats():
Batch
maxConcurrentSends from the SDK config.
Querying messages
MessageFilter
Message query filter
MessageFilter
Message query filter
Unread messages
getUnreadMessages() groups results by sender:
Listing chats
ListChatsOptions
Options for listing chats
ListChatsOptions
Options for listing chats
Real-time watching
Auto-reply with the message chain
sdk.message(msg) returns a — a fluent builder for filter-then-respond patterns:
Attachment helpers
Common media formats
Messages carries a wide range of formats through without transcoding. The SDK’sisImage / isVideo / isAudio helpers classify by the stored MIME type — there’s no allowlist.
Scheduling
MessageScheduler
(sdk, config?, events?) — three positional args. Config is ; one-shot task shape is and recurring is . The scheduler loop is internal — no start() call needed.
Reminders — natural-language scheduling
- Duration:
"5 minutes","2 hours","1 day","30 seconds","1 week" - Time:
"5pm","5:30pm","17:30" - Day + time:
"tomorrow 9am","friday 2pm"
Plugins
onBeforeSend(to, content), onAfterSend(to, result) — not a single object. definePlugin() is a helper that just returns its argument for type inference.
Error handling
PlatformError, DatabaseError, SendError, WebhookError, ConfigError) produce IMessageError instances tagged with the corresponding code — switch on error.code rather than instanceof for each subtype.
Links
- Source: github.com/photon-hq/imessage-kit
- LLM context: llms.txt, or
use context7: photon-hq/imessage-kit - Discord: Join