touchdesigner-mcp-server 0.2.1 → 0.2.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.
- package/README.ja.md +107 -80
- package/README.md +154 -120
- package/dist/gen/endpoints/TouchDesignerAPI.js +0 -124
- package/package.json +1 -2
- package/dist/mock/index.js +0 -5
- package/dist/mock/node.js +0 -3
package/README.ja.md
CHANGED
|
@@ -4,20 +4,98 @@ TouchDesignerのためのMCP(Model Context Protocol) サーバー実装です。
|
|
|
4
4
|
|
|
5
5
|
## 概要
|
|
6
6
|
|
|
7
|
-

|
|
8
8
|
|
|
9
9
|
TouchDesigner MCPは、AIモデルとTouchDesigner WebServer DAT 間のブリッジとして機能し、AIエージェントが以下のことが可能になります
|
|
10
10
|
- ノードの作成、変更、削除
|
|
11
11
|
- ノードプロパティやプロジェクト構造の照会
|
|
12
12
|
- PythonスクリプトによるTouchDesignerのプログラム的制御
|
|
13
13
|
|
|
14
|
-
##
|
|
14
|
+
## 利用方法
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
- TouchDesigner(最新の安定版を推奨)
|
|
18
|
-
- Docker(Pythonサーバーコードの生成に必要)
|
|
16
|
+
*Node.js がインストールされていることが前提となります*
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
### 1. touchdesigner-mcp-server パッケージのインストール
|
|
19
|
+
|
|
20
|
+
`npm install touchdesigner-mcp-server`
|
|
21
|
+
|
|
22
|
+
### 2. TouchDesignerとの接続
|
|
23
|
+
|
|
24
|
+
#### mcp_webserver_base.tox を TouchDesigner に配置
|
|
25
|
+
|
|
26
|
+
TouchDesignerを起動し、`td/mcp_webserver_base.tox` コンポーネントをTouchDesignerプロジェクト直下にimportします。
|
|
27
|
+
例: `/project1/mcp_webserver_base` となるように配置
|
|
28
|
+
|
|
29
|
+
tox のimport により `td/import_modules.py` スクリプトが動作し、APIサーバのコントローラなどのモジュールがロードされます。
|
|
30
|
+
|
|
31
|
+
#### APIサーバの動作確認
|
|
32
|
+
`npm run test` を実行することでMCPサーバーコードのユニットテストと TouchDesigner への接続テストが実行されます。
|
|
33
|
+
このテストでは `td/modules` ディレクトリ内のPythonモジュールが `mcp_webserver_base` コンポーネントからアクセス可能であることを確認します。
|
|
34
|
+
TouchDesigner のメニューから Textportを起動すると通信のログを確認することができます。
|
|
35
|
+
|
|
36
|
+
### 3. TouchDesigner MCP Server の設定
|
|
37
|
+
TouchDesignerが起動した状態で、AIエージェント(Claude Desktop,Cursor, VSCode CopilotChatなど)をMCPサーバーに接続するように設定します。
|
|
38
|
+
|
|
39
|
+
*例 Claude Desktop*
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"mcpServers": {
|
|
43
|
+
"touchdesigner": {
|
|
44
|
+
"args": [
|
|
45
|
+
"/path/to/your/touchdesigner-mcp-server/dist/index.js", // <-- touchdesigner-mcp-server/dist/index.js への絶対パスに置き換えてください
|
|
46
|
+
"--stdio"
|
|
47
|
+
],
|
|
48
|
+
"command": "node",
|
|
49
|
+
"transportType": "stdio"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
MCPサーバーが認識されていればセットアップは完了です。
|
|
56
|
+
起動時にエラーが表示される場合はTouchDesignerを先に起動してから再度エージェントを起動してください。
|
|
57
|
+
TouchDesigner で APIサーバーが実行されていれば、エージェントは提供された TouchDesigner ツールを通じてTouchDesignerを使用できます。
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## MCPサーバーの機能
|
|
61
|
+
|
|
62
|
+
このサーバーは、Model Context Protocol (MCP) を通じてTouchDesigner への操作、および各種実装ドキュメントへの参照を可能にします。
|
|
63
|
+
|
|
64
|
+
### ツール (Tools)
|
|
65
|
+
|
|
66
|
+
ツールは、AIエージェントがTouchDesignerでアクションを実行できるようにします。
|
|
67
|
+
|
|
68
|
+
| ツール名 | 説明 |
|
|
69
|
+
| :-------------------------- | :--------------------------------------------- |
|
|
70
|
+
| `create_td_node` | 新しいノードを作成します。 |
|
|
71
|
+
| `delete_td_node` | 既存のノードを削除します。 |
|
|
72
|
+
| `exec_node_method`| ノードに対しPythonメソッドを呼び出します。 |
|
|
73
|
+
| `execute_python_script` | TD内で任意のPythonスクリプトを実行します。 |
|
|
74
|
+
| `get_td_class_details` | TD Pythonクラス/モジュールの詳細情報を取得します。 |
|
|
75
|
+
| `get_td_classes` | TouchDesigner Pythonクラスのリストを取得します。 |
|
|
76
|
+
| `get_td_info` | TDサーバー環境に関する情報を取得します。 |
|
|
77
|
+
| `get_td_node_parameters` | 特定ノードのパラメータを取得します。 |
|
|
78
|
+
| `get_td_nodes` | 親パス内のノードを取得します(オプションでフィルタリング)。 |
|
|
79
|
+
| `update_td_node_parameters` | 特定ノードのパラメータを更新します。 |
|
|
80
|
+
|
|
81
|
+
### プロンプト (Prompts)
|
|
82
|
+
|
|
83
|
+
プロンプトは、AIエージェントがTouchDesignerで特定のアクションを実行するための指示を提供します。
|
|
84
|
+
|
|
85
|
+
| プロンプト名 | 説明 |
|
|
86
|
+
| :-------------------------- | :--------------------------------------------- |
|
|
87
|
+
| `Search node` | ノードをファジー検索し、指定されたノード名、ファミリー、タイプに基づいて情報を取得します。 |
|
|
88
|
+
| `Node connection` | TouchDesigner内でノード同士を接続するための指示を提供します。 |
|
|
89
|
+
| `Check node errors` | 指定されたノードのエラーをチェックします。子ノードがあれば再帰的にチェックします。 |
|
|
90
|
+
|
|
91
|
+
### リソース (Resources)
|
|
92
|
+
|
|
93
|
+
未実装
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
## 開発者向け
|
|
97
|
+
|
|
98
|
+
### MCPサーバーコードのビルド
|
|
21
99
|
|
|
22
100
|
1. リポジトリのクローン
|
|
23
101
|
```bash
|
|
@@ -39,22 +117,23 @@ cp dotenv .env
|
|
|
39
117
|
npm run build
|
|
40
118
|
```
|
|
41
119
|
|
|
42
|
-
## 使い方
|
|
43
|
-
|
|
44
120
|
### TouchDesignerのセットアップ
|
|
45
121
|
|
|
46
|
-
1. **コード生成:**
|
|
47
|
-
|
|
122
|
+
#### 1. **コード生成:**
|
|
123
|
+
`npm run build` を実行します。これにより以下のコードが生成されます。
|
|
48
124
|
- MCPサーバコード
|
|
49
125
|
- TouchDesigner WebSever DAT向けのAPIサーバーコード
|
|
50
|
-
|
|
126
|
+
|
|
127
|
+
#### 2. **TouchDesigner に MCPサーバー向けWebServerをインポートする:**
|
|
51
128
|
TouchDesignerを起動し、`td/mcp_webserver_base.tox` コンポーネントをTouchDesignerプロジェクト直下にimportします。
|
|
52
129
|
tox のimport により `td/import_modules.py` スクリプトが動作し、APIサーバのコントローラなどのモジュールがロードされます。
|
|
53
130
|
|
|
54
|
-
3. **APIサーバの動作確認:**
|
|
131
|
+
#### 3. **APIサーバの動作確認:**
|
|
55
132
|
`td/modules` ディレクトリ内のPythonモジュールが `mcp_webserver_base` コンポーネントからアクセス可能であることを確認します。
|
|
56
133
|
`npm run test` を実行することでMCPサーバーコードのユニットテストと TouchDesigner への結合テストが実行されます。
|
|
57
|
-
|
|
134
|
+
TouchDesigner のメニューから Textportを起動すると通信のログを確認することができます。
|
|
135
|
+
|
|
136
|
+
`npm run dev` で @modelcontextprotocol/inspector させデバッグすることができます。
|
|
58
137
|
|
|
59
138
|
*TIPS*
|
|
60
139
|
`mcp_webserver_base.tox` には、MCPサーバーとTouchDesignerを連携させるように設定された WebServer DAT が含まれています。
|
|
@@ -68,23 +147,23 @@ TOuchDesigner のメニューから Textportを起動すると通信のログを
|
|
|
68
147
|
|
|
69
148
|
TouchDesignerが起動した状態で、AIエージェント(Cursor, Claude Desktop, VSCode CopilotChatなど)をMCPサーバーに接続するように設定します。
|
|
70
149
|
|
|
150
|
+
#### 例. Claude Desktop
|
|
71
151
|
```json
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
152
|
+
{
|
|
153
|
+
"mcpServers": {
|
|
154
|
+
"dev_touchdesigner": {
|
|
155
|
+
"args": [
|
|
156
|
+
"/path/to/your/touchdesigner-mcp/dist/index.js", // <-- ビルド後の /dist/index.js への絶対パスに置き換えてください
|
|
157
|
+
"--stdio"
|
|
158
|
+
],
|
|
159
|
+
"command": "node",
|
|
160
|
+
"transportType": "stdio"
|
|
81
161
|
}
|
|
162
|
+
}
|
|
82
163
|
}
|
|
83
164
|
```
|
|
84
165
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
## セットアップ後のプロジェクト構造概要
|
|
166
|
+
### セットアップ後のプロジェクト構造概要
|
|
88
167
|
|
|
89
168
|
```
|
|
90
169
|
├── src/ # MCPサーバー ソースコード
|
|
@@ -118,58 +197,6 @@ TouchDesigner で APIサーバーが実行されていれば、エージェン
|
|
|
118
197
|
└── orval.config.ts # Orval 設定 (TSクライアント生成)
|
|
119
198
|
```
|
|
120
199
|
|
|
121
|
-
## MCPサーバーの機能
|
|
122
|
-
|
|
123
|
-
このサーバーは、Model Context Protocol (MCP) を通じてTouchDesigner への操作、および各種実装ドキュメントへの参照を可能にします。
|
|
124
|
-
|
|
125
|
-
### ツール (Tools)
|
|
126
|
-
|
|
127
|
-
ツールは、AIエージェントがTouchDesignerでアクションを実行できるようにします。
|
|
128
|
-
|
|
129
|
-
| ツール名 | 説明 |
|
|
130
|
-
| :-------------------------- | :--------------------------------------------- |
|
|
131
|
-
| `create_td_node` | 新しいノードを作成します。 |
|
|
132
|
-
| `delete_td_node` | 既存のノードを削除します。 |
|
|
133
|
-
| `exec_node_method`| ノードに対しPythonメソッドを呼び出します。 |
|
|
134
|
-
| `execute_python_script` | TD内で任意のPythonスクリプトを実行します。 |
|
|
135
|
-
| `get_td_class_details` | TD Pythonクラス/モジュールの詳細情報を取得します。 |
|
|
136
|
-
| `get_td_classes` | TouchDesigner Pythonクラスのリストを取得します。 |
|
|
137
|
-
| `get_td_info` | TDサーバー環境に関する情報を取得します。 |
|
|
138
|
-
| `get_td_node_parameters` | 特定ノードのパラメータを取得します。 |
|
|
139
|
-
| `get_td_nodes` | 親パス内のノードを取得します(オプションでフィルタリング)。 |
|
|
140
|
-
| `update_td_node_parameters` | 特定ノードのパラメータを更新します。 |
|
|
141
|
-
|
|
142
|
-
### プロンプト (Prompts)
|
|
143
|
-
|
|
144
|
-
プロンプトは、AIエージェントがTouchDesignerで特定のアクションを実行するための指示を提供します。
|
|
145
|
-
|
|
146
|
-
| プロンプト名 | 説明 |
|
|
147
|
-
| :-------------------------- | :--------------------------------------------- |
|
|
148
|
-
| `Search node` | ノードをファジー検索し、指定されたノード名、ファミリー、タイプに基づいて情報を取得します。 |
|
|
149
|
-
| `Node connection` | TouchDesigner内でノード同士を接続するための指示を提供します。 |
|
|
150
|
-
| `Check node errors` | 指定されたノードのエラーをチェックします。子ノードがあれば再帰的にチェックします。 |
|
|
151
|
-
|
|
152
|
-
### リソース (Resources)
|
|
153
|
-
|
|
154
|
-
未実装
|
|
155
|
-
|
|
156
|
-
## 開発
|
|
157
|
-
|
|
158
|
-
### 開発環境のセットアップ
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
# 依存関係のインストール
|
|
162
|
-
npm install
|
|
163
|
-
|
|
164
|
-
# リンターと型チェッカーの実行
|
|
165
|
-
npm run lint
|
|
166
|
-
|
|
167
|
-
# テストの実行
|
|
168
|
-
npm test
|
|
169
|
-
|
|
170
|
-
# デバッグ用にMCP Inspectorを使用してサーバーを起動
|
|
171
|
-
npm run dev
|
|
172
|
-
```
|
|
173
200
|
|
|
174
201
|
### APIコード生成ワークフロー
|
|
175
202
|
|
|
@@ -192,9 +219,9 @@ npm run dev
|
|
|
192
219
|
|
|
193
220
|
ビルドプロセス (`npm run build`) は、必要なすべての生成ステップ (`npm run gen`) を実行し、その後にTypeScriptコンパイル (`tsc`) を行います。
|
|
194
221
|
|
|
195
|
-
##
|
|
222
|
+
## 開発で貢献
|
|
196
223
|
|
|
197
|
-
|
|
224
|
+
ぜひ一緒に改善しましょう!
|
|
198
225
|
|
|
199
226
|
1. リポジトリをフォーク
|
|
200
227
|
2. 機能ブランチを作成(`git checkout -b feature/amazing-feature`)
|
|
@@ -204,7 +231,7 @@ npm run dev
|
|
|
204
231
|
6. ブランチにプッシュ(`git push origin feature/amazing-feature`)
|
|
205
232
|
7. プルリクエストを開く
|
|
206
233
|
|
|
207
|
-
|
|
234
|
+
実装の変更時は必ず適切なテストを含めてください。
|
|
208
235
|
|
|
209
236
|
## ライセンス
|
|
210
237
|
|
package/README.md
CHANGED
|
@@ -1,91 +1,173 @@
|
|
|
1
1
|
# TouchDesigner MCP
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This is an implementation of an MCP (Model Context Protocol) server for TouchDesigner. The goal is to enable AI agents to control and operate TouchDesigner projects.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-

|
|
8
8
|
|
|
9
|
-
TouchDesigner MCP acts as a bridge between AI models and the TouchDesigner WebServer DAT,
|
|
9
|
+
TouchDesigner MCP acts as a bridge between AI models and the TouchDesigner WebServer DAT, enabling AI agents to:
|
|
10
10
|
- Create, modify, and delete nodes
|
|
11
11
|
- Query node properties and project structure
|
|
12
|
-
- Programmatically control TouchDesigner
|
|
12
|
+
- Programmatically control TouchDesigner via Python scripts
|
|
13
13
|
|
|
14
|
-
##
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
*Requires Node.js to be installed*
|
|
17
|
+
|
|
18
|
+
### 1. Install the touchdesigner-mcp-server package
|
|
19
|
+
|
|
20
|
+
`npm install touchdesigner-mcp-server`
|
|
21
|
+
|
|
22
|
+
### 2. Connect to TouchDesigner
|
|
23
|
+
|
|
24
|
+
#### Place mcp_webserver_base.tox in TouchDesigner
|
|
25
|
+
|
|
26
|
+
Start TouchDesigner and import the `td/mcp_webserver_base.tox` component directly under your TouchDesigner project.
|
|
27
|
+
Example: Place it as `/project1/mcp_webserver_base`
|
|
28
|
+
|
|
29
|
+
Importing the tox will trigger the `td/import_modules.py` script, which loads modules such as API server controllers.
|
|
30
|
+
|
|
31
|
+
#### Verify API server operation
|
|
32
|
+
Run `npm run test` to execute unit tests for the MCP server code and connection tests to TouchDesigner.
|
|
33
|
+
This test ensures that the Python modules in the `td/modules` directory are accessible from the `mcp_webserver_base` component.
|
|
34
|
+
You can check communication logs by opening the Textport from the TouchDesigner menu.
|
|
35
|
+
|
|
36
|
+
### 3. Configure the TouchDesigner MCP Server
|
|
37
|
+
With TouchDesigner running, configure your AI agent (Claude Desktop, Cursor, VSCode CopilotChat, etc.) to connect to the MCP server.
|
|
38
|
+
|
|
39
|
+
*Example: Claude Desktop*
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"mcpServers": {
|
|
43
|
+
"touchdesigner": {
|
|
44
|
+
"args": [
|
|
45
|
+
"/path/to/your/touchdesigner-mcp-server/dist/index.js", // <-- Replace with the absolute path to touchdesigner-mcp-server/dist/index.js
|
|
46
|
+
"--stdio"
|
|
47
|
+
],
|
|
48
|
+
"command": "node",
|
|
49
|
+
"transportType": "stdio"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
If the MCP server is recognized, setup is complete.
|
|
56
|
+
If you see an error at startup, try launching the agent again after starting TouchDesigner.
|
|
57
|
+
If the API server is running in TouchDesigner, the agent can use TouchDesigner via the provided tools.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## MCP Server Features
|
|
61
|
+
|
|
62
|
+
This server enables operations on TouchDesigner via the Model Context Protocol (MCP) and provides references to various implementation documents.
|
|
63
|
+
|
|
64
|
+
### Tools
|
|
65
|
+
|
|
66
|
+
Tools allow AI agents to perform actions in TouchDesigner.
|
|
67
|
+
|
|
68
|
+
| Tool Name | Description |
|
|
69
|
+
| :---------------------- | :----------------------------------------------------------------- |
|
|
70
|
+
| `create_td_node` | Create a new node. |
|
|
71
|
+
| `delete_td_node` | Delete an existing node. |
|
|
72
|
+
| `exec_node_method` | Call a Python method on a node. |
|
|
73
|
+
| `execute_python_script` | Execute an arbitrary Python script in TD. |
|
|
74
|
+
| `get_td_class_details` | Get details of a TD Python class/module. |
|
|
75
|
+
| `get_td_classes` | Get a list of TouchDesigner Python classes. |
|
|
76
|
+
| `get_td_info` | Get information about the TD server environment. |
|
|
77
|
+
| `get_td_node_parameters`| Get parameters of a specific node. |
|
|
78
|
+
| `get_td_nodes` | Get nodes under a parent path (optionally filtered). |
|
|
79
|
+
| `update_td_node_parameters` | Update parameters of a specific node. |
|
|
80
|
+
|
|
81
|
+
### Prompts
|
|
82
|
+
|
|
83
|
+
Prompts provide instructions for AI agents to perform specific actions in TouchDesigner.
|
|
84
|
+
|
|
85
|
+
| Prompt Name | Description |
|
|
86
|
+
| :------------------| :-------------------------------------------------------------------------- |
|
|
87
|
+
| `Search node` | Fuzzy search for nodes and retrieve information based on name, family, type. |
|
|
88
|
+
| `Node connection` | Provide instructions to connect nodes within TouchDesigner. |
|
|
89
|
+
| `Check node errors`| Check errors for a specified node, recursively for child nodes if any. |
|
|
90
|
+
|
|
91
|
+
### Resources
|
|
92
|
+
|
|
93
|
+
Not implemented
|
|
15
94
|
|
|
16
|
-
- Node.js (latest LTS version recommended)
|
|
17
|
-
- TouchDesigner (latest stable version recommended)
|
|
18
|
-
- Docker (Required for generating Python server code)
|
|
19
95
|
|
|
20
|
-
##
|
|
96
|
+
## For Developers
|
|
21
97
|
|
|
22
|
-
|
|
98
|
+
### Building the MCP Server Code
|
|
99
|
+
|
|
100
|
+
1. Clone the repository
|
|
23
101
|
```bash
|
|
24
102
|
git clone https://github.com/8beeeaaat/touchdesigner-mcp.git
|
|
25
103
|
```
|
|
26
104
|
|
|
27
|
-
2. Install dependencies
|
|
105
|
+
2. Install dependencies
|
|
28
106
|
```bash
|
|
29
107
|
cd touchdesigner-mcp
|
|
30
108
|
npm install
|
|
31
109
|
```
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
# Copy the template and adjust TD_WEB_SERVER_URL if needed
|
|
110
|
+
3. Set up environment file and build
|
|
111
|
+
```
|
|
112
|
+
# Copy the template and adjust TD_WEB_SERVER_URL as needed
|
|
36
113
|
cp dotenv .env
|
|
37
114
|
|
|
38
|
-
# Build the project (
|
|
39
|
-
#
|
|
115
|
+
# Build the project (generates API client/server schemas and compiles MCP resources)
|
|
116
|
+
# Make sure the Docker daemon is running before executing this command
|
|
40
117
|
npm run build
|
|
41
118
|
```
|
|
42
119
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
### Setting Up TouchDesigner
|
|
120
|
+
### TouchDesigner Setup
|
|
46
121
|
|
|
47
|
-
1.
|
|
48
|
-
|
|
122
|
+
#### 1. **Code Generation:**
|
|
123
|
+
Run `npm run build` to generate the following code:
|
|
49
124
|
- MCP server code
|
|
50
|
-
- API server code for
|
|
125
|
+
- API server code for TouchDesigner WebServer DAT
|
|
51
126
|
|
|
52
|
-
2.
|
|
53
|
-
|
|
127
|
+
#### 2. **Import the WebServer for MCP server into TouchDesigner:**
|
|
128
|
+
Start TouchDesigner and import the `td/mcp_webserver_base.tox` component directly under your project.
|
|
129
|
+
Importing the tox will trigger the `td/import_modules.py` script, which loads modules such as API server controllers.
|
|
54
130
|
|
|
55
|
-
3.
|
|
56
|
-
Ensure that the Python modules in the `td/modules` directory are accessible from the `mcp_webserver_base` component.
|
|
131
|
+
#### 3. **Verify API server operation:**
|
|
132
|
+
Ensure that the Python modules in the `td/modules` directory are accessible from the `mcp_webserver_base` component.
|
|
133
|
+
Run `npm run test` to execute unit and integration tests for the MCP server code and TouchDesigner connection.
|
|
134
|
+
You can check communication logs by opening the Textport from the TouchDesigner menu.
|
|
135
|
+
|
|
136
|
+
You can debug with @modelcontextprotocol/inspector using `npm run dev`.
|
|
57
137
|
|
|
58
138
|
*TIPS*
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
139
|
+
`mcp_webserver_base.tox` includes a WebServer DAT configured to link the MCP server and TouchDesigner.
|
|
140
|
+
Ensure this DAT is active and running on the port specified by `TD_WEB_SERVER_URL` in your `.env` file (default: `9981`).
|
|
141
|
+
To change the port:
|
|
142
|
+
1. Change `TD_WEB_SERVER_PORT` in `.env`
|
|
143
|
+
2. Re-run `npm run build`
|
|
144
|
+
3. Change the port in mcp_webserver_base (WebServer DAT) and restart the DAT
|
|
63
145
|
|
|
64
|
-
### Connecting
|
|
146
|
+
### Connecting with MCP-compatible AI Agents
|
|
65
147
|
|
|
66
|
-
With TouchDesigner running, configure
|
|
148
|
+
With TouchDesigner running, configure your AI agent (Cursor, Claude Desktop, VSCode CopilotChat, etc.) to connect to the MCP server.
|
|
67
149
|
|
|
150
|
+
#### Example: Claude Desktop
|
|
68
151
|
```json
|
|
69
|
-
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
152
|
+
{
|
|
153
|
+
"mcpServers": {
|
|
154
|
+
"dev_touchdesigner": {
|
|
155
|
+
"args": [
|
|
156
|
+
"/path/to/your/touchdesigner-mcp/dist/index.js", // <-- Replace with the absolute path to /dist/index.js after build
|
|
157
|
+
"--stdio"
|
|
158
|
+
],
|
|
159
|
+
"command": "node",
|
|
160
|
+
"transportType": "stdio"
|
|
78
161
|
}
|
|
162
|
+
}
|
|
79
163
|
}
|
|
80
164
|
```
|
|
81
165
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
## Project Structure Overview
|
|
166
|
+
### Project Structure After Setup
|
|
85
167
|
|
|
86
168
|
```
|
|
87
169
|
├── src/ # MCP server source code
|
|
88
|
-
│ ├── api/ # OpenAPI
|
|
170
|
+
│ ├── api/ # OpenAPI spec for TD WebServer
|
|
89
171
|
│ ├── core/ # Core utilities (logger, error handling)
|
|
90
172
|
│ ├── features/ # MCP feature implementations
|
|
91
173
|
│ │ ├── prompts/ # Prompt handlers
|
|
@@ -93,10 +175,10 @@ Once the API server is running in TouchDesigner, the agent can use the provided
|
|
|
93
175
|
│ │ └── tools/ # Tool handlers (e.g., tdTools.ts)
|
|
94
176
|
│ ├── gen/ # Code generated from OpenAPI schema for MCP server
|
|
95
177
|
│ ├── server/ # MCP server logic (connections, main server class)
|
|
96
|
-
│ ├── tdClient/ #
|
|
97
|
-
│ ├── index.ts # Main entry point for
|
|
178
|
+
│ ├── tdClient/ # TD connection API client
|
|
179
|
+
│ ├── index.ts # Main entry point for Node.js server
|
|
98
180
|
│ └── ...
|
|
99
|
-
├── td/ # TouchDesigner
|
|
181
|
+
├── td/ # TouchDesigner related files
|
|
100
182
|
│ ├── modules/ # Python modules for TouchDesigner
|
|
101
183
|
│ │ ├── mcp/ # Core logic for handling MCP requests in TD
|
|
102
184
|
│ │ │ ├── controllers/ # API request controllers (api_controller.py, generated_handlers.py)
|
|
@@ -104,100 +186,52 @@ Once the API server is running in TouchDesigner, the agent can use the provided
|
|
|
104
186
|
│ │ ├── td_server/ # Python model code generated from OpenAPI schema
|
|
105
187
|
│ │ └── utils/ # Shared Python utilities
|
|
106
188
|
│ ├── templates/ # Mustache templates for Python code generation
|
|
107
|
-
│ ├── genHandlers.js # Node.js script for generating
|
|
108
|
-
│ ├── import_modules.py # Helper script
|
|
189
|
+
│ ├── genHandlers.js # Node.js script for generating generated_handlers.py
|
|
190
|
+
│ ├── import_modules.py # Helper script to import API server modules into TD
|
|
109
191
|
│ └── mcp_webserver_base.tox # Main TouchDesigner component
|
|
110
192
|
├── tests/ # Test code
|
|
111
193
|
│ ├── integration/
|
|
112
194
|
│ └── unit/
|
|
113
|
-
├── .env # Local environment variables (
|
|
195
|
+
├── .env # Local environment variables (git ignored)
|
|
114
196
|
├── dotenv # Template for .env
|
|
115
|
-
└── orval.config.ts # Orval
|
|
197
|
+
└── orval.config.ts # Orval config (TS client generation)
|
|
116
198
|
```
|
|
117
199
|
|
|
118
|
-
## MCP Server Features
|
|
119
|
-
|
|
120
|
-
This server enables operations on TouchDesigner via the Model Context Protocol (MCP) and provides access to various tools.
|
|
121
|
-
|
|
122
|
-
### Tools
|
|
123
|
-
|
|
124
|
-
| Tool Name | Description |
|
|
125
|
-
| :-------------------------- | :--------------------------------------------------- |
|
|
126
|
-
| `create_td_node` | Creates a new node. |
|
|
127
|
-
| `delete_td_node` | Deletes an existing node. |
|
|
128
|
-
| `exec_node_method` | Calls a Python method on a node. |
|
|
129
|
-
| `execute_python_script` | Executes an arbitrary Python script in TD. |
|
|
130
|
-
| `get_td_class_details` | Retrieves details of TD Python classes/modules. |
|
|
131
|
-
| `get_td_classes` | Lists TouchDesigner Python classes. |
|
|
132
|
-
| `get_td_info` | Retrieves information about the TD server environment. |
|
|
133
|
-
| `get_td_node_parameters` | Retrieves parameters of a specific node. |
|
|
134
|
-
| `get_td_nodes` | Retrieves nodes within a parent path (optional filtering). |
|
|
135
|
-
| `update_td_node_parameters` | Updates parameters of a specific node. |
|
|
136
|
-
|
|
137
|
-
### Prompts
|
|
138
|
-
|
|
139
|
-
Prompts allow AI agents to perform specific actions in TouchDesigner.
|
|
140
|
-
|
|
141
|
-
| Prompt Name | Description |
|
|
142
|
-
| :-------------------------- | :--------------------------------------------------- |
|
|
143
|
-
| `Search node` | Performs a fuzzy search for nodes based on name, family, or type. |
|
|
144
|
-
| `Node connection` | Provides instructions for connecting nodes in TouchDesigner. |
|
|
145
|
-
| `Check node errors` | Checks for errors in specified nodes, recursively if child nodes exist. |
|
|
146
|
-
|
|
147
|
-
### Resources
|
|
148
|
-
|
|
149
|
-
Not implemented.
|
|
150
|
-
|
|
151
|
-
## Development
|
|
152
|
-
|
|
153
|
-
### Setting Up the Development Environment
|
|
154
|
-
|
|
155
|
-
```bash
|
|
156
|
-
# Install dependencies
|
|
157
|
-
npm install
|
|
158
|
-
|
|
159
|
-
# Run linters and type checkers
|
|
160
|
-
npm run lint
|
|
161
|
-
|
|
162
|
-
# Run tests
|
|
163
|
-
npm test
|
|
164
|
-
|
|
165
|
-
# Start the server with MCP Inspector for debugging
|
|
166
|
-
npm run dev
|
|
167
|
-
```
|
|
168
200
|
|
|
169
201
|
### API Code Generation Workflow
|
|
170
202
|
|
|
171
203
|
This project uses OpenAPI-based code generation tools (Orval / openapi-generator-cli):
|
|
172
204
|
|
|
173
|
-
**API Definition:** The API contract between the Node.js MCP server and the Python server running
|
|
205
|
+
**API Definition:** The API contract between the Node.js MCP server and the Python server running inside TouchDesigner is defined in `src/api/index.yml`.
|
|
174
206
|
|
|
175
|
-
1. **Python
|
|
176
|
-
* Uses
|
|
207
|
+
1. **Python server generation (`npm run gen:webserver`):**
|
|
208
|
+
* Uses `openapi-generator-cli` via Docker.
|
|
177
209
|
* Reads `src/api/index.yml`.
|
|
178
|
-
* Generates Python server skeleton (`td/modules/td_server/`)
|
|
210
|
+
* Generates a Python server skeleton (`td/modules/td_server/`) based on the API definition. This code runs inside TouchDesigner via WebServer DAT.
|
|
179
211
|
* **Requires Docker to be installed and running.**
|
|
180
|
-
2. **Python
|
|
212
|
+
2. **Python handler generation (`npm run gen:handlers`):**
|
|
181
213
|
* Uses a custom Node.js script (`td/genHandlers.js`) and Mustache templates (`td/templates/`).
|
|
214
|
+
* Reads the generated Python server code or OpenAPI spec.
|
|
182
215
|
* Generates handler implementations (`td/modules/mcp/controllers/generated_handlers.py`) that connect to business logic in `td/modules/mcp/services/api_service.py`.
|
|
183
|
-
3. **TypeScript
|
|
184
|
-
* Uses `Orval` to generate
|
|
216
|
+
3. **TypeScript client generation (`npm run gen:mcp`):**
|
|
217
|
+
* Uses `Orval` to generate API client code and Zod schemas for tool validation from the schema YAML bundled by `openapi-generator-cli`.
|
|
218
|
+
* Generates a typed TypeScript client (`src/tdClient/`) used by the Node.js server to make requests to the WebServer DAT.
|
|
185
219
|
|
|
186
|
-
The build process (`npm run build`)
|
|
220
|
+
The build process (`npm run build`) runs all necessary generation steps (`npm run gen`), followed by TypeScript compilation (`tsc`).
|
|
187
221
|
|
|
188
222
|
## Contributing
|
|
189
223
|
|
|
190
|
-
|
|
224
|
+
We welcome your contributions!
|
|
191
225
|
|
|
192
|
-
1. Fork the repository
|
|
193
|
-
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
194
|
-
3. Make your changes
|
|
195
|
-
4. Add tests and ensure everything works (`npm test`)
|
|
196
|
-
5. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
197
|
-
6. Push to
|
|
198
|
-
7. Open a
|
|
226
|
+
1. Fork the repository
|
|
227
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
228
|
+
3. Make your changes
|
|
229
|
+
4. Add tests and ensure everything works (`npm test`)
|
|
230
|
+
5. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
231
|
+
6. Push to your branch (`git push origin feature/amazing-feature`)
|
|
232
|
+
7. Open a pull request
|
|
199
233
|
|
|
200
|
-
|
|
234
|
+
Please always include appropriate tests when making implementation changes.
|
|
201
235
|
|
|
202
236
|
## License
|
|
203
237
|
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
* OpenAPI schema for generating TouchDesigner API client code
|
|
6
6
|
* OpenAPI spec version: 0.2.1
|
|
7
7
|
*/
|
|
8
|
-
import { faker } from '@faker-js/faker';
|
|
9
|
-
import { HttpResponse, delay, http } from 'msw';
|
|
10
8
|
import { customInstance } from '../../api/customInstance.js';
|
|
11
9
|
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
12
10
|
export const TdNodeFamilyType = {
|
|
@@ -126,125 +124,3 @@ export const getTdInfo = (options) => {
|
|
|
126
124
|
return customInstance({ url: `http://localhost:9981/api/td/server/td`, method: 'GET'
|
|
127
125
|
}, options);
|
|
128
126
|
};
|
|
129
|
-
export const getDeleteNodeResponseMock = (overrideResponse = {}) => ({ success: faker.datatype.boolean(), data: { deleted: faker.helpers.arrayElement([faker.datatype.boolean(), undefined]), node: faker.helpers.arrayElement([{ id: faker.number.int({ min: undefined, max: undefined }), opType: faker.string.alpha(20), name: faker.string.alpha(20), path: faker.string.alpha(20), properties: {} }, undefined]) }, error: faker.helpers.arrayElement([faker.string.alpha(20), null]), ...overrideResponse });
|
|
130
|
-
export const getGetNodesResponseMock = (overrideResponse = {}) => ({ success: faker.datatype.boolean(), data: { nodes: faker.helpers.arrayElement([Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({ id: faker.number.int({ min: undefined, max: undefined }), opType: faker.string.alpha(20), name: faker.string.alpha(20), path: faker.string.alpha(20), properties: {} })), undefined]) }, error: faker.helpers.arrayElement([faker.string.alpha(20), null]), ...overrideResponse });
|
|
131
|
-
export const getCreateNodeResponseMock = (overrideResponse = {}) => ({ success: faker.datatype.boolean(), data: { result: faker.helpers.arrayElement([{ id: faker.number.int({ min: undefined, max: undefined }), opType: faker.string.alpha(20), name: faker.string.alpha(20), path: faker.string.alpha(20), properties: {} }, undefined]) }, error: faker.helpers.arrayElement([faker.string.alpha(20), null]), ...overrideResponse });
|
|
132
|
-
export const getGetNodeDetailResponseMock = (overrideResponse = {}) => ({ success: faker.datatype.boolean(), data: { id: faker.number.int({ min: undefined, max: undefined }), opType: faker.string.alpha(20), name: faker.string.alpha(20), path: faker.string.alpha(20), properties: {} }, error: faker.helpers.arrayElement([faker.string.alpha(20), null]), ...overrideResponse });
|
|
133
|
-
export const getUpdateNodeResponseMock = (overrideResponse = {}) => ({ success: faker.datatype.boolean(), data: { path: faker.helpers.arrayElement([faker.string.alpha(20), undefined]), updated: faker.helpers.arrayElement([Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => (faker.string.alpha(20))), undefined]), failed: faker.helpers.arrayElement([Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({ name: faker.helpers.arrayElement([faker.string.alpha(20), undefined]), reason: faker.helpers.arrayElement([faker.string.alpha(20), undefined]) })), undefined]), message: faker.helpers.arrayElement([faker.string.alpha(20), undefined]) }, error: faker.helpers.arrayElement([faker.string.alpha(20), null]), ...overrideResponse });
|
|
134
|
-
export const getGetTdPythonClassesResponseMock = (overrideResponse = {}) => ({ success: faker.datatype.boolean(), data: { classes: faker.helpers.arrayElement([Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({ name: faker.string.alpha(20), type: faker.helpers.arrayElement(['class', 'module', 'function', 'object']), description: faker.helpers.arrayElement([faker.string.alpha(20), undefined]) })), undefined]) }, error: faker.helpers.arrayElement([faker.string.alpha(20), null]), ...overrideResponse });
|
|
135
|
-
export const getGetTdPythonClassDetailsResponseMock = (overrideResponse = {}) => ({ success: faker.datatype.boolean(), data: { name: faker.string.alpha(20), type: faker.helpers.arrayElement(['class', 'module', 'function', 'object']), description: faker.helpers.arrayElement([faker.string.alpha(20), undefined]), methods: Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({ name: faker.string.alpha(20), signature: faker.helpers.arrayElement([faker.string.alpha(20), undefined]), description: faker.helpers.arrayElement([faker.string.alpha(20), undefined]) })), properties: Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({ name: faker.string.alpha(20), type: faker.string.alpha(20), value: faker.helpers.arrayElement([{}, undefined]) })) }, error: faker.helpers.arrayElement([faker.string.alpha(20), null]), ...overrideResponse });
|
|
136
|
-
export const getExecNodeMethodResponseMock = (overrideResponse = {}) => ({ success: faker.datatype.boolean(), data: { result: {} }, error: faker.helpers.arrayElement([faker.string.alpha(20), null]), ...overrideResponse });
|
|
137
|
-
export const getExecPythonScriptResponseMock = (overrideResponse = {}) => ({ success: faker.datatype.boolean(), data: { result: { value: faker.helpers.arrayElement([{}, undefined]) } }, error: faker.helpers.arrayElement([faker.string.alpha(20), null]), ...overrideResponse });
|
|
138
|
-
export const getGetTdInfoResponseMock = (overrideResponse = {}) => ({ success: faker.datatype.boolean(), data: { server: faker.string.alpha(20), version: faker.string.alpha(20), osName: faker.string.alpha(20), osVersion: faker.string.alpha(20) }, error: faker.helpers.arrayElement([faker.string.alpha(20), null]), ...overrideResponse });
|
|
139
|
-
export const getDeleteNodeMockHandler = (overrideResponse) => {
|
|
140
|
-
return http.delete('*/api/nodes', async (info) => {
|
|
141
|
-
await delay(1000);
|
|
142
|
-
return new HttpResponse(JSON.stringify(overrideResponse !== undefined
|
|
143
|
-
? (typeof overrideResponse === "function" ? await overrideResponse(info) : overrideResponse)
|
|
144
|
-
: getDeleteNodeResponseMock()), { status: 200,
|
|
145
|
-
headers: { 'Content-Type': 'application/json' }
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
};
|
|
149
|
-
export const getGetNodesMockHandler = (overrideResponse) => {
|
|
150
|
-
return http.get('*/api/nodes', async (info) => {
|
|
151
|
-
await delay(1000);
|
|
152
|
-
return new HttpResponse(JSON.stringify(overrideResponse !== undefined
|
|
153
|
-
? (typeof overrideResponse === "function" ? await overrideResponse(info) : overrideResponse)
|
|
154
|
-
: getGetNodesResponseMock()), { status: 200,
|
|
155
|
-
headers: { 'Content-Type': 'application/json' }
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
};
|
|
159
|
-
export const getCreateNodeMockHandler = (overrideResponse) => {
|
|
160
|
-
return http.post('*/api/nodes', async (info) => {
|
|
161
|
-
await delay(1000);
|
|
162
|
-
return new HttpResponse(JSON.stringify(overrideResponse !== undefined
|
|
163
|
-
? (typeof overrideResponse === "function" ? await overrideResponse(info) : overrideResponse)
|
|
164
|
-
: getCreateNodeResponseMock()), { status: 200,
|
|
165
|
-
headers: { 'Content-Type': 'application/json' }
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
};
|
|
169
|
-
export const getGetNodeDetailMockHandler = (overrideResponse) => {
|
|
170
|
-
return http.get('*/api/nodes/detail', async (info) => {
|
|
171
|
-
await delay(1000);
|
|
172
|
-
return new HttpResponse(JSON.stringify(overrideResponse !== undefined
|
|
173
|
-
? (typeof overrideResponse === "function" ? await overrideResponse(info) : overrideResponse)
|
|
174
|
-
: getGetNodeDetailResponseMock()), { status: 200,
|
|
175
|
-
headers: { 'Content-Type': 'application/json' }
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
};
|
|
179
|
-
export const getUpdateNodeMockHandler = (overrideResponse) => {
|
|
180
|
-
return http.patch('*/api/nodes/detail', async (info) => {
|
|
181
|
-
await delay(1000);
|
|
182
|
-
return new HttpResponse(JSON.stringify(overrideResponse !== undefined
|
|
183
|
-
? (typeof overrideResponse === "function" ? await overrideResponse(info) : overrideResponse)
|
|
184
|
-
: getUpdateNodeResponseMock()), { status: 200,
|
|
185
|
-
headers: { 'Content-Type': 'application/json' }
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
};
|
|
189
|
-
export const getGetTdPythonClassesMockHandler = (overrideResponse) => {
|
|
190
|
-
return http.get('*/api/td/classes', async (info) => {
|
|
191
|
-
await delay(1000);
|
|
192
|
-
return new HttpResponse(JSON.stringify(overrideResponse !== undefined
|
|
193
|
-
? (typeof overrideResponse === "function" ? await overrideResponse(info) : overrideResponse)
|
|
194
|
-
: getGetTdPythonClassesResponseMock()), { status: 200,
|
|
195
|
-
headers: { 'Content-Type': 'application/json' }
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
};
|
|
199
|
-
export const getGetTdPythonClassDetailsMockHandler = (overrideResponse) => {
|
|
200
|
-
return http.get('*/api/td/classes/:className', async (info) => {
|
|
201
|
-
await delay(1000);
|
|
202
|
-
return new HttpResponse(JSON.stringify(overrideResponse !== undefined
|
|
203
|
-
? (typeof overrideResponse === "function" ? await overrideResponse(info) : overrideResponse)
|
|
204
|
-
: getGetTdPythonClassDetailsResponseMock()), { status: 200,
|
|
205
|
-
headers: { 'Content-Type': 'application/json' }
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
};
|
|
209
|
-
export const getExecNodeMethodMockHandler = (overrideResponse) => {
|
|
210
|
-
return http.post('*/api/td/nodes/exec', async (info) => {
|
|
211
|
-
await delay(1000);
|
|
212
|
-
return new HttpResponse(JSON.stringify(overrideResponse !== undefined
|
|
213
|
-
? (typeof overrideResponse === "function" ? await overrideResponse(info) : overrideResponse)
|
|
214
|
-
: getExecNodeMethodResponseMock()), { status: 200,
|
|
215
|
-
headers: { 'Content-Type': 'application/json' }
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
};
|
|
219
|
-
export const getExecPythonScriptMockHandler = (overrideResponse) => {
|
|
220
|
-
return http.post('*/api/td/server/exec', async (info) => {
|
|
221
|
-
await delay(1000);
|
|
222
|
-
return new HttpResponse(JSON.stringify(overrideResponse !== undefined
|
|
223
|
-
? (typeof overrideResponse === "function" ? await overrideResponse(info) : overrideResponse)
|
|
224
|
-
: getExecPythonScriptResponseMock()), { status: 200,
|
|
225
|
-
headers: { 'Content-Type': 'application/json' }
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
};
|
|
229
|
-
export const getGetTdInfoMockHandler = (overrideResponse) => {
|
|
230
|
-
return http.get('*/api/td/server/td', async (info) => {
|
|
231
|
-
await delay(1000);
|
|
232
|
-
return new HttpResponse(JSON.stringify(overrideResponse !== undefined
|
|
233
|
-
? (typeof overrideResponse === "function" ? await overrideResponse(info) : overrideResponse)
|
|
234
|
-
: getGetTdInfoResponseMock()), { status: 200,
|
|
235
|
-
headers: { 'Content-Type': 'application/json' }
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
};
|
|
239
|
-
export const getTouchDesignerAPIMock = () => [
|
|
240
|
-
getDeleteNodeMockHandler(),
|
|
241
|
-
getGetNodesMockHandler(),
|
|
242
|
-
getCreateNodeMockHandler(),
|
|
243
|
-
getGetNodeDetailMockHandler(),
|
|
244
|
-
getUpdateNodeMockHandler(),
|
|
245
|
-
getGetTdPythonClassesMockHandler(),
|
|
246
|
-
getGetTdPythonClassDetailsMockHandler(),
|
|
247
|
-
getExecNodeMethodMockHandler(),
|
|
248
|
-
getExecPythonScriptMockHandler(),
|
|
249
|
-
getGetTdInfoMockHandler()
|
|
250
|
-
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "touchdesigner-mcp-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "MCP server for TouchDesigner",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@biomejs/biome": "1.9.4",
|
|
31
|
-
"@faker-js/faker": "^9.7.0",
|
|
32
31
|
"@types/jsdom": "^21.1.7",
|
|
33
32
|
"@types/node": "^22.15.2",
|
|
34
33
|
"@vitest/coverage-v8": "^3.1.2",
|
package/dist/mock/index.js
DELETED
package/dist/mock/node.js
DELETED