touchdesigner-mcp-server 1.4.4 → 1.4.5
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,22 +1,22 @@
|
|
|
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 {
|
|
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
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
|
-
const execPythonScriptToolSchema =
|
|
8
|
+
const execPythonScriptToolSchema = ExecPythonScriptBody.extend(detailOnlyFormattingSchema.shape);
|
|
9
9
|
const tdInfoToolSchema = detailOnlyFormattingSchema;
|
|
10
|
-
const getNodesToolSchema =
|
|
11
|
-
const getNodeDetailToolSchema =
|
|
12
|
-
const getNodeErrorsToolSchema =
|
|
13
|
-
const createNodeToolSchema =
|
|
14
|
-
const updateNodeToolSchema =
|
|
15
|
-
const deleteNodeToolSchema =
|
|
10
|
+
const getNodesToolSchema = GetNodesQueryParams.extend(formattingOptionsSchema.shape);
|
|
11
|
+
const getNodeDetailToolSchema = GetNodeDetailQueryParams.extend(formattingOptionsSchema.shape);
|
|
12
|
+
const getNodeErrorsToolSchema = GetNodeErrorsQueryParams.extend(formattingOptionsSchema.shape);
|
|
13
|
+
const createNodeToolSchema = CreateNodeBody.extend(detailOnlyFormattingSchema.shape);
|
|
14
|
+
const updateNodeToolSchema = UpdateNodeBody.extend(detailOnlyFormattingSchema.shape);
|
|
15
|
+
const deleteNodeToolSchema = DeleteNodeQueryParams.extend(detailOnlyFormattingSchema.shape);
|
|
16
16
|
const classListToolSchema = formattingOptionsSchema;
|
|
17
|
-
const classDetailToolSchema =
|
|
18
|
-
const moduleHelpToolSchema =
|
|
19
|
-
const execNodeMethodToolSchema =
|
|
17
|
+
const classDetailToolSchema = GetTdPythonClassDetailsParams.extend(formattingOptionsSchema.shape);
|
|
18
|
+
const moduleHelpToolSchema = GetModuleHelpQueryParams.extend(detailOnlyFormattingSchema.shape);
|
|
19
|
+
const execNodeMethodToolSchema = ExecNodeMethodBody.extend(detailOnlyFormattingSchema.shape);
|
|
20
20
|
const describeToolsSchema = detailOnlyFormattingSchema.extend({
|
|
21
21
|
filter: z
|
|
22
22
|
.string()
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generated by orval
|
|
2
|
+
* Generated by orval v8.5.2 🍺
|
|
3
3
|
* Do not edit manually.
|
|
4
4
|
* TouchDesigner API
|
|
5
5
|
* OpenAPI schema for generating TouchDesigner API client code
|
|
6
6
|
* OpenAPI spec version: 1.4.3
|
|
7
7
|
*/
|
|
8
8
|
import { customInstance } from '../../api/customInstance.js';
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
10
9
|
export const TdNodeFamilyType = {
|
|
11
10
|
COMP: 'COMP',
|
|
12
11
|
CHOP: 'CHOP',
|
|
@@ -16,14 +15,12 @@ export const TdNodeFamilyType = {
|
|
|
16
15
|
MAT: 'MAT',
|
|
17
16
|
CUSTOM: 'CUSTOM',
|
|
18
17
|
};
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
20
18
|
export const TdPythonClassDetailsType = {
|
|
21
19
|
class: 'class',
|
|
22
20
|
module: 'module',
|
|
23
21
|
function: 'function',
|
|
24
22
|
object: 'object',
|
|
25
23
|
};
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
27
24
|
export const TdPythonClassInfoType = {
|
|
28
25
|
class: 'class',
|
|
29
26
|
module: 'module',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generated by orval
|
|
2
|
+
* Generated by orval v8.5.2 🍺
|
|
3
3
|
* Do not edit manually.
|
|
4
4
|
* TouchDesigner API
|
|
5
5
|
* OpenAPI schema for generating TouchDesigner API client code
|
|
@@ -9,10 +9,10 @@ import * as zod from 'zod';
|
|
|
9
9
|
/**
|
|
10
10
|
* @summary Delete an existing node
|
|
11
11
|
*/
|
|
12
|
-
export const
|
|
13
|
-
"nodePath": zod.string().describe('Path to the node to delete. e.g., \"
|
|
12
|
+
export const DeleteNodeQueryParams = zod.object({
|
|
13
|
+
"nodePath": zod.string().describe('Path to the node to delete. e.g., \"\/project1\/geo1\"')
|
|
14
14
|
});
|
|
15
|
-
export const
|
|
15
|
+
export const DeleteNodeResponse = zod.object({
|
|
16
16
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
17
17
|
"data": zod.object({
|
|
18
18
|
"deleted": zod.boolean().optional().describe('Whether the node was successfully deleted'),
|
|
@@ -29,14 +29,14 @@ export const deleteNodeResponse = zod.object({
|
|
|
29
29
|
/**
|
|
30
30
|
* @summary Get nodes in the path
|
|
31
31
|
*/
|
|
32
|
-
export const getNodesQueryPatternDefault =
|
|
32
|
+
export const getNodesQueryPatternDefault = `*`;
|
|
33
33
|
export const getNodesQueryIncludePropertiesDefault = false;
|
|
34
|
-
export const
|
|
35
|
-
"parentPath": zod.string().describe('Parent path e.g., \"
|
|
36
|
-
"pattern": zod.string().default(getNodesQueryPatternDefault).describe('Pattern to match against node names e.g., \"null
|
|
37
|
-
"includeProperties": zod.boolean().
|
|
34
|
+
export const GetNodesQueryParams = zod.object({
|
|
35
|
+
"parentPath": zod.string().describe('Parent path e.g., \"\/project1\"'),
|
|
36
|
+
"pattern": zod.string().default(getNodesQueryPatternDefault).describe('Pattern to match against node names e.g., \"null\*\"'),
|
|
37
|
+
"includeProperties": zod.boolean().default(getNodesQueryIncludePropertiesDefault).describe('Whether to include full node properties in the response (default false for better performance)')
|
|
38
38
|
});
|
|
39
|
-
export const
|
|
39
|
+
export const GetNodesResponse = zod.object({
|
|
40
40
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
41
41
|
"data": zod.object({
|
|
42
42
|
"nodes": zod.array(zod.object({
|
|
@@ -52,12 +52,12 @@ export const getNodesResponse = zod.object({
|
|
|
52
52
|
/**
|
|
53
53
|
* @summary Create a new node
|
|
54
54
|
*/
|
|
55
|
-
export const
|
|
56
|
-
"parentPath": zod.string().describe('Path to the parent node (e.g.,
|
|
55
|
+
export const CreateNodeBody = zod.object({
|
|
56
|
+
"parentPath": zod.string().describe('Path to the parent node (e.g., \/project1)'),
|
|
57
57
|
"nodeType": zod.string().describe('Type of the node to create (e.g., textTop)'),
|
|
58
58
|
"nodeName": zod.string().optional().describe('Name of the new node (optional)')
|
|
59
59
|
});
|
|
60
|
-
export const
|
|
60
|
+
export const CreateNodeResponse = zod.object({
|
|
61
61
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
62
62
|
"data": zod.object({
|
|
63
63
|
"result": zod.object({
|
|
@@ -74,10 +74,10 @@ export const createNodeResponse = zod.object({
|
|
|
74
74
|
* Retrieves detailed information about a specific node including its properties, parameters and connections
|
|
75
75
|
* @summary Get node detail
|
|
76
76
|
*/
|
|
77
|
-
export const
|
|
78
|
-
"nodePath": zod.string().describe('Node path. e.g., \"
|
|
77
|
+
export const GetNodeDetailQueryParams = zod.object({
|
|
78
|
+
"nodePath": zod.string().describe('Node path. e.g., \"\/project1\/textTOP\"')
|
|
79
79
|
});
|
|
80
|
-
export const
|
|
80
|
+
export const GetNodeDetailResponse = zod.object({
|
|
81
81
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
82
82
|
"data": zod.object({
|
|
83
83
|
"id": zod.number(),
|
|
@@ -91,11 +91,11 @@ export const getNodeDetailResponse = zod.object({
|
|
|
91
91
|
/**
|
|
92
92
|
* @summary Update node properties
|
|
93
93
|
*/
|
|
94
|
-
export const
|
|
95
|
-
"nodePath": zod.string().describe('Path to the node (e.g.,
|
|
94
|
+
export const UpdateNodeBody = zod.object({
|
|
95
|
+
"nodePath": zod.string().describe('Path to the node (e.g., \/project1\/null1)'),
|
|
96
96
|
"properties": zod.record(zod.string(), zod.unknown())
|
|
97
97
|
});
|
|
98
|
-
export const
|
|
98
|
+
export const UpdateNodeResponse = zod.object({
|
|
99
99
|
"success": zod.boolean().describe('Whether the update operation was successful'),
|
|
100
100
|
"data": zod.object({
|
|
101
101
|
"path": zod.string().optional().describe('Path of the node that was updated'),
|
|
@@ -112,10 +112,10 @@ export const updateNodeResponse = zod.object({
|
|
|
112
112
|
* Collects TouchDesigner error messages for a node and its children
|
|
113
113
|
* @summary Get node errors
|
|
114
114
|
*/
|
|
115
|
-
export const
|
|
116
|
-
"nodePath": zod.string().describe('Absolute path to the node to inspect. e.g., \"
|
|
115
|
+
export const GetNodeErrorsQueryParams = zod.object({
|
|
116
|
+
"nodePath": zod.string().describe('Absolute path to the node to inspect. e.g., \"\/project1\/text1\"')
|
|
117
117
|
});
|
|
118
|
-
export const
|
|
118
|
+
export const GetNodeErrorsResponse = zod.object({
|
|
119
119
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
120
120
|
"data": zod.object({
|
|
121
121
|
"nodePath": zod.string().describe('Path that was inspected for errors'),
|
|
@@ -136,7 +136,7 @@ export const getNodeErrorsResponse = zod.object({
|
|
|
136
136
|
* Returns a list of Python classes, modules, and functions available in TouchDesigner
|
|
137
137
|
* @summary Get a list of Python classes and modules
|
|
138
138
|
*/
|
|
139
|
-
export const
|
|
139
|
+
export const GetTdPythonClassesResponse = zod.object({
|
|
140
140
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
141
141
|
"data": zod.object({
|
|
142
142
|
"classes": zod.array(zod.object({
|
|
@@ -151,10 +151,10 @@ export const getTdPythonClassesResponse = zod.object({
|
|
|
151
151
|
* Returns detailed information about a specific Python class, module, or function including methods, properties, and documentation
|
|
152
152
|
* @summary Get details of a specific Python class or module
|
|
153
153
|
*/
|
|
154
|
-
export const
|
|
154
|
+
export const GetTdPythonClassDetailsParams = zod.object({
|
|
155
155
|
"className": zod.string().describe('Name of the class or module. e.g., \"textTOP\"')
|
|
156
156
|
});
|
|
157
|
-
export const
|
|
157
|
+
export const GetTdPythonClassDetailsResponse = zod.object({
|
|
158
158
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
159
159
|
"data": zod.object({
|
|
160
160
|
"name": zod.string().describe('Name of the class or module'),
|
|
@@ -168,7 +168,7 @@ export const getTdPythonClassDetailsResponse = zod.object({
|
|
|
168
168
|
"properties": zod.array(zod.object({
|
|
169
169
|
"name": zod.string().describe('Property name'),
|
|
170
170
|
"type": zod.string().describe('Type of the property'),
|
|
171
|
-
"value": zod.
|
|
171
|
+
"value": zod.looseObject({}).nullish().describe('Current value of the property (if serializable)')
|
|
172
172
|
}).describe('Information about a Python property')).describe('List of properties available in the class or module')
|
|
173
173
|
}).describe('Detailed information about a Python class or module'),
|
|
174
174
|
"error": zod.string().nullable().describe('Error message if the operation was not successful')
|
|
@@ -177,13 +177,13 @@ export const getTdPythonClassDetailsResponse = zod.object({
|
|
|
177
177
|
* Retrieve Python help() documentation for TouchDesigner modules, classes, or utilities like tdu.
|
|
178
178
|
* @summary Get module/class Python help documentation
|
|
179
179
|
*/
|
|
180
|
-
export const
|
|
180
|
+
export const GetModuleHelpQueryParams = zod.object({
|
|
181
181
|
"moduleName": zod.string().describe('Module or class name (e.g., \"noiseCHOP\", \"td.noiseCHOP\", \"tdu\").')
|
|
182
182
|
});
|
|
183
|
-
export const
|
|
183
|
+
export const GetModuleHelpResponse = zod.object({
|
|
184
184
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
185
185
|
"data": zod.object({
|
|
186
|
-
"moduleName": zod.string().describe('Normalized module
|
|
186
|
+
"moduleName": zod.string().describe('Normalized module\/class name the help text was generated for'),
|
|
187
187
|
"helpText": zod.string().describe('Captured output from Python\'s help() function')
|
|
188
188
|
}).describe('Raw Python help() output for a TouchDesigner module or class'),
|
|
189
189
|
"error": zod.string().nullable().describe('Error message if the operation was not successful')
|
|
@@ -195,16 +195,16 @@ This allows operations equivalent to TouchDesigner's Python API such as
|
|
|
195
195
|
|
|
196
196
|
* @summary Call a method of the specified node
|
|
197
197
|
*/
|
|
198
|
-
export const
|
|
199
|
-
"nodePath": zod.string().describe('Path to the node (e.g.,
|
|
198
|
+
export const ExecNodeMethodBody = zod.object({
|
|
199
|
+
"nodePath": zod.string().describe('Path to the node (e.g., \/project1\/null1)'),
|
|
200
200
|
"method": zod.string().describe('Name of the method to call'),
|
|
201
201
|
"args": zod.array(zod.union([zod.string(), zod.number(), zod.boolean()])).optional().describe('List of arguments for the method call'),
|
|
202
202
|
"kwargs": zod.record(zod.string(), zod.unknown()).optional().describe('Keyword arguments for the method call')
|
|
203
203
|
});
|
|
204
|
-
export const
|
|
204
|
+
export const ExecNodeMethodResponse = zod.object({
|
|
205
205
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
206
206
|
"data": zod.object({
|
|
207
|
-
"result": zod.
|
|
207
|
+
"result": zod.looseObject({}).describe('Result of the method call. Can be any type (equivalent to unknown in TypeScript).')
|
|
208
208
|
}).nullable(),
|
|
209
209
|
"error": zod.string().nullable().describe('Error message if the operation was not successful')
|
|
210
210
|
});
|
|
@@ -216,14 +216,14 @@ This endpoint allows you to interact with TouchDesigner nodes programmatically.
|
|
|
216
216
|
|
|
217
217
|
* @summary Execute python code on the server
|
|
218
218
|
*/
|
|
219
|
-
export const
|
|
220
|
-
"script": zod.string().describe('e.g., \"op(\'
|
|
219
|
+
export const ExecPythonScriptBody = zod.object({
|
|
220
|
+
"script": zod.string().describe('e.g., \"op(\'\/project1\/text_over_image\').outputConnectors[0].connect(op(\'\/project1\/out1\'))\"')
|
|
221
221
|
});
|
|
222
|
-
export const
|
|
222
|
+
export const ExecPythonScriptResponse = zod.object({
|
|
223
223
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
224
224
|
"data": zod.object({
|
|
225
225
|
"result": zod.object({
|
|
226
|
-
"value": zod.
|
|
226
|
+
"value": zod.looseObject({}).optional().describe('Return value of the executed script, can be any serializable value')
|
|
227
227
|
}).describe('Result of the executed script')
|
|
228
228
|
}).nullable(),
|
|
229
229
|
"error": zod.string().nullable().describe('Error message if the operation was not successful')
|
|
@@ -232,7 +232,7 @@ export const execPythonScriptResponse = zod.object({
|
|
|
232
232
|
* Returns information about the TouchDesigner
|
|
233
233
|
* @summary Get TouchDesigner information
|
|
234
234
|
*/
|
|
235
|
-
export const
|
|
235
|
+
export const GetTdInfoResponse = zod.object({
|
|
236
236
|
"success": zod.boolean().describe('Whether the operation was successful'),
|
|
237
237
|
"data": zod.object({
|
|
238
238
|
"mcpApiVersion": zod.string().describe('Version of the TouchDesigner MCP API server'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "touchdesigner-mcp-server",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.5",
|
|
4
4
|
"description": "MCP server for TouchDesigner",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,31 +26,31 @@
|
|
|
26
26
|
"touchdesigner-mcp-server": "dist/cli.js"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
29
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
30
30
|
"@mozilla/readability": "^0.6.0",
|
|
31
31
|
"@types/axios": "^0.14.4",
|
|
32
32
|
"@types/ws": "^8.18.1",
|
|
33
33
|
"@types/yargs": "^17.0.35",
|
|
34
|
-
"axios": "^1.13.
|
|
34
|
+
"axios": "^1.13.6",
|
|
35
35
|
"express": "^5.2.1",
|
|
36
36
|
"mustache": "^4.2.0",
|
|
37
|
-
"semver": "^7.7.
|
|
37
|
+
"semver": "^7.7.4",
|
|
38
38
|
"yaml": "^2.8.2",
|
|
39
39
|
"zod": "4.3.6"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@biomejs/biome": "2.
|
|
43
|
-
"@openapitools/openapi-generator-cli": "^2.
|
|
42
|
+
"@biomejs/biome": "2.4.6",
|
|
43
|
+
"@openapitools/openapi-generator-cli": "^2.30.2",
|
|
44
44
|
"@types/express": "^5.0.6",
|
|
45
|
-
"@types/jsdom": "^
|
|
45
|
+
"@types/jsdom": "^28.0.0",
|
|
46
46
|
"@types/mustache": "^4.2.6",
|
|
47
|
-
"@types/node": "^25.
|
|
47
|
+
"@types/node": "^25.3.5",
|
|
48
48
|
"@types/semver": "^7.7.1",
|
|
49
49
|
"@vitest/coverage-v8": "^4.0.18",
|
|
50
50
|
"archiver": "^7.0.1",
|
|
51
|
-
"msw": "^2.12.
|
|
51
|
+
"msw": "^2.12.10",
|
|
52
52
|
"npm-run-all": "^4.1.5",
|
|
53
|
-
"orval": "^
|
|
53
|
+
"orval": "^8.5.2",
|
|
54
54
|
"prettier": "^3.8.1",
|
|
55
55
|
"shx": "^0.4.0",
|
|
56
56
|
"typescript": "^5.9.3",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"version:api": "node ./scripts/syncApiServerVersions.ts",
|
|
92
92
|
"version:mcp": "node ./scripts/syncMcpServerVersions.ts",
|
|
93
93
|
"gen": "run-s gen:*",
|
|
94
|
-
"gen:webserver": "openapi-generator-cli generate -i ./src/api/index.yml -g python-flask -o ./td/modules/td_server",
|
|
94
|
+
"gen:webserver": "openapi-generator-cli generate -i ./src/api/index.yml -g python-flask -o ./td/modules/td_server -t ./src/templates/python-flask",
|
|
95
95
|
"gen:handlers": "node td/genHandlers.js",
|
|
96
96
|
"gen:mcp": "orval --config ./orval.config.ts"
|
|
97
97
|
},
|
|
@@ -104,6 +104,6 @@
|
|
|
104
104
|
]
|
|
105
105
|
},
|
|
106
106
|
"overrides": {
|
|
107
|
-
"axios": "^1.13.
|
|
107
|
+
"axios": "^1.13.6"
|
|
108
108
|
}
|
|
109
109
|
}
|