Align MQTT_TRANSPORT and MQTT_WS_PATH defaults with MeshCore broker requirements

The MeshCore MQTT broker requires WebSocket transport, but Python defaults
were still tcp and /mqtt from the Mosquitto era. Align all defaults to
websockets and / to match Docker Compose and documented behavior.

Also fixes docs-sync audit findings:
- Remove stale PLAN.md/TASKS.md references from AGENTS.md
- Add missing NETWORK_DOMAIN, NETWORK_NAME vars to AGENTS.md env list
- Add missing WEBHOOK_CHANNEL_MESSAGE_SECRET and WEBHOOK_DIRECT_MESSAGE_SECRET
  to AGENTS.md webhook table
- Add native install note for MQTT_HOST in .env.example
- Update UPGRADING.md note to reflect aligned defaults
This commit is contained in:
Louis King
2026-04-17 18:16:25 +01:00
parent 179e3bd39b
commit 5bec26e5ff
9 changed files with 21 additions and 18 deletions
+1
View File
@@ -77,6 +77,7 @@ SEED_HOME=./seed
# MQTT Broker host
# When using the local MQTT broker (--profile mqtt), use "mqtt"
# When using an external broker, set the hostname/IP
# For native (non-Docker) installs, use "localhost" (the Python default)
MQTT_HOST=mqtt
# MQTT Broker port
+5 -3
View File
@@ -15,7 +15,7 @@ This document provides context and guidelines for AI coding assistants working o
- `source .venv/bin/activate`
* You MUST install all project dependencies using `pip install -e ".[dev]"` command`
* You MUST install `pre-commit` for quality checks
* You MUST keep project documentation in sync with behavior/config/schema changes made in code (at minimum update relevant sections in `README.md`, `SCHEMAS.md`, `PLAN.md`, and/or `TASKS.md` when applicable)
* You MUST keep project documentation in sync with behavior/config/schema changes made in code (at minimum update relevant sections in `README.md`, `SCHEMAS.md`, and/or `UPGRADING.md` when applicable)
* Before commiting:
- Run **targeted tests** for the components you changed, not the full suite:
- `pytest tests/test_web/` for web-only changes (templates, static JS, web routes)
@@ -593,8 +593,6 @@ meshcore-hub collector
## Environment Variables
See [PLAN.md](PLAN.md#configuration-environment-variables) for complete list.
Key variables:
- `COMPOSE_PROJECT_NAME` - Docker Compose project prefix for containers and volumes (default: `hub`)
- `DATA_HOME` - Base directory for runtime data (default: `./data`)
@@ -613,6 +611,8 @@ Key variables:
- `WEB_AUTO_REFRESH_SECONDS` - Auto-refresh interval in seconds for list pages (default: `30`, `0` to disable)
- `TZ` - Timezone for web dashboard date/time display (default: `UTC`, e.g., `America/New_York`, `Europe/London`)
- `FEATURE_DASHBOARD`, `FEATURE_NODES`, `FEATURE_ADVERTISEMENTS`, `FEATURE_MESSAGES`, `FEATURE_MAP`, `FEATURE_MEMBERS`, `FEATURE_PAGES` - Feature flags to enable/disable specific web dashboard pages (default: all `true`). Dependencies: Dashboard auto-disables when all of Nodes/Advertisements/Messages are disabled. Map auto-disables when Nodes is disabled.
- `NETWORK_DOMAIN` - Network domain name (default: none)
- `NETWORK_NAME` - Network display name (default: `MeshCore Network`)
- `METRICS_ENABLED` - Enable Prometheus metrics endpoint at /metrics (default: `true`)
- `METRICS_CACHE_TTL` - Seconds to cache metrics output (default: `60`)
- `LOG_LEVEL` - Logging verbosity
@@ -692,7 +692,9 @@ The collector supports forwarding events to external HTTP endpoints:
| `WEBHOOK_MESSAGE_URL` | Webhook for all message events (channel + direct) |
| `WEBHOOK_MESSAGE_SECRET` | Secret for message webhook |
| `WEBHOOK_CHANNEL_MESSAGE_URL` | Override for channel messages only |
| `WEBHOOK_CHANNEL_MESSAGE_SECRET` | Secret for channel message webhook |
| `WEBHOOK_DIRECT_MESSAGE_URL` | Override for direct messages only |
| `WEBHOOK_DIRECT_MESSAGE_SECRET` | Secret for direct message webhook |
| `WEBHOOK_TIMEOUT` | Request timeout (default: 10.0s) |
| `WEBHOOK_MAX_RETRIES` | Max retries on failure (default: 3) |
| `WEBHOOK_RETRY_BACKOFF` | Exponential backoff multiplier (default: 2.0) |
+1 -1
View File
@@ -157,7 +157,7 @@ MQTT_WS_PORT=9001
| `MQTT_USERNAME` | (empty/optional) | Subscriber username | Now **required** for collector subscriber auth. Set to match your broker's `SUBSCRIBER_1` config. |
| `MQTT_PASSWORD` | (empty/optional) | Subscriber password | Now **required** for collector subscriber auth. Generate a secure password: `openssl rand -base64 32` |
> **Note:** The Python-level defaults for `MQTT_TRANSPORT` and `MQTT_WS_PATH` remain `tcp` and `/mqtt` respectively. The new values above are set in `.env.example` and `docker-compose.yml`, which override the Python defaults for Docker deployments. Non-Docker users must set these environment variables explicitly.
> **Note:** The Python-level defaults for `MQTT_TRANSPORT` and `MQTT_WS_PATH` are now `websockets` and `/`, matching the Docker Compose and `.env.example` values. No additional configuration is needed for non-Docker users.
### Variables to Add
+2 -2
View File
@@ -55,8 +55,8 @@ def create_app(
mqtt_password: str | None = None,
mqtt_prefix: str = "meshcore",
mqtt_tls: bool = False,
mqtt_transport: str = "tcp",
mqtt_ws_path: str = "/mqtt",
mqtt_transport: str = "websockets",
mqtt_ws_path: str = "/",
cors_origins: list[str] | None = None,
metrics_enabled: bool = True,
metrics_cache_ttl: int = 60,
+2 -2
View File
@@ -91,14 +91,14 @@ import click
@click.option(
"--mqtt-transport",
type=click.Choice(["tcp", "websockets"], case_sensitive=False),
default="tcp",
default="websockets",
envvar="MQTT_TRANSPORT",
help="MQTT transport protocol",
)
@click.option(
"--mqtt-ws-path",
type=str,
default="/mqtt",
default="/",
envvar="MQTT_WS_PATH",
help="MQTT WebSocket path (used when transport=websockets)",
)
+2 -2
View File
@@ -60,8 +60,8 @@ def get_mqtt_client(request: Request) -> MQTTClient:
mqtt_password = getattr(request.app.state, "mqtt_password", None)
mqtt_prefix = getattr(request.app.state, "mqtt_prefix", "meshcore")
mqtt_tls = getattr(request.app.state, "mqtt_tls", False)
mqtt_transport = getattr(request.app.state, "mqtt_transport", "tcp")
mqtt_ws_path = getattr(request.app.state, "mqtt_ws_path", "/mqtt")
mqtt_transport = getattr(request.app.state, "mqtt_transport", "websockets")
mqtt_ws_path = getattr(request.app.state, "mqtt_ws_path", "/")
# Use unique client ID to allow multiple API instances
unique_id = uuid.uuid4().hex[:8]
+2 -2
View File
@@ -57,14 +57,14 @@ if TYPE_CHECKING:
@click.option(
"--mqtt-transport",
type=click.Choice(["tcp", "websockets"], case_sensitive=False),
default="tcp",
default="websockets",
envvar="MQTT_TRANSPORT",
help="MQTT transport protocol",
)
@click.option(
"--mqtt-ws-path",
type=str,
default="/mqtt",
default="/",
envvar="MQTT_WS_PATH",
help="MQTT WebSocket path (used when transport=websockets)",
)
+4 -4
View File
@@ -473,8 +473,8 @@ def create_subscriber(
mqtt_password: Optional[str] = None,
mqtt_prefix: str = "meshcore",
mqtt_tls: bool = False,
mqtt_transport: str = "tcp",
mqtt_ws_path: str = "/mqtt",
mqtt_transport: str = "websockets",
mqtt_ws_path: str = "/",
database_url: str = "sqlite:///./meshcore.db",
webhook_dispatcher: Optional["WebhookDispatcher"] = None,
cleanup_enabled: bool = False,
@@ -556,8 +556,8 @@ def run_collector(
mqtt_password: Optional[str] = None,
mqtt_prefix: str = "meshcore",
mqtt_tls: bool = False,
mqtt_transport: str = "tcp",
mqtt_ws_path: str = "/mqtt",
mqtt_transport: str = "websockets",
mqtt_ws_path: str = "/",
database_url: str = "sqlite:///./meshcore.db",
webhook_dispatcher: Optional["WebhookDispatcher"] = None,
cleanup_enabled: bool = False,
+2 -2
View File
@@ -57,11 +57,11 @@ class CommonSettings(BaseSettings):
default=False, description="Enable TLS/SSL for MQTT connection"
)
mqtt_transport: MQTTTransport = Field(
default=MQTTTransport.TCP,
default=MQTTTransport.WEBSOCKETS,
description="MQTT transport protocol (tcp or websockets)",
)
mqtt_ws_path: str = Field(
default="/mqtt",
default="/",
description="WebSocket path for MQTT transport (used when MQTT_TRANSPORT=websockets)",
)