Skip to main content

MeshTUI

MeshTUI: A Full-Featured MeshCore Client with Terminal UI

Description

MeshTUI is a comprehensive terminal user interface (TUI) client for MeshCore devices. Built with Textual, it provides a complete mesh networking experience with an intuitive, keyboard-driven interface for managing mesh networks, sending messages, administering nodes, and monitoring network status.

Unlike the command-line meshcore-cli, MeshTUI offers a rich visual interface with real-time updates, persistent message history, contact management, device configuration, and full node administration capabilities all in one terminal window.

Features

  • Real-time chat interface with contacts and channels
  • Message delivery tracking - ACK tracking, retry logic, and delivery status
  • Device management - scan, connect, and monitor MeshCore devices
  • Device identification - automatically detects and identifies MeshCore devices
  • Contact management - view, add, and manage mesh network contacts
  • Channel creation - create custom encrypted channels with auto-hash support
  • Node management - remote control of repeaters and room servers
  • Message history - browse and search through message history with delivery status
  • Async operations - built with asyncio for responsive UI
  • Multiple connection types - BLE, TCP, and Serial support
  • TCP Proxy (⚠️ Experimental) - Expose Serial/BLE devices over TCP for remote access
  • Command line options - specify connection method and device directly
  • Integrated logs - all logging output displayed in a dedicated Logs tab within the TUI
  • Configuration persistence - remembers device connections and settings
  • Automatic retry - messages automatically retry with flood routing fallback
  • F1 Help - comprehensive in-app help system

Message Delivery Tracking

MeshTUI provides comprehensive message delivery tracking for direct messages:

  • ✓ Sent - Message successfully transmitted from your device
  • ✓ Heard X repeats - Number of repeaters that acknowledged forwarding the message
  • ✗ Delivery failed - No repeaters responded within timeout period
  • Automatic retry - Up to 3 send attempts with intelligent flood routing fallback
  • Database tracking - All delivery information stored for later analysis

Note: Channel broadcasts show "✓ Sent (broadcast)" and don't have ACK tracking (per MeshCore API design).

Channel replies and @mentions

Channel replies use the same text format as the official MeshCore apps:

@[Alice]: thanks, that path worked

