touchdesigner-mcp-server 0.4.0-alpha.3 → 0.4.0-alpha.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.
package/README.ja.md CHANGED
@@ -46,6 +46,17 @@ npxを使用する場合、TouchDesignerコンポーネントを別途ダウン
46
46
  }
47
47
  }
48
48
  ```
49
+
50
+ **TIPS:** `--host`と`--port`引数を追加することで、TouchDesignerサーバー接続をカスタマイズできます:
51
+ ```json
52
+ "args": [
53
+ "-y",
54
+ "touchdesigner-mcp-server@prerelease",
55
+ "--stdio",
56
+ "--host=http://custom_host",
57
+ "--port=9982"
58
+ ]
59
+ ```
49
60
  </details>
50
61
 
51
62
  <details>
@@ -59,11 +70,10 @@ git clone https://github.com/8beeeaaat/touchdesigner-mcp.git
59
70
  cd touchdesigner-mcp
60
71
  ```
61
72
 
62
- ##### 2. 環境設定ファイルの設置とコードのビルド
63
- .envのテンプレートファイルをコピーし、必要に応じて TD_WEB_SERVER_HOST / TD_WEB_SERVER_PORT を調整してから Dockerイメージをビルドしてください。
64
-
73
+ ##### 2. Dockerイメージのビルド
65
74
  ```bash
66
- cp dotenv .env
75
+ git clone https://github.com/8beeeaaat/touchdesigner-mcp.git
76
+ cd touchdesigner-mcp
67
77
  make build
68
78
  ```
69
79
 
@@ -103,14 +113,25 @@ docker-compose up -d
103
113
  "touchdesigner-mcp-server",
104
114
  "node",
105
115
  "dist/cli.js",
106
- "--stdio"
116
+ "--stdio",
117
+ "--host=http://host.docker.internal"
107
118
  ]
108
119
  }
109
120
  }
110
121
  }
111
122
  ```
112
123
 
113
- *Windows環境では C:\\ の様にドライブレターを含めてください。 例. `C:\\path\\to\\your\\touchdesigner-mcp\\docker-compose.yml`*
124
+ *Windows システムでは、ドライブレターを含めてください。例:`C:\\path\\to\\your\\touchdesigner-mcp\\docker-compose.yml`*
125
+
126
+ **TIPS:** `--port`引数を追加することで、TouchDesignerサーバー接続をカスタマイズできます:
127
+ ```json
128
+ "args": [
129
+ ...,
130
+ "--stdio",
131
+ "--host=http://host.docker.internal",
132
+ "--port=9982"
133
+ ]
134
+ ```
114
135
  </details>
115
136
 
116
137
 
@@ -181,8 +202,10 @@ td/
181
202
 
182
203
  1. **環境設定:**
183
204
  ```bash
184
- cp dotenv .env
185
- # .env ファイルの TD_WEB_SERVER_HOST, TD_WEB_SERVER_PORT を開発環境に合わせて変更
205
+ # リポジトリをクローンして依存関係をインストール
206
+ git clone https://github.com/8beeeaaat/touchdesigner-mcp.git
207
+ cd touchdesigner-mcp
208
+ npm install
186
209
  ```
187
210
 
188
211
  2. **プロジェクトをビルド:**
@@ -229,8 +252,6 @@ td/
229
252
  ├── tests/ # テストコード
230
253
  │ ├── integration/
231
254
  │ └── unit/
232
- ├── .env # ローカル環境変数 (git無視)
233
- ├── dotenv # .env用テンプレート
234
255
  └── orval.config.ts # Orval 設定 (TSクライアント生成)
235
256
  ```
236
257
 
package/README.md CHANGED
@@ -47,6 +47,17 @@ Example: Place it as `/project1/mcp_webserver_base`
47
47
  }
48
48
  }
49
49
  ```
50
+
51
+ **Note:** You can customize the TouchDesigner server connection by adding `--host` and `--port` arguments:
52
+ ```json
53
+ "args": [
54
+ "-y",
55
+ "touchdesigner-mcp-server@prerelease",
56
+ "--stdio",
57
+ "--host=http://custom_host",
58
+ "--port=9982"
59
+ ]
60
+ ```
50
61
  </details>
51
62
 
52
63
  <details>
@@ -60,11 +71,10 @@ Example: Place it as `/project1/mcp_webserver_base`
60
71
  cd touchdesigner-mcp
61
72
  ```
