Remote iMessage gateway for macOS
Project description
iuselinux
A web interface for reading and sending iMessages on macOS.
Quick Start
Run directly with uvx (no installation required):
uvx iuselinux@latest
Then open http://127.0.0.1:1960 in your browser.
Options:
uvx iuselinux@latest --host 0.0.0.0 --port 8000
uvx iuselinux@latest --api-token SECRET
Installation
For persistent installation (adds iuselinux to your PATH):
uv tool install iuselinux
For development:
uv pip install -e .
uv sync --group dev
Initial Setup
Important: iUseLinux needs Full Disk Access permission to read the iMessage database.
If running from terminal (e.g., uvx iuselinux):
- Open System Settings > Privacy & Security > Full Disk Access
- Click the + button and add your terminal app (Terminal, iTerm2, VS Code, etc.)
- Restart your terminal for the permission to take effect
If running as a service (e.g., uvx iuselinux service install):
See Full Disk Access for Service Mode below.
Without this permission, iUseLinux will show an error page explaining how to fix it.
Run as Service (Recommended)
Install as a macOS LaunchAgent that starts on login and auto-restarts:
# Basic install (localhost only)
uv tool install iuselinux && uvx iuselinux service install
# With custom port
uvx iuselinux service install --port 8000
# With Tailscale remote access
uvx iuselinux service install --tailscale
# Skip the menu bar tray icon
uvx iuselinux service install --no-tray
Manage the service:
# Check status
uvx iuselinux service status
# Upgrade and restart the service
iuselinux service upgrade
# Uninstall
uvx iuselinux service uninstall
Full Disk Access for Service Mode
When running as a service, you need to grant Full Disk Access to the iUseLinux launcher app (not your terminal):
- Open System Settings > Privacy & Security > Full Disk Access
- Click the + button
- Press Cmd+Shift+G and enter:
~/Library/Application Support/iuselinux/ - Select iUseLinux Service.app and click Open
- Restart the service:
uvx iuselinux@latest service uninstall && uvx iuselinux@latest service install
The service install creates this app bundle automatically. It's a lightweight wrapper that allows macOS to grant Full Disk Access to the background service.
Menu Bar Tray
By default, a menu bar icon is installed with the service. Manage it separately:
uvx iuselinux tray status
uvx iuselinux tray start
uvx iuselinux tray stop
Features
- View all conversations and messages
- Send messages and attachments via the web UI
- Real-time updates via WebSocket
- Search messages
- Attachment support (images, videos with HEIC→WebP and MOV→MP4 conversion)
- Contact name and photo resolution
- Menu bar tray icon for quick access
- Light/dark/auto theme
- Browser notifications with custom sounds
- Custom CSS theming
- API token authentication (optional)
- Prevents Mac from sleeping while running (configurable)
- Auto-updates
Local Network Access
Bind to all interfaces for LAN access:
uvx iuselinux --host 0.0.0.0
Access from any device on your network at http://your-mac-ip:1960
Find your Mac's IP:
ipconfig getifaddr en0
Warning: This exposes iuselinux to everyone on your local network. Use --api-token SECRET for basic protection.
Remote Access via SSH Tunnel
The API binds to 127.0.0.1 by default for security. To access it remotely, use an SSH tunnel.
From your remote machine
ssh -L 1960:localhost:1960 user@your-mac-ip
This forwards your remote machine's localhost:1960 to the Mac's localhost:1960.
Now access the API at http://localhost:1960 from your remote machine.
Persistent tunnel with autossh
Install autossh for auto-reconnecting tunnels:
# On Linux
sudo apt install autossh
# On Mac (remote machine)
brew install autossh
Run with auto-reconnect:
autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" \
-L 1960:localhost:1960 user@your-mac-ip
SSH config shortcut
Add to ~/.ssh/config on your remote machine:
Host iuselinux
HostName your-mac-ip
User your-username
LocalForward 1960 localhost:1960
ServerAliveInterval 30
ServerAliveCountMax 3
Then connect with just:
ssh iuselinux
Troubleshooting
Port already in use: Another process is using port 1960. Either stop it or use a different port:
ssh -L 9000:localhost:1960 user@your-mac-ip
# Then access at http://localhost:9000
Connection refused: Ensure the iUseLinux server is running on the Mac.
Permission denied: Check your SSH key is added or use password auth.
Remote Access via Tailscale
Tailscale creates a secure mesh VPN that's easier to set up than traditional SSH tunnels. Your Mac acts as the host and other devices on your tailnet can connect to it.
Setup
-
Install Tailscale on both machines:
- Mac (server): Download from tailscale.com or
brew install tailscale - Remote machine: See download page for your OS
- Mac (server): Download from tailscale.com or
-
Sign in on both machines:
tailscale up -
Find your Mac's Tailscale IP or hostname:
tailscale ip -4 # Example: 100.64.0.1 tailscale status # Shows your machine name, e.g., "macbook" -> access via macbook.tailnet-name.ts.net
Option 1: Bind to Tailscale Interface Only (Recommended)
Bind the server specifically to your Tailscale IP so only tailnet devices can connect:
# Get your Tailscale IP
tailscale ip -4
# Example: 100.64.0.1
# On Mac - bind to Tailscale interface only
iuselinux --host 100.64.0.1
Then access from any device on your tailnet:
http://100.64.0.1:1960orhttp://your-mac.tailnet-name.ts.net:1960
Security note: Binding to the Tailscale IP (100.x.x.x) ensures only devices on your tailnet can connect. This is much safer than --host 0.0.0.0 which exposes the server on all interfaces (local network, etc.).
For additional security, set an API token:
iuselinux --host 100.64.0.1 --api-token YOUR_SECRET_TOKEN
Option 2: Tailscale Serve (HTTPS with Magic DNS) - Recommended
Use the built-in Tailscale integration for automatic HTTPS and lifecycle management:
# Install as a service with Tailscale enabled
iuselinux service install --tailscale
This gives you:
- HTTPS URL like
https://your-mac.tailnet-name.ts.net - Automatic TLS certificates
- No need to remember port numbers
- Tailscale serve lifecycle tied to iuselinux - it starts and stops with the service
Access from any device on your tailnet:
https://your-mac.tailnet-name.ts.net
To check status:
iuselinux service status
To uninstall (this also disables Tailscale serve):
iuselinux service uninstall
Important: Tailscale Lifecycle Management
When you use --tailscale, iuselinux manages the Tailscale serve lifecycle:
- Tailscale serve starts when iuselinux starts
- Tailscale serve stops when iuselinux stops (graceful shutdown, crash, or uninstall)
- Uninstalling clears Tailscale config - no dangling ports left exposed
This is a security feature. If iuselinux stops for any reason, Tailscale won't continue exposing the port to your tailnet.
Manual Tailscale Control
You can also enable/disable Tailscale serve via the web UI settings, or via API:
# Enable (also saves config for restarts)
curl -X POST "http://localhost:1960/service/tailscale/enable?port=1960"
# Disable (also clears config)
curl -X POST "http://localhost:1960/service/tailscale/disable"
Legacy Manual Setup (Not Recommended)
If you prefer to manage Tailscale serve separately (not recommended as it decouples lifecycles):
# Start iuselinux without --tailscale
iuselinux service install
# Manually run tailscale serve with --bg for persistence
tailscale serve --bg 1960
Warning: With this approach, if you uninstall iuselinux, Tailscale will continue serving port 1960. You must manually run tailscale serve off to clean up.
Option 3: SSH Tunnel over Tailscale (Overkill)
If you're paranoid and want double encryption (Tailscale already encrypts everything):
# On Mac - start server on localhost only
iuselinux
# On remote machine - create tunnel over Tailscale
ssh -L 1960:localhost:1960 user@100.64.0.1
Then access at http://localhost:1960 on the remote machine.
Security Notes
- Tailscale traffic is encrypted end-to-end
- Only devices in your tailnet can connect
- Consider enabling Tailscale ACLs for fine-grained access control
- The
tailscale serveoption provides HTTPS automatically - Always use
--api-tokenwhen binding to 0.0.0.0 for an extra layer of security
Remote Access via WireGuard
For self-hosted VPN, use WireGuard.
Setup
-
Install WireGuard on both machines:
- Mac:
brew install wireguard-tools - Linux:
sudo apt install wireguard
- Mac:
-
Generate keys on both machines:
wg genkey | tee privatekey | wg pubkey > publickey
-
Create
/etc/wireguard/wg0.confon your Mac:[Interface] PrivateKey = <mac-private-key> Address = 10.0.0.1/24 ListenPort = 51820 [Peer] PublicKey = <remote-public-key> AllowedIPs = 10.0.0.2/32
-
Create
/etc/wireguard/wg0.confon remote machine:[Interface] PrivateKey = <remote-private-key> Address = 10.0.0.2/24 [Peer] PublicKey = <mac-public-key> Endpoint = your-mac-public-ip:51820 AllowedIPs = 10.0.0.1/32 PersistentKeepalive = 25
-
Start WireGuard:
sudo wg-quick up wg0
-
Access the gateway via SSH tunnel over WireGuard:
ssh -L 1960:localhost:1960 user@10.0.0.1
Then open
http://localhost:1960
Port Forwarding
If your Mac is behind a router, forward UDP port 51820 to your Mac's local IP.
API Endpoints
Messages & Chats
GET /chats- List conversations (supportslimit)GET /messages- Get messages (chat_id,limit,after_rowid,before_rowid)GET /search- Search messages (q,chat_id,limit,offset)GET /poll- Poll for new messages (after_rowid,chat_id,limit)POST /send- Send a text messagePOST /send-with-attachment- Send a file attachmentWebSocket /ws- Real-time updates (chat_id,tokenfor auth)
Attachments
GET /attachments/{id}- Get attachment file (auto-converts HEIC to WebP)GET /attachments/{id}/thumbnail- Get video thumbnail (requires ffmpeg)GET /attachments/{id}/stream- Stream/transcode video to MP4
Contacts
GET /contacts/{handle}- Look up contact infoGET /contacts/{handle}/image- Get contact photo
Configuration
GET /config- Get all settingsPUT /config- Update settingsGET /config/defaults- Get default values
Service Management
GET /service/status- Service and Tailscale statusPOST /service/install- Install LaunchAgentPOST /service/uninstall- Uninstall servicePOST /service/tailscale/enable- Enable Tailscale servePOST /service/tailscale/disable- Disable Tailscale serve
System
GET /health- Health check with ffmpeg/contacts statusGET /version- Current and latest version infoPOST /version/check- Force check for updatesPOST /version/update- Trigger updateGET /sleep/status- Check sleep prevention statusPOST /sleep/allow- Temporarily allow sleepPOST /sleep/prevent- Re-engage sleep prevention
Configuration
Settings are accessible via the web UI (Settings → General) or the /config API. Available options:
| Setting | Default | Description |
|---|---|---|
theme |
auto |
UI theme: auto, light, or dark |
prevent_sleep |
true |
Keep Mac awake while running |
api_token |
"" |
API token for authentication (empty = no auth) |
notifications_enabled |
true |
Browser notifications for new messages |
notification_sound_enabled |
true |
Play sound with notifications |
use_custom_notification_sound |
false |
Use uploaded custom sound |
auto_update_enabled |
true |
Auto-install updates |
update_check_interval |
86400 |
Seconds between update checks |
custom_css |
"" |
Custom CSS for UI styling |
websocket_poll_interval |
1.0 |
Seconds between message polls |
thumbnail_cache_ttl |
86400 |
Video thumbnail cache duration |
thumbnail_timestamp |
3.0 |
Seconds into video for thumbnail |
contact_cache_ttl |
86400 |
Contact info cache duration |
log_level |
WARNING |
Logging verbosity |
macOS Permissions
iUseLinux requires certain macOS permissions to function fully.
Full Disk Access (Required)
The app needs to read the iMessage database located at ~/Library/Messages/chat.db.
- Open System Settings → Privacy & Security → Full Disk Access
- Click the + button and add Terminal (or your terminal app)
- Restart Terminal
Contacts Access (Automatic via Full Disk Access)
Contact names and photos are resolved by reading the macOS AddressBook database directly. This uses the same Full Disk Access permission required for the iMessage database - no separate Contacts permission is needed.
If contacts aren't showing, ensure Full Disk Access is properly configured (see above).
Automation (Required for Sending)
To send messages, the app uses AppleScript to control Messages.app:
- When you first send a message, macOS will prompt for permission
- Click OK to allow Terminal to control Messages.app
- If denied, go to System Settings → Privacy & Security → Automation
- Enable Terminal → Messages
Optional Dependencies
FFmpeg (for video features)
Video thumbnails and MOV→MP4 transcoding require ffmpeg:
brew install ffmpeg
Without ffmpeg, videos will still display but thumbnails and streaming won't be available. The /health endpoint shows whether ffmpeg is detected.
Manual Removal
To completely remove iUseLinux from your system:
-
Uninstall the service (if installed):
uvx iuselinux service uninstall
-
Remove application data and logs:
rm -rf ~/Library/Application\ Support/iuselinux/ rm -rf ~/Library/Logs/iuselinux/
-
Remove the app bundle (if present):
rm -rf ~/Applications/iUseLinux.app/
-
Remove the uv tool installation (if installed via
uv tool install):uv tool uninstall iuselinux
-
Revoke permissions (optional):
- Open System Settings → Privacy & Security → Full Disk Access
- Remove any iUseLinux-related entries (Terminal, iUseLinux Service.app, etc.)
- Similarly check Automation and remove Terminal → Messages if desired
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file iuselinux-0.1.9.tar.gz.
File metadata
- Download URL: iuselinux-0.1.9.tar.gz
- Upload date:
- Size: 4.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64f19cdf061df83c0ca0a4f9743ca0128aab5f161adfc3699ba4cddaeb8cbbcb
|
|
| MD5 |
677164b216d2ec02cbfbb8394669204e
|
|
| BLAKE2b-256 |
fe664be73f2d6813de1f4d71b7201be5b176f5efbd6336899f820fe1ee19f1e3
|
File details
Details for the file iuselinux-0.1.9-py3-none-macosx_10_9_universal2.whl.
File metadata
- Download URL: iuselinux-0.1.9-py3-none-macosx_10_9_universal2.whl
- Upload date:
- Size: 3.4 MB
- Tags: Python 3, macOS 10.9+ universal2 (ARM64, x86-64)
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88155e21ac00db949df0f6325706b214a8a414d75af38e5e066bc30999a172d9
|
|
| MD5 |
e0d03f920ce29d275708605618d42223
|
|
| BLAKE2b-256 |
766bed01e0d9420fffd31e3dda936a19c771ae6e00bf4b091b328fcc3bb7a47f
|