Skip to main content
Glama
index.ts4.09 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { HAClient } from './ha-client.js'; import { tools } from './tools/index.js'; import { toolHandlers } from './handlers.js'; // Get configuration from environment const HA_AGENT_URL = process.env.HA_AGENT_URL || 'http://homeassistant.local:8099'; const HA_AGENT_KEY = process.env.HA_AGENT_KEY; if (!HA_AGENT_KEY) { // Always log errors - these are critical console.error('❌ Error: HA_AGENT_KEY environment variable is required'); console.error('Please set it in Cursor: Settings → Tools & MCP → Add Custom MCP Server'); console.error('Or manually in ~/.cursor/mcp.json'); process.exit(1); } // Initialize HA client const haClient = new HAClient({ baseURL: HA_AGENT_URL, token: HA_AGENT_KEY, }); // Create MCP server const server = new Server( { name: 'home-assistant-mcp', version: '3.2.20', }, { capabilities: { tools: {}, }, } ); // Register tool list handler server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools }; }); // Register tool execution handler server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (!args) { return { content: [{ type: 'text', text: 'Error: No arguments provided' }], isError: true, }; } try { // Look up handler from registry const handler = toolHandlers[name]; if (!handler) { throw new Error(`Unknown tool: ${name}`); } // Execute handler return await handler(haClient, args); } catch (error: any) { let errorMessage: string; // Handle axios errors if (error.response?.data) { const data = error.response.data; if (typeof data.detail === 'string') { errorMessage = data.detail; } else if (typeof data.detail === 'object') { errorMessage = JSON.stringify(data.detail, null, 2); } else if (typeof data === 'string') { errorMessage = data; } else if (typeof data === 'object') { errorMessage = JSON.stringify(data, null, 2); } else { errorMessage = String(data); } } else if (error.message) { errorMessage = error.message; } else if (typeof error === 'object') { errorMessage = JSON.stringify(error, null, 2); } else { errorMessage = String(error || 'Unknown error'); } return { content: [{ type: 'text', text: `Error: ${errorMessage}` }], isError: true, }; } }); // Start server async function main() { // Test connection on startup try { const health = await haClient.healthCheck(); // Only log connection info if DEBUG mode is enabled (to avoid cluttering logs) // In production, connection is silent unless there's an error if (process.env.DEBUG === 'true') { console.error(`✅ Connected to HA Vibecode Agent v${health.version}`); console.error(`📁 Config path: ${health.config_path}`); console.error(`🔄 Git versioning auto: ${health.git_versioning_auto}`); } } catch (error: any) { // Always log errors - these are important console.error('❌ Failed to connect to HA Vibecode Agent'); console.error(`URL: ${HA_AGENT_URL}`); console.error(`Error: ${error.message}`); console.error('\nPlease ensure:'); console.error('1. HA Vibecode Agent add-on is running'); console.error('2. HA_AGENT_URL is correct'); console.error('3. HA_AGENT_KEY is valid'); process.exit(1); } const transport = new StdioServerTransport(); await server.connect(transport); // Only log startup message if DEBUG mode is enabled if (process.env.DEBUG === 'true') { console.error('🚀 MCP Home Assistant server running'); } } main().catch((error) => { console.error('Fatal error:', error); process.exit(1); });

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/Coolver/mcp-home-assistant'

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