Skip to main content
Glama

HomeAssistant MCP

list-devices.tool.ts3.72 kB
import { z } from "zod"; import { Tool } from "../types/index.js"; import { APP_CONFIG } from "../config/app.config.ts"; import { HassState } from "../types/index.js"; export const listDevicesTool: Tool = { name: "list_devices", description: "List all available Home Assistant devices", parameters: z.object({ domain: z.enum([ "light", "climate", "alarm_control_panel", "cover", "switch", "contact", "media_player", "fan", "lock", "vacuum", "scene", "script", "camera", ]).optional(), area: z.string().optional(), floor: z.string().optional(), }).describe("Filter devices by domain, area, or floor"), execute: async (params: { domain?: string; area?: string; floor?: string }) => { try { const response = await fetch(`${APP_CONFIG.HASS_HOST}/api/states`, { headers: { Authorization: `Bearer ${APP_CONFIG.HASS_TOKEN}`, "Content-Type": "application/json", }, }); if (!response.ok) { throw new Error(`Failed to fetch devices: ${response.statusText}`); } const states = (await response.json()) as HassState[]; let filteredStates = states; // Apply filters if (params.domain) { filteredStates = filteredStates.filter(state => state.entity_id.startsWith(`${params.domain}.`)); } if (params.area) { filteredStates = filteredStates.filter(state => state.attributes?.area_id === params.area); } if (params.floor) { filteredStates = filteredStates.filter(state => state.attributes?.floor === params.floor); } const devices: Record<string, HassState[]> = {}; // Group devices by domain filteredStates.forEach(state => { const [domain] = state.entity_id.split('.'); if (!devices[domain]) { devices[domain] = []; } devices[domain].push(state); }); // Calculate device statistics const deviceStats = Object.entries(devices).map(([domain, entities]) => { const activeStates = ['on', 'home', 'unlocked', 'open']; const active = entities.filter(e => activeStates.includes(e.state)).length; const uniqueStates = [...new Set(entities.map(e => e.state))]; return { domain, count: entities.length, active, inactive: entities.length - active, states: uniqueStates, sample: entities.slice(0, 2).map(e => ({ id: e.entity_id, state: e.state, name: e.attributes?.friendly_name || e.entity_id, area: e.attributes?.area_id, floor: e.attributes?.floor, })) }; }); const totalDevices = filteredStates.length; const deviceTypes = Object.keys(devices); const deviceSummary = { total_devices: totalDevices, device_types: deviceTypes, by_domain: Object.fromEntries( deviceStats.map(stat => [ stat.domain, { count: stat.count, active: stat.active, states: stat.states, sample: stat.sample } ]) ) }; return { success: true, devices, device_summary: deviceSummary }; } catch (error) { console.error('Error in list devices tool:', error); return { success: false, message: error instanceof Error ? error.message : "Unknown error occurred", devices: {}, device_summary: { total_devices: 0, device_types: [], by_domain: {} } }; } }, };

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/jango-blockchained/advanced-homeassistant-mcp'

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