diff --git a/package.json b/package.json
index d99bc88..f7e1a74 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "netfelix-audio-fix",
- "version": "2026.04.14.2",
+ "version": "2026.04.14.3",
"scripts": {
"dev:server": "NODE_ENV=development bun --hot server/index.tsx",
"dev:client": "vite",
diff --git a/src/features/settings/MqttSection.tsx b/src/features/settings/MqttSection.tsx
index b696c48..079516e 100644
--- a/src/features/settings/MqttSection.tsx
+++ b/src/features/settings/MqttSection.tsx
@@ -28,6 +28,23 @@ const HANDLEBARS_TEMPLATE = `{
"itemType": "{{ItemType}}"
}`;
+/**
+ * Pull host / port / TLS out of the mqtt_url the user saved. The Jellyfin
+ * plugin's MQTT destination asks for host and port as separate fields
+ * plus an explicit TLS checkbox, whereas we store a single URL.
+ */
+function parseBroker(raw: string): { host: string; port: string; useTls: boolean } {
+ if (!raw) return { host: "", port: "1883", useTls: false };
+ try {
+ const u = new URL(raw);
+ const useTls = u.protocol === "mqtts:" || u.protocol === "wss:";
+ const port = u.port || (useTls ? "8883" : "1883");
+ return { host: u.hostname, port, useTls };
+ } catch {
+ return { host: "", port: "1883", useTls: false };
+ }
+}
+
function CopyableValue({ label, value, mono = true }: { label: string; value: string; mono?: boolean }) {
const [copied, setCopied] = useState(false);
const copy = async () => {
@@ -230,13 +247,40 @@ export function MqttSection({ cfg, locked }: { cfg: Record
+ Open Jellyfin → Dashboard → Plugins → Webhook → Add Generic Destination → MQTT + tab, and fill in: +
+ {(() => { + const broker = parseBroker(url); + const useCredentials = !!(username || cfg.mqtt_password); + return ( ++ Jellyfin's plugin doesn't expose an "Item Updated" event. When we rewrite a file, Jellyfin treats it as a new add + and fires Item Added — that's the event we listen for. +
);