Skip to content

gnufood/imsg

Repository files navigation

imsg connects to a paired iPhone using the standard Bluetooth MAP (Message Access Profile) and PBAP (Phone Book Access Profile) protocols. No iCloud credentials, no Apple Silicon, no macOS bridge.


Requirements

  • Linux with BlueZ (bluetoothd running)

πŸ“Ž That's it!

Install

curl -sSfL https://releases.gnu.foo/imsg/latest/install.sh | sh

Or via cargo:

cargo install imsg

Quick start

Note

Before you begin: your iPhone must be paired to this machine via bluetoothctl, and imsg needs the RFCOMM channel numbers iOS has assigned to its MAP and PBAP services β€” these are dynamic and change across iOS versions and re-pairings so they can't be hardcoded.

Run setup to discover them automatically from any paired device:

curl -sSfL "https://releases.gnu.foo/imsg/latest/setup-$(uname -m)" -o setup && chmod +x setup && ./setup

Feed the printed channel numbers into step 1 below.

1. Configure imsg

imsg config set-device A1:B2:C3:D4:E5:F6

If your channel numbers differ from the defaults (map=2, pbap=13), set them in ~/.config/imsg/imsg.toml:

[device]
address      = "A1:B2:C3:D4:E5:F6"
map_channel  = 2
pbap_channel = 13

2. Read and send messages

imsg list                                     # inbox
imsg list --unread                            # unread only
imsg list sent                                # sent folder
imsg list --from +15550001234 --limit 20      # filter by sender
imsg list --since 20260601T000000 --long      # since a date, show MAP handles
imsg get <handle>                             # full message body
imsg get <handle> --mark-read                 # fetch and mark as read
imsg send +15550001234 "hey"                  # send a message
imsg threads                                  # conversations grouped by contact

Commands

Command What it does
send <number> <message> Send a message
list [folder] List messages β€” inbox (default), sent, outbox, deleted; filter with --unread, --from, --since, --limit, --offset; add --long for MAP handles
get <handle> Fetch full message body; --mark-read to mark it read
delete <handle> Delete a message; --undelete to restore
contacts Pull contacts via PBAP; --list handles, --get <handle>, --lookup <number>, --limit/--page for pagination, --raw to skip E.164 normalisation
threads Group inbox and sent into per-contact conversations
watch Stream live MAP notification events
folders List the MAP folder tree on the device
config show Print the resolved configuration
config set-device <MAC> Persist the paired device address

Run imsg <command> --help for the full flag reference.


Hub / spoke (remote Bluetooth adapter)

If your iPhone is paired to a different machine β€” a Raspberry Pi, a server, a desktop in another room β€” you can run imsg from any machine on the internet without re-pairing.

On the machine with the paired phone:

imsg hub
# prints: node key: <KEY>

On your laptop (or anywhere else):

imsg spoke add <KEY>
imsg --hub list
imsg --hub send +15550001234 "hello from anywhere"
imsg --hub watch

The hub and spoke connect over QUIC via iroh β€” no port forwarding or VPN required.


Watch (live events)

imsg watch streams MAP notification events directly from the paired phone over RFCOMM. Add --hub to receive events forwarded from a remote hub instead.

For a scrollable TUI panel (local watch only), build with the tui feature:

cargo install imsg --features tui
imsg watch   # launches the ratatui panel automatically

Use ↑/↓ to scroll the event log, q / Esc / Ctrl+C to exit.


Configuration

Config is layered in ascending priority:

compiled-in defaults
/etc/imsg.toml
~/.config/imsg/imsg.toml
./imsg.toml
--config <path>
IMSG_ environment variables   (e.g. IMSG_DEVICE__MAP_CHANNEL=15)

Full key reference:

[device]
address      = "A1:B2:C3:D4:E5:F6"   # required; set via `imsg config set-device`
map_channel  = 2                       # RFCOMM channel for MAP MAS  [1–30], default 2
pbap_channel = 13                      # RFCOMM channel for PBAP PSE [1–30], default 13

[hub]
node_key = "..."                       # set via `imsg spoke add <KEY>`; absent until then

Building from source

git clone https://github.com/gnufood/imsg
cd imsg
cargo build --release                    # standard build
cargo build --release --features tui    # include ratatui watch panel

See CONTRIBUTING.md for the full development workflow.


License

MIT β€” see LICENSE.

About

iMessage client over Bluetooth MAP/PBAP

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Contributors