touchdesigner-mcp-server 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,19 +1,21 @@
1
1
  import { z } from "zod";
2
2
  import { REFERENCE_COMMENT, TOOL_NAMES } from "../../../core/constants.js";
3
3
  import { handleToolError } from "../../../core/errorHandling.js";
4
- import { createNodeBody, deleteNodeQueryParams, execNodeMethodBody, execPythonScriptBody, getNodeDetailQueryParams, getNodesQueryParams, getTdPythonClassDetailsParams, updateNodeBody, } from "../../../gen/mcp/touchDesignerAPI.zod.js";
4
+ import { createNodeBody, deleteNodeQueryParams, execNodeMethodBody, execPythonScriptBody, getModuleHelpQueryParams, getNodeDetailQueryParams, getNodeErrorsQueryParams, getNodesQueryParams, getTdPythonClassDetailsParams, updateNodeBody, } from "../../../gen/mcp/touchDesignerAPI.zod.js";
5
5
  import { getTouchDesignerToolMetadata } from "../metadata/touchDesignerToolMetadata.js";
6
- import { formatClassDetails, formatClassList, formatCreateNodeResult, formatDeleteNodeResult, formatExecNodeMethodResult, formatNodeDetails, formatNodeList, formatScriptResult, formatTdInfo, formatToolMetadata, formatUpdateNodeResult, } from "../presenter/index.js";
6
+ import { formatClassDetails, formatClassList, formatCreateNodeResult, formatDeleteNodeResult, formatExecNodeMethodResult, formatModuleHelp, formatNodeDetails, formatNodeErrors, formatNodeList, formatScriptResult, formatTdInfo, formatToolMetadata, formatUpdateNodeResult, } from "../presenter/index.js";
7
7
  import { detailOnlyFormattingSchema, formattingOptionsSchema, } from "../types.js";
8
8
  const execPythonScriptToolSchema = execPythonScriptBody.extend(detailOnlyFormattingSchema.shape);
9
9
  const tdInfoToolSchema = detailOnlyFormattingSchema;
10
10
  const getNodesToolSchema = getNodesQueryParams.extend(formattingOptionsSchema.shape);
11
11
  const getNodeDetailToolSchema = getNodeDetailQueryParams.extend(formattingOptionsSchema.shape);
12
+ const getNodeErrorsToolSchema = getNodeErrorsQueryParams.extend(formattingOptionsSchema.shape);
12
13
  const createNodeToolSchema = createNodeBody.extend(detailOnlyFormattingSchema.shape);
13
14
  const updateNodeToolSchema = updateNodeBody.extend(detailOnlyFormattingSchema.shape);
14
15
  const deleteNodeToolSchema = deleteNodeQueryParams.extend(detailOnlyFormattingSchema.shape);
15
16
  const classListToolSchema = formattingOptionsSchema;
16
17
  const classDetailToolSchema = getTdPythonClassDetailsParams.extend(formattingOptionsSchema.shape);
18
+ const moduleHelpToolSchema = getModuleHelpQueryParams.extend(detailOnlyFormattingSchema.shape);
17
19
  const execNodeMethodToolSchema = execNodeMethodBody.extend(detailOnlyFormattingSchema.shape);
