MeshCore Beacon
Monitoring / Management BetaBeacon
Real-time LoRa mesh network observation stack: a Go backend subscribes to MeshCore MQTT brokers, decodes and deduplicates packets, stores nodes, routes, traces and channel messages in PostgreSQL, and streams live events via WebSocket and REST API — paired with a React web frontend for packet inspection, node tracking, channel messages, stats and mesh maps.
- Maintainer
- MeshCore-Beacon ↗
- Kind
- Monitoring & Management
- Maturity
- Beta
- Languages
- Go TypeScript
- Licensing
- Open source
- Latest version
- 1.6.0 · 2026-07-24
- License
- AGPL-3.0
- Platforms
- Docker Linux Web
Capabilities
Interfaces
- ✓ Web
- ✓ API
Connections
- ✓ MQTT
- ✓ WebSocket
- ✓ HTTP
Capabilities
- ✓ Monitoring
- ✓ Telemetry
- ✓ Packet analysis
- ✓ Mapping
- ✓ Bridging
Install
Releases
from GitHub · updated 2026-07-24v1.6.0 # Latest 14 days ago · 2026-07-24 20:37 UTC
New Features
- Channel message backfill at boot — when a channel's decryption key is added to config, packets for that channel that arrived before the key was known (and were stored as hash-only, undecrypted rows) are now retried against the keystore on the next startup. Previously that history just sat in the database unused forever; now it surfaces automatically. Backfilled messages don't emit live WebSocket events (they're history, not new activity), and the process is non-fatal — a decrypt failure logs and moves on rather than blocking boot. (3cad2df)
- Node staleness & automatic deletion — new config:
nodes.stale_threshold(default 24h) marks a nodestale: truein the API once it hasn't been seen in that long;nodes.delete_after(default 30 days, same default as packet retention) removes nodes from the database entirely once they've been gone that long, via the existing cleanup background job. Node deletion correctly excludes any node with a manually-recorded owner record, so operator-curated ownership data is never silently orphaned. (99d7eb0) - IATA region borders (GeoJSON) —
GET /api/v1/iatas/{iata}/borderreturns a region's border as a GeoJSON Feature (Polygon or MultiPolygon, with a server-computed bounding box) for map rendering —204when a region has no border configured,404for an unknown IATA. Borders are supplied per-IATA via config (borderFile: path/to.geojson) and validated at boot — malformed geometry, out-of-range coordinates, or unclosed rings fail startup rather than shipping bad data silently. Deliberately kept off the main/iataslist response so it stays lightweight for callers that don't need it. (3f2506f) - Node clock drift detection — repeaters and room servers self-report a device clock in every advert; the server now compares that against its own receive time and surfaces the delta (
clockDriftSeconds,clockOutOfSync,clockCheckedAt) on the node API, with the out-of-sync threshold configurable (nodes.clock_drift_threshold, default 5m). Useful for spotting devices with a broken or badly-drifted RTC. (8e27986) - Top advertisers & top talkers stats — two new endpoints,
GET /stats/top-advertisersandGET /stats/top-talkers, following the samesince/limit/iatasshape as the existing top-observers endpoint. Top advertisers counts distinct ADVERT packets per node (not raw hearings, so a broadcast heard by five observers doesn't inflate the count); top talkers aggregates by decrypted sender display name. Now served from materialized views (see Performance) rather than live queries. (b38663d, later matview-backed in cbde3d0/bc3a375) - Node public-key prefix search —
GET /nodes?pubkeyPrefix=...matches nodes by a partial hex prefix of their public key, alongside the existing exact-matchpubkeyfilter — useful when a UI only shows a node's key truncated. (0ca28cc) - Plural filter params on packet list —
GET /packetsnow accepts comma-separatedpayloadTypes,routeTypes, andscopesalongside the existing singular params, so multi-select filters can be expressed in one request instead of requiring client-side post-filtering. (b33ebc0) - Source/destination endpoints in resolved path data — packet path data (both the live WebSocket feed and the REST packet detail) now resolves and includes the sender and, where determinable, the recipient — not just the intermediate hops — for payload types where that's meaningful (ADVERT, TEXT_MESSAGE, PATH, REQUEST/RESPONSE, ANON_REQ's destination). This is what makes the live map able to draw a packet's full source→destination path instead of stopping at the first/last known repeater. (f07edf9)
?neighborson node list —GET /nodes?neighborsopts into including each node's known neighbor IDs in the list response. (4e2ee62)- Resolved path in WebSocket observation events — live packet observation events over the WebSocket now carry the same resolved-path …
v1.5.4 # 2 months ago · 2026-06-24 15:11 UTC
Fixes
- Packet Observation Duplication - The packet observations were being constrained as unique on observer, packet hash and the heard at TS. The TS has been removed and a migration is in place to clean up bad data.
Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.5.3...v1.5.4
v1.5.3 # 2 months ago · 2026-06-20 17:41 UTC
Features
- Discovery request/response parsing — Beacon now parses
DISCOVER_REQ/DISCOVER_RESPcontrol payloads from the mesh, feeding directly into neighbor data. - Neighbor SNR tracking — a new optional
snrcolumn onnode_neighbors, now populated from three independent sources:- discovery responses observed by Beacon
- zero-hop adverts seen directly by observers
- hop pairs derived from TRACE packets
- Observer online check uses last seen — ingest now factors in an observer's last-seen timestamp when determining online status, rather than relying solely on connection state.
Fixes
- Node summary neighbor counts — deduplicated neighbor counts in node summaries that were previously inflated by duplicate rows.
- Release image publishing — fixed the GitHub Actions release workflow so built images are pushed to the public registry correctly. (Thanks, @MrAlders0n!)
Maintenance
- Bumped
meshcore-goto v1.0.8. - SECURITY: Bumped
github.com/go-chi/chi/v5from v5.2.2 to v5.2.4 (dependabot). - Documented the remaining parsed ingest payload structs.
- Added the new neighbor
snrfield to the swagger docs.
Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.5.2...v1.5.3
- Discovery request/response parsing — Beacon now parses
Project signals
popularity 2026-08-08 verification 2026-08-08
- GitHub stars
- 7
- Forks
- 2
- Watchers
- 1
- Open issues
- 11
- Contributors
- 4
- Release downloads
- 3
- Latest downloads
- 0
- Source available
- Yes
- Releases available
- Yes
- Signed releases
- No
- CI builds
- Yes
- Documentation
- Yes
- API authentication is not yet implemented; intended for trusted internal or reverse-proxy deployments.
- Full-stack Docker Compose configs (server + web + PostgreSQL + Redis + Caddy TLS) are in the beacon-docs repo.
- Swagger UI available at /swagger/index.html on a running instance.