Skip to main content
Glama
unifi-client.js10 kB
import axios from 'axios'; // UniFi Cloud API base URL const CLOUD_API_BASE = 'https://api.ui.com'; // Create axios instance for UniFi Cloud API const cloudApi = axios.create({ baseURL: CLOUD_API_BASE, timeout: 30000, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); // Get API key from environment function getApiKey() { const apiKey = process.env.UNIFI_API_KEY; if (!apiKey) { throw new Error('UNIFI_API_KEY environment variable is required'); } return apiKey; } // Add API key to requests cloudApi.interceptors.request.use((config) => { config.headers['X-API-Key'] = getApiKey(); return config; }); // Response interceptor for error handling cloudApi.interceptors.response.use( (response) => response, (error) => { const message = error.response?.data?.message || error.message; const status = error.response?.status; console.error(`UniFi API Error [${status}]:`, message); throw new Error(`UniFi API Error: ${message}`); } ); // ======================================== // Hosts / Consoles // ======================================== /** * List all UniFi OS hosts (consoles) */ export async function listHosts() { const response = await cloudApi.get('/v1/hosts'); return response.data; } /** * Get a specific host by ID */ export async function getHost(hostId) { const response = await cloudApi.get(`/v1/hosts/${hostId}`); return response.data; } // ======================================== // Sites // ======================================== /** * List all sites across all hosts */ export async function listSites() { const response = await cloudApi.get('/v1/sites'); return response.data; } /** * Get sites for a specific host */ export async function getSitesForHost(hostId) { const response = await cloudApi.get(`/v1/hosts/${hostId}/sites`); return response.data; } // ======================================== // Devices // ======================================== /** * List all devices across all sites */ export async function listAllDevices() { const response = await cloudApi.get('/v1/devices'); return response.data; } /** * Get devices for a specific host */ export async function getDevicesForHost(hostId) { const response = await cloudApi.get(`/v1/hosts/${hostId}/devices`); return response.data; } /** * Get devices for a specific site */ export async function getDevicesForSite(hostId, siteId) { const response = await cloudApi.get(`/v1/hosts/${hostId}/sites/${siteId}/devices`); return response.data; } /** * Get a specific device */ export async function getDevice(hostId, deviceId) { const response = await cloudApi.get(`/v1/hosts/${hostId}/devices/${deviceId}`); return response.data; } // ======================================== // Clients // ======================================== /** * List all clients across all sites */ export async function listAllClients() { const response = await cloudApi.get('/v1/clients'); return response.data; } /** * Get clients for a specific host */ export async function getClientsForHost(hostId) { const response = await cloudApi.get(`/v1/hosts/${hostId}/clients`); return response.data; } /** * Get clients for a specific site */ export async function getClientsForSite(hostId, siteId) { const response = await cloudApi.get(`/v1/hosts/${hostId}/sites/${siteId}/clients`); return response.data; } // ======================================== // Network Operations // ======================================== /** * Block a client */ export async function blockClient(hostId, siteId, mac) { const response = await cloudApi.post(`/v1/hosts/${hostId}/sites/${siteId}/clients/${mac}/block`); return response.data; } /** * Unblock a client */ export async function unblockClient(hostId, siteId, mac) { const response = await cloudApi.post(`/v1/hosts/${hostId}/sites/${siteId}/clients/${mac}/unblock`); return response.data; } /** * Reconnect/kick a client */ export async function reconnectClient(hostId, siteId, mac) { const response = await cloudApi.post(`/v1/hosts/${hostId}/sites/${siteId}/clients/${mac}/reconnect`); return response.data; } /** * Locate device (flash LEDs) */ export async function locateDevice(hostId, deviceId, enabled = true) { const response = await cloudApi.post(`/v1/hosts/${hostId}/devices/${deviceId}/locate`, { enabled }); return response.data; } /** * Restart a device */ export async function restartDevice(hostId, deviceId) { const response = await cloudApi.post(`/v1/hosts/${hostId}/devices/${deviceId}/restart`); return response.data; } // ======================================== // ISP Metrics // ======================================== /** * Get ISP metrics for a host */ export async function getIspMetrics(hostId, duration = '1d') { const response = await cloudApi.get(`/v1/hosts/${hostId}/isp-metrics`, { params: { duration } }); return response.data; } // ======================================== // Protect (Cameras) // ======================================== /** * List all cameras */ export async function listCameras(hostId) { const response = await cloudApi.get(`/v1/hosts/${hostId}/cameras`); return response.data; } /** * Get camera details */ export async function getCamera(hostId, cameraId) { const response = await cloudApi.get(`/v1/hosts/${hostId}/cameras/${cameraId}`); return response.data; } /** * Set camera privacy mode */ export async function setCameraPrivacy(hostId, cameraId, enabled) { const response = await cloudApi.patch(`/v1/hosts/${hostId}/cameras/${cameraId}`, { privacyMode: enabled }); return response.data; } /** * Set camera recording mode */ export async function setCameraRecording(hostId, cameraId, mode) { const response = await cloudApi.patch(`/v1/hosts/${hostId}/cameras/${cameraId}`, { recordingSettings: { mode } }); return response.data; } // ======================================== // Access (Doors) // ======================================== /** * List all doors */ export async function listDoors(hostId) { const response = await cloudApi.get(`/v1/hosts/${hostId}/doors`); return response.data; } /** * Get door details */ export async function getDoor(hostId, doorId) { const response = await cloudApi.get(`/v1/hosts/${hostId}/doors/${doorId}`); return response.data; } /** * Unlock a door */ export async function unlockDoor(hostId, doorId, duration = 5) { const response = await cloudApi.post(`/v1/hosts/${hostId}/doors/${doorId}/unlock`, { duration }); return response.data; } /** * Lock a door */ export async function lockDoor(hostId, doorId) { const response = await cloudApi.post(`/v1/hosts/${hostId}/doors/${doorId}/lock`); return response.data; } // ======================================== // Health & Status // ======================================== /** * Check API connectivity and get basic info */ export async function healthCheck() { try { const hosts = await listHosts(); return { ok: true, timestamp: new Date().toISOString(), hostsCount: hosts.data?.length || 0, apiBase: CLOUD_API_BASE }; } catch (error) { return { ok: false, timestamp: new Date().toISOString(), error: error.message, apiBase: CLOUD_API_BASE }; } } /** * Get comprehensive system status */ export async function getSystemStatus() { const status = { timestamp: new Date().toISOString(), hosts: [], summary: { totalHosts: 0, totalSites: 0, totalDevices: 0, totalClients: 0, onlineDevices: 0, offlineDevices: 0 } }; try { const hostsResponse = await listHosts(); const hosts = hostsResponse.data || []; status.summary.totalHosts = hosts.length; for (const host of hosts) { const hostStatus = { id: host.id, name: host.name || host.hostname, type: host.type, status: host.status, sites: [], deviceCount: 0, clientCount: 0 }; try { const sitesResponse = await getSitesForHost(host.id); const sites = sitesResponse.data || []; status.summary.totalSites += sites.length; for (const site of sites) { hostStatus.sites.push({ id: site.id, name: site.name }); } } catch (e) { // Site fetch may fail for some hosts } try { const devicesResponse = await getDevicesForHost(host.id); const devices = devicesResponse.data || []; hostStatus.deviceCount = devices.length; status.summary.totalDevices += devices.length; for (const device of devices) { if (device.state === 'ONLINE' || device.state === 1) { status.summary.onlineDevices++; } else { status.summary.offlineDevices++; } } } catch (e) { // Device fetch may fail } try { const clientsResponse = await getClientsForHost(host.id); const clients = clientsResponse.data || []; hostStatus.clientCount = clients.length; status.summary.totalClients += clients.length; } catch (e) { // Client fetch may fail } status.hosts.push(hostStatus); } status.ok = true; } catch (error) { status.ok = false; status.error = error.message; } return status; } export default { // Hosts listHosts, getHost, // Sites listSites, getSitesForHost, // Devices listAllDevices, getDevicesForHost, getDevicesForSite, getDevice, locateDevice, restartDevice, // Clients listAllClients, getClientsForHost, getClientsForSite, blockClient, unblockClient, reconnectClient, // ISP getIspMetrics, // Protect listCameras, getCamera, setCameraPrivacy, setCameraRecording, // Access listDoors, getDoor, unlockDoor, lockDoor, // Health healthCheck, getSystemStatus };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vandreus/Unifi-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server