Skip to main content
Glama
trace.tool.ts4.69 kB
/** * Trace Tool for Home Assistant * * This tool provides access to automation and script execution traces via WebSocket API. * These operations are WebSocket-only in Home Assistant - no REST endpoints exist. */ import { z } from "zod"; import { logger } from "../../utils/logger.js"; import { BaseTool } from "../base-tool.js"; import { MCPContext } from "../../mcp/types.js"; import { get_hass_ws } from "../../hass/websocket-manager.js"; import { Tool } from "../../types/index.js"; // Define the schema for our tool parameters const traceSchema = z.object({ action: z.enum(["list", "get", "contexts"]).describe("Action to perform with traces"), domain: z .enum(["automation", "script"]) .optional() .default("automation") .describe("Domain to query traces for (automation or script)"), item_id: z .string() .optional() .describe( "Internal automation/script ID (NOT entity_id). Use the 'id' field from automation list, e.g., 'office_carbon_filter_person_detection' or '1759324158284'. Do NOT include 'automation.' prefix.", ), run_id: z .string() .optional() .describe("Specific trace run_id from the list results (required for 'get' action)"), }); // Infer the type from the schema type TraceParams = z.infer<typeof traceSchema>; // Shared execution logic async function executeTraceLogic(params: TraceParams): Promise<string> { logger.debug(`Executing trace logic with params: ${JSON.stringify(params)}`); // Normalize item_id: strip domain prefix if accidentally included (e.g., 'automation.xyz' → 'xyz') if (params.item_id) { const domainPrefix = `${params.domain}.`; if (params.item_id.startsWith(domainPrefix)) { params.item_id = params.item_id.replace(domainPrefix, ""); } } try { const hass = await get_hass_ws(); switch (params.action) { case "list": { const traces = await hass.listTraces(params.domain, params.item_id); return JSON.stringify({ success: true, traces, total_count: traces.length, domain: params.domain, ...(params.item_id && { item_id: params.item_id }), }); } case "get": { if (!params.item_id || !params.run_id) { throw new Error("Both item_id and run_id are required for 'get' action"); } const trace = await hass.getTrace(params.domain!, params.item_id, params.run_id); return JSON.stringify({ success: true, trace, domain: params.domain, item_id: params.item_id, run_id: params.run_id, }); } case "contexts": { const contexts = await hass.listTraceContexts(params.domain, params.item_id); return JSON.stringify({ success: true, contexts, total_count: contexts.length, ...(params.domain && { domain: params.domain }), ...(params.item_id && { item_id: params.item_id }), }); } default: throw new Error(`Unknown action: ${params.action}`); } } catch (error) { logger.error(`Error in trace logic: ${error instanceof Error ? error.message : String(error)}`); return JSON.stringify({ success: false, message: error instanceof Error ? error.message : "Unknown error occurred", }); } } // Tool object export (for FastMCP) export const traceTool: Tool = { name: "trace", description: "Access automation and script execution traces. List recent traces, get detailed trace data, or list trace contexts. Useful for debugging automation issues.", annotations: { title: "Automation Trace", description: "View execution traces for automations and scripts", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true, }, parameters: traceSchema, execute: executeTraceLogic, }; /** * TraceTool class extending BaseTool (for compatibility with src/index.ts) */ export class TraceTool extends BaseTool { constructor() { super({ name: traceTool.name, description: traceTool.description, parameters: traceSchema, metadata: { category: "home_assistant", version: "1.0.0", tags: ["trace", "automation", "script", "debugging", "home_assistant"], }, }); } /** * Execute method for the BaseTool class */ public async execute(params: TraceParams, _context: MCPContext): Promise<string> { logger.debug(`Executing TraceTool (BaseTool) with params: ${JSON.stringify(params)}`); const validatedParams = this.validateParams(params); return await executeTraceLogic(validatedParams); } }

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

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