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.
- package/README.ja.md +46 -0
- package/README.md +46 -0
- package/dist/cli.js +1 -1
- package/dist/core/compatibility.js +236 -0
- package/dist/core/constants.js +5 -3
- package/dist/core/errorHandling.js +18 -3
- package/dist/core/logger.js +17 -32
- package/dist/core/result.js +2 -2
- package/dist/core/version.js +24 -0
- package/dist/features/prompts/handlers/td_prompts.js +24 -18
- package/dist/features/tools/handlers/tdTools.js +75 -18
- package/dist/features/tools/metadata/touchDesignerToolMetadata.js +246 -172
- package/dist/features/tools/presenter/classListFormatter.js +22 -22
- package/dist/features/tools/presenter/index.js +2 -0
- package/dist/features/tools/presenter/moduleHelpFormatter.js +315 -0
- package/dist/features/tools/presenter/nodeDetailsFormatter.js +17 -17
- package/dist/features/tools/presenter/nodeErrorsFormatter.js +68 -0
- package/dist/features/tools/presenter/nodeListFormatter.js +12 -12
- package/dist/features/tools/presenter/operationFormatter.js +26 -19
- package/dist/features/tools/presenter/responseFormatter.js +4 -4
- package/dist/features/tools/presenter/scriptResultFormatter.js +14 -14
- package/dist/features/tools/presenter/toolMetadataFormatter.js +8 -8
- package/dist/gen/endpoints/TouchDesignerAPI.js +22 -4
- package/dist/gen/mcp/touchDesignerAPI.zod.js +52 -12
- package/dist/server/connectionManager.js +11 -28
- package/dist/server/touchDesignerServer.js +4 -3
- package/dist/tdClient/touchDesignerClient.js +267 -46
- package/package.json +31 -17
|
@@ -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
|
-
|
|
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
|
-
|
|
24
|
+
type: "'json' | 'yaml' | 'markdown'",
|
|
22
25
|
},
|
|
23
26
|
],
|
|
24
27
|
returns: "TouchDesigner build metadata (server, version, operating system).",
|
|
25
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
58
|
+
type: "'json' | 'yaml' | 'markdown'",
|
|
54
59
|
},
|
|
55
60
|
],
|
|
56
61
|
returns: "Result payload that mirrors `result` from the executed script (if set).",
|
|
57
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
111
|
+
type: "'json' | 'yaml' | 'markdown'",
|
|
106
112
|
},
|
|
107
113
|
],
|
|
108
114
|
returns: "Set of nodes (id, opType, name, path, optional properties) under parentPath.",
|
|
109
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
149
|
+
type: "'json' | 'yaml' | 'markdown'",
|
|
147
150
|
},
|
|
148
151
|
],
|
|
149
152
|
returns: "Full node record with parameters, paths, and metadata.",
|
|
150
|
-
|
|
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
|
-
|
|
164
|
-
|
|
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
|
-
|
|
176
|
-
|
|
176
|
+
description: "Formatter verbosity for the returned error list.",
|
|
177
|
+
name: "detailLevel",
|
|
177
178
|
required: false,
|
|
178
|
-
|
|
179
|
+
type: "'minimal' | 'summary' | 'detailed'",
|
|
179
180
|
},
|
|
180
181
|
{
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
description: "Optional limit on how many errors are displayed.",
|
|
183
|
+
name: "limit",
|
|
183
184
|
required: false,
|
|
184
|
-
|
|
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
|
-
|
|
191
|
+
type: "'json' | 'yaml' | 'markdown'",
|
|
191
192
|
},
|
|
192
193
|
],
|
|
193
|
-
returns: "
|
|
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
|
-
|
|
212
|
-
|
|
212
|
+
description: "Where the new node should be created.",
|
|
213
|
+
name: "parentPath",
|
|
213
214
|
required: true,
|
|
214
|
-
|
|
215
|
+
type: "string",
|
|
215
216
|
},
|
|
216
217
|
{
|
|
217
|
-
|
|
218
|
-
|
|
218
|
+
description: "OP type (e.g. textTOP, constantCHOP).",
|
|
219
|
+
name: "nodeType",
|
|
219
220
|
required: true,
|
|
220
|
-
|
|
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
|
-
|
|
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
|
-
|
|
239
|
+
type: "'json' | 'yaml' | 'markdown'",
|
|
233
240
|
},
|
|
234
241
|
],
|
|
235
|
-
returns: "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
279
|
+
type: "'json' | 'yaml' | 'markdown'",
|
|
267
280
|
},
|
|
268
281
|
],
|
|
269
|
-
returns: "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
365
|
+
type: "'json' | 'yaml' | 'markdown'",
|
|
317
366
|
},
|
|
318
367
|
],
|
|
319
368
|
returns: "Raw method return payload including any serializable values.",
|
|
320
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
397
|
+
type: "'json' | 'yaml' | 'markdown'",
|
|
353
398
|
},
|
|
354
399
|
],
|
|
355
400
|
returns: "Python class catalogue with names, types, and optional summaries.",
|
|
356
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
435
|
+
type: "'json' | 'yaml' | 'markdown'",
|
|
391
436
|
},
|
|
392
437
|
],
|
|
393
438
|
returns: "Deep description of a Python class including methods and properties.",
|
|
394
|
-
|
|
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
|
|
397
|
-
console.log(
|
|
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() {
|