Skill v0.1.0
currentAutomated scan100/100name: fundamentals description: This skill should be used when working with TouchDesigner through the touchdesigner-mcp tools — for example when asked to "build a network in TouchDesigner", "create a node", "wire operators together", add or configure a TOP/CHOP/SOP/DAT/COMP/MAT, inspect or edit a .toe or .tox file, set node parameters, or otherwise construct or modify a TouchDesigner project. Provides the conventions the tools expect (node paths, nodeType and parameter naming, family-bound wiring), the cook model that explains what the tools report, the inspect-create-verify workflow, and the procedures for reading families, operator types, and parameter names live from the running TouchDesigner instead of recalling them. version: 0.1.0
TouchDesigner Fundamentals
What TouchDesigner Is
TouchDesigner is a node-based visual programming environment for real-time procedural content: interactive installations, live visuals, data visualization, and control systems. A TouchDesigner project is a network of operators — small processing nodes wired together into a directed graph, cooked continuously at the project's frame rate rather than run once and discarded. Projects save as .toe files (a full project) or .tox files (a reusable component embeddable inside another project). Treat every task here as manipulating that node graph, either through the touchdesigner-mcp tools connected to a live TouchDesigner instance, or by reasoning about .tox/.toe structure.
The MCP tools substitute for the two things a human normally does with the mouse: browsing the OP Create dialog (its category tabs mirror the six operator families below) and dragging wires between operators in the network editor. Every action described in this skill has a direct tool equivalent — there is no need to open TouchDesigner's UI to inspect, build, or debug a network reachable through these tools.
Work through the bundled MCP tools rather than assuming network contents by memory: get_td_info, get_td_nodes, get_td_node_parameters, get_td_node_errors, create_td_node, update_td_node_parameters, delete_td_node, exec_node_method, execute_python_script, get_td_classes, get_td_class_details, get_td_module_help, get_top_image, and describe_td_tools. At runtime these are namespaced (e.g. mcp__plugin_touchdesigner_touchdesigner__create_td_node); refer to them by their logical name below and let the runtime prefix resolve automatically. When a tool's exact input shape is unclear, call describe_td_tools rather than guessing at parameter names.
Operator Families
Every operator belongs to exactly one family, determined by the kind of data flowing through it. Family membership decides which wires are legal and which suffix the operator's nodeType carries.
Which families exist, and which operator types belong to each, is a property of the installed TouchDesigner build — the roster grows between releases, and a family that did not exist in an older build appears without warning in a newer one. Do not work from a remembered list. Discover the current one with the procedure in references/operator-guide.md, which reads it structurally from td.OP.__subclasses__() and each class's family attribute.
The rules that hold regardless of the roster:
- Operators of the same family wire together directly, an output connector into an input connector.
- A wire never crosses families. Crossing needs an explicit converter operator, named
<source>to<TARGET>— look up which ones the build actually ships rather than recalling a pair; the real set is much larger than the few commonly cited. - Materials attach through the Geometry COMP's
materialparameter, not through a wire. - CHOP values commonly drive parameters of other families through a parameter export or an expression rather than a wire at all — see Wiring below.
Node Paths and Hierarchy
Every node has an absolute path rooted at the project, e.g. /project1/container1/noise1. Nodes always live inside a COMP — /project1 itself is a COMP, and any COMP can contain child operators of any family. Before creating anything, call get_td_nodes on the intended parent path to see what already exists; never assume a network's contents from a prior turn or from memory of a similar project.
parentPath passed to create_td_node must be an existing COMP. Creating into the wrong parent is a frequent mistake in deeply nested networks — re-verify the parent path with get_td_nodes immediately before creating, rather than trusting an earlier listing.
Node names must be unique among siblings; if a requested nodeName collides with an existing child, TouchDesigner silently renames the new node (typically by appending or incrementing a numeric suffix) rather than raising an error. Never assume the requested name is the name that resulted — read the resolved path back from create_td_node's response, and use that path for every subsequent call against the node.
Creating Nodes: nodeType and Parameter Naming
create_td_node takes a nodeType matching TouchDesigner's Python class-name convention: lowercase-first, family-suffixed CamelCase — textTOP has the shape, TextTop and text_top do not. The convention is stable; the set of names obeying it is not. Getting a name wrong — an extra or missing letter, wrong case on the suffix — is the single most common tool-call failure, and a plausible-looking name is exactly the kind that fails.
Confirm every unfamiliar nodeType before using it. The cheapest check is getattr(td, '<name>', None) through execute_python_script; references/operator-guide.md covers that and the roster-browsing alternatives.
{ "parentPath": "/project1", "nodeType": "textTOP", "nodeName": "title" }
Set parameters through update_td_node_parameters's properties map, keyed by TouchDesigner's lowercase parameter name, not the capitalized label shown in the UI. The mapping from label to name is not always a literal lowercasing and varies by operator, so never infer it — read the exact name from get_td_node_parameters on the node (or the type-level lookup in references/operator-guide.md, which also returns each parameter's default, legal menu values, and official help text) before writing to it.
The Cook Model
TouchDesigner is pull-based and lazy: an operator recomputes ("cooks") only when something downstream actually requests its output, and it skips recooking when neither its inputs nor its parameters changed since the last cook. This has two practical consequences. First, a node with no active downstream consumer — no open viewer, no export, not on a rendered path — may never cook, so reading its output or expecting a side effect from it can silently do nothing; ensure a consuming path exists, or force a cook explicitly from execute_python_script with op(path).cook(force=True) before reading its output. Second, trace errors and stale values back to a node that isn't cooking at all before assuming it is computing the wrong thing — get_td_node_errors reports cook errors, but a node that never cooks reports none, so an empty error report is not proof of correctness.
Wiring Operators Together
No dedicated "connect nodes" MCP tool exists. Wire operators together with execute_python_script, using the input/output connector arrays each operator exposes. Connector indices are operator-specific — an operator's second input is not always index 1 in the sense a caller assumes, and some operators expose more connectors than their UI suggests — so read the actual arrays (print(len(op(path).inputConnectors))) or get_td_class_details on the operator's class when wiring anything beyond a single-input chain:
op("/project1/noise1").outputConnectors[0].connect(op("/project1/level1").inputConnectors[0])# equivalently, from the consuming side:op("/project1/level1").inputConnectors[0].connect(op("/project1/noise1"))
Drive a parameter continuously from a CHOP channel through parameter export rather than a wire — in the UI this is normally a drag-and-drop action. When scripting an export, confirm the exact Par/Channel API for the running TD version with get_td_class_details rather than assuming a call signature, since this is one of the areas most likely to differ subtly between versions. A one-time or formula-based link instead sets the parameter's expression string, which re-evaluates on every cook:
op("/project1/noise1").par.tx.expr = "op('lfo1')[0]"
Export and expression are not interchangeable — decide which behavior is wanted (continuous binding vs. formula re-evaluated per cook) before choosing between them.
Canonical Workflow
Treat every network change as a loop, never a single fire-and-forget call:
- Inspect — call
get_td_nodeson the parent path (andget_td_node_parameterson any node being modified) to see the real current state. Never assume a network's contents. - Create — call
create_td_nodewith the verifiednodeTypeandparentPath. - Configure — call
update_td_node_parameterswith lowercase parameter names confirmed viaget_td_node_parameters. - Wire — call
execute_python_scriptto connectinputConnectors/outputConnectors, or to set an export/expression link. - Verify — call
get_td_node_errorson the affected subtree and, for visual chains,get_top_imageto actually look at the rendered result. Never report a network change as done without this step — a node can be created and wired with no thrown error while still cooking incorrectly, or not cooking at all.
Return to step 1 after any unexpected result — re-inspect the live state rather than guessing at what went wrong from the last known state.
Common Pitfalls
- Wrong nodeType spelling. Confirm with
get_td_classes/get_td_class_detailsinstead of guessing from memory, especially for less common operators. - Wrong parameter casing or name. UI labels are capitalized;
propertieskeys are not, and the two don't always match one-to-one. Confirm withget_td_node_parameters. - Creating into the wrong parent. Re-check
parentPathwithget_td_nodesimmediately before creating, especially in deeply nested COMP hierarchies. - Forgetting display/render flags. A TOP/SOP/CHOP can be fully correct but invisible in the network editor or absent from a render because its display or render flag is off. Check flags via
get_td_node_parametersorexec_node_methodrather than assuming visibility follows from correct wiring. - Confusing expression, export, and literal values. Setting
par.tx = 5overwrites any existing expression or export; settingpar.tx.expr = "..."leaves a live formula; a parameter export binds a continuous channel. Choose deliberately, and confirm the export mechanism's exact API before scripting it. - Assuming success without verification. A tool call returning without an exception is not proof the network behaves as intended. Always close the loop with
get_td_node_errorsand, for visual work,get_top_image. - Crossing families without a converter. A TOP output cannot feed a CHOP input (or vice versa) through a plain wire — use the matching
xToYconverter operator, or an export/expression link for parameter-level cross-family driving.
Additional Resources
references/operator-guide.md— the live-lookup procedure for fetching an operator's parameter names, defaults, menus, and official help text from the running TouchDesigner on demand.scripts/dump_operator_pars.py— batch utility: send throughexecute_python_scriptto inspect parameter names, labels, defaults, menus, and official help text for several operators in one call.references/python-patterns.md—op()/parent()/me, absolute vs. relative paths, reading and setting parameters, export vs. expression, iterating children, creating operators from Python,run()/delayed execution, and debugging viaexecute_python_script.