AI Tools Review
What is imsg CLI? The Programmatic Gateway to iMessage

Insights

What is imsg CLI? The Programmatic Gateway to iMessage

AI Tools Review Editorial TeamFebruary 01, 2026
  • iMessage
  • CLI
  • Automation
  • Swift

1. Solving a Specific Itch

Introduction

"Every once in a while I stumble on a project that solves a very specific itch in a surprisingly elegant way. imsg is one of those."

In the rapidly evolving landscape of automation and AI, the missing link has often been personal communication. While APIs exist for Slack, Discord, and Telegram, iMessage has remained a walled garden on macOS, until now.

imsg is a small but powerful Swift CLI that provides programmatic access to iMessage and SMS on macOS, backed by the native Messages app database. It represents a shift from "hacking" the system to "respecting" it, providing a stable bridge between your chat history and your custom tools.

imsg CLI Terminal Interface Concept

2. What is imsg?

At its core, imsg is a command-line tool designed for developers who need to treat iMessage as a data source. Whether you want to list your chats, pull deep message history, or "watch" conversations in real time, imsg makes it possible with a few keystrokes.

Programmatic Access

List chats, fetch history, and monitor incoming messages directly from your terminal or scripts.

JSON-First

Everything is emitted as clean JSON, making it trivial to plug into custom tooling or AI agents.

What makes it truly interesting is the ability to emit everything as JSON. This means you can plug your Messages straight into your own tooling, scripts, or agents without the "weird hacks" typical of previous iMessage automation attempts.

3. How It Works Under the Hood

imsg Technical Architecture

The genius of imsg lies in its respect for the macOS ecosystem. It doesn't attempt to reverse-engineer iMessage's encryption or private cloud protocols. Instead, it works with the data your system already has.

Read-Only Database Access

Incoming messages are fetched directly from chat.db in read-only mode. This ensures that the tool never risks corrupting your primary message database.

AppleScript for Sending

Rather than using private APIs that could break with every macOS update, imsg leverages official AppleScript hooks to send messages. It's stable, supported, and safe.

Data Normalisation

It handles the boring details that developers hate: E.164 phone number normalisation, attachment metadata extraction, and multi-participant thread grouping.

4. IMsgCore: The Engine behind the CLI

For those building more complex macOS applications, the project isn't just a binary. It's powered by IMsgCore, a modular Swift library.

Swift Developer Note

You can pull IMsgCore directly into your own macOS app or background helper. This allows you to treat Messages as just another data source, like a REST API or a local JSON file, within your native Swift code.

This dual-layered approach (CLI for shell users, Library for app developers) makes imsg one of the most versatile tools in the macOS automation toolkit.

5. The AI-Native Social Graph

The true potential of imsg is realised when paired with AI agents. In the "OpenClaw" ecosystem (formerly Moltbot), imsg acts as the sensory input and motor output for autonomous agents.

By transforming a messy database into a stream of structured JSON-RPC events, the tool allows AI models to understand who they are talking to, recall previous context across weeks of history, and respond with human-like timing and awareness. It’s the infrastructure required for an AI-native social graph.

6. Quick Setup Guide

Getting started with imsg is straightforward thanks to its availability via Homebrew.

# 1. Install via Homebrew

brew install steipete/tap/imsg

# 2. Grant permissions in System Settings

# Full Disk Access for Terminal/iTerm

# 3. Test your first command

imsg chats --limit 5

7. Advanced Configurations

For AI agent gateways (like OpenClaw), imsg runs in RPC mode. This spawns a JSON-RPC session over stdio, allowing the gateway to pipe events back and forth continuously.

Remote/SSH Variant

You can even run imsg on a remote Mac (e.g. a dedicated Mac Mini) and communicate via an SSH wrapper:

#!/usr/bin/env bash
exec ssh -T bot-mac-mini imsg rpc "$@"

⚠️ 8. Security & Permissions