18
20
  const describeToolsSchema = detailOnlyFormattingSchema.extend({
19
21
  filter: z
@@ -38,22 +40,22 @@ export function registerTdTools(server, logger, tdClient) {
38
40
  return {
39
41
  content: [
40
42
  {
41
- type: "text",
42
43
  text: message,
44
+ type: "text",
43
45
  },
44
46
  ],
45
47
  };
46
48
  }
47
49
  const formattedText = formatToolMetadata(filteredEntries, {
48
50
  detailLevel: detailLevel ?? (filter ? "summary" : "minimal"),
49
- responseFormat,
50
51
  filter: normalizedFilter,
52
+ responseFormat,
51
53
  });
52
54
  return {
53
55
  content: [
54
56
  {
55
- type: "text",
56
57
  text: formattedText,
58
+ type: "text",
57
59
  },
58
60
  ],
59
61
  };
@@ -76,8 +78,8 @@ export function registerTdTools(server, logger, tdClient) {
76
78
  return {
77
79
  content: [
78
80
  {
79
- type: "text",
80
81
  text: formattedText,
82
+ type: "text",
81
83
  },
82
84
  ],
83
85
  };
@@ -89,7 +91,10 @@ export function registerTdTools(server, logger, tdClient) {
89
91
  server.tool(TOOL_NAMES.EXECUTE_PYTHON_SCRIPT, "Execute a Python script in TouchDesigner (detailLevel=minimal|summary|detailed, responseFormat=json|yaml|markdown)", execPythonScriptToolSchema.strict().shape, async (params) => {
90
92
  try {
91
93
  const { detailLevel, responseFormat, ...scriptParams } = params;
92
- logger.debug(`Executing script: ${scriptParams.script}`);
94
+ logger.sendLog({
95
+ data: `Executing script: ${scriptParams.script}`,
96
+ level: "debug",
97
+ });
93
98
  const result = await tdClient.execPythonScript(scriptParams);
94
99
  if (!result.success) {
95
100
  throw result.error;
@@ -102,8 +107,8 @@ export function registerTdTools(server, logger, tdClient) {
102
107
  return {
103
108
  content: [
104
109
  {
105
- type: "text",
106
110
  text: formattedText,
111
+ type: "text",
107
112
  },
108
113
  ],
109
114
  };
@@ -126,8 +131,8 @@ export function registerTdTools(server, logger, tdClient) {
126
131
  return {
127
132
  content: [
128
133
  {
129
- type: "text",
130
134
  text: formattedText,
135
+ type: "text",
131
136
  },
132
137
  ],
133
138
  };
@@ -150,8 +155,8 @@ export function registerTdTools(server, logger, tdClient) {
150
155
  return {
151
156
  content: [
152
157
  {
153
- type: "text",
154
158
  text: formattedText,
159
+ type: "text",
155
160
  },
156
161
  ],
157
162
  };
@@ -179,8 +184,8 @@ export function registerTdTools(server, logger, tdClient) {
179
184
  return {
180
185
  content: [
181
186
  {
182
- type: "text",
183
187
  text: formattedText,
188
+ type: "text",
184
189
  },
185
190
  ],
186
191
  };
@@ -205,8 +210,8 @@ export function registerTdTools(server, logger, tdClient) {
205
210
  return {
206
211
  content: [
207
212
  {
208
- type: "text",
209
213
  text: formattedText,
214
+ type: "text",
210
215
  },
211
216
  ],
212
217
  };
@@ -215,6 +220,31 @@ export function registerTdTools(server, logger, tdClient) {
215
220
  return handleToolError(error, logger, TOOL_NAMES.GET_TD_NODE_PARAMETERS, REFERENCE_COMMENT);
216
221
  }
217
222
  });
223
+ server.tool(TOOL_NAMES.GET_TD_NODE_ERRORS, "Check node and descendant errors reported by TouchDesigner", getNodeErrorsToolSchema.strict().shape, async (params) => {
224
+ try {
225
+ const { detailLevel, limit, responseFormat, ...queryParams } = params;
226
+ const result = await tdClient.getNodeErrors(queryParams);
227
+ if (!result.success) {
228
+ throw result.error;
229
+ }
230
+ const formattedText = formatNodeErrors(result.data, {
231
+ detailLevel: detailLevel ?? "summary",
232
+ limit,
233
+ responseFormat,
234
+ });
235
+ return {
236
+ content: [
237
+ {
238
+ text: formattedText,
239
+ type: "text",
240
+ },
241
+ ],
242
+ };
243
+ }
244
+ catch (error) {
245
+ return handleToolError(error, logger, TOOL_NAMES.GET_TD_NODE_ERRORS, REFERENCE_COMMENT);
246
+ }
247
+ });
218
248
  server.tool(TOOL_NAMES.UPDATE_TD_NODE_PARAMETERS, "Update parameters of a specific node in TouchDesigner", updateNodeToolSchema.strict().shape, async (params) => {
219
249
  try {
220
250
  const { detailLevel, responseFormat, ...updateParams } = params;
@@ -229,8 +259,8 @@ export function registerTdTools(server, logger, tdClient) {
229
259
  return {
230
260
  content: [
231
261
  {
232
- type: "text",
233
262
  text: formattedText,
263
+ type: "text",
234
264
  },
235
265
  ],
236
266
  };
@@ -247,18 +277,21 @@ export function registerTdTools(server, logger, tdClient) {
247
277
  if (!result.success) {
248
278
  throw result.error;
249
279
  }
250
- const formattedText = formatExecNodeMethodResult(result.data, { nodePath, method, args, kwargs }, { detailLevel: detailLevel ?? "summary", responseFormat });
280
+ const formattedText = formatExecNodeMethodResult(result.data, { args, kwargs, method, nodePath }, { detailLevel: detailLevel ?? "summary", responseFormat });
251
281
  return {
252
282
  content: [
253
283
  {
254
- type: "text",
255
284
  text: formattedText,
285
+ type: "text",
256
286
  },
257
287
  ],
258
288
  };
259
289
  }
260
290
  catch (error) {
261
- logger.error(error);
291
+ logger.sendLog({
292
+ data: error,
293
+ level: "error",
294
+ });
262
295
  return handleToolError(error, logger, TOOL_NAMES.EXECUTE_NODE_METHOD, REFERENCE_COMMENT);
263
296
  }
264
297
  });
@@ -277,8 +310,8 @@ export function registerTdTools(server, logger, tdClient) {
277
310
  return {
278
311
  content: [
279
312
  {
280
- type: "text",
281
313
  text: formattedText,
314
+ type: "text",
282
315
  },
283
316
  ],
284
317
  };
@@ -303,8 +336,8 @@ export function registerTdTools(server, logger, tdClient) {
303
336
  return {
304
337
  content: [
305
338
  {
306
- type: "text",
307
339
  text: formattedText,
340
+ type: "text",
308
341
  },
309
342
  ],
310
343
  };
@@ -313,6 +346,30 @@ export function registerTdTools(server, logger, tdClient) {
313
346
  return handleToolError(error, logger, TOOL_NAMES.GET_TD_CLASS_DETAILS, REFERENCE_COMMENT);
314
347
  }
315
348
  });
349
+ server.tool(TOOL_NAMES.GET_TD_MODULE_HELP, "Retrieve Python help() text for a TouchDesigner module or class", moduleHelpToolSchema.strict().shape, async (params) => {
350
+ try {
351
+ const { detailLevel, moduleName, responseFormat } = params;
352
+ const result = await tdClient.getModuleHelp({ moduleName });
353
+ if (!result.success) {
354
+ throw result.error;
355
+ }
356
+ const formattedText = formatModuleHelp(result.data, {
357
+ detailLevel: detailLevel ?? "summary",
358
+ responseFormat,
359
+ });
360
+ return {
361
+ content: [
362
+ {
363
+ text: formattedText,
364
+ type: "text",
365
+ },
366
+ ],
367
+ };
368
+ }
369
+ catch (error) {
370
+ return handleToolError(error, logger, TOOL_NAMES.GET_TD_MODULE_HELP);
371
+ }
372
+ });
316
373
  }
317
374
  function matchesMetadataFilter(entry, keyword) {
318
375
  const normalizedKeyword = keyword.toLowerCase();