Deployment defaults
Legacy hybrid installs are possible: a systemd or launchd unit may wrap a checkout under a user's home directory and load .env.local, without /opt or /etc TOML files. Inspect the running command, working directory, service unit, and environment/config source before choosing the modern managed-install path.
- Manual/PyPI:
pipx install meshcore-packet-capture gives the CLI and does not install a background service.
- Managed Linux/macOS: the root bootstrap installer creates
/opt/meshcore-packet-capture, /etc/meshcore-packet-capture, a virtual environment, and a system service. It installs the latest published release by default; use --tag or --branch to pin.
- User service (v2.1.0+): for a local checkout on Linux,
./install.sh --user-service creates a per-user systemd service that runs from the checkout's .venv (pass --repo-dir PATH if the checkout is not the script's directory). Config files live in the repo itself (.env, .env.local, config.toml, config.d/). Remove with ./uninstall.sh --user-service from the same checkout; add --remove-venv to also delete the local .venv. Manage with systemctl --user status|restart meshcore-packet-capture and journalctl --user -u meshcore-packet-capture -f.
- macOS BLE: use the per-user LaunchAgent because Bluetooth permission belongs to the login user. Serial/TCP can use a LaunchDaemon.
- Docker: use the published image or
docker compose up -d; serial needs a device mapping, while BLE generally needs privileged: true and may need host networking. Linux is the most reliable container host for hardware access.
- NixOS: use
services.meshcore-packet-capture and rebuild with sudo nixos-rebuild switch.
Read references/deployment-and-troubleshooting.md for service commands, Docker hardware access, migration/update behavior, and bounded diagnostics.
Output and verification
Normal mode prints minimal packet information. --verbose adds JSON packet data; --debug adds connection, retry, packet parsing, and MQTT diagnostics. --output PATH writes packet data to a file. Captured records include device identity, timestamp, packet type, route, payload length, raw hex, SNR, RSSI, and a hash. When decode_payloads is enabled, records also carry a nested decoded object with human-readable fields (channel message sender/text, ADVERT name/role/coordinates, type/route labels).
When troubleshooting, collect evidence in this order:
meshcore-packet-capture --debug --no-mqtt and confirm a real BLE, serial, or TCP connection.
- Confirm packet records appear in console or the
--output file.
- Enable one broker and inspect broker connection/reconnect messages.
- Check the resolved environment/config and topic names, without printing secrets.
- For a managed service, inspect the service's own logs and status. For Docker, use
docker compose config, docker compose ps, and docker compose logs.
Do not delete the install directory, state directory, or configuration during diagnosis. The uninstaller is interactive and backs up user configuration, but it still performs destructive removal only after confirmation.
When not to use
Do not use this skill for MeshCore repeater or RoomServer packet capture, generic MQTT administration, or implementing changes inside the upstream repository. For code changes, use the repository's contribution workflow and verify the project tests separately.
References
Completion condition
Stop when the selected transport connects, a packet is observed locally, the intended MQTT topic receives data if MQTT is in scope, and the relevant service/container reports healthy. If hardware, credentials, or broker access is unavailable, report that exact unverified boundary instead of claiming success.