iMessage on Omarchy. BlueBubbles runs on a Mac signed into iMessage.
imsg-sync runs on Linux and talks to that server. The bar plugin talks
only to the local daemon over a Unix socket.
- Install BlueBubbles Server. Right-click the
.dmgand choose Open. - Grant Full Disk Access to BlueBubbles in System Settings, Privacy and Security.
- Set a server password in BlueBubbles.
- If you use Tailscale, leave the BlueBubbles proxy off.
- Keep the Mac awake. The default listen port is 1234.
HTTP on the Tailscale IP is enough:
http://<mac-tailscale-ip>:1234For HTTPS on MagicDNS, on the Mac run:
tailscale serve --bg 1234The URL is then https://<machine>.<tailnet>.ts.net. If Serve uses another
HTTPS port, put that port on the URL.
Do not install bluebubbles-bin on Linux.
GitHub Releases v0.1.0 is the old Mac pairing build. Build imsg from this repo.
git clone https://github.com/PanicIsReal/imsg.git
cd imsg
cargo install --path cli --locked
imsg install --plugin plugin/imsg install writes ~/.config/systemd/user/imsg-sync.service with the
real binary path, copies the plugin, and starts the daemon.
To take the published plugin instead of plugin/, after cargo install:
omarchy plugin add https://github.com/PanicIsReal/omarchy-imessage.git --enable
imsg installomarchy plugin add requires manifest.json at the clone root. Point it at
PanicIsReal/omarchy-imessage, not this monorepo.
Open the iMessage panel. The first run is Settings. Enter the BlueBubbles URL
and password. Save. The password is stored in the system keyring as service
imsg-sync and username bluebubbles. It is never written to config.toml.
The CLI writes the same store:
imsg setup connect --url http://<mac-tailscale-ip>:1234 --password <password>Prefer the panel form so the password does not land in shell history. Reconnect from Settings retries the Mac without restarting the daemon.
New iMessages default to a 2s REST poll. Settings can switch to a webhook doorbell. The POST is only a poke. imsg-sync then pulls the real message over REST with the password. A 30-second REST recovery sync remains active while the webhook is on. It checks the latest 200 messages; it is not a complete historical backfill.
Settings walks you through three steps. Turn on the webhook, publish with Tailscale, then register with BlueBubbles. Register is the step that is easy to skip. Incoming pokes do not start until it is done.
The Tailscale step opens the same floating Omarchy window as install. It runs
tailscale serve for the port in the form. Not Funnel. Remove serve shows
when Serve is active and runs tailscale serve reset. To publish by hand:
tailscale serve --bg localhost:18792Restrict the Linux Serve ACL to your Mac. Treat the webhook URL token like a password.
Click the bar icon, or Super+Ctrl+I, to open the panel. j/k move conversations. l or Enter focuses the composer. Escape blurs. Escape again closes. Enter sends. a or Photo attaches an image. A send shows as Sending until the Mac accepts it.
Add the keybind in ~/.config/hypr/bindings.lua:
o.bind("SUPER + CTRL + I", "iMessage", "omarchy-shell shell toggle io.github.panic.imessage")Move the widget with:
omarchy bar move io.github.panic.imessage --section rightomarchy plugin remove io.github.panic.imessage
imsg uninstallimsg uninstall --purge also deletes the local cache and config. It does not
stop BlueBubbles on the Mac.
| Path | What |
|---|---|
sync/ |
Linux daemon. BlueBubbles REST, cache, Unix socket |
plugin/ |
Omarchy QML plugin. Source of truth |
cli/ |
imsg binary |
bridge/ |
Leftover Mac daemon. Do not add features |
setup/ |
Leftover pairing wizard |
tui/ |
Leftover Mac setup TUI |
See AGENTS.md for agent rules. After you change plugin/, run
./scripts/publish-plugin.sh. CI does that on main when
PLUGIN_SYNC_SSH_KEY is set.