UNPKG

domotz-mcp

Version:

MCP server for Domotz API and BMS (Building Management System) integration with IoT device monitoring

122 lines (121 loc) 4.63 kB
import mqtt from "mqtt"; import { z } from "zod"; import { MCPTool } from "mcp-framework"; // Store active MQTT connections const mqttConnections = new Map(); export default class MQTTConnectionTool extends MCPTool { name = "mqtt_connect"; description = "Connect to an MQTT broker for IoT device communication"; schema = { broker_url: { type: z.string(), description: "MQTT broker URL (e.g., mqtt://localhost, ws://broker.hivemq.com)" }, client_id: { type: z.string().optional(), description: "Client ID for the connection (auto-generated if not provided)" }, username: { type: z.string().optional(), description: "Username for authentication" }, password: { type: z.string().optional(), description: "Password for authentication" }, port: { type: z.string().optional(), description: "Port number (default: 1883 for mqtt, 8083 for ws)" }, clean_session: { type: z.boolean().optional(), description: "Start with clean session (default: true)" }, keepalive: { type: z.string().optional(), description: "Keepalive interval in seconds (default: 60)" } }; async execute(params) { try { const { broker_url, client_id = `mcp_${Date.now()}`, username, password, port, clean_session = true, keepalive = "60" } = params; // Close existing connection if any const existingClient = mqttConnections.get(client_id); if (existingClient) { existingClient.end(); mqttConnections.delete(client_id); } // Parse broker URL and set default port if not provided let connectUrl = broker_url; // Ensure the URL has a protocol if (!broker_url.startsWith('mqtt://') && !broker_url.startsWith('mqtts://') && !broker_url.startsWith('ws://') && !broker_url.startsWith('wss://')) { // If no protocol specified, assume mqtts:// for port 8883, mqtt:// otherwise const protocol = port === '8883' ? 'mqtts://' : 'mqtt://'; connectUrl = protocol + broker_url; } if (port) { try { const url = new URL(connectUrl); url.port = port; connectUrl = url.toString(); } catch (e) { return { success: false, error: `Invalid broker URL: ${broker_url}` }; } } // Connection options const options = { clientId: client_id, clean: clean_session, keepalive: parseInt(keepalive), reconnectPeriod: 5000, }; if (username) { options.username = username; options.password = password; } // Create connection const client = mqtt.connect(connectUrl, options); return new Promise((resolve) => { const timeout = setTimeout(() => { client.end(); resolve({ success: false, error: "Connection timeout after 10 seconds" }); }, 10000); client.on("connect", () => { clearTimeout(timeout); mqttConnections.set(client_id, client); resolve({ success: true, message: "Connected to MQTT broker", connection_id: client_id, broker: connectUrl, status: "connected" }); }); client.on("error", (error) => { clearTimeout(timeout); client.end(); resolve({ success: false, error: `MQTT connection error: ${error.message}` }); }); }); } catch (error) { return { success: false, error: error.message || "Failed to connect to MQTT broker" }; } } } // Export the connections map for use in other tools export { mqttConnections };