Self-hosted service
openclaw/imsg avatar
openclaw/imsg

imsg: A Swift CLI That Reads and Sends iMessage Without Touching Private APIs

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

1,328 stars180 forksSwiftMIT

At a glance

What is it?
imsg is a macOS command-line tool that reads the local Messages database, streams updates, and sends texts through AppleScript automation. It targets scripters and AI agents, with a read-only Linux build as a bonus.
Who is it for?
Adopt imsg if you are a macOS power user or developer who needs scriptable access to iMessage history and sending, especially for agent workflows. Avoid it if you require reliable sending on macOS with SIP enabled for advanced features, or if you need full functionality on Linux, where only read-only database queries work.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Swift, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 14, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The Problem: iMessage Is a Walled Garden for Scripts

Apple's Messages.app has no official CLI or API. Scripting it usually means fragile UI automation or reverse-engineering private frameworks. imsg solves that by providing a Swift CLI that reads the local SQLite database directly and sends messages through the app's AppleScript surface. The target audience is clear: developers building agents, chatbots, or personal automation that need to interact with iMessage and SMS without clicking. The README pitches it as 'Messages, piped,' and the core commands reflect that: list chats, read history, watch for new messages, and send text.

How It Works: Database Reads and AppleScript Sends

The architecture splits into two halves. Reading is done by opening ~/Library/Messages/chat.db in SQLite read-only mode. The watch command follows filesystem events on the database and WAL files, with a polling fallback when macOS drops an event or rotates a sidecar file. Sending is handled by asking Messages.app to do the work via AppleScript, which means the app must be running and have the right permissions. The README notes that normal workflows do not use private frameworks or process injection. Advanced features like read receipts, typing indicators, and message mutation require an injected helper inside Messages.app, which in turn requires SIP to be disabled. That is a hard boundary: the basic tool is clean, but the advanced path is fragile and may be blocked by library validation on current macOS.

Getting Started: Install, Permissions, and First Commands

Installation is straightforward on macOS 14 or newer via Homebrew: brew install steipete/tap/imsg. After that, you must grant your terminal Full Disk Access in System Settings, then reopen it. The quick start shows: imsg chats --limit 3 to list chats and get IDs, then imsg history --chat-id 42 --limit 10 to read messages. Sending requires Automation permission for Messages, and optional Contacts access only adds resolved names. For SMS, you need Text Message Forwarding enabled on a paired iPhone. The README warns that send cannot force a particular outgoing number when several numbers share one Apple ID, which is a real limitation for multi-number setups.

JSON and JSON-RPC: Built for Agents, Not Just Humans

The CLI emits NDJSON with --json, one JSON object per line, keeping human progress and warnings on stderr so stdout stays clean for piping. Finite commands can be piped through jq -s to get an array. For long-running automation, imsg rpc starts a JSON-RPC stdio transport, ideal for agents or gateways. The JSON schema covers chats, messages, attachments, reactions, polls, scheduled messages, and statistics. This is a deliberate design choice: the tool is not just an interactive REPL but a data source for scripts. The watch command streams new messages and tapbacks, so an agent can react to incoming texts in near real-time.

Limitations: Full Disk Access, AppleScript Sends, and Linux Read-Only

The biggest practical hurdle is permissions. Full Disk Access is non-negotiable for reading chat.db, and the README points to a troubleshooting guide for stale TCC entries. Sending relies on AppleScript, which is slower and less reliable than a native API, and it cannot control which outgoing number is used. On Linux, the build is read-only: you can query a chat.db copied from macOS, but you cannot connect to iMessage or send messages. That limits Linux to analysis and logging, not interactive use. The advanced IMCore features require SIP disabled, which is a dealbreaker for many users because it weakens macOS security. If you need those features, you must accept the risk and the possibility that Apple will block them in future updates.

Alternatives: AppleScript Directly or Private Framework Hacks

A direct alternative is writing your own AppleScript to control Messages.app, which gives you send capability without a third-party tool, but you still need Full Disk Access to read the database, and you lose the structured JSON output and watch functionality. Another approach is using private frameworks like IMCore directly, which some projects do, but that requires code signing and is brittle across macOS versions. imsg's advantage is that it wraps the clean path (database + AppleScript) in a tested CLI with a documented JSON schema. The trade-off is that you depend on a third-party tool's maintenance, though the MIT license and Swift 6 codebase make it auditable.

Maintenance and Upgrade Costs: Swift 6, MIT License, and Active Releases

The repository shows recent releases (v0.14.2 in August 2026) and a CI workflow, indicating active development. The package is split into IMsgCore (reusable Swift core), imsg (CLI), and IMsgHelper (optional injected helper). Upgrading is a matter of brew upgrade, but watch for breaking changes in JSON schema or RPC methods, as the tool is pre-1.0. The MIT license is permissive, so you can fork and modify, but you must handle your own signing if you distribute modified builds. There is no affiliation with Apple, and the README notes that iMessage and SMS are trademarks of their owners, so you are on your own regarding Apple's terms of service. The advanced IMCore bridge is the biggest upgrade risk: it depends on SIP being disabled and may break with each macOS release, so evaluate whether you need those features before relying on them.

Editorial conclusion

Adopt imsg if you are a macOS power user or developer who needs scriptable access to iMessage history and sending, especially for agent workflows. Avoid it if you require reliable sending on macOS with SIP enabled for advanced features, or if you need full functionality on Linux, where only read-only database queries work. Before adopting, verify that your macOS version is 14 or newer, grant Full Disk Access and Automation permissions, and test the watch command on your system to confirm file event reliability. For production use, check the JSON-RPC stability and the current state of the advanced IMCore bridge, as it depends on SIP being disabled and may break with future macOS updates.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Community notes

Community notes