Your AI can answer your texts. Nothing sends without your green light.
WeMessage is an open-source macOS gateway that lets AI agents draft replies to your iMessages. Every draft waits for your approval. Local-only. No cloud. Kill switch always on top.
Free · Apache-2.0 · macOS
How it works
Connect. Watch. Approve.
Three moves. The agent does the writing, you keep the send button.
01
Connect
A guided onboarding walks each macOS permission with a plain-English privacy promise: what it grants, why we need it, what we never do. Live checks confirm every grant.
02
Watch
Rules decide what your agent even sees: keywords, regex, and contact scopes — plus a pluggable theme classifier you point at your own LLM endpoint. Dry-run any rule against your last 50 messages before it goes live.
03
Approve
Drafts land in a queue built for keyboard triage. Approve one, approve twenty, edit in place, or let a scoped auto-respond handle the boring ones. Undo grace on every send.
The approval gate
The gate is the product.
Reading and writing iMessage is commodity plumbing. What nobody shipped is message-level approve-before-send. That is the whole point of WeMessage.
- Individual or bulk approval. Clear twenty drafts in under a minute without leaving the keyboard.
- Edit in place. Change a draft before it goes; the audit log records exactly what you changed.
- Undo grace. Every approval holds for 10 seconds with a countdown ring before it actually sends.
- Context inline. The last three turns of conversation expand under every draft, so you approve with eyes open.
Control
Off means off.
Autonomy is opt-in, scoped, and instantly revocable. Every control fails closed.
Kill switch
⌘⇧K, the menu bar, or wemessage kill. Instant, no animation, freezes every draft. Deliberately boring.
The kill switch is the only control with zero ceremony. That's the message.
Time windows
Arm the gateway only when you want it live: work hours, evenings, weekends. Outside a window, rules queue silently or stand down — your call, per rule. DST handled properly.
Per-contact policy
Deny by default. Every contact is deny / draft-only / auto, individually or in bulk. And disconnect is real: --purge removes everything WeMessage ever stored.
Agents
Bring whatever thinks for you.
WeMessage is agent-agnostic. Adapters ship for the platforms below, and the protocol, SDK, and companion skill make new ones an afternoon of work.
OpenClaw
native skill
Hermes
adapter
Sol
adapter + streaming
Luna
adapter
Yours
CLI · WS/SSE · SKILL.md
CLI
Everything the GUI does, headless.
The app and the CLI are both thin clients of the same local daemon. Agents and scripts get JSON everywhere; you get a queue you can triage over SSH.
$ wemessage doctor ✓ daemon running (127.0.0.1, token auth) ✓ Full Disk Access — chat.db readable (read-only) ✓ Automation → Messages granted ✓ send-verify loop passed $ wemessage watch --json {"evt":"message","from":"maria","text":"Are we still on for Thursday?","rule":"dinner-plans"} {"evt":"draft","id":"dr_7f3a","agent":"sol","state":"awaiting_approval"} $ wemessage drafts approve dr_7f3a approved — sending in 10s (undo: wemessage drafts undo dr_7f3a) sent ✓ · audit #482 appended to hash chain $ wemessage kill OUTBOUND: KILLED — all drafts frozen, adapters notified
# v1 surface — in development, not yet installable. Watch the repo.
Permissions
Exactly two grants. Here's why.
Full Disk Access
WeMessage reads chat.db, the local iMessage database, in read-only immutable mode. That is how every iMessage tool on macOS works. Nothing is ever written to it.
Automation → Messages
Lets the daemon tell Messages.app to send — only after you approve. This is the single seam where a send can happen, and the kill switch sits directly on it.
Privacy & security
Built like it handles your texts. Because it does.
Local daemon only
Binds 127.0.0.1 with token auth and fails closed. No listening on your network, ever.
Keychain-held secrets
Adapter tokens and LLM keys live in the macOS Keychain, not in config files.
Hash-chained audit log
Every draft, approval, edit, and send is appended to a tamper-evident chain you can verify.
Injection-hardened
Inbound text is sanitized before any agent sees it, and agents structurally cannot send.
FAQ
Honest answers.
What do I need to run it?
One Mac, signed into Messages.app with your Apple ID. WeMessage runs entirely on that machine — it reads the local database and drives the local Messages app. No jailbreak, no SIP changes, no private APIs.
Can my agent text people it has never talked to?
No. v1 is replies-only: agents can only draft into conversations that already exist. New-recipient outreach is deliberately cut, and attempts fail fast and get audited.
Can a sent message be unsent?
Not by us — Apple offers no unsend hook to automation. That is exactly why the gate sits in front of the send, plus a 10-second undo grace after you approve, before anything actually goes out.
What if the AI writes something I'd never say?
Then you reject it, or edit it in place. Nothing sends without your approval unless you explicitly turned on auto-respond for that specific rule and contact scope — and even then rate limits, loop prevention, and the kill switch stay on top.
Does it handle green-bubble SMS too?
SMS relayed through your Mac is supported but auto-respond for it is off by default. Carrier texts deserve extra caution.
Is it really free?
Free and open source, Apache-2.0. It runs on your hardware against your own LLM endpoint or agent platform. No accounts, no hosted tier, nothing to upsell.
When can I use it?
It's in active development, building in the open. Watch the GitHub repo — the first public demo is the live message tail, and v1 ships when the adversarial gate test suite says it's safe.