Because imsg needs to read the Messages database, it requires elevated permissions on macOS:

  • 01.Full Disk Access: Required for accessing ~/Library/Messages/chat.db.
  • 02.Automation: Required when sending messages, to allow imsg to control the Messages app via AppleScript.

9. The Command Surface in Practice

The thing that makes imsg pleasant to work with is that its command set is small enough to hold in your head. There is no plugin system to learn and no configuration file to write before you can get an answer out of it. Six commands cover essentially everything most people need.

imsg chats

Lists your conversations and, more importantly, returns the chat identifiers that every other command needs. Accepts --limit to keep the output manageable and --json to make it machine-readable.

imsg history

Reads and searches your local message archive. Combine --chat-id with --limit to pull a specific thread, and add --attachments when you need file metadata alongside the text.

imsg watch

Streams new messages as they arrive, one JSON object per line. Pass --reactions to include tapbacks, which matters more than you would expect when an agent needs to know whether a human acknowledged something.

imsg send and imsg react

The write path. send takes --to and --text and handles files as well as plain messages; react adds the standard tapbacks. Both route through Messages.app rather than any private interface.

imsg stats and imsg rpc

stats counts messages and media, which is handy for sanity-checking that permissions are actually working. rpc is the long-running JSON-RPC stdio transport that agents and gateways speak to. There is also imsg completions for shell completions.

NDJSON, and why the stream discipline matters

The JSON output is newline-delimited: one object per line, emitted as it becomes available rather than buffered into a single array at the end. Crucially, human-readable progress messages and warnings are routed to stderr, which leaves stdout clean for piping. That sounds like a trivial detail until you have spent an afternoon debugging a pipeline that broke because a tool printed a status banner into the middle of your data stream.

In practice it means you can do something like imsg chats --json | jq -s to collapse the stream back into a single array, or feed imsg watch --json straight into a long-running process without any parsing ceremony at all. For agents, the RPC transport does the same job with a persistent session, so a gateway can keep a single process open and exchange commands and events continuously instead of paying process-spawn cost on every message.

10. Platform Support & Requirements

The requirements are modest but non-negotiable. You need macOS 14 or newer, Messages.app signed in, and an existing ~/Library/Messages/chat.db. Building from source needs Swift 6. Signed macOS builds are published to GitHub Releases, and Homebrew is the simplest route for everyone else.

What you want to doPermission required
Read the local message databaseFull Disk Access
Send messages and tapbacksAutomation → Messages
Resolve contact names instead of raw numbersContacts (optional)
See green-bubble SMS as well as iMessageText Message Forwarding enabled on the paired iPhone

Contacts access is genuinely optional. Without it the tool still works perfectly well, it simply leaves names unresolved and hands you E.164 phone numbers. If you are running over SSH, contacts can still be resolved through the Mac's read-only address book provided the SSH service itself has been granted Full Disk Access, which is a detail worth remembering when you inevitably discover that your headless Mac Mini is returning numbers instead of names.

There are also read-only Linux builds for x86_64. These do not connect to iMessage and cannot send anything; they read a chat.db that you have copied across from a Mac. That is useful for analysis and archival work, and useless for automation, so set your expectations accordingly. The project is MIT licensed.

How watch actually works

Real-time monitoring is the part most home-grown iMessage scripts get wrong. Naive implementations poll the database on a timer, which is either laggy or wasteful depending on the interval you pick. imsg watch follows filesystem events on the database and its write-ahead log, with a polling fallback for the cases where macOS drops events or rotates the sidecar files out from under it. All read commands open SQLite in read-only mode, so there is no realistic path by which the tool corrupts the database it is reading.

11. Limitations and the SIP Question

It is worth being clear about what imsg cannot do, because the boundary is a deliberate design decision rather than an oversight.

