gabrielmeir53/iphonebridge

A native Linux desktop bridge for a paired iPhone over Bluetooth.

23

stars

28

commits

Python

primary language

May 20, 2026

updated

bluetooth
bluetooth-low-energy
bluez
dbus
gnome
imessage
iphone
linux
map-profile
pop-os
python
sms
systemd

README

πŸ“± iphonebridge

Your iPhone's messages, calls, notifications, and contacts β€” on your Linux desktop, over Bluetooth.

CI Release License: GPL v2 Python 3.10+ Platform: Linux

No Mac relay. No cloud service. No subscription. Just Bluetooth.


Microsoft's Phone Link gives Windows users their iPhone's texts and notifications on the desktop. There has never been a Linux equivalent β€” KDE Connect needs the Android/iOS app and only does Wi-Fi, ancs4linux does notifications only, Mac-relay bridges (BlueBubbles, AirMessage) need an actual Mac, and Beeper costs money.

iphonebridge is that missing piece. It's a small Python daemon that talks to a paired iPhone over standard Bluetooth profiles (MAP, PBAP, ANCS, HFP) and surfaces everything as native desktop notifications, a CLI, and a GTK4 desktop app.

✨ What it does

FeatureHowStatus
πŸ“¨ Incoming SMS + iMessage as desktop notificationsMAP MNS pushβœ…
πŸ“€ Send SMS + iMessage from the CLI or appMAP PushMessageβœ…
πŸ“‹ Verification codes auto-copied to the clipboardOTP detectionβœ…
πŸ‘€ Contact-name resolution (1000s of contacts)PBAP β†’ SQLite cacheβœ…
πŸ”” Every app's notifications β€” Slack, WhatsApp, Mail…ANCS over BLEβœ…
πŸ“ž Take & place phone calls β€” caller ID, answer/decline, dialHFP via oFonoβœ…
πŸ” Read-state sync β€” read on either device, syncs to bothMAP read-state writesβœ…
πŸ“œ Message history β€” incoming + your desktop repliessms-list / the appβœ…
πŸ–₯️ Desktop app β€” conversations, notification feed, call UIGTK4 / libadwaitaβœ…
βš™οΈ Runs unattended as a systemd user serviceβ€”βœ…

🀯 The iMessage surprise

Every prior writeup of Bluetooth on iOS says iMessage is invisible to a paired computer β€” that you must use a Mac relay to bridge blue-bubble messages.

That is not true on iOS 26.5. iphonebridge receives and sends iMessage through the standard MAP Bluetooth profile, with no Mac, no Apple ID login, nothing. iOS labels iMessage and SMS identically (Type: sms-gsm) and exposes both. Outgoing messages route as iMessage automatically when the recipient is iMessage-capable.

As far as we know, iphonebridge is the first free, open-source, Mac-free iMessage bridge for Linux. The empirical proof is in spike/RESULTS.md Β§6.

πŸ“‹ Requirements

MinimumTested with
OSLinux + GNOME, BlueZ 5.72+Pop!_OS 24.04
Bluetooth adapterIntel chipset (for ANCS)Intel AX-series
Python3.10+3.12
iPhoneiOS 16.5+iPhone 16 Pro Max, iOS 26.5
System packagesbluez, bluez-obexd, python3-dbus, python3-gi (+ ofono for calls, wl-clipboard for code auto-copy)β€”

⚠️ Adapter chipset matters for ANCS. Per-app notifications need a real BLE bond with the iPhone. Intel adapters do this reliably. Realtek adapters and every USB Bluetooth dongle tested so far do not β€” their firmware negotiates legacy keys that block the cross-transport key derivation iOS needs. SMS/iMessage/contacts (MAP/PBAP) work on any adapter; only ANCS is picky. See bmh129/ancs4linux's hardware notes.

πŸš€ Installation

1 Β· System packages

sudo apt install bluez bluez-obexd python3-dbus python3-gi python3-venv
# For the desktop app (iphonebridge-ui):
sudo apt install gir1.2-gtk-4.0 gir1.2-adw-1
# For auto-copying verification codes (Wayland):
sudo apt install wl-clipboard

2 Β· Clone & install

git clone https://github.com/gabrielmeir53/iphonebridge.git
cd iphonebridge

