Skip to main content
Glama

HomeAssistant MCP

index.js4.67 kB
class HomeAssistantAPI { baseUrl; token; cache = new Map(); constructor() { this.baseUrl = process.env.HASS_HOST || "http://localhost:8123"; this.token = process.env.HASS_TOKEN || ""; if (!this.token || this.token === "your_hass_token_here") { throw new Error("HASS_TOKEN is required but not set in environment variables"); } console.log(`Initializing Home Assistant API with base URL: ${this.baseUrl}`); } getCache(key, ttlMs = 30000) { const entry = this.cache.get(key); if (entry && Date.now() - entry.timestamp < ttlMs) { return entry.data; } return null; } setCache(key, data) { this.cache.set(key, { data, timestamp: Date.now() }); } async fetchApi(endpoint, options = {}) { const url = `${this.baseUrl}/api/${endpoint}`; console.log(`Making request to: ${url}`); console.log('Request options:', { method: options.method || 'GET', headers: { Authorization: 'Bearer [REDACTED]', "Content-Type": "application/json", ...options.headers, }, body: options.body ? JSON.parse(options.body) : undefined }); try { const response = await fetch(url, { ...options, headers: { Authorization: `Bearer ${this.token}`, "Content-Type": "application/json", ...options.headers, }, }); if (!response.ok) { const errorText = await response.text(); console.error('Home Assistant API error:', { status: response.status, statusText: response.statusText, error: errorText }); throw new Error(`Home Assistant API error: ${response.status} ${response.statusText} - ${errorText}`); } const data = await response.json(); console.log('Response data:', data); return data; } catch (error) { console.error('Failed to make request:', error); throw error; } } async getStates() { // Check cache first (30 second TTL for device states) const cached = this.getCache("states", 30000); if (cached) { return cached; } const data = await this.fetchApi("states"); const states = data; this.setCache("states", states); return states; } async getState(entityId) { // Check cache first (10 second TTL for individual states) const cached = this.getCache(`state_${entityId}`, 10000); if (cached) { return cached; } const data = await this.fetchApi(`states/${entityId}`); const state = data; this.setCache(`state_${entityId}`, state); return state; } async callService(domain, service, data) { await this.fetchApi(`services/${domain}/${service}`, { method: "POST", body: JSON.stringify(data), }); // Clear states cache when services are called as they may change state this.cache.delete("states"); } } let instance = null; export async function get_hass() { if (!instance) { try { instance = new HomeAssistantAPI(); // Verify connection by trying to get states await instance.getStates(); console.log('Successfully connected to Home Assistant'); } catch (error) { console.error('Failed to initialize Home Assistant connection:', error); instance = null; throw error; } } return instance; } // Helper function to call Home Assistant services export async function call_service(domain, service, data) { const hass = await get_hass(); return hass.callService(domain, service, data); } // Helper function to list devices export async function list_devices() { const hass = await get_hass(); const states = await hass.getStates(); return states.map((state) => ({ entity_id: state.entity_id, state: state.state, attributes: state.attributes })); } // Helper function to get entity states export async function get_states() { const hass = await get_hass(); return hass.getStates(); } // Helper function to get a specific entity state export async function get_state(entity_id) { const hass = await get_hass(); return hass.getState(entity_id); }

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