touchdesigner-mcp-server 1.1.1 → 1.1.2

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.
Files changed (27) hide show
  1. package/README.ja.md +75 -26
  2. package/README.md +74 -25
  3. package/dist/core/constants.js +1 -0
  4. package/dist/features/tools/handlers/tdTools.js +162 -50
  5. package/dist/features/tools/metadata/touchDesignerToolMetadata.js +402 -0
  6. package/dist/features/tools/presenter/classListFormatter.js +187 -0
  7. package/dist/features/tools/presenter/index.js +11 -0
  8. package/dist/features/tools/presenter/markdownRenderer.js +25 -0
  9. package/dist/features/tools/presenter/nodeDetailsFormatter.js +140 -0
  10. package/dist/features/tools/presenter/nodeListFormatter.js +124 -0
  11. package/dist/features/tools/presenter/operationFormatter.js +117 -0
  12. package/dist/features/tools/presenter/presenter.js +62 -0
  13. package/dist/features/tools/presenter/responseFormatter.js +66 -0
  14. package/dist/features/tools/presenter/scriptResultFormatter.js +171 -0
  15. package/dist/features/tools/presenter/templates/markdown/classDetailsSummary.md +13 -0
  16. package/dist/features/tools/presenter/templates/markdown/classListSummary.md +7 -0
  17. package/dist/features/tools/presenter/templates/markdown/default.md +3 -0
  18. package/dist/features/tools/presenter/templates/markdown/detailedPayload.md +5 -0
  19. package/dist/features/tools/presenter/templates/markdown/nodeDetailsSummary.md +10 -0
  20. package/dist/features/tools/presenter/templates/markdown/nodeListSummary.md +8 -0
  21. package/dist/features/tools/presenter/templates/markdown/scriptSummary.md +15 -0
  22. package/dist/features/tools/presenter/toolMetadataFormatter.js +118 -0
  23. package/dist/features/tools/types.js +26 -1
  24. package/dist/gen/endpoints/TouchDesignerAPI.js +1 -1
  25. package/dist/gen/mcp/touchDesignerAPI.zod.js +1 -1
  26. package/dist/server/touchDesignerServer.js +1 -1
  27. package/package.json +6 -5
