Meshtastic Monitor
A tiny web dashboard + JSON API for Meshtastic over TCP (direct to your node, default port 4403).
What you need (before you start)
- A Meshtastic node reachable over Wi‑Fi (you know its IP/hostname)
- Python
3.9+
Start (2 minutes)
1) Install (one time)
pip install meshtastic-monitor
If pip is not available, use:
python3 -m pip install meshtastic-monitor
2) Run
python -m meshtastic_monitor --host YOUR_MESH_IP
If python is not available, use:
python3 -m meshtastic_monitor --host YOUR_MESH_IP
Then open:
- UI:
http://localhost:8880/ - Health (JSON):
http://localhost:8880/api/health
If you run this on another computer in your LAN, open:
http://SERVER_IP:8880/
2a) Config file (created automatically)
On first run, a config file is created in the current folder:
./meshmon.ini
This file stores your mesh host/port, optional TCP relay, and SMS relay settings. You can also choose a custom path:
python -m meshtastic_monitor --config /path/to/meshmon.ini
3) Stop
Press Ctrl+C in the terminal where it is running.
Configure (if you didn’t pass --host)
- Open the UI
- Click Settings
- Put your Meshtastic IP/host + port (
4403) - Click Save & Apply
The UI stores these settings in your browser (localStorage) and the backend config file
(meshmon.ini) when started via python -m meshtastic_monitor.
SMS relay (optional)
If you want every incoming packet forwarded via SMS, configure it in Settings:
- Enable SMS relay
- Set SMS API URL, API key, and Phone
You can also apply allow-list filters:
- Allowed From IDs (comma-separated or
ALL) - Allowed Types (comma-separated or
ALL)- Types can be
TEXT, app names (e.g.POSITION_APP), or port numbers (e.g.5)
- Types can be
TCP relay (optional)
If you want more than one TCP client, enable the relay. The app will keep a single connection to your radio and expose a TCP port for other clients:
- Enable TCP relay
- Listen host:
0.0.0.0(default) - Listen port:
4403(default)
Other clients should then connect to your app machine on RELAY_HOST:RELAY_PORT
instead of connecting directly to the radio.
Where to see relay status
- UI: Stats → TCP Relay (upstream status + connected clients)
- API:
GET /api/relay
Security note
Binding to 0.0.0.0 exposes the relay to your LAN. Do not expose it to the public internet
unless you add firewall rules.
Command-line options (copy/paste)
Show all options:
python -m meshtastic_monitor --help
Most used:
--host/--mesh-host(Meshtastic IP/hostname)--mesh-port(default4403)--http-port(default8880)--log-file(default./meshmon.log)--log-level(defaultINFO)--nodes-history-interval(default60seconds)--config(path tomeshmon.ini)--sms-enabled/--sms-disabled--sms-api-url--sms-api-key--sms-phone--sms-allow-from(comma-separated sender IDs orALL)--sms-allow-types(comma-separated types orALL)--relay-enabled/--relay-disabled--relay-host(default0.0.0.0)--relay-port(default4403)
You can also set env vars instead of flags:
MESH_HOST(default empty; can also be set via UI)MESH_PORT(default4403)HTTP_PORT(default8880when usingpython -m meshtastic_monitor)NODES_REFRESH_SEC(default5) refresh live node snapshotMAX_MESSAGES(default200) in-memory ring buffer sizeSTATS_DB_PATH(defaultmeshmon.db, set tooffto disable persistence)NODES_HISTORY_INTERVAL_SEC(default60) how often to store node history samplesSTATUS_HISTORY_INTERVAL_SEC(default60) how often to store status samplesSTATS_WINDOW_HOURS(default24) used by/api/statsMESH_HTTP_PORT(default80) forhttp://MESH_HOST[:port]/json/reportSTATUS_TTL_SEC(default5) cache/json/reportfor this many secondsLOG_LEVEL(defaultINFO)MESHMON_LOG_FILE(default./meshmon.log)MESHMON_CONFIG(path tomeshmon.ini)SMS_ENABLED(1/0)SMS_API_URL(base URL, e.g.https://your-sms-gateway.example/api)SMS_API_KEYSMS_PHONESMS_ALLOW_FROM_IDS(comma-separated sender IDs orALL)SMS_ALLOW_TYPES(comma-separated types orALL)SMS_TIMEOUT_SEC(seconds, default4)RELAY_ENABLED(1/0)RELAY_HOST(default0.0.0.0)RELAY_PORT(default4403)
Logs (where are they?)
By default the app writes logs to:
./meshmon.log(the directory where you started the command)
You can change it:
python -m meshtastic_monitor --log-file /path/to/meshmon.log
Logs are rotated (to avoid infinite growth): ~2MB per file, up to 3 backups.
TCP relay events (listen/upstream/client connect/disconnect) are logged to the same file.
How it works (simple mental model)
Two layers
- Backend (Python/Flask) exposes JSON endpoints under
/api/*and serves the UI. - Frontend (HTML/JS) is just static files that poll the JSON API.
What it connects to
- Meshtastic TCP interface (library:
meshtastic, class:TCPInterface) - Your node’s optional HTTP status endpoint:
http://<mesh-host>/json/report
Data flow (incoming packets)
- Backend connects to your node over TCP (
MESH_HOST:MESH_PORT) - The
meshtasticlibrary publishes received packets onmeshtastic.receive(viapypubsub) - We convert every packet to a thin, JSON-safe dict (no raw
bytes) and:- keep the last
MAX_MESSAGESin memory - store everything in SQLite (if enabled)
- keep the last
- If SMS relay is enabled, the packet is forwarded to your SMS gateway URL
Nodes
- Live node list comes from the Meshtastic node DB (
iface.nodes) - Node history is sampled to the DB every
NODES_HISTORY_INTERVAL_SECseconds (default60) to avoid DB explosion
Status (“/json/report”)
- The UI shows a nice summary of
http://<mesh-host>/json/report(if your node exposes it) - Backend caches it for
STATUS_TTL_SECand stores a compact subset in SQLite everySTATUS_HISTORY_INTERVAL_SEC
Persistence (history / database)
By default, the app creates a SQLite file:
meshmon.db
It stores:
- message history (so you can scroll back)
- per-node counters (
fromCount,toCount, last RSSI/SNR, etc.) - node “quality over time” samples (SNR/quality/hops/lastHeard)
- mesh connect/disconnect/error events
- compact status samples (battery/utilization/wifi/etc.)
To disable persistence:
export STATS_DB_PATH=off
python -m meshtastic_monitor --host YOUR_MESH_IP
To reset history: stop the app and delete meshmon.db.
Security notes (important)
- There is no login/auth. Run this only on a trusted network.
GET /api/device/configredacts PSKs by default.GET /api/device/config?includeSecrets=1will include secrets — do this only if you understand the risk.
API (for developers)
Quick overview:
GET /api/health– backend status + mesh connection statusGET /api/status– cached/json/report+ link to the JSONGET /api/config– current runtime config (mesh + SMS, no secrets)GET /api/nodes– live nodes (direct + relayed)GET /api/messages– message history (SQLite if enabled, else memory)POST /api/send– send text (optionaltoandchannel)GET /api/relay– TCP relay status + connected clientsGET /api/stats– aggregates + charts dataGET /api/node/<id>– combined live + persisted stats for one nodeGET /api/nodes/history/GET /api/node/<id>/history– history samples
Example:
curl -s http://localhost:8880/api/health
curl -s http://localhost:8880/api/nodes
curl -s http://localhost:8880/api/messages?limit=20
curl -s -X POST http://localhost:8880/api/send -H 'Content-Type: application/json' -d '{"text":"hello","channel":0}'
Development (optional)
From a git checkout:
pip install -U pip
pip install -e .
pip install -r backend/requirements-dev.txt
pytest -q
Metadata
Release files for meshtastic-monitor 0.1.29
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| meshtastic_monitor-0.1.29.tar.gz | 74.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| meshtastic_monitor-0.1.29-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 150.3 kB
Release files / meshtastic_monitor-0.1.29.tar.gz
| Download URL | meshtastic_monitor-0.1.29.tar.gz |
|---|---|
| Size | 74.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7f809688af5ac7209be0400c14b9949dabd2ac26d1324969df0ebe6725256920
|
|
BLAKE2b-256 checksum How to use checksums |
aee867f351e4bc50d69fe422c3c2a65a9845168544646b2ca7090b3f690b3b66
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|
Release files / meshtastic_monitor-0.1.29-py3-none-any.whl
| Download URL | meshtastic_monitor-0.1.29-py3-none-any.whl |
|---|---|
| Size | 75.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
336b901ada8aa74537e7d29b0e47745cd6675ce1168a2a01788539cab6975c2f
|
|
BLAKE2b-256 checksum How to use checksums |
e40995928caae0a0a60662ff93722d19f7de8767ce52ce3f2ba6f826fa35c49c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|