Skip to content

feebleai/imsg

 
 

Repository files navigation

💬 imsg — Send, read, stream iMessage & SMS

A macOS Messages.app CLI to send, read, and stream iMessage/SMS (with attachment metadata). Read-only for receives; send uses AppleScript (no private APIs).

Features

  • List chats, view history, or stream new messages (watch).
  • Send text and attachments via iMessage or SMS (AppleScript, no private APIs).
  • Phone normalization to E.164 for reliable buddy lookup (--region, default US).
  • Optional attachment metadata output (mime, name, path, missing flag).
  • Filters: participants, start/end time, JSON output for tooling.
  • Read-only DB access (mode=ro), no DB writes.
  • Event-driven watch via filesystem events.
  • Optional advanced IMCore features (typing, launch, status) behind explicit SIP-off setup.

Requirements

  • macOS 14+ with Messages.app signed in.
  • Full Disk Access for your terminal to read ~/Library/Messages/chat.db.
  • Automation permission for your terminal to control Messages.app (for sending).
  • For SMS relay, enable “Text Message Forwarding” on your iPhone to this Mac.

Install

make build
# binary at ./bin/imsg

Commands

  • imsg chats [--limit 20] [--json] — list recent conversations.
  • imsg history --chat-id <id> [--limit 50] [--attachments] [--participants +15551234567,...] [--start 2025-01-01T00:00:00Z] [--end 2025-02-01T00:00:00Z] [--json]
  • imsg watch [--chat-id <id>] [--since-rowid <n>] [--debounce 250ms] [--attachments] [--participants …] [--start …] [--end …] [--json]
  • imsg send --to <handle> [--text "hi"] [--file /path/img.jpg] [--service imessage|sms|auto] [--region US]
  • imsg read --to <handle> [--chat-id <id> | --chat-identifier <id> | --chat-guid <guid>]
  • imsg typing --to <handle> [--duration 5s] [--stop true] [--service imessage|sms|auto]
  • imsg status [--json] — advanced feature and SIP status
  • imsg launch [--dylib <path>] [--kill-only] [--json]

Quick samples

# list 5 chats
imsg chats --limit 5

# list chats as JSON
imsg chats --limit 5 --json

# last 10 messages in chat 1 with attachments
imsg history --chat-id 1 --limit 10 --attachments

# filter by date and emit JSON
imsg history --chat-id 1 --start 2025-01-01T00:00:00Z --json

# live stream a chat
imsg watch --chat-id 1 --attachments --debounce 250ms

# send a picture
imsg send --to "+14155551212" --text "hi" --file ~/Desktop/pic.jpg --service imessage

# mark a chat as read
imsg read --to "+14155551212"

# advanced status check
imsg status

# launch Messages with injection (SIP must be disabled first)
imsg launch

# show typing indicator for 5s
imsg typing --to "+14155551212" --duration 5s

Attachment notes

--attachments prints per-attachment lines with name, MIME, missing flag, and resolved path (tilde expanded). Only metadata is shown; files aren’t copied.

JSON output

imsg chats --json emits one JSON object per chat with fields: id, name, identifier, service, last_message_at. imsg history --json and imsg watch --json emit one JSON object per message with fields: id, chat_id, guid, reply_to_guid, destination_caller_id, sender, is_from_me, text, created_at, attachments (array of metadata with filename, transfer_name, uti, mime_type, total_bytes, is_sticker, original_path, missing), reactions.

Note: reply_to_guid, destination_caller_id, and reactions are read-only metadata.

Permissions troubleshooting

If you see “unable to open database file” or empty output:

  1. Grant Full Disk Access: System Settings → Privacy & Security → Full Disk Access → add your terminal.
  2. Ensure Messages.app is signed in and ~/Library/Messages/chat.db exists.
  3. For send, allow the terminal under System Settings → Privacy & Security → Automation → Messages.

Advanced Features (SIP-Off Only)

Advanced features (typing, launch, IMCore bridge) require injecting a helper dylib into Messages.app.

Important:

  • This is opt-in only. Default send/history/watch flows do not need injection.
  • imsg launch refuses to inject when SIP is enabled.
  • imsg status is read-only and does not auto-launch or auto-inject.

Setup:

  1. Disable SIP from Recovery mode: csrutil disable
  2. Grant Full Disk Access to your terminal
  3. Build helper dylib: make build-dylib
  4. Launch with injection: imsg launch
  5. Verify: imsg status

To revert after testing, re-enable SIP in Recovery mode: csrutil enable.

Testing

make test

Note: make test applies a small patch to SQLite.swift to silence a SwiftPM warning about PrivacyInfo.xcprivacy.

Linting & formatting

make lint
make format

Core library

The reusable Swift core lives in Sources/IMsgCore and is consumed by the CLI target. Apps can depend on the IMsgCore library target directly.

About

CLI for Apple's Messages.app so your agent can send and receive text messages/iMessages.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Swift 90.1%
  • Objective-C 7.2%
  • Shell 2.2%
  • Makefile 0.5%