跳到主要内容

Touchdesigner Mcp

通过 twozero MCP 控制正在运行的 TouchDesigner 实例——创建运算符(operators)、设置参数、连接线路、执行 Python 代码、构建实时视觉效果。包含 36 个原生工具。

技能元数据

来源可选 — 使用 hermes skills install official/creative/touchdesigner-mcp 安装
路径optional-skills/creative/touchdesigner-mcp
版本1.0.0
作者kshitijk4poor
许可证MIT
标签TouchDesigner, MCP, twozero, creative-coding, real-time-visuals, generative-art, audio-reactive, VJ, installation, GLSL
相关技能native-mcp, ascii-video, manim-video, hermes-video

参考:完整 SKILL.md

信息

以下是 Hermes 在触发此技能时加载的完整技能定义。这是技能激活时代理所看到的指令。

TouchDesigner 集成 (twozero MCP)

关键规则

  1. 切勿猜测参数名称。 首先针对运算符类型调用 td_get_par_info。你的训练数据对于 TD 2025.32 是错误的。
  2. 如果触发 tdAttributeError,立即停止。 在继续之前,对失败的节点调用 td_get_operator_info
  3. 切勿在脚本回调中硬编码绝对路径。 使用 me.parent() / scriptOp.parent()
  4. 优先使用原生 MCP 工具而非 td_execute_python。 使用 td_create_operatortd_set_operator_parstd_get_errors 等。仅在处理复杂的多步逻辑时才回退到 td_execute_python
  5. 在构建之前调用 td_get_hints 它会返回与你正在处理的运算符类型特定的模式。

架构

Hermes Agent -> MCP (Streamable HTTP) -> twozero.tox (port 40404) -> TD Python

36 个原生工具。免费插件(无需付费/许可——已于 2026 年 4 月确认)。 上下文感知(知晓选中的 OP、当前网络)。 Hub 健康检查:GET http://localhost:40404/mcp 返回包含实例 PID、项目名称、TD 版本的 JSON。

设置(自动化)

运行设置脚本以处理所有事项:

bash "${HERMES_HOME:-$HOME/.hermes}/skills/creative/touchdesigner-mcp/scripts/setup.sh"

该脚本将:

  1. 检查 TD 是否正在运行
  2. 如果尚未缓存,则下载 twozero.tox
  3. twozero_td MCP 服务器添加到 Hermes 配置中(如果缺失)
  4. 测试端口 40404 上的 MCP 连接
  5. 报告剩余的手动步骤(将 .tox 拖入 TD,启用 MCP 切换开关)

手动步骤(一次性,无法自动化)

  1. ~/Downloads/twozero.tox 拖入 TD 网络编辑器 → 点击 Install(安装)
  2. 启用 MCP: 点击 twozero 图标 → Settings(设置) → mcp → "auto start MCP"(自动启动 MCP) → Yes(是)
  3. 重启 Hermes 会话 以加载新的 MCP 服务器

设置完成后,验证:

nc -z 127.0.0.1 40404 && echo "twozero MCP: READY"

