A cross-platform bridge that exposes a TCP API to Bluetooth Low Energy (BLE) Meshtastic devices. Available as a Docker container for Linux or native Windows application with system tray interface. Designed for use with MeshMonitor, but works with any tool that supports the Meshtastic TCP interface.
| Platform | Status | Interface | Download |
|---|---|---|---|
| Linux | β Stable | Docker | ghcr.io/yeraze/meshtastic-ble-bridge |
| Windows | β Stable | GUI (System Tray) | Releases |
| macOS | π Planned | TBD | Coming soon |
Features:
- BLE-to-TCP protocol translation
- Automatic reconnection on node reboots or disconnects (v1.3+)
- Optional config caching for faster reconnections (v1.4.0+)
- Configurable cache size limits for memory management (v1.4.0+)
- mDNS/Avahi autodiscovery for zero-configuration networking
- Automatic service registration and cleanup
- Graceful shutdown with proper resource cleanup
- Comprehensive test suite with CI/CD
meshmonitor-ble-bridge/
βββ README.md # This file
βββ QUICK_START.md # Get up and running fast
βββ docker-compose.ble.yml # Docker Compose configuration
βββ src/
β βββ ble_tcp_bridge.py # Main bridge application
β βββ Dockerfile # Container build instructions
β βββ .dockerignore # Docker build exclusions
βββ docs/
βββ CLAUDE_BLE_BRIDGE.md # Claude Code context & technical details
βββ BLE_TCP_BRIDGE_ANALYSIS.md # Comprehensive technical analysis
βββ README_BLE_BRIDGE.md # User documentation
βββ DEPLOY_BLE_BRIDGE.md # Deployment guide
- Docker installed
- Bluetooth adapter (built-in or USB)
- Meshtastic device with BLE enabled
docker pull ghcr.io/yeraze/meshtastic-ble-bridge:latestdocker run --rm --privileged \
-v /var/run/dbus:/var/run/dbus \
ghcr.io/yeraze/meshtastic-ble-bridge:latest --scanbluetoothctl
pair AA:BB:CC:DD:EE:FF # Replace with your device MAC
trust AA:BB:CC:DD:EE:FF
exitdocker run -d --name ble-bridge \
--privileged \
-p 4403:4403 \
--restart unless-stopped \
-v /var/run/dbus:/var/run/dbus \
-v /var/lib/bluetooth:/var/lib/bluetooth:ro \
-v /etc/avahi/services:/etc/avahi/services \
ghcr.io/yeraze/meshtastic-ble-bridge:latest AA:BB:CC:DD:EE:FFThe bridge will automatically register an mDNS service for network autodiscovery.
Point MeshMonitor to:
- IP:
<bridge-host-ip> - Port:
4403
Or use mDNS autodiscovery to find the bridge automatically on your network:
# Test mDNS discovery
avahi-browse -rt _meshtastic._tcpThe bridge advertises itself as _meshtastic._tcp.local. with TXT records containing:
bridge=bleport=4403ble_address=<device-mac>version=<bridge-version>
- Download
MeshtasticBLEBridge-Windows-vX.X.X.zipfrom Releases - Extract
MeshtasticBLEBridge.exe
- Open Settings β Bluetooth & devices β Add device
- Select your Meshtastic device and pair
- Note the MAC address (e.g.,
48:CA:43:59:4C:71)
- Run
MeshtasticBLEBridge.exe - Find tray icon (bottom-right corner)
- Right-click β Settings
- Enter BLE MAC address
- Right-click β Connect
See Windows GUI Guide for detailed instructions
- Windows GUI: See
docs/WINDOWS_GUI.mdfor Windows application guide - Quick Start: See
QUICK_START.mdfor Linux/Docker step-by-step setup - Deployment: See
docs/DEPLOY_BLE_BRIDGE.mdfor production deployment - User Guide: See
docs/README_BLE_BRIDGE.mdfor usage and troubleshooting - Technical Details: See
docs/CLAUDE_BLE_BRIDGE.mdfor architecture and development - Analysis: See
docs/BLE_TCP_BRIDGE_ANALYSIS.mdfor comprehensive protocol analysis
This package includes docs/CLAUDE_BLE_BRIDGE.md which provides complete context for working on the BLE bridge with Claude Code. Simply:
- Extract this tarball on your target machine
- Open the directory in Claude Code
- Reference
docs/CLAUDE_BLE_BRIDGE.mdfor full technical context
ββββββββββββββββ TCP 4403 βββββββββββββββββ
β MeshMonitor β βββββββββββββββββββ BLE Bridge β
ββββββββββββββββ βββββββββ¬ββββββββ
β β BLE
β mDNS autodiscovery βββββββββΌββββββββ
βββββββββββββββββββββββββββββββ Meshtastic β
βββββββββββββββββ
The bridge translates between:
- BLE: Raw protobuf bytes on Meshtastic GATT characteristics
- TCP: Framed protocol
[0x94][0xC3][LEN][PROTOBUF]
And provides:
- mDNS: Automatic service discovery via Avahi (
_meshtastic._tcp.local.)
For MeshMonitor users, use the included docker-compose.ble.yml as an overlay:
# Copy to MeshMonitor directory
cp docker-compose.ble.yml /path/to/meshmonitor/
# Create .env file
echo "BLE_ADDRESS=AA:BB:CC:DD:EE:FF" > /path/to/meshmonitor/.env
# Start both services
cd /path/to/meshmonitor
docker compose -f docker-compose.yml -f docker-compose.ble.yml up -dsudo systemctl start bluetoothContainer needs --privileged flag for BLE access
- Ensure device BLE is enabled
- Move closer (BLE range ~10-30m)
- Check device not connected to another app
- Verify bridge listening on
0.0.0.0:4403 - Check firewall allows port 4403
- Test with:
telnet <bridge-ip> 4403
The bridge now automatically handles node reboots and BLE disconnections:
Internal Reconnection:
- Detects disconnections via the BLE disconnect callback and via polling, including silent link loss where no callback fires or reads/writes start failing
- Attempts up to 10 reconnections with exponential backoff (2s, 4s, 8s, ... capped at 60s), giving slow-rebooting nodes several minutes to come back
- Each new outage gets the full set of attempts
- Continues operation if reconnection succeeds
Container Restart:
- If all reconnection attempts fail, the bridge exits with error code 1 instead of serving TCP with no BLE link behind it
- Docker's
restart: unless-stoppedpolicy automatically restarts the container - Fresh container attempts clean connection to the device
Healthcheck:
- The Docker image sets
HEALTH_FILE=/tmp/ble-bridge.health; the bridge touches this file every 10s while BLE is connected (use--health-file PATHoutside Docker) - The container is reported healthy only while that file is fresh, so a TCP port that still accepts connections no longer hides a dead BLE link
- Note: plain Docker does not restart unhealthy containers; recovery comes from the
exit code above plus
restart: unless-stopped
Recommended Docker Configuration:
services:
ble-bridge:
restart: unless-stopped # Auto-restart on failure
environment:
- HEALTH_FILE=/tmp/ble-bridge.health
healthcheck:
test: ["CMD", "python3", "-c", "import os, sys, time; f = '/tmp/ble-bridge.health'; sys.exit(0 if os.path.exists(f) and time.time() - os.path.getmtime(f) < 60 else 1)"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60sMonitoring: Check logs to see reconnection activity:
docker logs -f ble-bridgeLook for:
β οΈ BLE connection lost during polling/β οΈ BLE device disconnected- Disconnect detectedπ Reconnection attempt X/10- Retry in progressβ Reconnection successful- Successπ Failed to reconnect to BLE device after all attempts- Bridge will exit and the container restarts
For issues, questions, or contributions:
- MeshMonitor: https://github.com/Yeraze/meshmonitor
- Meshtastic: https://meshtastic.org
BSD-3-Clause (same as MeshMonitor)