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.
@@ -2,195 +2,201 @@ import { TOOL_NAMES } from "../../../core/constants.js";
2
2
  const MODULE_ROOT = "servers/touchdesigner";
3
3
  export const TOUCH_DESIGNER_TOOL_METADATA = [
4
4
  {
5
- tool: TOOL_NAMES.GET_TD_INFO,
6
- modulePath: `${MODULE_ROOT}/getTdInfo.ts`,
7
- functionName: "getTdInfo",
8
- description: "Get server information from TouchDesigner",
9
5
  category: "system",
6
+ description: "Get server information from TouchDesigner",
7
+ example: `import { getTdInfo } from './servers/touchdesigner/getTdInfo';
8
+
9
+ const info = await getTdInfo();
10
+ console.log(\`\${info.server} \${info.version}\`);`,
11
+ functionName: "getTdInfo",
12
+ modulePath: `${MODULE_ROOT}/getTdInfo.ts`,
10
13
  parameters: [
11
14
  {
15
+ description: "Optional presenter granularity for formatted output.",
12
16
  name: "detailLevel",
13
- type: "'minimal' | 'summary' | 'detailed'",
14
17
  required: false,
15
- description: "Optional presenter granularity for formatted output.",
18
+ type: "'minimal' | 'summary' | 'detailed'",
16
19
  },
17
20
  {
21
+ description: "Overrides the formatter output format for automation.",
18
22
  name: "responseFormat",
19
- type: "'json' | 'yaml' | 'markdown'",
20
23
  required: false,
21
- description: "Overrides the formatter output format for automation.",
24
+ type: "'json' | 'yaml' | 'markdown'",
22
25
  },
23
26
  ],
24
27
  returns: "TouchDesigner build metadata (server, version, operating system).",
25
- example: `import { getTdInfo } from './servers/touchdesigner/getTdInfo';
26
-
27
- const info = await getTdInfo();
28
- console.log(\`\${info.server} \${info.version}\`);`,
28
+ tool: TOOL_NAMES.GET_TD_INFO,
29
29
  },
30
30
  {
31
- tool: TOOL_NAMES.EXECUTE_PYTHON_SCRIPT,
32
- modulePath: `${MODULE_ROOT}/executePythonScript.ts`,
33
- functionName: "executePythonScript",
34
- description: "Execute arbitrary Python against the TouchDesigner session",
35
31
  category: "python",
32
+ description: "Execute arbitrary Python against the TouchDesigner session",
33
+ example: `import { executePythonScript } from './servers/touchdesigner/executePythonScript';
34
+
35
+ await executePythonScript({
36
+ script: "op('/project1/text1').par.text = 'Hello MCP'",
37
+ });`,
38
+ functionName: "executePythonScript",
39
+ modulePath: `${MODULE_ROOT}/executePythonScript.ts`,
40
+ notes: "Wrap long-running scripts with logging so the agent can stream intermediate checkpoints.",
36
41
  parameters: [
37
42
  {
43
+ description: "Python source that TouchDesigner will eval. Multiline scripts supported.",
38
44
  name: "script",
39
- type: "string",
40
45
  required: true,
41
- description: "Python source that TouchDesigner will eval. Multiline scripts supported.",
46
+ type: "string",
42
47
  },
43
48
  {
49
+ description: "Choose how much of the execution metadata to surface back to the agent.",
44
50
  name: "detailLevel",
45
- type: "'minimal' | 'summary' | 'detailed'",
46
51
  required: false,
47
- description: "Choose how much of the execution metadata to surface back to the agent.",
52
+ type: "'minimal' | 'summary' | 'detailed'",
48
53
  },
49
54
  {
55
+ description: "Structured response encoding for downstream tooling.",
50
56
  name: "responseFormat",
51
- type: "'json' | 'yaml' | 'markdown'",
52
57
  required: false,
53
- description: "Structured response encoding for downstream tooling.",
58
+ type: "'json' | 'yaml' | 'markdown'",
54
59
  },
55
60
  ],
56
61
  returns: "Result payload that mirrors `result` from the executed script (if set).",
57
- example: `import { executePythonScript } from './servers/touchdesigner/executePythonScript';
58
-
59
- await executePythonScript({
60
- script: "op('/project1/text1').par.text = 'Hello MCP'",
61
- });`,
62
- notes: "Wrap long-running scripts with logging so the agent can stream intermediate checkpoints.",
62
+ tool: TOOL_NAMES.EXECUTE_PYTHON_SCRIPT,
63
63
  },
64
64
  {
65
- tool: TOOL_NAMES.GET_TD_NODES,
66
- modulePath: `${MODULE_ROOT}/getTdNodes.ts`,
67
- functionName: "getTdNodes",
68
- description: "List nodes below a parent path",
69
65
  category: "nodes",
66
+ description: "List nodes below a parent path",
67
+ example: `import { getTdNodes } from './servers/touchdesigner/getTdNodes';
68
+
69
+ const nodes = await getTdNodes({
70
+ parentPath: '/project1',
71
+ pattern: 'geo*',
72
+ });
73
+ console.log(nodes.nodes?.map(node => node.path));`,
74
+ functionName: "getTdNodes",
75
+ modulePath: `${MODULE_ROOT}/getTdNodes.ts`,
70
76
  parameters: [
71
77
  {
78
+ description: "Root operator path (e.g. /project1).",
72
79
  name: "parentPath",
73
- type: "string",
74
80
  required: true,
75
- description: "Root operator path (e.g. /project1).",
81
+ type: "string",
76
82
  },
77
83
  {
84
+ description: "Glob pattern to filter node names (default '*').",
78
85
  name: "pattern",
79
- type: "string",
80
86
  required: false,
81
- description: "Glob pattern to filter node names (default '*').",
87
+ type: "string",
82
88
  },
83
89
  {
90
+ description: "Include expensive property blobs when you truly need them.",
84
91
  name: "includeProperties",
85
- type: "boolean",
86
92
  required: false,
87
- description: "Include expensive property blobs when you truly need them.",
93
+ type: "boolean",
88
94
  },
89
95
  {
96
+ description: "Formatter verbosity for the returned list.",
90
97
  name: "detailLevel",
91
- type: "'minimal' | 'summary' | 'detailed'",
92
98
  required: false,
93
- description: "Formatter verbosity for the returned list.",
99
+ type: "'minimal' | 'summary' | 'detailed'",
94
100
  },
95
101
  {
102
+ description: "Optional cap on how many nodes to return.",
96
103
  name: "limit",
97
- type: "number",
98
104
  required: false,
99
- description: "Optional cap on how many nodes to return.",
105
+ type: "number",
100
106
  },
101
107
  {
108
+ description: "Structured export for writing to disk.",
102
109
  name: "responseFormat",
103
- type: "'json' | 'yaml' | 'markdown'",
104
110
  required: false,
105
- description: "Structured export for writing to disk.",
111
+ type: "'json' | 'yaml' | 'markdown'",
106
112
  },
107
113
  ],
108
114
  returns: "Set of nodes (id, opType, name, path, optional properties) under parentPath.",
109
- example: `import { getTdNodes } from './servers/touchdesigner/getTdNodes';
110
-
111
- const nodes = await getTdNodes({
112
- parentPath: '/project1',
113
- pattern: 'geo*',
114
- });
115
- console.log(nodes.nodes?.map(node => node.path));`,
115
+ tool: TOOL_NAMES.GET_TD_NODES,
116
116
  },
117
117
  {
118
- tool: TOOL_NAMES.GET_TD_NODE_PARAMETERS,
119
- modulePath: `${MODULE_ROOT}/getTdNodeParameters.ts`,
120
- functionName: "getTdNodeParameters",
121
- description: "Inspect an individual node with formatter-aware output",
122
118
  category: "nodes",
119
+ description: "Inspect an individual node with formatter-aware output",
120
+ example: `import { getTdNodeParameters } from './servers/touchdesigner/getTdNodeParameters';
121
+
122
+ const node = await getTdNodeParameters({ nodePath: '/project1/text1' });
123
+ console.log(node.properties?.Text);`,
124
+ functionName: "getTdNodeParameters",
125
+ modulePath: `${MODULE_ROOT}/getTdNodeParameters.ts`,
123
126
  parameters: [
124
127
  {
128
+ description: "Absolute path to the operator (e.g. /project1/text1).",
125
129
  name: "nodePath",
126
- type: "string",
127
130
  required: true,
128
- description: "Absolute path to the operator (e.g. /project1/text1).",
131
+ type: "string",
129
132
  },
130
133
  {
134
+ description: "Controls how many parameters and properties are shown.",
131
135
  name: "detailLevel",
132
- type: "'minimal' | 'summary' | 'detailed'",
133
136
  required: false,
134
- description: "Controls how many parameters and properties are shown.",
137
+ type: "'minimal' | 'summary' | 'detailed'",
135
138
  },
136
139
  {
140
+ description: "Trim parameter listings to the first N entries.",
137
141
  name: "limit",
138
- type: "number",
139
142
  required: false,
140
- description: "Trim parameter listings to the first N entries.",
143
+ type: "number",
141
144
  },
142
145
  {
146
+ description: "Switch between machine vs human friendly layouts.",
143
147
  name: "responseFormat",
144
- type: "'json' | 'yaml' | 'markdown'",
145
148
  required: false,
146
- description: "Switch between machine vs human friendly layouts.",
149
+ type: "'json' | 'yaml' | 'markdown'",
147
150
  },
148
151
  ],
149
152
  returns: "Full node record with parameters, paths, and metadata.",
150
- example: `import { getTdNodeParameters } from './servers/touchdesigner/getTdNodeParameters';
151
-
152
- const node = await getTdNodeParameters({ nodePath: '/project1/text1' });
153
- console.log(node.properties?.Text);`,
153
+ tool: TOOL_NAMES.GET_TD_NODE_PARAMETERS,
154
154
  },
155
155
  {
156
- tool: TOOL_NAMES.CREATE_TD_NODE,
157
- modulePath: `${MODULE_ROOT}/createTdNode.ts`,
158
- functionName: "createTdNode",
159
- description: "Create an operator under a parent path",
160
156
  category: "nodes",
157
+ description: "Collect errors emitted by a node and its children",
158
+ example: `import { getTdNodeErrors } from './servers/touchdesigner/getTdNodeErrors';
159
+
160
+ const report = await getTdNodeErrors({
161
+ nodePath: '/project1/text1',
162
+ });
163
+ if (report.hasErrors) {
164
+ console.log(report.errors?.map(err => err.message));
165
+ }`,
166
+ functionName: "getTdNodeErrors",
167
+ modulePath: `${MODULE_ROOT}/getTdNodeErrors.ts`,
161
168
  parameters: [
162
169
  {
163
- name: "parentPath",
164
- type: "string",
170
+ description: "Absolute path to inspect (e.g. /project1/text1).",
171
+ name: "nodePath",
165
172
  required: true,
166
- description: "Where the new node should be created.",
167
- },
168
- {
169
- name: "nodeType",
170
173
  type: "string",
171
- required: true,
172
- description: "OP type (e.g. textTOP, constantCHOP).",
173
174
  },
174
175
  {
175
- name: "nodeName",
176
- type: "string",
176
+ description: "Formatter verbosity for the returned error list.",
177
+ name: "detailLevel",
177
178
  required: false,
178
- description: "Optional custom name. When omitted TouchDesigner assigns one.",
179
+ type: "'minimal' | 'summary' | 'detailed'",
179
180
  },
180
181
  {
181
- name: "detailLevel",
182
- type: "'minimal' | 'summary' | 'detailed'",
182
+ description: "Optional limit on how many errors are displayed.",
183
+ name: "limit",
183
184
  required: false,
184
- description: "Formatter verbosity for the creation result.",
185
+ type: "number",
185
186
  },
186
187
  {
188
+ description: "Structured output encoding (json/yaml/markdown).",
187
189
  name: "responseFormat",
188
- type: "'json' | 'yaml' | 'markdown'",
189
190
  required: false,
190
- description: "Switch result serialization to JSON for scripts.",
191
+ type: "'json' | 'yaml' | 'markdown'",
191
192
  },
192
193
  ],
193
- returns: "Created node metadata including resolved path and properties.",
194
+ returns: "Error report outlining offending nodes, messages, and counts.",
195
+ tool: TOOL_NAMES.GET_TD_NODE_ERRORS,
196
+ },
197
+ {
198
+ category: "nodes",
199
+ description: "Create an operator under a parent path",
194
200
  example: `import { createTdNode } from './servers/touchdesigner/createTdNode';
195
201
 
196
202
  const created = await createTdNode({
@@ -199,202 +205,270 @@ const created = await createTdNode({
199
205
  nodeName: 'title',
200
206
  });
201
207
  console.log(created.result?.path);`,
202
- },
203
- {
204
- tool: TOOL_NAMES.UPDATE_TD_NODE_PARAMETERS,
205
- modulePath: `${MODULE_ROOT}/updateTdNodeParameters.ts`,
206
- functionName: "updateTdNodeParameters",
207
- description: "Patch node properties in bulk",
208
- category: "nodes",
208
+ functionName: "createTdNode",
209
+ modulePath: `${MODULE_ROOT}/createTdNode.ts`,
209
210
  parameters: [
210
211
  {
211
- name: "nodePath",
212
- type: "string",
212
+ description: "Where the new node should be created.",
213
+ name: "parentPath",
213
214
  required: true,
214
- description: "Target operator path.",
215
+ type: "string",
215
216
  },
216
217
  {
217
- name: "properties",
218
- type: "Record<string, unknown>",
218
+ description: "OP type (e.g. textTOP, constantCHOP).",
219
+ name: "nodeType",
219
220
  required: true,
220
- description: "Key/value pairs to update on the node.",
221
+ type: "string",
222
+ },
223
+ {
224
+ description: "Optional custom name. When omitted TouchDesigner assigns one.",
225
+ name: "nodeName",
226
+ required: false,
227
+ type: "string",
221
228
  },
222
229
  {
230
+ description: "Formatter verbosity for the creation result.",
223
231
  name: "detailLevel",
224
- type: "'minimal' | 'summary' | 'detailed'",
225
232
  required: false,
226
- description: "Controls how many updated keys are echoed back.",
233
+ type: "'minimal' | 'summary' | 'detailed'",
227
234
  },
228
235
  {
236
+ description: "Switch result serialization to JSON for scripts.",
229
237
  name: "responseFormat",
230
- type: "'json' | 'yaml' | 'markdown'",
231
238
  required: false,
232
- description: "Choose JSON when writing audit logs to disk.",
239
+ type: "'json' | 'yaml' | 'markdown'",
233
240
  },
234
241
  ],
235
- returns: "Lists of updated vs failed parameters so the agent can retry selectively.",
242
+ returns: "Created node metadata including resolved path and properties.",
243
+ tool: TOOL_NAMES.CREATE_TD_NODE,
244
+ },
245
+ {
246
+ category: "nodes",
247
+ description: "Patch node properties in bulk",
236
248
  example: `import { updateTdNodeParameters } from './servers/touchdesigner/updateTdNodeParameters';
237
249
 
238
250
  await updateTdNodeParameters({
239
251
  nodePath: '/project1/text1',
240
252
  properties: { text: 'Hello TouchDesigner' },
241
253
  });`,
242
- },
243
- {
244
- tool: TOOL_NAMES.DELETE_TD_NODE,
245
- modulePath: `${MODULE_ROOT}/deleteTdNode.ts`,
246
- functionName: "deleteTdNode",
247
- description: "Remove an operator safely",
248
- category: "nodes",
254
+ functionName: "updateTdNodeParameters",
255
+ modulePath: `${MODULE_ROOT}/updateTdNodeParameters.ts`,
249
256
  parameters: [
250
257
  {
258
+ description: "Target operator path.",
251
259
  name: "nodePath",
260
+ required: true,
252
261
  type: "string",
262
+ },
263
+ {
264
+ description: "Key/value pairs to update on the node.",
265
+ name: "properties",
253
266
  required: true,
254
- description: "Absolute path of the operator to delete.",
267
+ type: "Record<string, unknown>",
255
268
  },
256
269
  {
270
+ description: "Controls how many updated keys are echoed back.",
257
271
  name: "detailLevel",
258
- type: "'minimal' | 'summary' | 'detailed'",
259
272
  required: false,
260
- description: "Sends only boolean flags when set to minimal.",
273
+ type: "'minimal' | 'summary' | 'detailed'",
261
274
  },
262
275
  {
276
+ description: "Choose JSON when writing audit logs to disk.",
263
277
  name: "responseFormat",
264
- type: "'json' | 'yaml' | 'markdown'",
265
278
  required: false,
266
- description: "Structured payload when you need audit logs.",
279
+ type: "'json' | 'yaml' | 'markdown'",
267
280
  },
268
281
  ],
269
- returns: "Deletion status plus previous node metadata when available.",
282
+ returns: "Lists of updated vs failed parameters so the agent can retry selectively.",
283
+ tool: TOOL_NAMES.UPDATE_TD_NODE_PARAMETERS,
284
+ },
285
+ {
286
+ category: "nodes",
287
+ description: "Remove an operator safely",
270
288
  example: `import { deleteTdNode } from './servers/touchdesigner/deleteTdNode';
271
289
 
272
290
  const result = await deleteTdNode({ nodePath: '/project1/tmp1' });
273
291
  console.log(result.deleted);`,
292
+ functionName: "deleteTdNode",
293
+ modulePath: `${MODULE_ROOT}/deleteTdNode.ts`,
294
+ parameters: [
295
+ {
296
+ description: "Absolute path of the operator to delete.",
297
+ name: "nodePath",
298
+ required: true,
299
+ type: "string",
300
+ },
301
+ {
302
+ description: "Sends only boolean flags when set to minimal.",
303
+ name: "detailLevel",
304
+ required: false,
305
+ type: "'minimal' | 'summary' | 'detailed'",
306
+ },
307
+ {
308
+ description: "Structured payload when you need audit logs.",
309
+ name: "responseFormat",
310
+ required: false,
311
+ type: "'json' | 'yaml' | 'markdown'",
312
+ },
313
+ ],
314
+ returns: "Deletion status plus previous node metadata when available.",
315
+ tool: TOOL_NAMES.DELETE_TD_NODE,
274
316
  },
275
317
  {
276
- tool: TOOL_NAMES.EXECUTE_NODE_METHOD,
277
- modulePath: `${MODULE_ROOT}/execNodeMethod.ts`,
278
- functionName: "execNodeMethod",
279
- description: "Call TouchDesigner node methods directly",
280
318
  category: "nodes",
319
+ description: "Call TouchDesigner node methods directly",
320
+ example: `import { execNodeMethod } from './servers/touchdesigner/execNodeMethod';
321
+
322
+ const renderStatus = await execNodeMethod({
323
+ nodePath: '/project1/render1',
324
+ method: 'par',
325
+ kwargs: { enable: true },
326
+ });
327
+ console.log(renderStatus.result);`,
328
+ functionName: "execNodeMethod",
329
+ modulePath: `${MODULE_ROOT}/execNodeMethod.ts`,
281
330
  parameters: [
282
331
  {
332
+ description: "OP to target.",
283
333
  name: "nodePath",
284
- type: "string",
285
334
  required: true,
286
- description: "OP to target.",
335
+ type: "string",
287
336
  },
288
337
  {
338
+ description: "Name of the method to call on that operator.",
289
339
  name: "method",
290
- type: "string",
291
340
  required: true,
292
- description: "Name of the method to call on that operator.",
341
+ type: "string",
293
342
  },
294
343
  {
344
+ description: "Positional arguments forwarded to the TouchDesigner API.",
295
345
  name: "args",
296
- type: "Array<string | number | boolean>",
297
346
  required: false,
298
- description: "Positional arguments forwarded to the TouchDesigner API.",
347
+ type: "Array<string | number | boolean>",
299
348
  },
300
349
  {
350
+ description: "Keyword arguments for the method call.",
301
351
  name: "kwargs",
302
- type: "Record<string, unknown>",
303
352
  required: false,
304
- description: "Keyword arguments for the method call.",
353
+ type: "Record<string, unknown>",
305
354
  },
306
355
  {
356
+ description: "How much of the result payload to echo back.",
307
357
  name: "detailLevel",
308
- type: "'minimal' | 'summary' | 'detailed'",
309
358
  required: false,
310
- description: "How much of the result payload to echo back.",
359
+ type: "'minimal' | 'summary' | 'detailed'",
311
360
  },
312
361
  {
362
+ description: "Switch to JSON when storing method responses.",
313
363
  name: "responseFormat",
314
- type: "'json' | 'yaml' | 'markdown'",
315
364
  required: false,
316
- description: "Switch to JSON when storing method responses.",
365
+ type: "'json' | 'yaml' | 'markdown'",
317
366
  },
318
367
  ],
319
368
  returns: "Raw method return payload including any serializable values.",
320
- example: `import { execNodeMethod } from './servers/touchdesigner/execNodeMethod';
321
-
322
- const renderStatus = await execNodeMethod({
323
- nodePath: '/project1/render1',
324
- method: 'par',
325
- kwargs: { enable: true },
326
- });
327
- console.log(renderStatus.result);`,
369
+ tool: TOOL_NAMES.EXECUTE_NODE_METHOD,
328
370
  },
329
371
  {
330
- tool: TOOL_NAMES.GET_TD_CLASSES,
331
- modulePath: `${MODULE_ROOT}/getTdClasses.ts`,
332
- functionName: "getTdClasses",
333
- description: "List TouchDesigner Python classes/modules",
334
372
  category: "classes",
373
+ description: "List TouchDesigner Python classes/modules",
374
+ example: `import { getTdClasses } from './servers/touchdesigner/getTdClasses';
375
+
376
+ const classes = await getTdClasses({ limit: 20 });
377
+ console.log(classes.classes?.map(cls => cls.name));`,
378
+ functionName: "getTdClasses",
379
+ modulePath: `${MODULE_ROOT}/getTdClasses.ts`,
335
380
  parameters: [
336
381
  {
382
+ description: "Minimal returns only names, summary adds short descriptions.",
337
383
  name: "detailLevel",
338
- type: "'minimal' | 'summary' | 'detailed'",
339
384
  required: false,
340
- description: "Minimal returns only names, summary adds short descriptions.",
385
+ type: "'minimal' | 'summary' | 'detailed'",
341
386
  },
342
387
  {
388
+ description: "Restrict the number of classes returned to save tokens.",
343
389
  name: "limit",
344
- type: "number",
345
390
  required: false,
346
- description: "Restrict the number of classes returned to save tokens.",
391
+ type: "number",
347
392
  },
348
393
  {
394
+ description: "Return the catalog as JSON when writing caches.",
349
395
  name: "responseFormat",
350
- type: "'json' | 'yaml' | 'markdown'",
351
396
  required: false,
352
- description: "Return the catalog as JSON when writing caches.",
397
+ type: "'json' | 'yaml' | 'markdown'",
353
398
  },
354
399
  ],
355
400
  returns: "Python class catalogue with names, types, and optional summaries.",
356
- example: `import { getTdClasses } from './servers/touchdesigner/getTdClasses';
357
-
358
- const classes = await getTdClasses({ limit: 20 });
359
- console.log(classes.classes?.map(cls => cls.name));`,
401
+ tool: TOOL_NAMES.GET_TD_CLASSES,
360
402
  },
361
403
  {
362
- tool: TOOL_NAMES.GET_TD_CLASS_DETAILS,
363
- modulePath: `${MODULE_ROOT}/getTdClassDetails.ts`,
364
- functionName: "getTdClassDetails",
365
- description: "Fetch detailed docs for a TouchDesigner class or module",
366
404
  category: "classes",
405
+ description: "Fetch detailed docs for a TouchDesigner class or module",
406
+ example: `import { getTdClassDetails } from './servers/touchdesigner/getTdClassDetails';
407
+
408
+ const textTop = await getTdClassDetails({ className: 'textTOP' });
409
+ console.log(textTop.methods?.length);`,
410
+ functionName: "getTdClassDetails",
411
+ modulePath: `${MODULE_ROOT}/getTdClassDetails.ts`,
367
412
  parameters: [
368
413
  {
414
+ description: "Class/module name like textTOP or CHOP.",
369
415
  name: "className",
370
- type: "string",
371
416
  required: true,
372
- description: "Class/module name like textTOP or CHOP.",
417
+ type: "string",
373
418
  },
374
419
  {
420
+ description: "Switch to detailed when generating docs.",
375
421
  name: "detailLevel",
376
- type: "'minimal' | 'summary' | 'detailed'",
377
422
  required: false,
378
- description: "Switch to detailed when generating docs.",
423
+ type: "'minimal' | 'summary' | 'detailed'",
379
424
  },
380
425
  {
426
+ description: "Cap how many methods/properties are surfaced.",
381
427
  name: "limit",
382
- type: "number",
383
428
  required: false,
384
- description: "Cap how many methods/properties are surfaced.",
429
+ type: "number",
385
430
  },
386
431
  {
432
+ description: "Emit YAML or JSON for caching results to disk.",
387
433
  name: "responseFormat",
388
- type: "'json' | 'yaml' | 'markdown'",
389
434
  required: false,
390
- description: "Emit YAML or JSON for caching results to disk.",
435
+ type: "'json' | 'yaml' | 'markdown'",
391
436
  },
392
437
  ],
393
438
  returns: "Deep description of a Python class including methods and properties.",
394
- example: `import { getTdClassDetails } from './servers/touchdesigner/getTdClassDetails';
439
+ tool: TOOL_NAMES.GET_TD_CLASS_DETAILS,
440
+ },
441
+ {
442
+ category: "classes",
443
+ description: "Run Python help() to inspect documentation for TouchDesigner modules or classes",
444
+ example: `import { getTdModuleHelp } from './servers/touchdesigner/getTdModuleHelp';
395
445
 
396
- const textTop = await getTdClassDetails({ className: 'textTOP' });
397
- console.log(textTop.methods?.length);`,
446
+ const docs = await getTdModuleHelp({ moduleName: 'noiseCHOP' });
447
+ console.log(docs.helpText?.slice(0, 200));`,
448
+ functionName: "getTdModuleHelp",
449
+ modulePath: `${MODULE_ROOT}/getTdModuleHelp.ts`,
450
+ parameters: [
451
+ {
452
+ description: "Module or class name (e.g., 'noiseCHOP', 'td.noiseCHOP', 'tdu').",
453
+ name: "moduleName",
454
+ required: true,
455
+ type: "string",
456
+ },
457
+ {
458
+ description: "Controls how much of the help text is shown.",
459
+ name: "detailLevel",
460
+ required: false,
461
+ type: "'minimal' | 'summary' | 'detailed'",
462
+ },
463
+ {
464
+ description: "Select markdown/json/yaml output for automation.",
465
+ name: "responseFormat",
466
+ required: false,
467
+ type: "'json' | 'yaml' | 'markdown'",
468
+ },
469
+ ],
470
+ returns: "Captured Python help() output with formatter context.",
471
+ tool: TOOL_NAMES.GET_TD_MODULE_HELP,
398
472
  },
399
473
  ];
400
474
  export function getTouchDesignerToolMetadata() {