The Problem

Meshtastic nodes are single-transceiver devices: they only see their own traffic and require a phone app for messaging. A mesh network operator who wants to observe all packets in range, run a persistent base station, or message from a browser has no off-the-shelf option. Meshpoint solves this by pairing a Raspberry Pi with an SX1302/SX1303 concentrator, which decodes multiple spreading factors in parallel and can transmit natively.

What This Does

Meshpoint is an open-source LoRa base station for Meshtastic (and MeshCore via a USB companion). It captures all packets in range, stores them in SQLite, and exposes a browser dashboard for chat, node discovery, radio configuration, and a live packet feed. It can also relay captured packets back onto the mesh with identity preservation.

The core logic lives in src/ (323 Python files), with a substantial browser frontend in frontend/ (108 JavaScript files). The backend is a Python API server (src/api/server.py) with an Express.js frontend served statically. Configuration is YAML-based (config/default.yaml), and the system supports multiple regional frequency plans (US915, EU868, ANZ915, IN865, KR920, SG923).

How It Is Wired

Execution starts at src/main.py, which initializes the coordinator (src/coordinator), the API server (src/api/server.py), and the transmit service (src/transmit/tx_service.py). The API server is the central hub: it imports 45 modules and is imported by 6, making it the most coupled file in the system. The src/config module is the true hub, with 72 modules depending on it — a change there has a high blast radius.

The packet flow: the concentrator receives packets → src/models/packet (40 dependents) normalizes them → src/storage/database.py persists to SQLite → the API server pushes them to the frontend via WebSocket (frontend/js/websocket_client.js). Transmit path: src/transmit/tx_service.py (15 dependents) handles outbound messages, with src/transmit/meshcore_tx_client.py for MeshCore traffic. The src/api/auth/jwt_session module (50 dependents) handles authentication, making it another high-blast-radius hub.

Four modules participate in circular imports: src/transmit/meshcore_tx_client.py, src/cli/setup_wizard.py, and src/transmit/meshcore_exclusive_radio.py. This costs maintainers: changing any one requires understanding the others' coupling.

How To Use It

Setup: Clone with git clone https://github.com/moses-y/meshpoint. The repo uses requirements.txt for Python dependencies — install with pip install -r requirements.txt. There is no lockfile, so builds are not reproducible.

Configuration: Edit config/default.yaml for region, frequency, TX power, and relay settings. Channel/PSK configuration happens from the dashboard, not the file.

Running it: The entry point is src/main.py — run python src/main.py. The frontend is served by the API server; open frontend/index.html in a browser.

Real-World Use

A community mesh network with a Raspberry Pi 4 and SX1302 concentrator deployed as a permanent base station. Operators monitor all traffic in range, message from any browser, and optionally relay packets with relay.enabled: true in local.yaml. The system syncs upstream to Meshradar for multi-site aggregation. A typical workflow: power on the Pi, open the dashboard, configure the region, and watch the packet feed populate — no phone app needed.

Code Health & Issues

Static analysis found 198 issues (36 high, 162 medium). Key findings:

  • High - SQL injection risk in src/api/server.py: uses string interpolation in .execute() instead of bound parameters. Fix: use placeholders.
  • High - Oversized files: src/transmit/tx_service.py (1031 lines) and src/api/server.py are too large to hold in one head. Fix: split by responsibility.
  • High - Import cycle members in src/transmit/meshcore_tx_client.py, src/cli/setup_wizard.py, src/transmit/meshcore_exclusive_radio.py. Fix: extract shared types or defer imports.
  • Medium - Broad exception handling in 29 places, notably src/transmit/tx_service.py and src/decode/crypto_service.py. Fix: catch specific exceptions.
  • Medium - CI workflow lacks least-privilege GITHUB_TOKEN permissions, no dependency scan, and persist-credentials is not disabled. Fix: add permissions: contents: read, enable Dependabot, add dependency-review-action.
  • Medium - Deep nesting in src/config.py, src/transmit/tx_service.py, src/storage/database.py. Fix: early returns and guard clauses.

The repo has tests (146 files) and CI (GitHub Actions), but no Dockerfile and no lockfile.

The Bottom Line

Meshpoint is a serious, feature-complete base station solution for Meshtastic operators. The architecture is sound but the hub modules (src/config, src/api/server) carry real risk, and the SQL injection issue in src/api/server.py should be fixed before production use. Best for technical operators comfortable with Python and Raspberry Pi who need persistent mesh visibility and browser-based messaging.