# A venv that inherits the system PyGObject + dbus-python.
# (Never install those two from PyPI β€” the builds are notoriously fragile.)
python3 -m venv --system-site-packages .venv
source .venv/bin/activate
pip install -e .

# Put `iphonebridge` (CLI + daemon) and `iphonebridge-ui` (app) on your PATH
mkdir -p ~/.local/bin
ln -sf "$(pwd)/.venv/bin/iphonebridge" ~/.local/bin/iphonebridge
ln -sf "$(pwd)/.venv/bin/iphonebridge-ui" ~/.local/bin/iphonebridge-ui

3 Β· Pair your iPhone

Pair normally β€” GNOME Settings β†’ Bluetooth, or bluetoothctl. Then run the wizard:

iphonebridge pair-setup

It finds your iPhone among paired devices, writes ~/.config/iphonebridge/local.env, and prints the iPhone-side steps.

4 Β· Install the daemon as a service

mkdir -p ~/.config/systemd/user
cp systemd/iphonebridge.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now iphonebridge

5 Β· iPhone-side toggles

On the iPhone: Settings β†’ Bluetooth β†’ tap the β“˜ next to your computer β†’ enable

  • Show Message Notifications β€” gates SMS/iMessage (MAP)
  • Sync Contacts β€” gates contacts (PBAP)
  • Show System Notifications β€” gates per-app notifications (ANCS)