62
73
 
63
- #### 2. Set up the environment file and build:
64
- Copy the template file and adjust the TD_WEB_SERVER_HOST and TD_WEB_SERVER_PORT as needed before building the Docker image.
65
-
74
+ #### 2. Build the Docker image:
66
75
  ```bash
67
- cp dotenv .env
76
+ git clone https://github.com/8beeeaaat/touchdesigner-mcp.git
77
+ cd touchdesigner-mcp
68
78
  make build
69
79
  ```
70
80
 
@@ -81,7 +91,7 @@ Example: Place it as `/project1/mcp_webserver_base`
81
91
 
82
92
  ![import](https://github.com/8beeeaaat/touchdesigner-mcp/blob/main/assets/textport.png)
83
93
 
84
- #### 4. Start the MCP server container
94
+ #### 4. Start the MCP server container with your TouchDesigner configuration
85
95
 
86
96
  ```bash
87
97
  docker-compose up -d
@@ -104,7 +114,8 @@ Example: Place it as `/project1/mcp_webserver_base`
104
114
  "touchdesigner-mcp-server",
105
115
  "node",
106
116
  "dist/cli.js",
107
- "--stdio"
117
+ "--stdio",
118
+ "--host=http://host.docker.internal"
108
119
  ]
109
120
  }
110
121
  }
@@ -112,6 +123,16 @@ Example: Place it as `/project1/mcp_webserver_base`
112
123
  ```
113
124
 
114
125
  *On Windows systems, include the drive letter like C: e.g. `C:\\path\\to\\your\\touchdesigner-mcp\\docker-compose.yml`*
126
+
127
+ **Note:** You can customize the TouchDesigner server connection by adding `--host` and `--port` arguments:
128
+ ```json
129
+ "args": [
130
+ ...,
131
+ "--stdio",
132
+ "--host=http://host.docker.internal",
133
+ "--port=9982"
134
+ ]
135
+ ```
115
136
  </details>
116
137
 
117
138
 
@@ -183,8 +204,10 @@ Not implemented
183
204
 
184
205
  1. **Setup environment:**
185
206
  ```bash
186
- cp dotenv .env
187
- # Adjust TD_WEB_SERVER_HOST and TD_WEB_SERVER_PORT in .env file
207
+ # Clone and install dependencies
208
+ git clone https://github.com/8beeeaaat/touchdesigner-mcp.git
209
+ cd touchdesigner-mcp
210
+ npm install
188
211
  ```
189
212
 
190
213
  2. **Build the project:**
@@ -231,8 +254,6 @@ Not implemented
231
254
  ├── tests/ # Test code
232
255
  │ ├── integration/
233
256
  │ └── unit/
234
- ├── .env # Local environment variables (git ignored)
235
- ├── dotenv # Template for .env
236
257
  └── orval.config.ts # Orval config (TS client generation)
237
258
  ```
238
259
 
@@ -1,6 +1,5 @@
1
1
  import Axios from "axios";
2
- const API_BASE_URL = `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}`;
3
- export const AXIOS_INSTANCE = Axios.create(API_BASE_URL ? { baseURL: API_BASE_URL } : {});
2
+ export const AXIOS_INSTANCE = Axios.create();
4
3
  export const customInstance = (config, options) => {
5
4
  const source = Axios.CancelToken.source();
6
5
  const promise = AXIOS_INSTANCE({
package/dist/cli.js CHANGED
@@ -1,37 +1,67 @@
1
1
  #!/usr/bin/env node
2
- import { resolve } from "node:path";
3
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { config } from "dotenv";
5
3
  import { TouchDesignerServer } from "./server/touchDesignerServer.js";
6
- config({ path: resolve(process.cwd(), ".env") });
4
+ // Note: Environment variables should be set by the Desktop Extensions runtime or CLI arguments
5
+ /**
6
+ * Parse command line arguments
7
+ */
8
+ export function parseArgs(args) {
9
+ const argsToProcess = args || process.argv.slice(2);
10
+ const parsed = {
11
+ host: "http://localhost",
12
+ port: 9981,
13
+ };
14
+ for (let i = 0; i < argsToProcess.length; i++) {
15
+ const arg = argsToProcess[i];
16
+ if (arg.startsWith("--host=")) {
17
+ parsed.host = arg.split("=")[1];
18
+ }
19
+ else if (arg.startsWith("--port=")) {
20
+ parsed.port = Number.parseInt(arg.split("=")[1], 10);
21
+ }
22
+ }
23
+ return parsed;
24
+ }
25
+ /**
26
+ * Determine if the server should run in stdio mode
27
+ */
28
+ export function isStdioMode(nodeEnv, argv) {
29
+ const env = nodeEnv ?? process.env.NODE_ENV;
30
+ const args = argv ?? process.argv;
31
+ return env === "cli" || args.includes("--stdio");
32
+ }
7
33
  /**
8
34
  * Start TouchDesigner MCP server
9
35
  */
10
- export async function startServer() {
11
- const isStdioMode = process.env.NODE_ENV === "cli" || process.argv.includes("--stdio");
36
+ export async function startServer(params) {
12
37
  try {
13
- const server = new TouchDesignerServer();
14
- if (isStdioMode) {
15
- const transport = new StdioServerTransport();
16
- const result = await server.connect(transport);
17
- if (!result.success) {
18
- throw new Error(`Failed to connect: ${result.error.message}`);
19
- }
20
- }
21
- else {
38
+ const isStdioModeFlag = isStdioMode(params?.nodeEnv, params?.argv);
39
+ if (!isStdioModeFlag) {
22
40
  throw new Error("Sorry, this server is not yet available in the browser. Please use the CLI mode.");
23
41
  }
42
+ // Parse command line arguments and set environment variables
43
+ const args = parseArgs(params?.argv);
44
+ process.env.TD_WEB_SERVER_HOST = args.host;
45
+ process.env.TD_WEB_SERVER_PORT = args.port.toString();
46
+ const server = new TouchDesignerServer();
47
+ const transport = new StdioServerTransport();
48
+ const result = await server.connect(transport);
49
+ if (!result.success) {
50
+ throw new Error(`Failed to connect: ${result.error.message}`);
51
+ }
24
52
  }
25
53
  catch (error) {
26
54
  const errorMessage = error instanceof Error ? error.message : String(error);
27
- console.error(`Failed to initialize server: ${errorMessage}`);
28
- process.exit(1);
55
+ throw new Error(`Failed to initialize server: ${errorMessage}`);
29
56
  }
30
57
  }
31
58
  // Start server if this file is executed directly
32
- if (process.argv[1]) {
33
- startServer().catch((error) => {
34
- console.error("Failed to start server:", error);
35
- process.exit(1);
36
- });
37
- }
59
+ startServer({
60
+ nodeEnv: process.env.NODE_ENV,
61
+ argv: process.argv,
62
+ }).catch((error) => {
63
+ console.error("Failed to start server:", error);
64
+ if (process.env.NODE_ENV === "test")
65
+ return;
66
+ process.exit(1);
67
+ });
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Generated by orval v7.9.0 🍺
2
+ * Generated by orval v7.10.0 🍺
3
3
  * Do not edit manually.
4
4
  * TouchDesigner API
5
5
  * OpenAPI schema for generating TouchDesigner API client code
6
- * OpenAPI spec version: 0.4.0-alpha.3
6
+ * OpenAPI spec version: 0.4.0-alpha.5
7
7
  */
8
8
  import { customInstance } from '../../api/customInstance.js';
9
9
  // eslint-disable-next-line @typescript-eslint/no-redeclare
@@ -34,7 +34,7 @@ export const TdPythonClassDetailsType = {
34
34
  * @summary Delete an existing node
35
35
  */
36
36
  export const deleteNode = (params, options) => {
37
- return customInstance({ url: `http://localhost:9981/api/nodes`, method: 'DELETE',
37
+ return customInstance({ url: `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}/api/nodes`, method: 'DELETE',
38
38
  params
39
39
  }, options);
