A TCP proxy that enables remote access to a locally-connected MeshCore companion radio.
MeshCore Proxy connects to a MeshCore radio via USB Serial or Bluetooth LE and exposes it over TCP, allowing remote clients to interact with the radio as if it were directly connected.
┌─────────────────┐ USB/BLE ┌──────────────────┐
│ MeshCore Radio │ ◄──────────────► │ meshcore-proxy │
│ (Companion FW) │ │ │
└─────────────────┘ │ TCP :5000 │
└────────┬─────────┘
│
┌───────────────────────────────┼───────────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ MeshCore-CLI │ │ Home Assistant│ │ MeshCore App │
└──────────────┘ └──────────────┘ └──────────────┘
Supported clients:
pip install meshcore-proxypipx install meshcore-proxygit clone --recursive https://github.com/rgregg/meshcore-proxy.git
cd meshcore-proxy
pip install -e .# Pull the published image (recommended)
docker pull ghcr.io/rgregg/meshcore-proxy:latest
# Or build locally
docker build -t meshcore-proxy .# Linux
meshcore-proxy --serial /dev/ttyUSB0
# macOS
meshcore-proxy --serial /dev/cu.usbmodem101
# Windows
meshcore-proxy --serial COM3# Linux/Windows - use MAC address
meshcore-proxy --ble 12:34:56:78:90:AB
# macOS - use UUID or device name (MAC addresses not supported)
meshcore-proxy --ble 7921236E-065C-0C7B-C04D-7F60E849DC47
meshcore-proxy --ble MeshCore-07BA3987Once the proxy is running, connect clients to localhost:5000:
meshcore-cli --tcp localhost:5000meshcore-proxy [OPTIONS]
Connection (one required):
--serial PORT Serial port path (e.g., /dev/ttyUSB0)
--ble ADDR BLE device address (see platform notes below)
Server options:
--host ADDR TCP bind address (default: 0.0.0.0)
--port PORT TCP port (default: 5000)
Serial options:
--baud RATE Serial baud rate (default: 115200)
BLE options:
--ble-pin PIN BLE pairing PIN (default: 123456)
Logging options:
--quiet Suppress non-error output
--log-events Log event summaries
--log-events-verbose Log full event details with hex payloads
--json Output event logs as JSON
--debug Enable debug logging
| Platform | Address Format | Example |
|---|---|---|
| Linux | MAC address | 12:34:56:78:90:AB |
| Windows | MAC address | 12:34:56:78:90:AB |
| macOS | UUID or device name | 7921236E-065C-0C7B-C04D-7F60E849DC47 or MeshCore-07BA3987 |
macOS uses Core Bluetooth which does not expose MAC addresses. Use the device UUID (found via BLE scanning tools) or the device name broadcast by the radio.
The proxy decodes and displays MeshCore protocol events for debugging and monitoring.
meshcore-proxy --serial /dev/ttyUSB0 --log-events-> CMD_APPSTART
<- SELF_INFO
-> CMD_DEVICE_QUERY
<- DEVICE_INFO
-> CMD_GET_CONTACTS
<- CONTACT_START
<- CONTACT_END
meshcore-proxy --serial /dev/ttyUSB0 --log-events-verbose-> CMD_APPSTART [13 bytes]: 01032020202020206d63636c69
<- SELF_INFO [66 bytes]: 05011616bfac8cd412f2e401...
-> CMD_GET_BATTERY [1 bytes]: 14
<- BATTERY [11 bytes]: 0cfc101600000064000000
meshcore-proxy --serial /dev/ttyUSB0 --log-events --json{"direction": "TO_RADIO", "packet_type": "CMD_APPSTART", "packet_type_raw": 1}
{"direction": "FROM_RADIO", "packet_type": "SELF_INFO", "packet_type_raw": 5}# Linux
docker run -d \
--name meshcore-proxy \
--device=/dev/ttyUSB0 \
-p 5000:5000 \
ghcr.io/rgregg/meshcore-proxy:latest \
--serial /dev/ttyUSB0
# macOS
docker run -d \
--name meshcore-proxy \
--device=/dev/cu.usbmodem101 \
-p 5000:5000 \
ghcr.io/rgregg/meshcore-proxy:latest \
--serial /dev/cu.usbmodem101BLE in Docker requires Linux with BlueZ. It does not work on macOS or Windows Docker.
# Requires host network and privileges for Bluetooth access
docker run -d \
--name meshcore-proxy \
--net=host \
--privileged \
-v /var/run/dbus:/var/run/dbus:ro \
ghcr.io/rgregg/meshcore-proxy:latest \
--ble 12:34:56:78:90:AB# USB Serial
docker compose --profile serial up -d
# BLE (set address in environment)
BLE_ADDRESS=12:34:56:78:90:AB docker compose --profile ble up -ddocker logs -f meshcore-proxy# Clone with submodules
git clone --recursive https://github.com/rgregg/meshcore-proxy.git
cd meshcore-proxy
# Or initialize submodules if already cloned
git submodule update --init --recursive
# Run directly
PYTHONPATH=src:meshcore_py/src python3 -m meshcore_proxy.cli \
--serial /dev/ttyUSB0 --log-eventsConfigure the MeshCore Home Assistant integration to connect via TCP:
- Host: IP address of machine running the proxy
- Port: 5000 (or your custom port)
Create /etc/systemd/system/meshcore-proxy.service:
[Unit]
Description=MeshCore Proxy
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/meshcore-proxy --serial /dev/ttyUSB0 --log-events
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl enable meshcore-proxy
sudo systemctl start meshcore-proxyAdd your user to the dialout group:
sudo usermod -aG dialout $USER
# Log out and back in for changes to take effectUse a different port:
meshcore-proxy --serial /dev/ttyUSB0 --port 5001- Ensure Bluetooth is enabled and the device is in range
- macOS: Use UUID or device name, not MAC address
- Linux: You may need
sudoor add user tobluetoothgroup - PIN-protected devices: Pair at the OS level first (System Preferences on macOS,
bluetoothctlon Linux), then the proxy will use the existing pairing
- Check that the radio is running companion firmware (not repeater/room server)
- Verify the serial port/BLE address is correct
- Try power cycling the radio
- Python 3.10+
- MeshCore companion radio with USB or BLE firmware
git clone --recursive https://github.com/rgregg/meshcore-proxy.git
cd meshcore-proxy
pip install -e ".[dev]"pytestThis project uses setuptools-scm for automatic versioning based on git tags.
Version format: Tags should follow the pattern vX.Y.Z or vX.Y.Z-alpha (e.g., v0.4.0, v0.4.0-alpha)
Release process:
- Ensure all changes are committed and pushed
- Create and push a version tag:
git tag v0.4.0-alpha git push origin v0.4.0-alpha
- GitHub Actions will automatically:
- Build the package with the version from the tag
- Publish to PyPI
- Build and publish Docker images to GHCR
Version resolution:
- On a tagged commit: uses the exact tag version (e.g.,
v0.4.0-alpha→0.4.0a0) - Between tags: uses a dev version (e.g.,
0.4.0a1.dev2for 2 commits afterv0.4.0-alpha)
MIT