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
|
@@ -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.
|
|
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, {
|
|
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.
|
|
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();
|