@@ -0,0 +1,7 @@
1
+ ## TouchDesigner Classes ({{classCount}})
2
+ {{#classes}}- `{{name}}` — {{{description}}}
3
+ {{/classes}}
4
+
5
+ ## Modules ({{moduleCount}})
6
+ {{#modules}}- `{{.}}`
7
+ {{/modules}}
@@ -0,0 +1,3 @@
1
+ ## {{title}}
2
+
3
+ {{{text}}}
@@ -0,0 +1,5 @@
1
+ ## {{title}}
2
+
3
+ ```{{payloadFormat}}
4
+ {{{payload}}}
5
+ ```
@@ -0,0 +1,10 @@
1
+ ## Node {{nodePath}}
2
+ - Type: `{{type}}` (ID: {{id}})
3
+ - Properties shown: {{displayed}} / {{total}}
4
+
5
+ | Property | Value |
6
+ | --- | --- |
7
+ {{#properties}}| {{name}} | {{{value}}} |
8
+ {{/properties}}
9
+
10
+ {{#truncated}}_💡 {{omittedCount}} more properties omitted._{{/truncated}}
@@ -0,0 +1,8 @@
1
+ ## Nodes in {{{parentPath}}} ({{totalCount}} total)
2
+ {{#groups}}
3
+ ### {{type}} ({{count}})
4
+ {{#nodes}}- **{{name}}** — `{{{path}}}`
5
+ {{/nodes}}
6
+
7
+ {{/groups}}
8
+ {{#truncated}}_💡 {{omittedCount}} more node(s) omitted. Use `limit` or `detailLevel=detailed` to view all._{{/truncated}}
@@ -0,0 +1,15 @@
1
+ ## Script Result
2
+ - Snippet: `{{{snippet}}}`
3
+ - Return type: {{resultType}}
4
+ {{#hasOutput}}- Output type: {{outputType}}
5
+ {{/hasOutput}}
6
+
7
+ ```text
8
+ {{{resultPreview}}}
9
+ ```
10
+
11
+ {{#outputPreview}}
12
+ ```text
13
+ {{{outputPreview}}}
14
+ ```
15
+ {{/outputPreview}}
@@ -0,0 +1,118 @@
1
+ import { finalizeFormattedText, mergeFormatterOptions, } from "./responseFormatter.js";
2
+ export function formatToolMetadata(entries, options) {
3
+ const { detailLevel, responseFormat } = mergeFormatterOptions(options);
4
+ if (entries.length === 0) {
5
+ return finalizeFormattedText("No tools matched the requested criteria.", { detailLevel, responseFormat }, {
6
+ context: { totalTools: 0, filter: options?.filter },
7
+ });
8
+ }
9
+ const sortedEntries = [...entries].sort((a, b) => a.modulePath.localeCompare(b.modulePath));
10
+ const structured = sortedEntries.map((entry) => ({
11
+ tool: entry.tool,
12
+ modulePath: entry.modulePath,
13
+ functionName: entry.functionName,
14
+ description: entry.description,
15
+ category: entry.category,
16
+ parameters: entry.parameters,
17
+ returns: entry.returns,
18
+ notes: entry.notes,
19
+ }));
20
+ const text = buildText(sortedEntries, detailLevel);
21
+ return finalizeFormattedText(text, { detailLevel, responseFormat }, {
22
+ structured,
23
+ context: {
24
+ totalTools: sortedEntries.length,
25
+ filter: options?.filter,
26
+ },
27
+ template: detailLevel === "detailed" ? "detailedPayload" : undefined,
28
+ });
29
+ }
30
+ function buildText(entries, detailLevel) {
31
+ switch (detailLevel) {
32
+ case "minimal":
33
+ return formatTree(entries);
34
+ case "detailed":
35
+ return formatDetailed(entries);
36
+ default:
37
+ return formatSummary(entries);
38
+ }
39
+ }
40
+ function formatTree(entries) {
41
+ const segmentsList = entries.map((entry) => entry.modulePath.replace(/^\.\//, "").split("/"));
42
+ const commonSegments = findCommonDirectorySegments(segmentsList);
43
+ const basePath = commonSegments.length > 0 ? `${commonSegments.join("/")}/` : "./";
44
+ const relativePaths = entries.map((entry, index) => {
45
+ const segments = segmentsList[index];
46
+ const relative = segments.slice(commonSegments.length).join("/");
47
+ const connector = index === entries.length - 1 ? "└──" : "├──";
48
+ return `${connector} ${relative} — ${entry.description}`;
49
+ });
50
+ return ["Filesystem blueprint:", basePath, ...relativePaths].join("\n");
51
+ }
52
+ function formatSummary(entries) {
53
+ return entries
54
+ .map((entry) => {
55
+ const params = entry.parameters.length > 0
56
+ ? entry.parameters
57
+ .map((param) => `- ${param.name}${param.required ? "" : "?"} (${param.type})${param.description ? ` — ${param.description}` : ""}`)
58
+ .join("\n")
59
+ : "- (no parameters)";
60
+ return `${entry.functionName} (${entry.modulePath})
61
+ Tool: ${entry.tool}
62
+ Category: ${entry.category}
63
+ Description: ${entry.description}
64
+ Parameters:
65
+ ${params}
66
+ Returns: ${entry.returns}`;
67
+ })
68
+ .join("\n\n");
69
+ }
70
+ function formatDetailed(entries) {
71
+ return entries
72
+ .map((entry) => {
73
+ const params = entry.parameters.length > 0
74
+ ? entry.parameters
75
+ .map((param) => `- ${param.name}${param.required ? "" : "?"} (${param.type})${param.description ? ` — ${param.description}` : ""}`)
76
+ .join("\n")
77
+ : "- (no parameters)";
78
+ const sections = [
79
+ `### ${entry.functionName} (${entry.tool})`,
80
+ `Module: ${entry.modulePath}`,
81
+ `Category: ${entry.category}`,
82
+ `Description: ${entry.description}`,
83
+ "Parameters:",
84
+ params,
85
+ `Returns: ${entry.returns}`,
86
+ "Example:",
87
+ "```ts",
88
+ entry.example.trim(),
89
+ "```",
90
+ ];
91
+ if (entry.notes) {
92
+ sections.push(`Notes: ${entry.notes}`);
93
+ }
94
+ return sections.join("\n");
95
+ })
96
+ .join("\n\n---\n\n");
97
+ }
98
+ function findCommonDirectorySegments(segmentsList) {
99
+ if (segmentsList.length === 0) {
100
+ return [];
101
+ }
102
+ const directories = segmentsList.map((parts) => parts.slice(0, Math.max(parts.length - 1, 0)));
103
+ let prefix = directories[0];
104
+ for (let i = 1; i < directories.length; i += 1) {
105
+ const current = directories[i];
106
+ let j = 0;
107
+ while (j < prefix.length &&
108
+ j < current.length &&
109
+ prefix[j] === current[j]) {
110
+ j += 1;
111
+ }
112
+ prefix = prefix.slice(0, j);
113
+ if (prefix.length === 0) {
114
+ break;
115
+ }
116
+ }
117
+ return prefix;
118
+ }
@@ -1 +1,26 @@
1
- "use strict";
1
+ import { z } from "zod";
2
+ /**
3
+ * Shared Zod schemas for MCP tool formatting parameters.
4
+ * These stay on the TypeScript side only and are not sent to TouchDesigner.
5
+ */
6
+ export const detailLevelSchema = z
7
+ .enum(["minimal", "summary", "detailed"])
8
+ .describe("Response detail level for tool output (minimal, summary, or detailed)");
9
+ export const limitSchema = z
10
+ .number()
11
+ .int()
12
+ .min(1)
13
+ .max(500)
14
+ .describe("Maximum number of items to include in formatted output");
15
+ export const presenterFormatSchema = z
16
+ .enum(["json", "yaml", "markdown"])
17
+ .describe("Structured output format for formatted responses");
18
+ export const detailOnlyFormattingSchema = z.object({
19
+ detailLevel: detailLevelSchema.optional(),
20
+ responseFormat: presenterFormatSchema.optional(),
21
+ });
22
+ export const formattingOptionsSchema = z.object({
23
+ detailLevel: detailLevelSchema.optional(),
24
+ limit: limitSchema.optional(),
25
+ responseFormat: presenterFormatSchema.optional(),
26
+ });
@@ -3,7 +3,7 @@
3
3
  * Do not edit manually.
4
4
  * TouchDesigner API
5
5
  * OpenAPI schema for generating TouchDesigner API client code
6
- * OpenAPI spec version: 1.1.1
6
+ * OpenAPI spec version: 1.1.2
7
7
  */
8
8
  import { customInstance } from '../../api/customInstance.js';
9
9
  // eslint-disable-next-line @typescript-eslint/no-redeclare
@@ -3,7 +3,7 @@
3
3
  * Do not edit manually.
4
4
  * TouchDesigner API
5
5
  * OpenAPI schema for generating TouchDesigner API client code
6
- * OpenAPI spec version: 1.1.1
6
+ * OpenAPI spec version: 1.1.2
7
7
  */
8
8
  import { z as zod } from 'zod';
9
9
  /**
@@ -18,7 +18,7 @@ export class TouchDesignerServer {
18
18
  constructor() {
19
19
  this.server = new McpServer({
20
20
  name: "TouchDesigner",
21
- version: "1.1.1",
21
+ version: "1.1.2",
22
22
  }, {
23
23
  capabilities: {
24
24
  prompts: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "touchdesigner-mcp-server",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "MCP server for TouchDesigner",
5
5
  "repository": {
6
6
  "type": "git",
@@ -29,23 +29,24 @@
29
29
  "@types/ws": "^8.18.1",
30
30
  "@types/yargs": "^17.0.33",
31
31
  "axios": "^1.12.2",
32
+ "mustache": "^4.2.0",
33
+ "yaml": "^2.8.1",
32
34
  "zod": "3.25.76"
33
35
  },
34
36
  "devDependencies": {
35
37
  "@biomejs/biome": "2.2.4",
36
38
  "@openapitools/openapi-generator-cli": "^2.23.1",
37
39
  "@types/jsdom": "^21.1.7",
40
+ "@types/mustache": "^4.2.6",
38
41
  "@types/node": "^24.4.0",
39
42
  "@vitest/coverage-v8": "^3.2.4",
40
43
  "archiver": "^7.0.1",
41
44
  "msw": "^2.11.2",
42
- "mustache": "^4.2.0",
43
45
  "npm-run-all": "^4.1.5",
44
46
  "orval": "^7.11.2",
45
47
  "shx": "^0.4.0",
46
48
  "typescript": "^5.9.2",
47
- "vitest": "^3.2.4",
48
- "yaml": "^2.8.1"
49
+ "vitest": "^3.2.4"
49
50
  },
50
51
  "type": "module",
51
52
  "exports": {
@@ -61,7 +62,7 @@
61
62
  "scripts": {
62
63
  "build": "run-s build:*",
63
64
  "build:gen": "npm run gen",
64
- "build:dist": "tsc && shx chmod +x dist/*.js",
65
+ "build:dist": "tsc && shx chmod +x dist/*.js && shx cp -r src/features/tools/presenter/templates dist/features/tools/presenter/",
65
66
  "build:dxt": "npx @anthropic-ai/dxt pack dxt/ touchdesigner-mcp.dxt",
66
67
  "lint": "run-p lint:*",
67
68
  "lint:biome": "biome check",