In a channel, type @ or @[ plus a few letters of a nickname and press Tab (or Right) to complete it. Candidates are people who have spoken in that channel, then your contacts. F4 prefills a reply to the last incoming sender. Messages that mention your name are highlighted.

Delivery Status Database

All messages are tracked in the database with delivery information:

  • ack_code - Unique acknowledgment code for tracking
  • delivery_status - Current status: 'sent', 'repeated', 'failed', or 'broadcast'
  • repeat_count - Number of repeater acknowledgments received
  • last_ack_time - Timestamp of most recent acknowledgment

This allows you to review message delivery history and identify network issues.

Installation

MeshTUI depends on the python meshcore package.

PyPI Installation

You can install it via pipx or uv:

pipx install meshtui
# or
uv tool install meshtui

This will install the meshtui command globally and isolate its dependencies.

Desktop notifications are optional and Linux-only (pipx install 'meshtui[notifications]'). They are not required to run the TUI. See Linux system packages if that extra fails to build.

Optional: TCP Proxy Component

⚠️ EXPERIMENTAL: The TCP proxy is a new feature in active development.

To install with the TCP proxy component (allows exposing Serial/BLE devices over TCP):

pipx install meshtui[proxy]
# or
uv tool install meshtui[proxy]

This installs the meshcore-tcp-proxy command in addition to meshtui. See the TCP Proxy section below for usage.

Arch Linux

For Arch Linux users, PKGBUILD files are available in the arch/ directory:

Stable version (from PyPI):

cd arch/meshtui
makepkg -si

Development version (from git):

cd arch/meshtui-git
makepkg -si

The -git version builds directly from the latest GitHub repository and conflicts with the stable package.

Development Installation

For development, use uv or standard pip:

git clone <your-repo-url>
cd meshtui
uv pip install -e .
# or with pip in a virtual environment:
# python -m venv .venv && source .venv/bin/activate && pip install -e .

Linux system packages (optional)

Desktop notifications use D-Bus (notify2 / dbus-python). They are not required to run MeshTUI.

Core install (recommended, works on Linux, macOS, and Windows):

pipx install meshtui
# or
uv tool install meshtui

Desktop notifications (Linux with D-Bus only):

# Debian / Ubuntu (including Debian 13 Trixie LXC)
sudo apt install pkg-config libdbus-1-dev libglib2.0-dev

# Fedora
sudo dnf install pkgconf-pkg-config dbus-devel glib2-devel

# then
pipx install 'meshtui[notifications]'
# or
uv tool install 'meshtui[notifications]'

On a minimal Debian/Ubuntu container, the pkg-config / libdbus-1-dev / libglib2.0-dev packages are only needed if you install the notifications extra.

macOS: D-Bus notifications are not used. Install with uv tool install meshtui or pipx install meshtui. Do not install the notifications extra unless you have dbus available (for example via brew install dbus).

Windows: dbus-python does not build on native Windows. Install with pipx install meshtui or uv tool install meshtui. WSL works the same as Linux.

Requirements

  • Python >= 3.10
  • A MeshCore-compatible radio device
  • BLE support (if using Bluetooth connectivity)

Usage

Launch MeshTUI with:

meshtui

Command Line Options

MeshTUI supports various connection methods via command line arguments:

# Connect via serial (USB)
meshtui --serial /dev/ttyUSB0

# Connect via serial with custom baudrate
meshtui --serial /dev/ttyACM0 --baudrate 9600

# Connect via TCP/IP
meshtui --tcp 192.168.1.100 --port 5000

# Connect via BLE address
meshtui --address C2:2B:A1:D5:3E:B6

# Compact layout for small displays (PicoCalc, 320x320, etc.)
meshtui --compact

# Show help
meshtui --help

Available options:

  • -s, --serial SERIAL: Connect via serial port (e.g., /dev/ttyUSB0)
  • -b, --baudrate BAUDRATE: Serial baudrate (default: 115200)
  • -t, --tcp TCP: Connect via TCP/IP hostname
  • -p, --port PORT: TCP port (default: 5000)
  • -a, --address ADDRESS: Connect via BLE address or name
  • --compact: Start in compact mode with the sidebar hidden
  • --low-power: Lighter UI and no radio polling (auto-enabled on original Raspberry Pi-class hosts)
  • --debug: Write DEBUG logs to ~/.config/meshtui/meshtui.log

Device Identification

MeshTUI automatically identifies MeshCore devices:

  • BLE devices: Scans for devices with names starting with "MeshCore-"
  • Serial devices: Tests each serial port to identify MeshCore-compatible devices
  • Automatic prioritization: Prefers /dev/ttyUSB0 if available, then other serial devices, then BLE devices

When scanning, MeshTUI will show which devices are confirmed MeshCore devices with device information like model and firmware version.

Interface Layout

MeshTUI features a two-panel layout with tabbed content:

  • Left Sidebar: Shows available mesh network contacts and channels
  • Main Content (Tabbed): Contains Chat, Device Settings, Node Management, and Logs tabs

Node Management

MeshTUI includes comprehensive remote node management capabilities for repeaters and room servers:

Node Management Tab Features:

  • Node Discovery: Automatically discovers available nodes in the mesh network
  • Node Login/Logout: Authenticate with repeaters and room servers
  • Command Execution: Send commands to remote nodes (no acknowledgment)
  • Status Monitoring: Request and display node status information
  • Real-time Feedback: All operations logged in the Logs tab

Node Management Workflow:

  1. Refresh Nodes: Click "Refresh Nodes" to scan for available nodes
  2. Login: Enter node name and password, then click "Login"
  3. Send Commands: Use the command input to send instructions to logged-in nodes
  4. Check Status: Click "Get Status" to retrieve node information
  5. Logout: Use the logout command when finished

Supported Node Types:

  • Repeaters: Extend network coverage by relaying messages
  • Room Servers: Provide shared messaging spaces (BBS-style)
  • Other Nodes: Any meshcore-compatible remote device

Creating Custom Channels

MeshTUI allows you to create encrypted channels for group communication:

How to Create a Channel:

  1. Click the "+" button next to the "Channels" header in the sidebar
  2. Enter a channel slot (1-7, slot 0 is reserved for Public channel)
  3. Enter a channel name:
    • Use # prefix (e.g., #mychannel) for auto-generated hash-based secret
    • Or enter a custom name without # for manual secret management
  4. Click "Create" to create the channel
  5. The new channel appears in your channels list

Joining an existing channel (you already have the key):

  1. Click the "+" button next to the "Channels" header
  2. Pick a free channel slot (1-7)
  3. Enter the channel name exactly as the other devices use it (do not add a # prefix if you are supplying the key)
  4. Paste the 16-byte secret as 32 hex characters (colons, spaces, dashes, or a 0x prefix are accepted)
  5. Click "Create" — this writes the name and secret into that slot on the radio

The # prefix always derives the secret from the name and ignores any key you type. Use #name only when every device joins that way.

Channel Security:

  • Channels with # prefix automatically generate a 16-byte secret from the hash of the channel name
  • Other devices can join by using the same channel name with # prefix
  • Custom channels require the same 16-byte secret on every device
  • All channel messages are encrypted using the channel secret

Example:

Creating a channel named #team will:

  • Generate a consistent secret from hash("#team")
  • Allow anyone with #team to decrypt messages
  • Secure from others who don't know the channel name

Small screens

On terminals under 80×24 (for example a PicoCalc 320×320 display), MeshTUI switches to compact chrome automatically and hides the contacts sidebar under 60 columns so the chat can use the full width.

  • F2 — show or hide the contacts/channels sidebar
  • F3 — force compact mode on or off
  • meshtui --compact — start with compact chrome and the sidebar hidden
  • Choice is saved in ~/.config/meshtui/ui.json

When the sidebar is hidden, a Show contacts (F2) bar appears above the chat, and the header subtitle shows the active conversation.

Key Bindings

  • Ctrl+C - Quit the application
  • Ctrl+R - Refresh current view
  • F1 - Show help
  • F2 - Toggle contacts sidebar
  • F3 - Toggle compact mode
  • F4 - Reply to the last person who spoke in the current channel
  • Tab - Complete an @ mention in the message box (or move focus)
  • Enter - Send message or activate button

First Time Setup

  1. Auto-connect: MeshTUI attempts to connect automatically on startup
  2. Manual scan: Click "Scan Devices" to manually search for devices
  3. Command line: Specify device directly with command line options
  4. Start chatting: Use the input field to send messages or commands

Connection Process

When you specify a serial device (e.g., --serial /dev/ttyUSB0), MeshTUI:

  1. Opens the serial connection at the specified baudrate (default: 115200)
  2. Sends a device query to verify the device is a MeshCore-compatible radio
  3. Retrieves device information (model, firmware version, capabilities)
  4. Sets up event handlers for real-time contact and message updates
  5. Refreshes the contact list from the device's memory

Why Contacts Don't Appear

Empty contact list is normal for several reasons:

  • Single device setup: If you're testing with only one MeshCore device, there are no other devices to communicate with
  • Fresh device: New or factory-reset devices have no saved contacts
  • Network isolation: Devices must be within radio range and on the same frequency/channel
  • No prior communication: Contacts are only created after successful message exchanges

How to Populate Contacts

To see contacts in the list:

  1. Add multiple devices to your mesh network
  2. Send messages between devices - this automatically creates contact entries
  3. Use the same frequency/channel settings across devices
  4. Ensure devices are powered on and within communication range
  5. Wait for advertisements - devices periodically announce themselves

Device Status Indicators

  • Connection successful: Device info appears in logs (model, firmware, etc.)
  • Zero contacts: Normal for single-device or new network setups
  • Communication working: Messages sent/received successfully

Troubleshooting

Serial Port Permissions (Linux/macOS)

If you get permission errors when connecting via serial port, you need to add your user to the appropriate group:

Linux:

# Add your user to the dialout group
sudo usermod -a -G dialout $USER

# Log out and log back in for changes to take effect
# Or use: newgrp dialout

macOS:

# macOS typically doesn't require special permissions
# If you encounter issues, check /dev/tty.* or /dev/cu.* devices
ls -l /dev/tty.* /dev/cu.*

Verify access:

# Check group membership
groups

# Test device access (replace with your device path)
ls -l /dev/ttyUSB0

Common error messages indicating permission issues:

  • "Permission denied" when opening serial port
  • "Could not open port /dev/ttyUSB0"
  • "Access denied"

Log Files for Debugging

All application logs are automatically saved to a log file for postmortem analysis:

  • Location: $HOME/.config/meshtui/meshtui.log
  • Content: Includes DEBUG level logs with detailed connection and event information
  • Rotation: Automatically rotates when reaching 5MB (keeps 3 backup files)
  • Usage: Check this file when the application behaves unexpectedly or for detailed debugging

Example log entries:

2024-01-15 10:30:15 - meshtui - INFO - MeshTUI started - logging to ~/.config/meshtui/meshtui.log
2024-01-15 10:30:16 - meshtui.connection - INFO - Connected to Heltec V3 via serial. Found 2 contacts
2024-01-15 10:30:17 - meshtui.connection - DEBUG - 📡 EVENT: New contact detected: {'name': 'Device2', 'id': 123}

Common Issues

  • Serial port permission denied: Add your user to the dialout group (Linux) - see above
  • No contacts appearing: See "Why Contacts Don't Appear" above
  • Connection fails: Check serial port permissions and device power
  • Device not found: Ensure the device is connected and appears in /dev/ttyUSB* or /dev/ttyACM*
  • Logs not updating: Switch to the Logs tab to view application logs
  • Performance issues: Check log file size and rotate if necessary
  • Very slow on a Raspberry Pi B / Zero: MeshTUI auto-enables --low-power on armv6 and other single-core ≤512MB hosts. Force it with meshtui --low-power. Use meshtui --debug only when diagnosing (DEBUG logs on an SD card are expensive).

Configuration

Configuration files are stored in $HOME/.config/meshtui/

Per-Device Databases

MeshTUI creates a separate database for each connected device to prevent data collision:

  • Location: $HOME/.config/meshtui/devices/{device_pubkey}.db
  • Automatic: Database is created on first connection to each device
  • Isolated: Each device has its own messages, contacts, and settings
  • Seamless: Switching devices automatically uses the correct database

When you connect to a device for the first time, a new database is created using the device's unique public key. This ensures that messages and contacts from one device don't mix with another device's data.

Other Configuration Files

  • Device connections: Preferences and last-used BLE address are saved
  • Message history: All conversations persist between sessions
  • Log files: All application logs are saved to meshtui.log for postmortem analysis
    • Location: $HOME/.config/meshtui/meshtui.log
    • Includes DEBUG level logs for detailed troubleshooting
    • Automatically rotates when reaching 5MB (keeps 3 backup files)
    • Use for debugging issues after the application closes

Connection Types

MeshTUI supports the same connection methods as meshcore-cli:

  • BLE (Bluetooth Low Energy): Default for most companion radios
  • TCP/IP: For network-connected devices
  • Serial: For direct serial connections

Commands and Features

MeshTUI provides access to all MeshCore functionality through an intuitive interface:

  • Messaging: Send direct messages or broadcast to channels
  • Contacts: Manage your mesh network contacts
  • Device Info: View device status, telemetry, and configuration
  • Channels: Join and participate in mesh channels
  • Repeaters: Connect through mesh repeaters
  • Administration: Device management and configuration

Development

To contribute or modify MeshTUI:

  1. Clone the repository
  2. Create a virtual environment: python -m venv .venv or uv venv
  3. Activate: source .venv/bin/activate (Linux/Mac) or .venv\Scripts\activate (Windows)
  4. Install dependencies: pip install -e . or uv pip install -e .
  5. Run: python -m meshtui

Project Structure

src/meshtui/
├── app.py           # Main Textual application (UI layer)
├── app.css          # UI styling
├── connection.py    # Connection orchestration and lifecycle
├── transport.py     # BLE, Serial, TCP transport layers
├── contact.py       # Contact/node management
├── channel.py       # Channel operations
├── room.py          # Room server handling
├── database.py      # SQLite message and contact persistence
├── __init__.py      # Package initialization
└── __main__.py      # Entry point

docs/
└── meshcore-api/    # MeshCore API reference (copied from installed package)
    ├── README.md    # API documentation and examples
    ├── commands/    # Command modules (messaging, contacts, device)
    └── *.py         # Core API files

API Reference

For MeshCore API reference, see docs/meshcore-api/README.md. This includes:

  • Complete API documentation
  • Command examples for messaging, contacts, and device management
  • Event types and handling
  • Room server administration
  • Contact type definitions

TCP Proxy (EXPERIMENTAL)

⚠️ Status: Experimental feature in active development (Phase 1 MVP complete)

The MeshCore TCP Proxy allows you to expose USB Serial or BLE-connected MeshCore devices over TCP/IP, enabling remote network access and TCP mode testing without WiFi firmware.

Features

  • Companion framing - Host→device 0x3C, device→host 0x3E (same as MeshCore serial/BLE/TCP)
  • Multi-client support - Multiple meshtui instances can connect simultaneously
  • Remote access - Access locally-connected devices over network
  • TCP testing - Test TCP connectivity without WiFi firmware

Installation

# Install meshtui with proxy support
pipx install meshtui[proxy]

Usage

Start the proxy (exposes serial device on TCP port 5000):

meshcore-tcp-proxy --serial /dev/ttyUSB0

Connect meshtui via TCP:

meshtui --tcp localhost --port 5000

Advanced Options

# Custom port
meshcore-tcp-proxy --serial /dev/ttyUSB0 --port 6000

# Debug mode with frame logging
meshcore-tcp-proxy --serial /dev/ttyUSB0 --debug --log-frames

# Use config file
meshcore-tcp-proxy --config /path/to/config.yaml

# Remote access (listen on all interfaces)
meshcore-tcp-proxy --serial /dev/ttyUSB0 --host 0.0.0.0

Configuration File

Example configuration (config.yaml):

proxy:
  listen_host: 0.0.0.0
  listen_port: 5000

backend:
  type: serial
  serial_port: /dev/ttyUSB0
  baudrate: 115200
  auto_reconnect: true

logging:
  level: INFO
  log_frames: false

See config/proxy/config.yaml.example for full configuration options.

Architecture

The proxy consists of:

  • Serial Backend - Connects to USB serial devices (Phase 1 ✅)
  • TCP Server - Accepts multiple client connections
  • Frame Router - Bidirectional forwarding (no protocol translation)
  • BLE Backend - Bluetooth LE support (Phase 3, planned)

Documentation

Complete design documentation: docs/MESHCORE_TCP_PROXY_DESIGN.md

Limitations (Phase 1)

  • Serial backend only (BLE support planned for Phase 3)
  • No authentication/encryption (use SSH tunnel or VPN for remote access)
  • Experimental status - may have bugs or breaking changes

Roadmap

  • Phase 1 (✅ Complete): Serial backend, basic TCP server
  • Phase 2 (Planned): Multi-client enhancements, session management
  • Phase 3 (Planned): BLE backend support
  • Phase 4 (Planned): Auto-reconnect, health monitoring, robustness
  • Phase 5 (Planned): Systemd service, packaging, deployment tools

License

MIT License - see LICENSE file for details

Contributing

Contributions welcome! Please feel free to submit issues and pull requests.

Related Projects

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

meshtui-0.2.10.tar.gz (604.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

meshtui-0.2.10-py3-none-any.whl (89.2 kB view details)

Uploaded Python 3

File details

Details for the file meshtui-0.2.10.tar.gz.

File metadata

  • Download URL: meshtui-0.2.10.tar.gz
  • Upload date:
  • Size: 604.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for meshtui-0.2.10.tar.gz
Algorithm Hash digest
SHA256 18d0c61098da8b30ba48649f5c767bac9642d78526cb15e2f2d1099ef37767fa
MD5 62d287d07bd1054a0319e396bc9d8bc0
BLAKE2b-256 6a460e186483b8b5d2a2a5add19dc3181a892d927e3fb8c7f7a1511670c74772

See more details on using hashes here.

File details

Details for the file meshtui-0.2.10-py3-none-any.whl.

File metadata

  • Download URL: meshtui-0.2.10-py3-none-any.whl
  • Upload date:
  • Size: 89.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for meshtui-0.2.10-py3-none-any.whl
Algorithm Hash digest
SHA256 98476519e954d1f70975fc53d083c724b801e71b503ee81e2828eb6112b51d16
MD5 d011231a5f06a3e4dfb68af0426d4c03
BLAKE2b-256 a1f7f2b406e7696c75b7e005caed4752553778c1bacf17c5704d1745af479e03

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page