40
40
  };
@@ -42,7 +42,7 @@ export const deleteNode = (params, options) => {
42
42
  * @summary Get nodes in the path
43
43
  */
44
44
  export const getNodes = (params, options) => {
45
- return customInstance({ url: `http://localhost:9981/api/nodes`, method: 'GET',
45
+ return customInstance({ url: `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}/api/nodes`, method: 'GET',
46
46
  params
47
47
  }, options);
48
48
  };
@@ -50,7 +50,7 @@ export const getNodes = (params, options) => {
50
50
  * @summary Create a new node
51
51
  */
52
52
  export const createNode = (createNodeRequest, options) => {
53
- return customInstance({ url: `http://localhost:9981/api/nodes`, method: 'POST',
53
+ return customInstance({ url: `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}/api/nodes`, method: 'POST',
54
54
  headers: { 'Content-Type': 'application/json', },
55
55
  data: createNodeRequest
56
56
  }, options);
@@ -60,7 +60,7 @@ export const createNode = (createNodeRequest, options) => {
60
60
  * @summary Get node detail
61
61
  */
62
62
  export const getNodeDetail = (params, options) => {
63
- return customInstance({ url: `http://localhost:9981/api/nodes/detail`, method: 'GET',
63
+ return customInstance({ url: `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}/api/nodes/detail`, method: 'GET',
64
64
  params
65
65
  }, options);
66
66
  };
@@ -68,7 +68,7 @@ export const getNodeDetail = (params, options) => {
68
68
  * @summary Update node properties
69
69
  */
70
70
  export const updateNode = (updateNodeRequest, options) => {
71
- return customInstance({ url: `http://localhost:9981/api/nodes/detail`, method: 'PATCH',
71
+ return customInstance({ url: `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}/api/nodes/detail`, method: 'PATCH',
72
72
  headers: { 'Content-Type': 'application/json', },
73
73
  data: updateNodeRequest
74
74
  }, options);
@@ -78,7 +78,7 @@ export const updateNode = (updateNodeRequest, options) => {
78
78
  * @summary Get a list of Python classes and modules
79
79
  */
80
80
  export const getTdPythonClasses = (options) => {
81
- return customInstance({ url: `http://localhost:9981/api/td/classes`, method: 'GET'
81
+ return customInstance({ url: `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}/api/td/classes`, method: 'GET'
82
82
  }, options);
83
83
  };
84
84
  /**
@@ -86,7 +86,7 @@ export const getTdPythonClasses = (options) => {
86
86
  * @summary Get details of a specific Python class or module
87
87
  */
88
88
  export const getTdPythonClassDetails = (className, options) => {
89
- return customInstance({ url: `http://localhost:9981/api/td/classes/${className}`, method: 'GET'
89
+ return customInstance({ url: `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}/api/td/classes/${className}`, method: 'GET'
90
90
  }, options);
91
91
  };
92
92
  /**
@@ -97,7 +97,7 @@ This allows operations equivalent to TouchDesigner's Python API such as
97
97
  * @summary Call a method of the specified node
98
98
  */
99
99
  export const execNodeMethod = (execNodeMethodRequest, options) => {
100
- return customInstance({ url: `http://localhost:9981/api/td/nodes/exec`, method: 'POST',
100
+ return customInstance({ url: `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}/api/td/nodes/exec`, method: 'POST',
101
101
  headers: { 'Content-Type': 'application/json', },
102
102
  data: execNodeMethodRequest
103
103
  }, options);
@@ -111,7 +111,7 @@ This endpoint allows you to interact with TouchDesigner nodes programmatically.
111
111
  * @summary Execute python code on the server
112
112
  */
113
113
  export const execPythonScript = (execPythonScriptRequest, options) => {
114
- return customInstance({ url: `http://localhost:9981/api/td/server/exec`, method: 'POST',
114
+ return customInstance({ url: `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}/api/td/server/exec`, method: 'POST',
115
115
  headers: { 'Content-Type': 'application/json', },
116
116
  data: execPythonScriptRequest
117
117
  }, options);
@@ -121,6 +121,6 @@ export const execPythonScript = (execPythonScriptRequest, options) => {
121
121
  * @summary Get TouchDesigner information
122
122
  */
123
123
  export const getTdInfo = (options) => {
124
- return customInstance({ url: `http://localhost:9981/api/td/server/td`, method: 'GET'
124
+ return customInstance({ url: `${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}/api/td/server/td`, method: 'GET'
125
125
  }, options);
126
126
  };
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Generated by orval v7.9.0 🍺
2
+ * Generated by orval v7.10.0 🍺
3
3
  * Do not edit manually.
4
4
  * TouchDesigner API
5
5
  * OpenAPI schema for generating TouchDesigner API client code
6
- * OpenAPI spec version: 0.4.0-alpha.3
6
+ * OpenAPI spec version: 0.4.0-alpha.5
7
7
  */
8
8
  import { z as zod } from 'zod';
9
9
  /**
@@ -24,10 +24,12 @@ export class ConnectionManager {
24
24
  try {
25
25
  await this.server.connect(transport);
26
26
  this.logger.log(`Server connected and ready to process requests: ${process.env.TD_WEB_SERVER_HOST}:${process.env.TD_WEB_SERVER_PORT}`);
27
+ // Connection will be checked when tools are actually used
27
28
  const connectionResult = await this.checkTDConnection();
28
29
  if (!connectionResult.success) {
29
- throw new Error(`Failed to connect to TouchDesigner: ${connectionResult.error.message}`);
30
+ throw new Error(`Failed to connect to TouchDesigner. The mcp_webserver_base on TouchDesigner not currently available: ${connectionResult.error.message}`);
30
31
  }
32
+ this.logger.log("TouchDesigner connection verified");
31
33
  return createSuccessResult(undefined);
32
34
  }
33
35
  catch (error) {
@@ -18,7 +18,7 @@ export class TouchDesignerServer {
18
18
  constructor() {
19
19
  this.server = new McpServer({
20
20
  name: "TouchDesigner",
21
- version: "0.4.0-alpha.3",
21
+ version: "0.4.0-alpha.5",
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": "0.4.0-alpha.3",
3
+ "version": "0.4.0-alpha.5",
4
4
  "description": "MCP server for TouchDesigner",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,29 +22,28 @@
22
22
  "touchdesigner-mcp-server": "dist/cli.js"
23
23
  },
24
24
  "dependencies": {
25
- "@modelcontextprotocol/sdk": "^1.11.1",
25
+ "@modelcontextprotocol/sdk": "^1.13.2",
26
26
  "@mozilla/readability": "^0.6.0",
27
27
  "@types/axios": "^0.14.4",
28
28
  "@types/ws": "^8.18.1",
29
29
  "@types/yargs": "^17.0.33",
30
- "axios": "^1.9.0",
31
- "dotenv": "^16.5.0",
32
- "zod": "^3.24.4"
30
+ "axios": "^1.10.0",
31
+ "zod": "^3.25.67"
33
32
  },
34
33
  "devDependencies": {
35
- "@biomejs/biome": "1.9.4",
36
- "@openapitools/openapi-generator-cli": "^2.20.0",
34
+ "@biomejs/biome": "2.0.6",
35
+ "@openapitools/openapi-generator-cli": "^2.21.0",
37
36
  "@types/jsdom": "^21.1.7",
38
- "@types/node": "^22.15.17",
39
- "@vitest/coverage-v8": "^3.1.3",
40
- "msw": "^2.8.2",
37
+ "@types/node": "^24.0.7",
38
+ "@vitest/coverage-v8": "^3.2.4",
39
+ "msw": "^2.10.2",
41
40
  "mustache": "^4.2.0",
42
41
  "npm-run-all": "^4.1.5",
43
- "orval": "^7.9.0",
42
+ "orval": "^7.10.0",
44
43
  "shx": "^0.4.0",
45
44
  "typescript": "^5.8.3",
46
- "vitest": "^3.1.3",
47
- "yaml": "^2.7.1"
45
+ "vitest": "^3.2.4",
46
+ "yaml": "^2.8.0"
48
47
  },
49
48
  "type": "module",
50
49
  "exports": {