imsg
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
More from trtmn/agent-skills
self-improvement
Run the self-improvement agent to review this session and the ~/.learnings/ log files. Use this skill whenever the user explicitly asks to review learnings, promote entries to CLAUDE.md, do an end-of-session review, or analyze GitHub PRs/issues for recurring patterns. Also use when the user says "promote", "review learnings", "what have we learned", or "self-improvement". Do NOT use this skill just for logging — logging happens automatically without the skill (see Passive Logging below). This skill is specifically for the *review and promotion* workflow.
20unifi-api
Query and control a UniFi network using the `unifi` CLI (a restish wrapper with 1Password auth) or the REST API as fallback. Use this skill whenever the user wants to manage their UniFi network — listing connected clients, blocking/unblocking devices, managing firewall policies, checking WAN health and speed test results, rebooting devices, managing VLANs or SSIDs, reading traffic stats, port forwarding, or any other UniFi network management task. Prefer the `unifi` CLI for Integration API endpoints; fall back to raw curl/python for legacy API endpoints. Trigger even if the user doesn't say "API" or "UniFi" — phrases like "check my network", "block that device", "show me who's connected", "add a firewall rule", "what's my WAN IP", "how's my internet speed", or "what's on the guest network" are all good triggers.
5homebrew-dev
Package and distribute macOS apps, fonts, CLI tools, and arbitrary files using Homebrew formulas and casks. Use this skill whenever the user wants to create a Homebrew formula or cask, set up a personal tap, package a macOS .app bundle, distribute fonts or pre-built binaries via brew, use `brew create`, bump a formula or cask to a new version, submit a package to homebrew-core or homebrew-cask, or publish anything with Homebrew — even if they just ask how to "make something installable with brew", "share my app through Homebrew", "update my formula", or "get my package into Homebrew".
5tailscale-policy-manager
>
5obsidian-cli
>
4home-assistant
Control and query Home Assistant smart home devices via the REST API. Use this skill whenever the user mentions Home Assistant, smart home control, IoT devices, home automation, turning lights on/off, checking sensor readings, thermostat control, door locks, or any task involving their home's connected devices — even if they don't explicitly say "Home Assistant." Also trigger when users ask about their home's state, want to create automations, or reference entity IDs like "light.living_room" or "switch.garage_door.
4