macOS internet connection monitor
Project description
mb-netwatch
macOS internet connection monitor. Tracks latency, VPN status, and public IP at a glance via a menu bar icon.
Status: Under active development.
What it monitors
Three types of checks run continuously in the background:
- Latency — HTTP probes against captive portal endpoints every 2 seconds (first response wins)
- VPN status — tunnel interface and routing table detection every 10 seconds
- Public IP — address and country code via plain-text IP services every 60 seconds
See docs/probes.md for detailed algorithms, endpoints, and design rationale.
CLI commands
mb-netwatch— TUI dashboard (default when no command given)mb-netwatch probe— one-shot connectivity probe, print resultmb-netwatch probed— run continuous background measurementsmb-netwatch tray— run menu bar UI processmb-netwatch start [probed|tray]— start processes in the background (no argument = both)mb-netwatch stop [probed|tray]— stop background processes (no argument = both)
Architecture
General CLI application architecture patterns are described in docs/cli-architecture.md. Database schema and storage rules are in docs/db.md. Below is the project-specific structure.
Core (core/)
Central application layer. Holds database, business logic, and probe implementations. Consumers never import from core/ directly — they receive a Core instance and access everything through it:
core.db— database (reads and writes)core.config— application configurationcore.service— business logic (running probes, storing results)
Consumers
Three independent consumers of Core:
- CLI (
cli/) — command-line interface. Each command receivesCoreandOutputviaCoreContext. - TUI (
tui/) — Textual terminal dashboard. Pollscore.dbfor latest results and renders a live view with latency sparkline, VPN/IP status, and recent events. - Daemon (
daemon.py) — long-running background process. Orchestrates scheduling (loops, timers, signals) and delegates all probe/store logic tocore.service. - Tray (
tray.py) — macOS menu bar UI. Pollscore.dbfor latest results and updates the icon.
Processes
Two long-running processes in normal operation:
- probed (
mb-netwatch probed) — runs the daemon; measures latency every 2 s, VPN status every 10 s, public IP every 60 s; writes to SQLite viacore.service. - tray (
mb-netwatch tray) — UI only; reads latest samples from SQLite viacore.db, updates menu bar icon and dropdown.
The tray must not perform network probing directly. This separation keeps UI responsive and simplifies debugging.
Storage
SQLite database at ~/.local/mb-netwatch/netwatch.db (WAL mode).
See docs/db.md for schema, deduplication strategy, and retention rules.
Configuration
Optional TOML config at ~/.local/mb-netwatch/config.toml. The file is not created automatically — create it only if you want to override defaults. All keys are optional — only specify what you want to change.
[probed]
latency_interval = 2.0 # seconds between latency probes (default: 2.0)
vpn_interval = 10.0 # seconds between VPN status checks (default: 10.0)
ip_interval = 60.0 # seconds between public IP lookups (default: 60.0)
purge_interval = 3600.0 # seconds between old-data purge runs (default: 3600.0)
latency_timeout = 5.0 # HTTP timeout for latency probes (default: 5.0)
ip_timeout = 5.0 # HTTP timeout for IP/country lookups (default: 5.0)
retention_days = 30 # days to keep raw rows before purging (default: 30)
[latency_threshold]
ok_ms = 300 # latency below this → OK (default: 300)
slow_ms = 800 # latency below this → SLOW, at or above → BAD (default: 800)
stale_seconds = 10.0 # seconds before data is considered stale (default: 10.0)
[tray]
poll_interval = 2.0 # seconds between tray DB polls (default: 2.0)
[tui]
poll_interval = 0.5 # seconds between TUI dashboard DB polls (default: 0.5)
latency_history_max = 300 # max latency readings in sparkline (default: 300)
The menu bar shows a fixed-width 3-character title: 2-letter country code + status symbol (● OK / ◐ SLOW / ○ BAD / ✕ DOWN), e.g. US●. Click the menu bar icon to see the exact latency in the dropdown. If probed stops writing data, the symbol changes to – (en dash) after stale_seconds seconds (default 10). While waiting for the first data, a middle dot · is displayed.
Installation
uv tool install mb-netwatch
mb-netwatch start
Tech stack
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mb_netwatch-0.1.4.tar.gz.
File metadata
- Download URL: mb_netwatch-0.1.4.tar.gz
- Upload date:
- Size: 36.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.4 {"installer":{"name":"uv","version":"0.11.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
838b995b1c34f0e819e223c051bbac66deefb8eb1b3fdcefe8d37d5d27b74165
|
|
| MD5 |
735165ac914d4036dd28e82de59dd918
|
|
| BLAKE2b-256 |
2c963c4d43921012974b3040f5162adc4b71ff6b2ba8d7b645b17eace7f8cda4
|
File details
Details for the file mb_netwatch-0.1.4-py3-none-any.whl.
File metadata
- Download URL: mb_netwatch-0.1.4-py3-none-any.whl
- Upload date:
- Size: 39.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.4 {"installer":{"name":"uv","version":"0.11.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4fd95020311bba35c0cf0e538370dd886abe0438a4af00627ab226459687bead
|
|
| MD5 |
efc7920c2b30555641742f23400830a8
|
|
| BLAKE2b-256 |
ea3adb652806b3a7a4b8edbfb33ad03b65fcedcedcf426687b27a4939fe20ec3
|