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 { createNodeBody, deleteNodeQueryParams, execNodeMethodBody, execPythonScriptBody, getModuleHelpQueryParams, getNodeDetailQueryParams, getNodeErrorsQueryParams, 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
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 = execPythonScriptBody.extend(detailOnlyFormattingSchema.shape);
8
+ const execPythonScriptToolSchema = ExecPythonScriptBody.extend(detailOnlyFormattingSchema.shape);
9
9
  const tdInfoToolSchema = detailOnlyFormattingSchema;
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);
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 = getTdPythonClassDetailsParams.extend(formattingOptionsSchema.shape);
18
- const moduleHelpToolSchema = getModuleHelpQueryParams.extend(detailOnlyFormattingSchema.shape);
19
- const execNodeMethodToolSchema = execNodeMethodBody.extend(detailOnlyFormattingSchema.shape);
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 v7.20.0 🍺
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 v7.20.0 🍺
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 deleteNodeQueryParams = zod.object({
13
- "nodePath": zod.string().describe('Path to the node to delete. e.g., \"/project1/geo1\"')
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 deleteNodeResponse = zod.object({
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 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().optional().describe('Whether to include full node properties in the response (default false for better performance)')
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 getNodesResponse = zod.object({
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 createNodeBody = zod.object({
56
- "parentPath": zod.string().describe('Path to the parent node (e.g., /project1)'),
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 createNodeResponse = zod.object({
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 getNodeDetailQueryParams = zod.object({
78
- "nodePath": zod.string().describe('Node path. e.g., \"/project1/textTOP\"')
77
+ export const GetNodeDetailQueryParams = zod.object({
78
+ "nodePath": zod.string().describe('Node path. e.g., \"\/project1\/textTOP\"')
79
79
  });
80
- export const getNodeDetailResponse = zod.object({
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 updateNodeBody = zod.object({
95
- "nodePath": zod.string().describe('Path to the node (e.g., /project1/null1)'),
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 updateNodeResponse = zod.object({
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 getNodeErrorsQueryParams = zod.object({
116
- "nodePath": zod.string().describe('Absolute path to the node to inspect. e.g., \"/project1/text1\"')
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 getNodeErrorsResponse = zod.object({
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 getTdPythonClassesResponse = zod.object({
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 getTdPythonClassDetailsParams = zod.object({
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 getTdPythonClassDetailsResponse = zod.object({
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.object({}).nullish().describe('Current value of the property (if serializable)')
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 getModuleHelpQueryParams = zod.object({
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 getModuleHelpResponse = zod.object({
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/class name the help text was generated for'),
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 execNodeMethodBody = zod.object({
199
- "nodePath": zod.string().describe('Path to the node (e.g., /project1/null1)'),
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 execNodeMethodResponse = zod.object({
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.object({}).describe('Result of the method call. Can be any type (equivalent to unknown in TypeScript).')
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 execPythonScriptBody = zod.object({
220
- "script": zod.string().describe('e.g., \"op(\'/project1/text_over_image\').outputConnectors[0].connect(op(\'/project1/out1\'))\"')
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 execPythonScriptResponse = zod.object({
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.object({}).optional().describe('Return value of the executed script, can be any serializable value')
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 getTdInfoResponse = zod.object({
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.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.25.3",
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.2",
34
+ "axios": "^1.13.6",
35
35
  "express": "^5.2.1",
36
36
  "mustache": "^4.2.0",
37
- "semver": "^7.7.3",
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.3.12",
43
- "@openapitools/openapi-generator-cli": "^2.28.0",
42
+ "@biomejs/biome": "2.4.6",
43
+ "@openapitools/openapi-generator-cli": "^2.30.2",
44
44
  "@types/express": "^5.0.6",
45
- "@types/jsdom": "^27.0.0",
45
+ "@types/jsdom": "^28.0.0",
46
46
  "@types/mustache": "^4.2.6",
47
- "@types/node": "^25.0.10",
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.7",
51
+ "msw": "^2.12.10",
52
52
  "npm-run-all": "^4.1.5",
53
- "orval": "^7.17.2",
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.2"
107
+ "axios": "^1.13.6"
108
108
  }
109
109
  }