
MeshMonitor
Monitoring / Management StableSelf-hosted multi-protocol dashboard for monitoring and administering MeshCore, Meshtastic and MQTT networks, with unified maps, messaging, telemetry, automation, alerts and per-source access control.
- Maintainer
- Yeraze ↗
- Kind
- Monitoring & Management
- Maturity
- Stable
- Languages
- TypeScript JavaScript
- Licensing
- Open source
- Latest version
- 4.14.1-rc1 · 2026-08-05
- License
- BSD-3-Clause
- Platforms
- Docker Kubernetes Linux macOS NixOS Proxmox Windows Web
Screenshots
Capabilities
Interfaces
- ✓ Web
- ✓ GUI
- ✓ API
- ✓ Headless
Connections
- ✓ BLE
- ✓ Serial
- ✓ USB
- ✓ TCP
- ✓ MQTT
- ✓ HTTP
- ✓ WebSocket
Capabilities
- ✓ Messaging
- ✓ Contacts
- ✓ Channels
- ✓ Node configuration
- ✓ Remote administration
- ✓ Monitoring
- ✓ Telemetry
- ✓ Packet analysis
- ✓ Mapping
- ✓ Firmware update
- ✓ Automation
- ✓ Notifications
- ✓ Bridging
Node role
- ✓ Companion
- ✓ Repeater
Install
Releases
from GitHub · updated 2026-08-05v4.14.1-rc1 # Latest Pre-release 3 days ago · 2026-08-05 18:02 UTC
MeshMonitor v4.14.1-rc1
⚠️ Pre-release. This is a release candidate for 4.14.1. It ships on the
:devDocker tag, not:latest. Run it if you want the fixes early and can tolerate rough edges; report anything you hit.Summary
This candidate is mostly MeshCore work plus two map-interaction fixes. The headline feature is strict receive-only mode for MeshCore Companion sources — a per-source switch that holds every transmitting command, scheduler and automation while leaving receive, the packet log, the Analyzer Observer and local serial configuration fully working. Because MeshCore firmware has no radio-level transmit switch, this is enforced in software; link-layer acknowledgements and any advert schedule configured outside MeshMonitor are unaffected, and the UI says so plainly. The Analyzer Observer gained battery, uptime and noise-floor reporting, and it now hot-swaps its publisher when you import a signing key instead of demanding a source disable/re-enable cycle. On the permissions side, MeshCore contact positions now honor
canViewOnMap, matching how Meshtastic nodes have always behaved — a migration backfills the flag so no existing user loses map access on upgrade. Two map fixes: clicking a marker now zooms in first only when the marker is genuinely crowded (isolated markers open their popup immediately at any zoom), and the threshold that governs it is configurable rather than hardcoded at z13. The zoom-to-fit button also stopped wearing a crosshair icon, which everyone reasonably read as "center on my GPS location."Features
- MeshCore strict receive-only mode — per-source enforcement (#4550), UI (#4552), and Virtual Node gating plus docs (#4555). Closes #4547.
- Analyzer Observer publishes battery, uptime and noise floor in its status payload (#4557). Closes #4556.
Bug Fixes
- MeshCore map positions now require
canViewOnMapinstead of onlynodes:read, so a read-only user can see the contact list without learning where those nodes are (#4560). Closes #4559. - Marker clicks gate on density, not zoom alone — an isolated marker opens its popup on the first click at any zoom, and the crowding threshold is now a setting (#4563). Closes #4551.
- Zoom-to-fit no longer uses the locate-me crosshair icon (#4564). Closes #4562.
- MeshCore contact Last Heard updates on incoming direct messages (#4554). Closes #4553.
- Analyzer Observer hot-swaps its publisher on a signing-key change — no more disable/re-enable dance after importing a key (#4544). Closes #4543.
- DeviceMetadata arriving before MyNodeInfo is buffered rather than dropped (#4548).
- Remote admin stops implying it knows a remote node's favorite/ignored state — the admin protocol has no readback for those flags, so the UI no longer pretends otherwise (#4542). Closes #4511.
Documentation
- Documented the new Map Click Zoom Gate setting and the MeshCore
canViewOnMapchange, including the upgrade backfill (#4565). - Site gallery: added Norway Østlandet Mesh (#4546). Closes #4545.
Tests / CI
- System tests moved off the v1 API root paths removed in 4.14 (#4565). The
/api/v1/nodes-style root paths were deleted in 4.14 (#4117); because a 404 body isn't JSON, every assertion was dying insidejqwith an opaque parse error. The same change corrects/api/upgrade/*from the transitional410to its post-removal404. Nothing user-facing — but the suite is honest again.
Translations
- Weblate updates (#4541, #4252) — thank you to everyone translating.
Upgrade Notes
- Migration 135 backfills
canViewOnMapon existingnodesgrants for MeshCore sources that already had read access, so current users keep map visibility across the upgrade. New grants must set the flag explicitly. - Receive-only mode is per source and defaults to off. Nothing changes unless you turn it on.
Thanks
- @wilhel1812 for reporting the zoom-to-fit icon confusion in Discord (#45 …
v4.14.0 # 4 days ago · 2026-08-03 18:26 UTC
MeshMonitor v4.14.0
The first stable release since v4.13.2 — the 4.13.3 release candidates were folded into this minor instead, because the work that landed is a minor's worth, not a patch's. The headline is the MeshCore Analyzer Observer: publish what your Companion hears to a regional analyzer without a second app fighting for the serial port, observation-only by design. Meshtastic and MeshCore sources now share one navigation system, which on phones means a bottom bar that scrolls sideways with readable labels instead of eleven crushed icons. Remote admin gained distinct ACK outcomes — rejected reads differently from timed out — plus opt-in auto-retry, and commands no longer die when the browser navigates away. MeshCore messages carry SNR and RSSI when heard directly, "Discover Nodes" now lists who answered with signal in both directions, and per-channel permissions finally do what they say. Node Details shows where a position came from and how precise it is, and Null Island estimates are no longer passed off as real fixes. The Packet Monitor's node filters became searchable comboboxes, which matters most on a phone and on a large mesh. Under the hood, the database driver moved to better-sqlite3 13 (N-API), verified at runtime on amd64, arm64 and armv7 before shipping.
⚠️ Breaking Change: v1 API root paths removed
4.13 moved the v1 mesh-data endpoints under
/api/v1/sources/{sourceId}/…and kept the old root paths alive for one release behind aWarning: 299header. That grace period ends here — these paths now return 404:/api/v1/nodes /api/v1/telemetry /api/v1/network /api/v1/messages /api/v1/traceroutes /api/v1/status /api/v1/channels /api/v1/packets /api/v1/position-historyMigrate by moving the source into the path:
# Before (4.13, deprecated) curl -H "Authorization: Bearer mm_v1_…" "https://host/api/v1/nodes?sourceId=abc123" # After (4.14) curl -H "Authorization: Bearer mm_v1_…" "https://host/api/v1/sources/abc123/nodes"GET /api/v1/sourceslists your source ids, or use the literaldefaultto target the primary source. The/api/upgrade/*endpoints, returning410 Gonesince 4.13, are also removed.If you script against the REST API, check for these paths before upgrading. Everything else is drop-in; the database schema migrates automatically on first boot.
Full details in the release announcement.
Features
- feat(analysis): show node names in the ok_to_mqtt violations report (#4343)
- feat(i18n): localize the MapStyleManager settings component (#4363)
- feat(meshcore): serve ExportPrivateKey over the Virtual Node behind an "Allow PKI export" gate (#4366)
- feat(automations): hop-count tapback + {{ trigger.hopEmoji }} (#4340 phase 1) (#4390)
- feat(traceroute): visual node strip on the Node Details panel (#4392)
- feat(automations): per-node cooldown scope (#4340 phase 2) (#4396)
- feat(meshcore): add per-node ignore list to the auto-responder (#4402)
- feat(map): per-overlay toggle to disable the GeoJSON click popup (#4403)
- feat(meshcore): add zero-hop ping action (#4404)
- feat(tx-guard): allow sends when UDP Broadcast can relay for a TX-disabled node (#4405)
- feat(waypoints): let the user pick the broadcast channel (#4406)
- feat(automations): Auto-Ack parity conditions (#4340 phase 3) (#4407)
- feat(automations): Auto-Acknowledge → Automation converter (#4340 phase 4) (#4408)
- feat(settings): per-source settings foundation and guardrails (#4412 Phase 1) (#4417)
- feat(traceroute): interactive strip — node popup More Details action + link tooltips (epic phase 1) (#4424)
- feat(settings): read Node Display settings per-source (#4412 Phase 2) (#4425)
- feat(traceroute): participation picker on all sources — brings the strip to MQTT (epic phase 2) (#4427)
- feat(traceroute): Copy Forward/Return/Both text links with insecure-context fallback (#4429) …
v4.13.3-rc5 # Pre-release 6 days ago · 2026-08-01 18:42 UTC
Release candidate 5 for 4.13.3. Twelve changes since rc4.
Remote administration no longer blocks on the mesh
Issue #4482 — a single remote admin action could legitimately hold a browser HTTP request open for up to 75 seconds (up to 45s acquiring the session passkey, plus up to 30s awaiting a routing ACK). Behind a reverse proxy or CDN that surfaced as an upstream 502 with an unhelpful "Request failed".
Remote admin commands, session-passkey acquisition, and remote config import now return
202 Acceptedwith an operation id and complete in the background, polled viaGET /api/admin/operations/:id. Local-node commands stay synchronous — they have no passkey step and no ACK wait.- Remote ignore/unignore now confirm. They wait for the routing ACK exactly as favorites do, so a remote ignore can be verified rather than "succeeding" instantly with no way to check.
- Partial config imports report what failed, not just what landed — "1 channel" is now distinguishable from "1 of 2 channels".
(#4485, #4486; documented in #4490)
Admin messages honor the configured hop limit
Admin packets were built with a hardcoded
hopLimit: 3— the firmware default, not the user's setting. Anyone who raised their node's LoRa hop limit to reach a deeper mesh still had every remote admin command expire 3 hops out, with no indication why. They now use the node's configured value, matching how the Meshtastic Python client behaves. (#4479)Fixes
GET /statsreturned 500 wheneversourceIdwas omitted — the cross-source aggregate path had never worked (#4470)- MeshCore: anon auth banner, channel-sync data loss, reply/trigger ordering (#4491)
- MeshCore: channel view now opens at the top, and Delete no longer appears to do nothing (#4488)
- MeshCore: hop/route/scope info preserved in channel message history (#4475)
- Older-message loads no longer force-scroll the view to the bottom (#4477)
- Restored the send-message button icon (#4480)
Navigation
- Unified Meshtastic/MeshCore per-source navigation (#4481)
- Meshtastic phone navigation moved to the shared bottom bar (#4484)
Validation
Full system-test suite passed on hardware — all 12 legs, including Configuration Import, which exercises the newly-async
/api/admin/import-configpath and the hop-limit change against a real device. This is the first build to put the async remote-admin work in front of hardware; it shipped on unit and route coverage alone.🚀 MeshMonitor v4.13.3-rc5
📦 Installation
Docker (recommended):
docker run -d \ --name meshmonitor \ -p 8080:3001 \ -v meshmonitor-data:/data \ ghcr.io/Yeraze/meshmonitor:4.13.3-rc5🧪 Testing
✅ All tests passed ✅ TypeScript checks passed ✅ Docker images built for linux/amd64, linux/arm64, linux/arm/v7
📋 Changes
See commit history for detailed changes.
Project signals
- GitHub stars
- 601
- Forks
- 74
- Watchers
- 5
- Open issues
- 20
- Contributors
- 36
- Release downloads
- 5,073
- Latest downloads
- 34
- Source available
- Yes
- Releases available
- Yes
- Signed releases
- No
- CI builds
- Yes
- Documentation
- Yes
- MeshCore devices connect over USB or TCP; BLE support uses a bridge sidecar.
- Native Windows and macOS desktop installers are published with GitHub releases.
- Docker images are published for amd64, arm64 and armv7.