iMessage
Overview
On macOS, Melian monitors iMessage by polling the system chat.db database on a short interval. Incoming messages are routed through a ContactRegistry that maps each sender to a per-contact mode. Melian maintains a separate conversation session for each contact, with an idle timeout after which context is reset. Draft responses are surfaced via self-chat: Melian messages herself with the proposed reply and awaits a send / skip / edit command.
Contact Configuration
Each entry in the contact registry is an IMessageContactConfig. The identifier is the iMessage handle (phone number or email). The optional context field injects standing instructions into that contact's session (e.g., "this is my manager").
export interface IMessageContactConfig {
identifier: string;
name: string;
mode: "auto" | "draft" | "notify" | "triage" | "spam";
unconstrained?: boolean; // bypass length and tone guardrails
context?: string; // injected into system prompt for this contact
busy_auto_reply?: boolean; // send a canned reply if no session is active
}Contact Modes
| Mode | Behavior |
|---|---|
auto |
Melian replies directly without approval |
draft |
Melian generates a reply and surfaces it via self-chat; you respond with send, skip, or edit <text> |
notify |
Melian summarizes the message and notifies you, but does not compose a reply |
triage |
Message is forwarded to the attention pipeline for classification; no reply is generated |
spam |
Message is silently discarded |
Tools
| Tool | Parameters | Description |
|---|---|---|
imessage_send |
message: string, contact?: string |
Send an iMessage to a contact (defaults to active session) |
imessage_history |
limit?: number, contact?: string |
Return recent messages from the active or specified thread |
Architecture
chat.db poll (interval)
└── new messages detected
└── ContactRegistry.lookup(sender)
├── mode: auto → generate + send
├── mode: draft → generate → self-chat draft → await command
│ "send" / "skip" / "edit <text>"
├── mode: notify → summarize → push notification
├── mode: triage → attention pipeline classifier
└── mode: spam → discardPer-contact sessions are isolated; context from one thread never leaks into another. Sessions expire after a configurable idle timeout (default 15 minutes), clearing the message history so the next conversation starts fresh.
Sending uses AppleScript (osascript) to hand off the message to the Messages app, which means Melian inherits your iCloud account and delivery receipts without requiring any additional credentials.