跳到主要内容

Touchdesigner Mcp

通过 twozero MCP 控制一个正在运行的 TouchDesigner 实例 — 创建算子、设置参数、连线、执行 Python、构建实时视觉效果。共包含 36 个原生工具。

技能元数据

来源内置(默认安装)
路径skills/creative/touchdesigner-mcp
版本1.1.0
作者kshitijk4poor
许可证MIT
平台linux, macos, windows
标签TouchDesigner, MCP, twozero, creative-coding, real-time-visuals, generative-art, audio-reactive, VJ, installation, GLSL
相关技能native-mcp, ascii-video, manim-video, hermes-video
信息

以下是 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 智能体 -> MCP (Streamable HTTP) -> twozero.tox (端口 40404) -> TD Python

36 个原生工具。免费插件(无需付费/许可——截至 2026 年 4 月已确认)。 上下文感知(知道选定的 OP、当前网络)。 集线器健康检查: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 网络编辑器 → 点击“安装”
  2. 启用 MCP: 点击 twozero 图标 → 设置 → mcp → “自动启动 MCP” → 是
  3. 重启 Hermes 会话 以加载新的 MCP 服务器

设置完成后,验证:

nc -z 127.0.0.1 40404 && echo "twozero MCP: 就绪"

环境说明

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

工作流程

步骤 0:发现 (在构建任何东西之前)

调用 td_get_par_info 并提供您计划使用的每种 op_type。
调用 td_get_hints 并提供您正在构建的主题 (例如 “glsl”, “audio reactive”, “feedback”)。
调用 td_get_focus 查看用户所在位置及选择内容。
调用 td_get_network 查看已存在的内容。

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

步骤 1:清理 + 构建

重要:将清理和创建拆分为单独的 MCP 调用。 在同一个 td_execute_python 脚本中销毁并重新创建同名节点会导致“无效 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 脚本:
root = op('/project1')
nodes = []
for name, optype in [('bg', noiseTOP), ('fx', levelTOP), ('out', nullTOP)]:
n = root.create(optype, name)
nodes.append(n.path)
# 连线链
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在整个项目中按名称/类型查找算子
td_search搜索代码、表达式、字符串参数

系统:

工具功能
td_get_perf性能分析 (FPS、慢速算子)
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在截图中点击一个点
td_screen_point_to_global将截图像素转换为绝对屏幕坐标

上表涵盖了典型创意工作流程中使用的 32 个工具。其余 4 个工具 (td_project_quit, td_test_session, td_dev_log, td_clear_dev_log) 是管理/开发模式实用程序——完整 36 工具参考(包含完整参数模式)请参见 references/mcp-tools.md

关键实现规则

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

# 首先调用 td_get_par_info(op_type="glslTOP") 确认参数名
td_set_operator_pars(path="/project1/shader", parameters={"value0name": "uTime"})
# 然后通过脚本设置表达式:
# op('/project1/shader').par.value0.expr = "absTime.seconds"
# GLSL 中:uniform float uTime;

备选方案:Constant TOP 使用 rgba32float 格式 (8 位会限制在 0-1,导致着色器冻结)。

Feedback TOP: 使用 top 参数引用,而不是直接输入连线。“源不足”在首次计算后解决。“计算依赖循环”警告是预期的。

分辨率: 非商业版限制在 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

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

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

清理节点: 在迭代和 child.valid 检查之前,始终 list(root.children)

录制 / 导出视频

# 通过 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 — 在 macOS 上不受许可限制
rec.par.record = True # 开始
# rec.par.record = False # 停止 (稍后单独调用)

H.264/H.265/AV1 需要商业许可。在 macOS 上使用 proresmjpa 作为备选。 提取帧: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. 如果录制带音频: 请先让音频开始,然后将录制延迟 3 帧。参见陷阱 #19。
  4. 在开始录制前设置输出路径 — 在同一脚本中设置两者可能会产生竞争。

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

正确的信号链路 (于2026年4月测试验证)

AudioFileIn CHOP (播放模式=顺序)
→ AudioSpectrum CHOP (FFT=512, 输出菜单=手动设置, 输出长度=256, 时间切片=开启)
→ Math CHOP (增益=10)
→ CHOP to TOP (数据格式=r, 布局=裁剪行)
→ GLSL TOP 输入端1 (频谱纹理, 256x2)

Constant TOP (rgba32float, 时间) → GLSL TOP 输入端0
GLSL TOP → Null TOP → MovieFileOut

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

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

GLSL频谱采样

// 输入端0 = 时间 (1x1 rgba32float), 输入端1 = 频谱 (256x2)
float iTime = texture(sTD2DInputs[0], vec2(0.5)).r;

// 为每个频带采样多个点并取平均以获得稳定性:
// 注意:y=0.25 代表第一个声道(立体声纹理为256x2,第一行中心是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 仅在本地主机运行(端口40404)。无身份验证 — 任何本地进程都可发送命令。
  • td_execute_python 以TD进程用户的权限,对TD Python环境和文件系统具有无限制访问权限。
  • setup.sh 从官方 404zero.com URL下载 twozero.tox。如有疑虑,请验证下载内容。
  • 该技能永远不会向本地主机外部发送数据。所有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连接诊断、调试
references/glsl.mdGLSL uniform 变量、内置函数、着色器模板
references/postfx.md后期特效:辉光、CRT、色差、反馈光晕
references/layout-compositor.md布局模式、面板网格、BSP风格布局
references/operator-tips.md线框渲染、反馈TOP设置
references/geometry-comp.mdGeometry COMP: 实例化、POP与SOP、变形
references/audio-reactive.md音频频带提取、节拍检测、包络跟随
references/animation.mdLFO、定时器、关键帧、缓动、表达式驱动的运动
references/midi-osc.mdMIDI/OSC控制器、TouchOSC、多机同步
references/particles.mdPOPs和传统particleSOP — 发射、力、碰撞
references/projection-mapping.md多窗口输出、边角定位、网格扭曲、边缘融合
references/external-data.mdHTTP、WebSocket、MQTT、串口、TCP、webserverDAT
references/panel-ui.md自定义参数、面板COMP、按钮/滑块/输入框、panelExecuteDAT
references/replicator.mdreplicatorCOMP — 数据驱动克隆、布局、回调
references/dat-scripting.mdExecute DAT 类族 — chop/dat/parameter/panel/op/executeDAT
references/3d-scene.md灯光设置、阴影、IBL/立方体贴图、多摄像机、PBR
scripts/setup.sh自动化设置脚本

你不是在写代码,而是在指挥光影。