meshmap
A tool for scanning and mapping meshcore radio networks. It discovers nearby nodes, logs in to each reachable repeater to enumerate its neighbours, and builds a graph of the network — including GPS coordinates where available.
Install
Requires Python 3.12+ and uv.
# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone and install
git clone https://github.com/mangelajo/meshmap
cd meshmap
uv sync
The meshmap command is then available via uv run meshmap.
Usage
All commands require -p to specify the serial port of your connected device.
meshmap -p PORT [OPTIONS] COMMAND
Global options (apply to all commands):
| Flag | Description |
|---|---|
-p, --serial-port |
Serial port (e.g. /dev/ttyUSB0, COM3) |
--sniff |
Print decoded RF packets in real time |
--sniff-key PATH |
Private key file for decryption (repeatable) |
-d, --debug |
Low-level meshcore debug output |
Commands
explore — map the network graph
The main command. Discovers 0-hop repeaters, then recursively logs in to each one to fetch its neighbour list, building a full network graph. Saves to a JSON file after each node so it can be paused and resumed.
# First scan
uv run meshmap -p /dev/ttyUSB0 explore
# Resume a previous scan, open live visualisation in browser
uv run meshmap -p /dev/ttyUSB0 explore --resume --serve
# Re-visit already-explored nodes to refresh SNR data
uv run meshmap -p /dev/ttyUSB0 explore --resume --refresh
# Retry nodes that failed on the last run
uv run meshmap -p /dev/ttyUSB0 explore --resume --retry
# Limit exploration to 3 hops, save to a custom file
uv run meshmap -p /dev/ttyUSB0 explore --depth 3 -o my-network.json
# Full run with live packet sniffing and web visualisation
uv run meshmap -p /dev/ttyUSB0 --sniff --sniff-key mykey.txt explore --serve --resume
The web visualisation (--serve) is available at http://localhost:8080 and auto-refreshes every 3 seconds while the scan runs.
| Option | Default | Description |
|---|---|---|
-o, --output |
meshmap-graph.json |
Output file |
--resume |
off | Load existing graph, skip already-visited nodes |
--refresh |
off | Re-queue already-visited nodes (oldest first) |
--retry |
off | Re-queue nodes whose last visit failed |
--serve |
off | Start web visualisation server |
--port |
8080 |
Web server port |
--depth |
5 |
Max BFS hop depth |
-w, --wait-time |
10.0 |
Seconds to wait for 0-hop discovery responses |
discover-repeaters — list nearby repeaters
uv run meshmap -p /dev/ttyUSB0 discover-repeaters
get-neighbours — inspect a single repeater
Log in to one repeater and print its neighbour list.
uv run meshmap -p /dev/ttyUSB0 get-neighbours
sniff — decode RF packets
Listen and decode raw RF traffic for a given duration.
uv run meshmap -p /dev/ttyUSB0 sniff 30
uv run meshmap -p /dev/ttyUSB0 sniff 60 --key mykey.txt
contacts — list known contacts
uv run meshmap -p /dev/ttyUSB0 contacts
scan — quick 0-hop node scan
uv run meshmap -p /dev/ttyUSB0 scan
Graph file format
The graph is saved as JSON and can be loaded by external tools:
{
"version": 1,
"last_updated": "2026-02-17T12:00:00+00:00",
"nodes": {
"<pubkey>": {
"public_key": "...", "name": "My Repeater",
"node_type": "repeater", "lat": 40.4, "lon": -3.7,
"depth": 1, "last_visited": "...", "visit_failed": false
}
},
"edges": [
{ "node_a": "...", "node_b": "...", "snr_a_hears_b": 12.5, "snr_b_hears_a": 9.0, "last_seen": "..." }
]
}
Metadata
Release files for meshmap 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| meshmap-0.1.0.tar.gz | 69.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| meshmap-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 128.4 kB
Release files / meshmap-0.1.0.tar.gz
| Download URL | meshmap-0.1.0.tar.gz |
|---|---|
| Size | 69.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dfb86aa0cc8d1540d0e42ecfce9bb21e7574b6a9a9605bbea9d1f35283c79b20
|
|
BLAKE2b-256 checksum How to use checksums |
94eeb8f8d95f425d1c798605604bf33150fb789ddaacad449be29977fe9a9d63
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.22
|
Release files / meshmap-0.1.0-py3-none-any.whl
| Download URL | meshmap-0.1.0-py3-none-any.whl |
|---|---|
| Size | 58.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a9f717a07cb86bd4fa6847c4d2fa8ca108a61abbe8762a48aeaeddad38646620
|
|
BLAKE2b-256 checksum How to use checksums |
429944c28133679bed5ccb92dbbf0dfca39c65f02e52950aa6e141784e42b727
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.22
|