import { z } from 'zod';
import * as unifi from '../unifi-client.js';
export const deviceTools = {
// ========================================
// Device Listing
// ========================================
list_all_devices: {
description: 'List all UniFi devices across all hosts and sites',
schema: z.object({}),
handler: async () => {
const devices = await unifi.listAllDevices();
return {
content: [{ type: 'text', text: JSON.stringify(devices, null, 2) }]
};
}
},
get_devices_for_host: {
description: 'Get all devices for a specific host',
schema: z.object({
hostId: z.string().describe('The host ID')
}),
handler: async ({ hostId }) => {
const devices = await unifi.getDevicesForHost(hostId);
return {
content: [{ type: 'text', text: JSON.stringify(devices, null, 2) }]
};
}
},
get_devices_for_site: {
description: 'Get all devices for a specific site',
schema: z.object({
hostId: z.string().describe('The host ID'),
siteId: z.string().describe('The site ID')
}),
handler: async ({ hostId, siteId }) => {
const devices = await unifi.getDevicesForSite(hostId, siteId);
return {
content: [{ type: 'text', text: JSON.stringify(devices, null, 2) }]
};
}
},
get_device: {
description: 'Get detailed information about a specific device',
schema: z.object({
hostId: z.string().describe('The host ID'),
deviceId: z.string().describe('The device ID or MAC address')
}),
handler: async ({ hostId, deviceId }) => {
const device = await unifi.getDevice(hostId, deviceId);
return {
content: [{ type: 'text', text: JSON.stringify(device, null, 2) }]
};
}
},
// ========================================
// Device Actions
// ========================================
locate_device: {
description: 'Flash the LEDs on a device to help physically locate it',
schema: z.object({
hostId: z.string().describe('The host ID'),
deviceId: z.string().describe('The device ID'),
enabled: z.boolean().optional().default(true).describe('Enable or disable locator mode')
}),
handler: async ({ hostId, deviceId, enabled }) => {
const result = await unifi.locateDevice(hostId, deviceId, enabled);
return {
content: [{
type: 'text',
text: `Device locate mode ${enabled ? 'enabled' : 'disabled'}. ${JSON.stringify(result, null, 2)}`
}]
};
}
},
restart_device: {
description: 'Restart a UniFi device (access point, switch, etc.)',
schema: z.object({
hostId: z.string().describe('The host ID'),
deviceId: z.string().describe('The device ID'),
confirm: z.boolean().describe('Confirm you want to restart the device')
}),
handler: async ({ hostId, deviceId, confirm }) => {
if (!confirm) {
return {
content: [{
type: 'text',
text: 'Device restart cancelled. Set confirm=true to proceed.'
}]
};
}
const result = await unifi.restartDevice(hostId, deviceId);
return {
content: [{ type: 'text', text: `Device restart initiated. ${JSON.stringify(result, null, 2)}` }]
};
}
},
// ========================================
// Device Search & Filter
// ========================================
find_device_by_mac: {
description: 'Find a device by its MAC address across all hosts',
schema: z.object({
mac: z.string().describe('The MAC address to search for')
}),
handler: async ({ mac }) => {
const normalizedMac = mac.toLowerCase().replace(/[:-]/g, '');
const allDevices = await unifi.listAllDevices();
const devices = allDevices.data || [];
const matches = devices.filter(d => {
const deviceMac = (d.mac || '').toLowerCase().replace(/[:-]/g, '');
return deviceMac === normalizedMac || deviceMac.includes(normalizedMac);
});
return {
content: [{
type: 'text',
text: JSON.stringify({
searchMac: mac,
matchCount: matches.length,
matches
}, null, 2)
}]
};
}
},
find_devices_by_name: {
description: 'Search for devices by name',
schema: z.object({
query: z.string().describe('The search query for device name')
}),
handler: async ({ query }) => {
const queryLower = query.toLowerCase();
const allDevices = await unifi.listAllDevices();
const devices = allDevices.data || [];
const matches = devices.filter(d => {
const name = (d.name || d.model || '').toLowerCase();
return name.includes(queryLower);
});
return {
content: [{
type: 'text',
text: JSON.stringify({
searchQuery: query,
matchCount: matches.length,
matches
}, null, 2)
}]
};
}
},
get_offline_devices: {
description: 'Get all devices that are currently offline',
schema: z.object({}),
handler: async () => {
const allDevices = await unifi.listAllDevices();
const devices = allDevices.data || [];
const offline = devices.filter(d => {
const state = d.state;
return state === 'OFFLINE' || state === 0 || state === 'DISCONNECTED';
});
return {
content: [{
type: 'text',
text: JSON.stringify({
offlineCount: offline.length,
totalDevices: devices.length,
offlineDevices: offline
}, null, 2)
}]
};
}
}
};
export default deviceTools;