imsg
The imsg command-line tool enables you to send and read iMessage and SMS messages directly from the terminal, query your Messages database, and watch for incoming messages.
⚠️ Important Privacy & Database Notes
- Database Access:
imsgreads from your local Messages database (~/Library/Messages/chat.db). This is a sensitive file containing your complete message history. - Permissions: macOS may prompt for permissions when accessing the Messages database. Terminal needs Full Disk Access on newer macOS versions.
- Data Sensitivity: Be cautious when working with message history — it contains private conversations.
- Database Locking: If Messages.app is open, the database may be locked. Close Messages.app if you encounter access issues.
Commands Overview
imsg has four main commands:
chats— List your recent iMessage/SMS conversationshistory— Show message history for a specific chatwatch— Stream incoming messages in real-timesend— Send a message (text and/or attachment)rpc— Run JSON-RPC over stdin/stdout (advanced)
chats — List Conversations
List recent iMessage and SMS conversations from your Messages database.
Usage
imsg chats [options]
Options
--limit <number>— Number of chats to list (e.g.,--limit 5)--jsonor-j— Output as machine-readable JSON--db <path>— Custom path to chat.db (defaults to~/Library/Messages/chat.db)-v, --verbose— Enable verbose logging--log-level <level>— Set log level:trace|verbose|debug|info|warning|error|critical
Examples
# List 10 most recent conversations
imsg chats --limit 10
# List conversations as JSON (easier to parse)
imsg chats --limit 5 --json
# List all conversations (no limit)
imsg chats
history — Show Message History
Retrieve message history for a specific conversation. Requires a chat ID (which you get from imsg chats).
Usage
imsg history [options]
Options
--chat-id <id>— Chat ID fromimsg chats(required unless using--participants)--limit <number>— Number of messages to show--participants <handles>— Filter by participant phone/email (e.g.,+15551234567oruser@example.com)--start <ISO8601>— Start date (inclusive), e.g.,2025-01-01T00:00:00Z--end <ISO8601>— End date (exclusive)--attachments— Include attachment metadata in results--jsonor-j— Output as JSON--db <path>— Custom path to chat.db-v, --verbose— Enable verbose logging--log-level <level>— Set log level
Examples
# Last 20 messages from chat ID 1
imsg history --chat-id 1 --limit 20
# Last 50 messages with attachment info
imsg history --chat-id 1 --limit 50 --attachments
# Messages in date range (as JSON)
imsg history --chat-id 1 --start 2025-01-01T00:00:00Z --end 2025-02-01T00:00:00Z --json
# Messages from specific participant
imsg history --chat-id 1 --participants +15551234567 --limit 10
watch — Stream Incoming Messages
Watch for and stream incoming iMessage/SMS messages in real-time. Useful for monitoring conversations without opening Messages.app.
Usage
imsg watch [options]
Options
--chat-id <id>— Limit to a specific chat (optional)--since-rowid <id>— Start watching after this message rowid (skip old messages)--participants <handles>— Filter by participant phone/email--start <ISO8601>— ISO8601 start time (inclusive)--end <ISO8601>— ISO8601 end time (exclusive)--debounce <duration>— Debounce filesystem events (e.g.,250ms) to avoid duplicate notifications--attachments— Include attachment metadata--jsonor-j— Output as JSON (one JSON object per message)--db <path>— Custom path to chat.db-v, --verbose— Enable verbose logging--log-level <level>— Set log level
Examples
# Watch all incoming messages
imsg watch
# Watch specific chat only (with attachments)
imsg watch --chat-id 1 --attachments
# Watch from specific participant
imsg watch --participants +15551234567
# Watch with debouncing (less spam)
imsg watch --chat-id 1 --debounce 500ms --json
send — Send a Message
Send an iMessage or SMS message. You can send text, attachments, or both.
Usage
imsg send [options]
Target Options (choose one method)
--to <handle>— Phone number or email address (e.g.,+14155551212oruser@example.com)--chat-id <id>— Send to an existing chat by rowid--chat-identifier <id>— Send to chat identifier string (e.g.,iMessage;+;chat...)--chat-guid <guid>— Send to chat by GUID
Message Options
--text <message>— Message body (plain text)--file <path>— Path to attachment file (e.g.,~/Desktop/photo.jpg)--service <type>— Service:imessage|sms|auto(default:auto)auto— Automatically choose iMessage if available, fallback to SMSimessage— Force iMessage (may fail if recipient not on iMessage)sms— Force SMS
Other Options
--region <code>— Default region for phone number normalization (e.g.,US)--jsonor-j— Output result as JSON--db <path>— Custom path to chat.db-v, --verbose— Enable verbose logging--log-level <level>— Set log level
Examples
# Send SMS to a phone number
imsg send --to +14155551212 --text "Hi there!"
# Send iMessage with attachment (auto-falls back to SMS if needed)
imsg send --to user@example.com --text "Check this out" --file ~/Desktop/photo.jpg --service auto
# Send to existing chat
imsg send --chat-id 1 --text "Hello from the terminal!"
# Send with JSON output (useful for scripting)
imsg send --to +14155551212 --text "Hi" --json
Service Selection (auto Fallback)
When using --service auto (recommended):
- If the recipient is on iMessage, the message sends as iMessage (free, full features)
- If iMessage fails, it automatically falls back to SMS (costs may apply, carrier fees)
- This ensures reliable delivery across Apple and non-Apple devices
rpc — JSON-RPC (Advanced)
For advanced use cases, imsg supports JSON-RPC over stdin/stdout. This allows programmatic interaction with the tool. See imsg rpc --help for details.
General Options (All Commands)
--db <path>— Override default chat.db location (defaults to~/Library/Messages/chat.db)--log-level <level>— Set verbosity:trace|verbose|debug|info|warning|error|critical-v, --verbose— Enable verbose output--jsonor-j— Output as JSON (available on most commands)
Workflow Examples
1. Find a Conversation and Read Recent Messages
# List recent chats
imsg chats --limit 10
# Read last 20 messages from chat ID 3
imsg history --chat-id 3 --limit 20
2. Send a Message to Someone
# Send SMS or iMessage (auto-selects)
imsg send --to +14155551212 --text "Hello!"
# Or send to an existing chat
imsg chats --limit 5
imsg send --chat-id 2 --text "Hi there!"
3. Monitor a Conversation in Real-Time
# Watch for new messages in chat ID 1
imsg watch --chat-id 1 --debounce 500ms
# Watch with JSON output
imsg watch --chat-id 1 --json
4. Extract Messages for Backup or Analysis
# Get all messages from a chat as JSON
imsg history --chat-id 1 --json > backup.json
# Get messages from a date range
imsg history --chat-id 1 --start 2024-01-01T00:00:00Z --end 2024-12-31T23:59:59Z --json
Tips & Troubleshooting
- Messages.app Lock: If you get database locked errors, close Messages.app first
- Permissions: On newer macOS (Ventura+), Terminal needs Full Disk Access to read the Messages database. Grant it in System Settings > Privacy & Security
- Phone Number Formatting: Use international format (e.g.,
+14155551212for US numbers) - JSON Output: Most commands support
--jsonfor scripting and parsing - Debouncing: When using
watch, set--debounceto avoid spam from rapid file system events - Private Data: Remember that message history is sensitive — be careful with backups and logs