The supported surface is built on AppleScript for writes and read-only database access for reads. That combination is stable across macOS updates, but it also caps what is reachable. A set of advanced capabilities does exist behind a bridge, covering things like read receipts, typing indicators, polls and programmatic chat creation, but these require System Integrity Protection to be disabled and may still be blocked by library validation on current macOS versions.

Our recommendation

Do not disable SIP on a machine that holds your real Apple ID, your keychain and your message history in order to get typing indicators. If you genuinely need the bridge features, put them on a dedicated device that holds nothing you would mind losing. The supported surface covers the overwhelming majority of automation use cases.

There is one more practical quirk. Because imsg send drives Messages.app's AppleScript interface, it cannot force a specific outgoing number when several numbers share a single Apple ID. If you run multiple lines through one account, the message goes out on whichever one Messages.app decides to use. That is a limitation of the supported interface, not of the tool.

12. Where imsg Fits in the Agent Stack

The reason imsg gets more attention than a well-built CLI normally would is that it sits at a specific structural gap. Personal AI agents that live on your own hardware need a channel to reach you through, and the obvious candidates all carry a cost. Slack and Discord mean your assistant lives somewhere you associate with work. Telegram and WhatsApp mean a bot account and a third party in the middle. iMessage is the channel most people in the UK and US already leave open by default, and until recently it was the one channel no tool could touch cleanly.

That is why the project has ended up as part of the plumbing under OpenClaw, the personal-agent framework formerly known as Moltbot and, before that, Clawdbot. The RPC transport is precisely what a gateway needs: one persistent process, structured events in, structured commands out, no polling loop to write yourself. If you want to see how it plugs together end to end, our iMessage setup guide walks through the gateway configuration, and the project overview covers the wider architecture.

Sensible things to build with it

  • A read-only digest. The lowest-risk starting point. Point imsg history at a busy group thread, summarise it, and send the summary somewhere else entirely. No write permissions, no chance of the agent embarrassing you.
  • Archival and search. Export to NDJSON, index it, and finally have a searchable record of a decade of conversations that Spotlight has never handled well.
  • Alerting. Use watch to trigger on specific senders or keywords, and route those to a pager, a smart light, or anything else that will actually get your attention.
  • Assisted replies. The genuinely useful and genuinely risky one. Draft rather than send, at least until you have watched it behave for a fortnight.

A word on consent

Every message in that database was written by somebody who thought they were talking to you, not to a language model. Piping an entire chat history into a hosted API is a decision with other people's privacy attached to it, and under UK data-protection norms it is not a decision you can make on their behalf lightly. Prefer local models for bulk processing, scope your queries to the threads you actually need, and be honest with the people you message if an assistant is drafting on your behalf.

Ready to experiment?

Find the source code and full documentation on GitHub. The repository now lives under the OpenClaw organisation at github.com/openclaw/imsg, following the project's rebrand, and Homebrew installation still runs through the original steipete/tap formula.

Build smarter, automate deeper, and bridge the gap between your conversations and your code.

Frequently Asked Questions

Does imsg work on Linux or Windows?
No. imsg is a macOS-only tool because it relies on the local Apple Messages app database and AppleScript engine. However, you can use an SSH bridge to control a Mac from a Linux/Windows machine.
Can I send images or attachments?
Yes! imsg includes metadata for attachments in its JSON output and supports sending files through the integrated AppleScript hooks. It handles files up to the native iMessage limits.
Why use this instead of a private API?
Stability. Apple's private internal APIs change frequently and using them can lead to account bans or system instability. imsg uses the official supported methods (AppleScript + File Reading) to ensure your automation keeps working.

Explore more AI tool comparisons

In-depth reviews, benchmarks and guides to help you choose the right AI tools.

Browse all reviews
AI Tools Review Editorial Team

AI Tools Review Editorial Team Expert verified

Our editorial team consists of veteran AI researchers, software engineers, and industry analysts. We spend hundreds of hours benchmarking frontier models natively to provide you with objective, actionable intelligence on agentic AI capabilities and cybersecurity landscapes.