MCP Server for TouchDesigner - implements MCP Streamable HTTP protocol (JSON-RPC over POST) to execute Python code, inspect operators, set parameters, create operators, wire connections, observe visual output, and manipulate DAT operators inside TouchDesigner.
Strong tool definitions with clear descriptions and well-structured schemas. All 13 tools have explicit registrations with inputSchema, descriptions, and parameter types. Descriptions are detailed and actionable (avg ~180 chars), exceeding the 10-1024 char baseline. However, output schemas are not documented, LLMs cannot predict return structure. Error handling guidance is minimal. Parameter descriptions are comprehensive but lack explicit constraints (enums, ranges) for some fields. No tool annotations (readOnlyHint, destructiveHint) despite clear read/write semantics. Naming is mostly verb-noun (run, inspect, set, create, observe, read, write, edit, wire, list, render, docs, map) but 'observe' and 'map' are slightly ambiguous compared to 'capture_snapshot' or 'visualize_network'.
Create a new operator with optional parameter setting and wiring. Handles type resolution, destroy-before-create (prevents duplicates), param/expression setting, and input/output connections in one call. Use docs tool first to look up correct type constants and parameter names.
Look up TouchDesigner documentation: operator types, parameter names, CHOP channels, TOP formats, DAT row/col structure. Essential before using create, set, or inspect tools. Supports queries like 'type=glslTOP', 'param=glslTOP.Inputfile', 'channels=lfoCHOP', 'formats=TOP'.
Find and replace text within a DAT operator. The old_string must match exactly once in the DAT's text (unless replace_all is true). Mirrors the Edit tool semantics.
Get detailed info about any TouchDesigner operator: type, channels (with values), parameters, errors, connections, extensions. Path should be absolute like '/project1/uniforms'.
List operators in a container or search by name/type. Returns operator paths, types, and basic info. Supports filtering by name pattern and operator type.
Output schemas not documented. LLMs cannot predict return structure for any tool, forcing them to reason about responses blindly. This violates pattern:tool and increases hallucination risk.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Tools like 'run', 'set', 'create', 'write', 'edit', 'wire', 'render' are clearly destructive/write operations but lack explicit hints. Agents cannot distinguish safe from unsafe tools without reading descriptions.
Parameter constraints not formalized. 'mode' in observe has enum, but 'duration', 'fps', 'depth', 'limit', 'offset' lack min/max bounds. Descriptions mention ranges (e.g. 'max 4.0', 'max 30') but JSON Schema constraints are missing, forcing LLMs to parse text.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | 2026-07-28+ | v2 |
Visualize the operator network layout. Returns a text-based map showing operator positions, connections, and hierarchy. Useful for understanding the current network and planning new operator placement.
Observe the current visual output. Two modes: 'snapshot' (default) returns a single PNG frame — fast and small. 'animated' returns an animated GIF — shows motion but larger response. Use snapshot for quick checks, animated when you need to see movement.
Read the text content of a DAT operator. Returns the full text and line count. Path should be absolute like '/project1/shader_code'.
Render a TOP to disk (PNG, JPG, EXR, etc.). Supports custom resolution, frame range, and format selection. Useful for batch exports and high-quality captures.
Execute Python code inside TouchDesigner and return the result. For expressions (e.g. "op('/project1/out').width"), returns the value directly. For multi-line code, captures print output. Returns errors with full tracebacks, and any operator-level errors (shader compile failures, missing inputs) detected after execution. IMPORTANT: Use the docs tool to look up correct parameter names before setting them — TD names are often abbreviated (e.g. 'rough' not 'roughness'). To set expressions on parameters, use par.expr = '...' — assigning a string to a numeric par will error.
Set parameters on a TouchDesigner operator. Validates parameter names and reports unknown ones as errors. Use 'params' for constant values and 'exprs' for expression strings. Returns the evaluated value of each successfully set parameter.
Connect operator outputs to inputs. Supports single connections (output → input) and bulk wiring (multiple outputs to multiple inputs in order). Validates paths and input availability.
Overwrite the full text content of a DAT operator. Creates a new TextDAT if the operator doesn't exist (under the parent path).
Error handling guidance absent. No tool description explains what to do on failure (e.g. 'If path not found, try list() to discover valid operators'). Agents have no recovery path on errors.
Ambiguous tool names. 'observe' could mean 'watch for changes' or 'capture output', 'capture_snapshot' or 'get_visual_output' would be clearer. 'map' is vague, 'visualize_network' or 'get_network_layout' is more explicit.