UNPKG

touchdesigner-mcp-server

Version:
151 lines (150 loc) 5.06 kB
import { createNode as apiCreateNode, deleteNode as apiDeleteNode, execNodeMethod as apiExecNodeMethod, execPythonScript as apiExecPythonScript, getNodeDetail as apiGetNodeDetail, getNodes as apiGetNodes, getTdInfo as apiGetTdInfo, getTdPythonClassDetails as apiGetTdPythonClassDetails, getTdPythonClasses as apiGetTdPythonClasses, updateNode as apiUpdateNode, } from "../gen/endpoints/TouchDesignerAPI.js"; /** * Default implementation of ITouchDesignerApi using generated API clients */ const defaultApiClient = { execNodeMethod: apiExecNodeMethod, execPythonScript: apiExecPythonScript, getTdInfo: apiGetTdInfo, getNodes: apiGetNodes, getNodeDetail: apiGetNodeDetail, createNode: apiCreateNode, updateNode: apiUpdateNode, deleteNode: apiDeleteNode, getTdPythonClasses: apiGetTdPythonClasses, getTdPythonClassDetails: apiGetTdPythonClassDetails, }; /** * Null logger implementation that discards all logs */ const nullLogger = { debug: () => { }, log: () => { }, warn: () => { }, error: () => { }, }; /** * Handle API error response * @param response - API response object * @returns ErrorResult object indicating failure */ function handleError(response) { if (response.error) { const errorMessage = response.error; return { success: false, error: new Error(errorMessage) }; } return { success: false, error: new Error("Unknown error occurred") }; } /** * Handle API response and return a structured result * @param response - API response object * @returns Result object indicating success or failure */ function handleApiResponse(response) { const { success, data } = response; if (!success) { return handleError(response); } if (data === null) { return { success: false, error: new Error("No data received") }; } if (data === undefined) { return { success: false, error: new Error("No data received") }; } return { success: true, data }; } /** * TouchDesigner client implementation with dependency injection * for better testability and separation of concerns */ export class TouchDesignerClient { logger; api; /** * Initialize TouchDesigner client with optional dependencies */ constructor(params = {}) { this.logger = params.logger || nullLogger; this.api = params.httpClient || defaultApiClient; } /** * Execute a node method */ async execNodeMethod(params) { this.logger.debug(`Executing node method: ${params.method} on ${params.nodePath}`); const result = await this.api.execNodeMethod(params); return handleApiResponse(result); } /** * Execute a script in TouchDesigner */ async execPythonScript(params) { this.logger.debug(`Executing Python script: ${params}`); const result = await this.api.execPythonScript(params); return handleApiResponse(result); } /** * Get TouchDesigner server information */ async getTdInfo() { this.logger.debug("Getting server info"); const result = await this.api.getTdInfo(); return handleApiResponse(result); } /** * Get list of nodes */ async getNodes(params) { this.logger.debug(`Getting nodes for parent: ${params.parentPath}`); const result = await this.api.getNodes(params); return handleApiResponse(result); } /** * Get node properties */ async getNodeDetail(params) { this.logger.debug(`Getting properties for node: ${params.nodePath}`); const result = await this.api.getNodeDetail(params); return handleApiResponse(result); } /** * Create a new node */ async createNode(params) { this.logger.debug(`Creating node: ${params.nodeName} of type ${params.nodeType} under ${params.parentPath}`); const result = await this.api.createNode(params); return handleApiResponse(result); } /** * Update node properties */ async updateNode(params) { this.logger.debug(`Updating node: ${params.nodePath}`); const result = await this.api.updateNode(params); return handleApiResponse(result); } /** * Delete a node */ async deleteNode(params) { this.logger.debug(`Deleting node: ${params.nodePath}`); const result = await this.api.deleteNode(params); return handleApiResponse(result); } /** * Get list of available Python classes/modules in TouchDesigner */ async getClasses() { this.logger.debug("Getting Python classes"); const result = await this.api.getTdPythonClasses(); return handleApiResponse(result); } /** * Get details of a specific class/module */ async getClassDetails(className) { this.logger.debug(`Getting class details for: ${className}`); const result = await this.api.getTdPythonClassDetails(className); return handleApiResponse(result); } }