/** * Shared building blocks for tool modules. * * Tools never touch HTTP or construct clients — they go through * {@link DeviceManager.withDevice}. What they *do* share is the `device` * argument, the result envelopes, and turning a thrown {@link TwinklyError} * into an MCP error result instead of a protocol-level exception. */ import { z } from 'zod'; import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'; import type { Logger } from '../logger.js'; import type { ToolGroup, TwinklyMcpConfig } from '../config.js'; /** * Whether a tool group is exposed at all. Honors the `tools` allow-list (when * set, only listed groups are exposed) and the admin gate (the `admin` group is * hidden unless `allowAdmin` is on). Read-only filtering is separate — see * {@link writesEnabled} — because some groups mix read and write tools. */ export declare function groupEnabled(config: TwinklyMcpConfig, group: ToolGroup): boolean; /** * Whether device-mutating (write) tools are exposed. In read-only mode they are * dropped, leaving the inspection tools (and the harmless discovery scan) intact. */ export declare function writesEnabled(config: TwinklyMcpConfig): boolean; /** The optional `device` argument every device-targeting tool accepts. */ export declare const deviceArg: { readonly device: z.ZodOptional; }; /** A JSON-serializable payload returned as both text and structured content. */ export declare function jsonResult(data: Record): CallToolResult; /** A plain-text result — used by write tools that need no structured output. */ export declare function textResult(text: string): CallToolResult; /** * An error result for invalid tool arguments that zod can't express on a flat * input shape (e.g. "exactly one of rgb / hsv"). Distinct from a device error. */ export declare function invalidInput(message: string): CallToolResult; /** Turn any thrown value into an MCP error result tagged with its Twinkly code. */ export declare function errorResult(err: unknown, logger: Logger): CallToolResult; /** * Run a tool body, converting any failure into an MCP error result. This keeps * every handler's happy path flat and uniform. */ export declare function guard(logger: Logger, body: () => Promise): Promise; /** * Run a device call that may be unsupported on older firmware, returning `null` * instead of failing the whole tool. Used for best-effort reads (e.g. the * color endpoint, which only exists since firmware 2.7.1). */ export declare function optional(fn: () => Promise): Promise;