iMessage Skill
August 24, 2026 · View on GitHub
AI-first macOS iMessage CLI. The repository is self-contained: a pure-Python package, a command-line entry point, offline tests, and a plain Markdown skill contract at skills/skill_imessage.md.
It does two things:
- Send outbound iMessages through the signed-in
Messages.appaccount. - Read local message history from
~/Library/Messages/chat.dbin read-only mode.
It does not modify messages, create groups, fall back to SMS, or run as a background daemon.
What It Does
Send:
- Sends iMessage messages through the signed-in macOS
Messages.appaccount. - Accepts an explicit iMessage handle such as an Apple ID email address or phone number.
- Dry-runs by default for agent review; requires
--confirm-sendfor real sends.
Read:
- Reads a conversation with a contact (
read), full-text searches history (search), or lists recent conversations (chats). - Decodes message bodies from the
attributedBodyBLOB (Applestreamtypedformat) — thetextcolumn is mostly empty. - Dry-runs by default (reports match counts only); requires
--confirm-readto return message content. - Opens the database read-only and never writes to it.
Install
From this repository root:
uv venv .venv
source .venv/bin/activate
uv pip install -e '.[dev]'
This installs the imessage-send console script and the imessage_skill Python package.
Configure
No configuration is required for dry-runs or ordinary CLI use when the target handle is passed with --to.
For live integration tests, copy .env.example to .env and put the private recipient handle there:
IMESSAGE_LIVE_TO=alice@example.com
IMESSAGE_ENABLE_LIVE_TESTS=1
IMESSAGE_LIVE_ALLOW_SEND=1
Do not commit .env. Public examples must use fake handles.
macOS Permission Setup
The Mac must be signed in to iMessage in Messages.app. Two separate permission surfaces are involved:
- Sending (Automation). The first real send from a launcher (Terminal, OpenCode, Python, …) may trigger a macOS Automation prompt asking whether that app can control Messages. Approve it once; subsequent sends from the same launcher should not prompt per message. If automation fails, check
System Settings → Privacy & Security → Automationand confirm the launcher is allowed to control Messages. - Reading (Full Disk Access). Reading
~/Library/Messages/chat.dbrequires the launcher to be able to read that file. On recent macOS this usually means granting Full Disk Access (System Settings → Privacy & Security → Full Disk Access) to the terminal or agent host. If the database is not accessible, the CLI returns a clean error instead of crashing.imessage-send doctor messages-dbchecks this.
Use the CLI
Dry-run a send:
imessage-send send --to alice@example.com --body "Hello from an agent" --dry-run --format json
Send for real after review:
imessage-send send --to alice@example.com --body "Hello from an agent" --confirm-send --format json
Read the body from a file:
imessage-send send --to alice@example.com --body-file body.txt --dry-run --format json
Read a conversation (dry-run reports the match count; add --confirm-read for content):
imessage-send read --to +15555550123 --since 2026-08-01 --until 2026-08-24 --format json
imessage-send read --to +15555550123 --confirm-read --limit 50 --format json
imessage-send read --name "Alice" --direction in --confirm-read --format json
Search across history:
imessage-send search --query "invoice" --since 2026-01-01 --confirm-read --format json
List recent conversations:
imessage-send chats --limit 20 --confirm-read --format json
Check the local automation surface and database readability without sending or reading content:
imessage-send doctor applescript --format json
imessage-send doctor messages-db --format json
Install the Agent Skill
This project uses a plain Markdown skill contract, not a Codex or Claude Code packaged skill format.
- Put
skills/skill_imessage.mdsomewhere your agent can discover, usually a global or workspaceskills/directory. - Look at the workspace root guidance files such as
AGENTS.md,CLAUDE.md, or equivalent. - If those files point to a skill index or discovery document, add this skill there.
- If no discovery file exists, add a short note to the root guidance file telling the agent to read
skills/skill_imessage.mdfor iMessage send/read tasks.
Example guidance:
For macOS iMessage sending and reading, read skills/skill_imessage.md and follow its CLI contract. Private contact aliases live outside the public skill repository.
Test
Default tests are offline:
.venv/bin/python -m pytest -v
Live integration is opt-in and sends a real iMessage:
IMESSAGE_ENABLE_LIVE_TESTS=1 \
IMESSAGE_LIVE_ALLOW_SEND=1 \
IMESSAGE_LIVE_TO=alice@example.com \
IMESSAGE_LOAD_DOTENV=1 .venv/bin/python -m pytest -v -m live_integration
You can also put those variables in private .env and run only:
IMESSAGE_LOAD_DOTENV=1 .venv/bin/python -m pytest -v -m live_integration
Run the live test only when a Mac user is ready to approve any first-time macOS Automation prompt.
Privacy
Do not commit .env, private handles, contact maps, message bodies, screenshots, chat exports, local Messages databases, token caches, or real automation logs. This repository is designed to be publishable with only fake examples.