These toggles only appear once the daemon has run at least once (it sets the adapter's Bluetooth class + advertises correctly). If you don't see them, re-run iphonebridge pair-setup and restart the daemon.

6 Β· (Optional) Enable per-app notifications β€” ANCS

ANCS needs a true BLE bond, which only forms during a fresh pairing while the adapter is correctly configured. One-time setup:

# Install the privileged helper (writes one specific BlueZ setting)
sudo bash systemd/install-ancs-sudoers.sh

# Apply it and re-pair
iphonebridge ancs-enable

Then forget + re-pair the iPhone one more time (the wizard walks you through it). After the fresh pair, iOS performs cross-transport key derivation and the BLE bond sticks β€” ANCS notifications start flowing automatically. You only do this once.

7 Β· (Optional) Enable phone calls β€” HFP

To take and place calls on the laptop, iphonebridge uses oFono for HFP call control and PipeWire's oFono backend for the call audio.

# Install oFono
sudo apt install ofono
sudo systemctl enable --now ofono

# Write the WirePlumber config + print the remaining steps
iphonebridge hfp-enable

hfp-enable writes ~/.config/wireplumber/wireplumber.conf.d/51-bluez-hfp-hf.conf (routing HFP through oFono) and restarts WirePlumber. Follow its printed steps β€” restart oFono after WirePlumber so it can claim the HFP profile, reconnect the iPhone, restart the daemon β€” and incoming calls will pop up with Answer / Decline buttons. Place calls with iphonebridge call.

(Optional) Persist the Bluetooth class across reboots
sudo bash systemd/install-cod-sudoers.sh

Lets the daemon set the adapter's Class-of-Device on every start without a password prompt. Without it you'd occasionally need to re-run setup after a reboot.

πŸ–₯️ Desktop app

iphonebridge-ui is a GTK4 / libadwaita app β€” a separate process from the daemon, talking to it over D-Bus, so you can open and close it freely while the daemon keeps running in the background. Four tabs:

  • Messages β€” SMS & iMessage conversations grouped by contact. Read history and reply from a compose box; the replies you send are saved into the thread.
  • Notifications β€” a live feed of every app's notifications (Slack, Mail, WhatsApp…), mirrored from the iPhone over ANCS.
  • Calls β€” a dialer to place calls, plus Answer / Hang-up controls for active ones; an incoming call raises this tab automatically.
  • Setup β€” daemon health, contact and message counts, and the iPhone-toggle checklist.
iphonebridge-ui

πŸ’» CLI

The iphonebridge command does everything the app does, plus setup and diagnostics:

CommandWhat it does
iphonebridge runRun the daemon in the foreground (the systemd service uses this)
iphonebridge doctorCheck prerequisites β€” config, adapter class, obexd, state dir
iphonebridge pair-setupFirst-run wizard β€” find the paired iPhone, write config
iphonebridge sms-listRecent messages β€” -n N, --from <contact>, --source iphone|local
iphonebridge sms-send <to> <body>Send an SMS / iMessage (<to> = number or contact name)
iphonebridge call <to>Place a phone call over HFP
iphonebridge callsList active calls
iphonebridge hangupHang up the active call(s)
iphonebridge contacts-syncForce a contacts refresh (otherwise automatic every 24 h)
iphonebridge ancs-enableOne-time setup for per-app notifications (ANCS)
iphonebridge hfp-enableOne-time setup for phone calls (HFP)
iphonebridge versionPrint the version
# Recent messages β€” live from the iPhone, or from the daemon's own log
iphonebridge sms-list -n 20
iphonebridge sms-list --from Maddie
iphonebridge sms-list --source local

# Send β€” recipient can be a phone number OR a contact name
iphonebridge sms-send "+15551234567" "on my way"
iphonebridge sms-send Maddie "running late"

# Calls β€” needs HFP set up (install step 7)
iphonebridge call Maddie
iphonebridge calls
iphonebridge hangup

# Watch the daemon live Β· control the service
journalctl --user -u iphonebridge -f
systemctl --user {start,stop,restart} iphonebridge

πŸ”” How it behaves

  • Incoming messages appear as persistent notifications β€” they stay until you dismiss them on the desktop or read the message on your iPhone. Read-state syncs both ways.
  • Verification codes β€” when a text carries a one-time / 2FA code, iphonebridge detects it and copies it to your clipboard automatically; press Ctrl+V to paste. Detection needs both a verification keyword and a 4–8 digit number, so ordinary texts don't trigger it.
  • Incoming calls raise a notification with Answer / Decline buttons that act on the call directly.
  • Sent messages β€” replies you send from the desktop are recorded into conversation history, so a thread shows both sides.

πŸ—οΈ How it works

              iPhone  (paired: BR/EDR + BLE)
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ MAP      β”‚ PBAP     β”‚ ANCS      β”‚ HFP      β”‚
   β”‚ (OBEX)   β”‚ (OBEX)   β”‚ (BLE GATT)β”‚ (oFono)  β”‚
   β–Ό          β–Ό          β–Ό           β–Ό
 messages   contacts   app notifs   calls
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
           iphonebridge daemon
         (Python Β· GLib Β· D-Bus)
                     β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β–Ό            β–Ό            β–Ό
  notifications   JSONL log   D-Bus service
  + clipboard     (history)   (CLI Β· GTK app)
  • MAP (Message Access Profile) β€” read SMS/iMessage, get real-time push of new ones, and send.
  • PBAP (Phone Book Access Profile) β€” pull the iPhone's contacts so messages show names, not numbers.
  • ANCS (Apple Notification Center Service) β€” every app's notifications, over a BLE GATT link.
  • HFP (Hands-Free Profile) β€” take and place calls; oFono speaks the HFP protocol, PipeWire's oFono backend carries the call audio to the laptop's mic/speakers.
  • One daemon, pluggable sinks (desktop popups, verification-code clipboard copy, append-only JSONL log), and a D-Bus service so the CLI and the GTK app can send messages, control calls, and subscribe to a live event feed.

Design rationale and the empirical Bluetooth findings that shaped it are in spike/RESULTS.md.

🩺 Troubleshooting

Messages stopped arriving

The iPhone times out OBEX sessions. Restart the daemon:

systemctl --user restart iphonebridge

If the iOS toggles vanished from Bluetooth settings, forget + re-pair the iPhone.

Forbidden errors in the log

An iPhone toggle is off. Check Settings β†’ Bluetooth β†’ β“˜ β†’ Show Message Notifications / Sync Contacts / Show System Notifications.

ANCS notifications never arrive

ANCS needs a BLE bond, which needs a fresh pair done with the adapter correctly set up. Run iphonebridge ancs-enable, then forget + re-pair the iPhone. Also confirm your adapter is Intel β€” Realtek and USB dongles can't do it.

Calls don't connect, or there's no call audio

HFP needs oFono, and oFono must start after WirePlumber so it can claim the HFP profile. Run iphonebridge hfp-enable, then sudo systemctl restart ofono, reconnect the iPhone, and restart the daemon. If journalctl -u ofono shows RegisterProfile … UUID already registered, the start order is wrong β€” restart oFono again after WirePlumber is up.

Verification codes aren't being copied

Install a clipboard tool: sudo apt install wl-clipboard (Wayland) or xclip (X11). The daemon log shows no clipboard tool worked when none is present.

iphonebridge: command not found

The CLI lives in the venv. Either source .venv/bin/activate, or create the ~/.local/bin symlink from install step 2.

🚧 Limitations

These are Apple's Bluetooth-stack limits, not bugs:

  • No iMessage attachments, reactions, read receipts, or typing indicators (MAP doesn't carry them).
  • No group iMessage / MMS / RCS β€” MAP is 1-to-1 only.
  • Messages composed on the iPhone itself don't sync β€” iOS exposes only your inbox over MAP, never the sent folder. Replies you send from iphonebridge are recorded into conversation history; texts you type on the phone aren't visible to any Bluetooth bridge.
  • HFP calls are 1-to-1 voice only β€” no conference calls, no FaceTime (HFP carries neither).
  • Notification bodies are subject to the iPhone's "Show Previews" setting.

πŸ—ΊοΈ Roadmap

  • Flatpak for the UI β€” a draft manifest lives in packaging/flatpak/; it still needs a build pass.

See BACKLOG.md.

πŸ™ Credits

iphonebridge stands on the shoulders of two prior projects, both GPL-2.0:

  • bmh129/ancs4linux β€” an actively-maintained 2026 fork whose empirical work on BR/EDR-vs-BLE coexistence, the LastUsedBearer=le unlock, and adapter compatibility made iphonebridge's ANCS support possible. The ANCS wire-format code in src/iphonebridge/ancs/ is derived from their observer/ancs/ modules.
  • pzmarzly/ancs4linux β€” the original 2022 reference implementation of ANCS on Linux.

πŸ“„ License

GPL-2.0-or-later Β· Β© 2026 Gabe Shatunovsky

Contributors

gabrielmeir53

28 commits

gabrielmeir53/iphonebridge

A native Linux desktop bridge for a paired iPhone over Bluetooth.

23

stars

28

commits

Python

primary language

May 20, 2026

updated

bluetooth
bluetooth-low-energy
bluez
dbus
gnome
imessage
iphone
linux
map-profile
pop-os
python
sms
systemd

README

πŸ“± iphonebridge

Your iPhone's messages, calls, notifications, and contacts β€” on your Linux desktop, over Bluetooth.

CI Release License: GPL v2 Python 3.10+ Platform: Linux

No Mac relay. No cloud service. No subscription. Just Bluetooth.


Microsoft's Phone Link gives Windows users their iPhone's texts and notifications on the desktop. There has never been a Linux equivalent β€” KDE Connect needs the Android/iOS app and only does Wi-Fi, ancs4linux does notifications only, Mac-relay bridges (BlueBubbles, AirMessage) need an actual Mac, and Beeper costs money.

iphonebridge is that missing piece. It's a small Python daemon that talks to a paired iPhone over standard Bluetooth profiles (MAP, PBAP, ANCS, HFP) and surfaces everything as native desktop notifications, a CLI, and a GTK4 desktop app.

✨ What it does

FeatureHowStatus
πŸ“¨ Incoming SMS + iMessage as desktop notificationsMAP MNS pushβœ…
πŸ“€ Send SMS + iMessage from the CLI or appMAP PushMessageβœ…
πŸ“‹ Verification codes auto-copied to the clipboardOTP detectionβœ…
πŸ‘€ Contact-name resolution (1000s of contacts)PBAP β†’ SQLite cacheβœ…
πŸ”” Every app's notifications β€” Slack, WhatsApp, Mail…ANCS over BLEβœ…
πŸ“ž Take & place phone calls β€” caller ID, answer/decline, dialHFP via oFonoβœ…
πŸ” Read-state sync β€” read on either device, syncs to bothMAP read-state writesβœ…
πŸ“œ Message history β€” incoming + your desktop repliessms-list / the appβœ…
πŸ–₯️ Desktop app β€” conversations, notification feed, call UIGTK4 / libadwaitaβœ…
βš™οΈ Runs unattended as a systemd user serviceβ€”βœ…

🀯 The iMessage surprise

Every prior writeup of Bluetooth on iOS says iMessage is invisible to a paired computer β€” that you must use a Mac relay to bridge blue-bubble messages.

That is not true on iOS 26.5. iphonebridge receives and sends iMessage through the standard MAP Bluetooth profile, with no Mac, no Apple ID login, nothing. iOS labels iMessage and SMS identically (Type: sms-gsm) and exposes both. Outgoing messages route as iMessage automatically when the recipient is iMessage-capable.

As far as we know, iphonebridge is the first free, open-source, Mac-free iMessage bridge for Linux. The empirical proof is in spike/RESULTS.md Β§6.

πŸ“‹ Requirements

MinimumTested with
OSLinux + GNOME, BlueZ 5.72+Pop!_OS 24.04
Bluetooth adapterIntel chipset (for ANCS)Intel AX-series
Python3.10+3.12
iPhoneiOS 16.5+iPhone 16 Pro Max, iOS 26.5
System packagesbluez, bluez-obexd, python3-dbus, python3-gi (+ ofono for calls, wl-clipboard for code auto-copy)β€”

⚠️ Adapter chipset matters for ANCS. Per-app notifications need a real BLE bond with the iPhone. Intel adapters do this reliably. Realtek adapters and every USB Bluetooth dongle tested so far do not β€” their firmware negotiates legacy keys that block the cross-transport key derivation iOS needs. SMS/iMessage/contacts (MAP/PBAP) work on any adapter; only ANCS is picky. See bmh129/ancs4linux's hardware notes.

πŸš€ Installation

1 Β· System packages

sudo apt install bluez bluez-obexd python3-dbus python3-gi python3-venv
# For the desktop app (iphonebridge-ui):
sudo apt install gir1.2-gtk-4.0 gir1.2-adw-1
# For auto-copying verification codes (Wayland):
sudo apt install wl-clipboard

2 Β· Clone & install

git clone https://github.com/gabrielmeir53/iphonebridge.git
cd iphonebridge

# A venv that inherits the system PyGObject + dbus-python.
# (Never install those two from PyPI β€” the builds are notoriously fragile.)
python3 -m venv --system-site-packages .venv
source .venv/bin/activate
pip install -e .

# Put `iphonebridge` (CLI + daemon) and `iphonebridge-ui` (app) on your PATH
mkdir -p ~/.local/bin
ln -sf "$(pwd)/.venv/bin/iphonebridge" ~/.local/bin/iphonebridge
ln -sf "$(pwd)/.venv/bin/iphonebridge-ui" ~/.local/bin/iphonebridge-ui

3 Β· Pair your iPhone

Pair normally β€” GNOME Settings β†’ Bluetooth, or bluetoothctl. Then run the wizard:

iphonebridge pair-setup

It finds your iPhone among paired devices, writes ~/.config/iphonebridge/local.env, and prints the iPhone-side steps.

4 Β· Install the daemon as a service

mkdir -p ~/.config/systemd/user
cp systemd/iphonebridge.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now iphonebridge

5 Β· iPhone-side toggles

On the iPhone: Settings β†’ Bluetooth β†’ tap the β“˜ next to your computer β†’ enable

  • Show Message Notifications β€” gates SMS/iMessage (MAP)
  • Sync Contacts β€” gates contacts (PBAP)
  • Show System Notifications β€” gates per-app notifications (ANCS)

These toggles only appear once the daemon has run at least once (it sets the adapter's Bluetooth class + advertises correctly). If you don't see them, re-run iphonebridge pair-setup and restart the daemon.

6 Β· (Optional) Enable per-app notifications β€” ANCS

ANCS needs a true BLE bond, which only forms during a fresh pairing while the adapter is correctly configured. One-time setup:

# Install the privileged helper (writes one specific BlueZ setting)
sudo bash systemd/install-ancs-sudoers.sh

# Apply it and re-pair
iphonebridge ancs-enable

Then forget + re-pair the iPhone one more time (the wizard walks you through it). After the fresh pair, iOS performs cross-transport key derivation and the BLE bond sticks β€” ANCS notifications start flowing automatically. You only do this once.

7 Β· (Optional) Enable phone calls β€” HFP

To take and place calls on the laptop, iphonebridge uses oFono for HFP call control and PipeWire's oFono backend for the call audio.

# Install oFono
sudo apt install ofono
sudo systemctl enable --now ofono

# Write the WirePlumber config + print the remaining steps
iphonebridge hfp-enable

hfp-enable writes ~/.config/wireplumber/wireplumber.conf.d/51-bluez-hfp-hf.conf (routing HFP through oFono) and restarts WirePlumber. Follow its printed steps β€” restart oFono after WirePlumber so it can claim the HFP profile, reconnect the iPhone, restart the daemon β€” and incoming calls will pop up with Answer / Decline buttons. Place calls with iphonebridge call.

(Optional) Persist the Bluetooth class across reboots
sudo bash systemd/install-cod-sudoers.sh

Lets the daemon set the adapter's Class-of-Device on every start without a password prompt. Without it you'd occasionally need to re-run setup after a reboot.

πŸ–₯️ Desktop app

iphonebridge-ui is a GTK4 / libadwaita app β€” a separate process from the daemon, talking to it over D-Bus, so you can open and close it freely while the daemon keeps running in the background. Four tabs:

  • Messages β€” SMS & iMessage conversations grouped by contact. Read history and reply from a compose box; the replies you send are saved into the thread.
  • Notifications β€” a live feed of every app's notifications (Slack, Mail, WhatsApp…), mirrored from the iPhone over ANCS.
  • Calls β€” a dialer to place calls, plus Answer / Hang-up controls for active ones; an incoming call raises this tab automatically.
  • Setup β€” daemon health, contact and message counts, and the iPhone-toggle checklist.
iphonebridge-ui

πŸ’» CLI

The iphonebridge command does everything the app does, plus setup and diagnostics:

CommandWhat it does
iphonebridge runRun the daemon in the foreground (the systemd service uses this)
iphonebridge doctorCheck prerequisites β€” config, adapter class, obexd, state dir
iphonebridge pair-setupFirst-run wizard β€” find the paired iPhone, write config
iphonebridge sms-listRecent messages β€” -n N, --from <contact>, --source iphone|local
iphonebridge sms-send <to> <body>Send an SMS / iMessage (<to> = number or contact name)
iphonebridge call <to>Place a phone call over HFP
iphonebridge callsList active calls
iphonebridge hangupHang up the active call(s)
iphonebridge contacts-syncForce a contacts refresh (otherwise automatic every 24 h)
iphonebridge ancs-enableOne-time setup for per-app notifications (ANCS)
iphonebridge hfp-enableOne-time setup for phone calls (HFP)
iphonebridge versionPrint the version
# Recent messages β€” live from the iPhone, or from the daemon's own log
iphonebridge sms-list -n 20
iphonebridge sms-list --from Maddie
iphonebridge sms-list --source local

# Send β€” recipient can be a phone number OR a contact name
iphonebridge sms-send "+15551234567" "on my way"
iphonebridge sms-send Maddie "running late"

# Calls β€” needs HFP set up (install step 7)
iphonebridge call Maddie
iphonebridge calls
iphonebridge hangup

# Watch the daemon live Β· control the service
journalctl --user -u iphonebridge -f
systemctl --user {start,stop,restart} iphonebridge

πŸ”” How it behaves

  • Incoming messages appear as persistent notifications β€” they stay until you dismiss them on the desktop or read the message on your iPhone. Read-state syncs both ways.
  • Verification codes β€” when a text carries a one-time / 2FA code, iphonebridge detects it and copies it to your clipboard automatically; press Ctrl+V to paste. Detection needs both a verification keyword and a 4–8 digit number, so ordinary texts don't trigger it.
  • Incoming calls raise a notification with Answer / Decline buttons that act on the call directly.
  • Sent messages β€” replies you send from the desktop are recorded into conversation history, so a thread shows both sides.

πŸ—οΈ How it works

              iPhone  (paired: BR/EDR + BLE)
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ MAP      β”‚ PBAP     β”‚ ANCS      β”‚ HFP      β”‚
   β”‚ (OBEX)   β”‚ (OBEX)   β”‚ (BLE GATT)β”‚ (oFono)  β”‚
   β–Ό          β–Ό          β–Ό           β–Ό
 messages   contacts   app notifs   calls
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
           iphonebridge daemon
         (Python Β· GLib Β· D-Bus)
                     β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β–Ό            β–Ό            β–Ό
  notifications   JSONL log   D-Bus service
  + clipboard     (history)   (CLI Β· GTK app)
  • MAP (Message Access Profile) β€” read SMS/iMessage, get real-time push of new ones, and send.
  • PBAP (Phone Book Access Profile) β€” pull the iPhone's contacts so messages show names, not numbers.
  • ANCS (Apple Notification Center Service) β€” every app's notifications, over a BLE GATT link.
  • HFP (Hands-Free Profile) β€” take and place calls; oFono speaks the HFP protocol, PipeWire's oFono backend carries the call audio to the laptop's mic/speakers.
  • One daemon, pluggable sinks (desktop popups, verification-code clipboard copy, append-only JSONL log), and a D-Bus service so the CLI and the GTK app can send messages, control calls, and subscribe to a live event feed.

Design rationale and the empirical Bluetooth findings that shaped it are in spike/RESULTS.md.

🩺 Troubleshooting

Messages stopped arriving

The iPhone times out OBEX sessions. Restart the daemon:

systemctl --user restart iphonebridge

If the iOS toggles vanished from Bluetooth settings, forget + re-pair the iPhone.

Forbidden errors in the log

An iPhone toggle is off. Check Settings β†’ Bluetooth β†’ β“˜ β†’ Show Message Notifications / Sync Contacts / Show System Notifications.

ANCS notifications never arrive

ANCS needs a BLE bond, which needs a fresh pair done with the adapter correctly set up. Run iphonebridge ancs-enable, then forget + re-pair the iPhone. Also confirm your adapter is Intel β€” Realtek and USB dongles can't do it.

Calls don't connect, or there's no call audio

HFP needs oFono, and oFono must start after WirePlumber so it can claim the HFP profile. Run iphonebridge hfp-enable, then sudo systemctl restart ofono, reconnect the iPhone, and restart the daemon. If journalctl -u ofono shows RegisterProfile … UUID already registered, the start order is wrong β€” restart oFono again after WirePlumber is up.

Verification codes aren't being copied

Install a clipboard tool: sudo apt install wl-clipboard (Wayland) or xclip (X11). The daemon log shows no clipboard tool worked when none is present.

iphonebridge: command not found

The CLI lives in the venv. Either source .venv/bin/activate, or create the ~/.local/bin symlink from install step 2.

🚧 Limitations

These are Apple's Bluetooth-stack limits, not bugs:

  • No iMessage attachments, reactions, read receipts, or typing indicators (MAP doesn't carry them).
  • No group iMessage / MMS / RCS β€” MAP is 1-to-1 only.
  • Messages composed on the iPhone itself don't sync β€” iOS exposes only your inbox over MAP, never the sent folder. Replies you send from iphonebridge are recorded into conversation history; texts you type on the phone aren't visible to any Bluetooth bridge.
  • HFP calls are 1-to-1 voice only β€” no conference calls, no FaceTime (HFP carries neither).
  • Notification bodies are subject to the iPhone's "Show Previews" setting.

πŸ—ΊοΈ Roadmap

  • Flatpak for the UI β€” a draft manifest lives in packaging/flatpak/; it still needs a build pass.

See BACKLOG.md.

πŸ™ Credits

iphonebridge stands on the shoulders of two prior projects, both GPL-2.0:

  • bmh129/ancs4linux β€” an actively-maintained 2026 fork whose empirical work on BR/EDR-vs-BLE coexistence, the LastUsedBearer=le unlock, and adapter compatibility made iphonebridge's ANCS support possible. The ANCS wire-format code in src/iphonebridge/ancs/ is derived from their observer/ancs/ modules.
  • pzmarzly/ancs4linux β€” the original 2022 reference implementation of ANCS on Linux.

πŸ“„ License

GPL-2.0-or-later Β· Β© 2026 Gabe Shatunovsky

See what people are saying

Contributors

gabrielmeir53

28 commits

Languages

Python

96.4%

Shell

3.6%