环境说明

  • 非商业版 TD 将分辨率限制为 1280×1280。使用 outputresolution = 'custom' 并显式设置宽度/高度。
  • 编解码器: prores(macOS 上首选)或作为后备的 mjpa。H.264/H.265/AV1 需要商业许可证。
  • 在设置参数之前始终调用 td_get_par_info —— 名称因 TD 版本而异(参见关键规则 #1)。

工作流

步骤 0:发现(在构建任何内容之前)

Call td_get_par_info with op_type for each type you plan to use.
Call td_get_hints with the topic you're building (e.g. "glsl", "audio reactive", "feedback").
Call td_get_focus to see where the user is and what's selected.
Call td_get_network to see what already exists.

无临时节点,无清理。这完全取代了旧的发现流程。

步骤 1:清理 + 构建

重要提示:将清理和创建拆分为单独的 MCP 调用。 在一个 td_execute_python 脚本中销毁并重新创建同名节点会导致“Invalid OP object”(无效的 OP 对象)错误。参见陷阱 #11b。

对每个节点使用 td_create_operator(自动处理视口定位):

td_create_operator(type="noiseTOP", parent="/project1", name="bg", parameters={"resolutionw": 1280, "resolutionh": 720})
td_create_operator(type="levelTOP", parent="/project1", name="brightness")
td_create_operator(type="nullTOP", parent="/project1", name="out")

对于批量创建或连线,使用 td_execute_python

# td_execute_python script:
root = op('/project1')
nodes = []
for name, optype in [('bg', noiseTOP), ('fx', levelTOP), ('out', nullTOP)]:
n = root.create(optype, name)
nodes.append(n.path)
# Wire chain
for i in range(len(nodes)-1):
op(nodes[i]).outputConnectors[0].connect(op(nodes[i+1]).inputConnectors[0])
result = {'created': nodes}

步骤 2:设置参数

优先使用原生工具(验证参数,不会崩溃):

td_set_operator_pars(path="/project1/bg", parameters={"roughness": 0.6, "monochrome": true})

对于表达式或模式,使用 td_execute_python

op('/project1/time_driver').par.colorr.expr = "absTime.seconds % 1000.0"

步骤 3:连线

使用 td_execute_python —— 不存在原生的连线工具:

op('/project1/bg').outputConnectors[0].connect(op('/project1/fx').inputConnectors[0])

步骤 4:验证

td_get_errors(path="/project1", recursive=true)
td_get_perf()
td_get_operator_info(path="/project1/out", detail="full")

步骤 5:显示 / 捕获

td_get_screenshot(path="/project1/out")

或通过脚本打开窗口:

win = op('/project1').create(windowCOMP, 'display')
win.par.winop = op('/project1/out').path
win.par.winw = 1280; win.par.winh = 720
win.par.winopen.pulse()

MCP 工具快速参考

核心(最常用):

工具功能
td_execute_python在 TD 中运行任意 Python 代码。拥有完整的 API 访问权限。
td_create_operator创建带有参数和自动定位的节点
td_set_operator_pars安全地设置参数(进行验证,不会崩溃)
td_get_operator_info检查单个节点:连接、参数、错误
td_get_operators_info在一次调用中检查多个节点
td_get_network查看指定路径下的网络结构
td_get_errors递归查找错误/警告
td_get_par_info获取 OP 类型的参数名称(取代发现流程)
td_get_hints在构建之前获取模式/提示
td_get_focus哪个网络已打开,选中了什么

读/写:

工具功能
td_read_dat读取 DAT 文本内容
td_write_dat写入/修补 DAT 内容
td_read_chop读取 CHOP 通道值
td_read_textport读取 TD 控制台输出

视觉:

工具功能
td_get_screenshot将单个 OP 查看器捕获为文件
td_get_screenshots一次性捕获多个 OP
td_get_screen_screenshot通过 TD 捕获实际屏幕
td_navigate_to将网络编辑器跳转到指定 OP

搜索:

工具功能
td_find_op在整个项目中按名称/类型查找 OP
td_search搜索代码、表达式、字符串参数

系统:

工具功能
td_get_perf性能分析(FPS、慢速 OP)
td_list_instances列出所有正在运行的 TD 实例
td_get_docs获取关于特定 TD 主题的深入文档
td_agents_md读取/写入每个 COMP 的 Markdown 文档
td_reinit_extension在代码编辑后重新加载扩展
td_clear_textport在调试会话前清除控制台

输入自动化:

工具功能
td_input_execute向 TD 发送鼠标/键盘输入
td_input_status轮询输入队列状态
td_input_clear停止输入自动化
td_op_screen_rect获取节点的屏幕坐标
td_click_screen_point点击截图中的某一点

完整参数架构请参阅 references/mcp-tools.md

关键实现规则

GLSL 时间: GLSL TOP 中不使用 uTDCurrentTime。使用 Values 页面:

# Call td_get_par_info(op_type="glslTOP") first to confirm param names
td_set_operator_pars(path="/project1/shader", parameters={"value0name": "uTime"})
# Then set expression via script:
# op('/project1/shader').par.value0.expr = "absTime.seconds"
# In GLSL: uniform float uTime;

回退方案:使用 rgba32float 格式的 Constant TOP(8 位会将值钳制在 0-1 之间,导致着色器冻结)。

Feedback TOP: 使用 top 参数引用,而非直接输入连线。“Not enough sources”(源不足)会在首次烹饪(cook)后解决。“Cook dependency loop”(烹饪依赖循环)警告是预期行为。

分辨率: 非商业版上限为 1280×1280。使用 outputresolution = 'custom'

大型着色器: 将 GLSL 写入 /tmp/file.glsl,然后使用 td_write_dattd_execute_python 加载。

顶点/点访问(TD 2025.32): 使用 point.P[0]point.P[1]point.P[2] — 而非 .x.y.z

扩展(Extensions): CONSTANT 模式下,ext0object 格式为 "op('./datName').module.ClassName(me)"。使用 td_write_dat 编辑扩展代码后,调用 td_reinit_extension

脚本回调: 始终通过 me.parent() / scriptOp.parent() 使用相对路径。

清理节点: 迭代前始终执行 list(root.children) 并进行 child.valid 检查。

录制 / 导出视频

# via td_execute_python:
root = op('/project1')
rec = root.create(moviefileoutTOP, 'recorder')
op('/project1/out').outputConnectors[0].connect(rec.inputConnectors[0])
rec.par.type = 'movie'
rec.par.file = '/tmp/output.mov'
rec.par.videocodec = 'prores' # Apple ProRes — NOT license-restricted on macOS
rec.par.record = True # start
# rec.par.record = False # stop (call separately later)

H.264/H.265/AV1 需要商业许可证。在 macOS 上使用 prores,或使用 mjpa 作为回退方案。 提取帧:ffmpeg -i /tmp/output.mov -vframes 120 /tmp/frames/frame_%06d.png

TOP.save() 对动画无效 — 每次都会捕获相同的 GPU 纹理。始终使用 MovieFileOut。

录制前:检查清单

  1. 通过 td_get_perf 验证 FPS > 0。如果 FPS=0,录制内容将为空。参见陷阱 #38-39。
  2. 通过 td_get_screenshot 验证着色器输出不是黑色。黑色输出意味着着色器错误或输入缺失。参见陷阱 #8、#40。
  3. 如果录制包含音频: 先 cue 音频开始播放,然后将录制延迟 3 帧。参见陷阱 #19。
  4. 在开始录制前设置输出路径 — 在同一脚本中同时设置两者可能会导致竞态条件。

音频响应式 GLSL(经验证的方案)

正确的信号链(2026 年 4 月测试)

AudioFileIn CHOP (playmode=sequential)
→ AudioSpectrum CHOP (FFT=512, outputmenu=setmanually, outlength=256, timeslice=ON)
→ Math CHOP (gain=10)
→ CHOP to TOP (dataformat=r, layout=rowscropped)
→ GLSL TOP input 1 (spectrum texture, 256x2)

Constant TOP (rgba32float, time) → GLSL TOP input 0
GLSL TOP → Null TOP → MovieFileOut

关键的音频响应式规则(经验证)

  1. AudioSpectrum 的 TimeSlice 必须保持开启。关闭 = 处理整个音频文件 → 24000+ 样本 → CHOP 到 TOP 溢出。
  2. 手动设置输出长度 为 256,使用 outputmenu='setmanually'outlength=256。默认输出 22050 个样本。
  3. 不要使用 Lag CHOP 进行频谱平滑。 Lag CHOP 在 timeslice 模式下运行,会将 256 个样本扩展到 2400+,将所有值平均为接近零 (~1e-06)。着色器接收不到可用数据。这是测试中排名第一的音频同步失败原因。
  4. 也不要使用 Filter CHOP — 频谱数据存在同样的 timeslice 扩展问题。
  5. 如果需要平滑,应在 GLSL 着色器中进行,通过带有反馈纹理的时间线性插值(temporal lerp):mix(prevValue, newValue, 0.3)。这能提供帧级精确同步且零管道延迟。
  6. CHOP to TOP 的 dataformat = 'r',layout = 'rowscropped'。频谱输出为 256x2(立体声)。在 y=0.25 处采样第一个通道。
  7. Math gain = 10(而非 5)。原始频谱值在低音范围约为 ~0.19。增益为 10 可为着色器提供可用的 ~5.0。
  8. 不需要 Resample CHOP。 直接通过 AudioSpectrum 的 outlength 参数控制输出大小。

GLSL 频谱采样

// Input 0 = time (1x1 rgba32float), Input 1 = spectrum (256x2)
float iTime = texture(sTD2DInputs[0], vec2(0.5)).r;

// Sample multiple points per band and average for stability:
// NOTE: y=0.25 for first channel (stereo texture is 256x2, first row center is 0.25)
float bass = (texture(sTD2DInputs[1], vec2(0.02, 0.25)).r +
texture(sTD2DInputs[1], vec2(0.05, 0.25)).r) / 2.0;
float mid = (texture(sTD2DInputs[1], vec2(0.2, 0.25)).r +
texture(sTD2DInputs[1], vec2(0.35, 0.25)).r) / 2.0;
float hi = (texture(sTD2DInputs[1], vec2(0.6, 0.25)).r +
texture(sTD2DInputs[1], vec2(0.8, 0.25)).r) / 2.0;

完整的构建脚本和着色器代码请参阅 references/network-patterns.md

运算符快速参考

家族颜色Python 类 / MCP 类型后缀
TOP紫色noiseTOP, glslTOP, compositeTOP, levelTop, blurTOP, textTOP, nullTOPTOP
CHOP绿色audiofileinCHOP, audiospectrumCHOP, mathCHOP, lfoCHOP, constantCHOPCHOP
SOP蓝色gridSOP, sphereSOP, transformSOP, noiseSOPSOP
DAT白色textDAT, tableDAT, scriptDAT, webserverDATDAT
MAT黄色phongMAT, pbrMAT, glslMAT, constMATMAT
COMP灰色geometryCOMP, containerCOMP, cameraCOMP, lightCOMP, windowCOMPCOMP

安全说明

  • MCP 仅在 localhost 上运行(端口 40404)。无身份验证——任何本地进程均可发送命令。
  • td_execute_python 以 TD 进程用户身份,对 TD Python 环境和文件系统拥有不受限制的访问权限。
  • setup.sh 从官方 404zero.com URL 下载 twozero.tox。如有疑虑,请验证下载内容。
  • 该技能绝不会向 localhost 之外发送数据。所有 MCP 通信均在本地进行。

参考资料

文件内容
references/pitfalls.md实际会话中积累的宝贵经验教训
references/operators.md所有运算符家族,包含参数和使用案例
references/network-patterns.md配方:音频响应、生成式、GLSL、实例化
references/mcp-tools.md完整的 twozero MCP 工具参数架构
references/python-api.mdTD Python:op()、脚本编写、扩展
references/troubleshooting.md连接诊断、调试
scripts/setup.sh自动化设置脚本

你不是在编写代码。你是在指挥光线。