0.0 / 30
What changed in the harness
Selection accuracy 95→93, token cost up 2%, unconfirmed writes 0%→0%.
Category breakdown
Where the score comes from.
Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.
01Safety
02Legibility
17.1 / 30
03Economics
0.0 / 20
04Discoverability
8.8 / 20
Highest-impact fix
Estimated gain +30 pointsAdd explicit identity and permission preflight tools
Expose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.
Description evidence
Defects and rewrites.
123 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.
| Tool | Defect types | Suggested rewrite |
|---|---|---|
create_raytk_op |
no_return_description |
Copy a RayTK ROP master (SDF / camera / light / combine / material / render) into a network and optionally wire an existing op into one of its typed inputs, using the same COMP.copy primitive RayTK's own palette uses. Resolves the install-dependent master path live (RayTK's pathsByOpType lookup, or a category-folder search) — never hardcoded — so it requires the RayTK toolkit staged + loaded first (see manage_packages / the tdmcp://raytk/operators catalog). Returns the created ROP (its path and type) so you can confirm the master was copied in and the optional connect_from input wire was applied. Complementary to the GLSL create_raymarch_scene: this instances RayTK's own operators instead of authoring a shader. |
execute_python_script |
no_return_description |
Escape hatch — run an arbitrary Python script inside the TouchDesigner process. Code runs in TD only, never on the local machine. Returns the script's captured output: the value of the last expression plus any written stdout, when return_output is true (default); set return_output:false to run for side effects without receiving captured output. Prefer the structured tools (find_td_nodes, get_td_node_parameters, update_td_node_parameters, summarize_td_errors, snapshot_td_graph, …); reach for this only when no structured tool can express the operation. |
exec_node_method |
no_return_description |
Escape hatch — invoke an arbitrary Python method on a node (operator) inside the TouchDesigner process and return the method's evaluated result (e.g. a freshly copied op from .copy(), or None for methods like .cook()). Prefer structured tools where one exists; use this for operations they don't cover (e.g. .cook(), .copy(), .destroy()). |
draft_recipe_from_operator_chain |
params_unexplained |
Read-only: convert an ordered TouchDesigner operator chain into a RecipeSchema draft without writing files or touching the TD bridge. `difficulty` (beginner/intermediate/advanced, default intermediate) labels the proposed recipe's difficulty level, and `td_version_min` (default 2023) sets the recipe's minimum compatible TouchDesigner version. |
draft_recipe_from_tutorial |
params_unexplained |
Read-only: extract a conservative operator chain from an embedded TouchDesigner tutorial and draft a RecipeSchema JSON without writing files or touching the TD bridge. `difficulty` (beginner/intermediate/advanced, default intermediate) labels the drafted recipe's difficulty level, and `td_version_min` (default 2023) sets the recipe's minimum compatible TouchDesigner version. |
manage_packages |
no_return_description |
Search, list, inspect, doctor, dry-run install, stage, and uninstall manifest-driven TouchDesigner community packages, returning the action's result payload: search/list results, package info or doctor report, a dry-run install plan or staged-package status, and uninstall/path confirmation, with warnings. Dry-run is the default. Installs stage packages under ~/.tdmcp/packages and only import into TouchDesigner when the bridge is reachable and the package has a safe .tox import path. This tool never runs third-party scripts, pip installs, model downloads, or external app setup. |
optimize_performance |
no_return_description |
Scan a network for cook-time bottlenecks and (optionally) fix them. By default it only reports: the return lists the flagged bottleneck nodes with their cook time and a concrete suggestion for each, and when apply:true is set it also reports which flagged TOPs had their resolution lowered and the new resolution given `scale`. Run get_td_performance first if you just want the numbers; use this to act on them. |
render_output |
no_return_description |
Save a TOP to an image file at its native, full resolution (PNG/JPG/EXR/TIFF by extension) — for exporting a finished frame, unlike get_preview which only transfers a small inline thumbnail. The file is written by TouchDesigner on the TD machine; pass an absolute path. Returns the export outcome: the written file path and the success/error status of the write. |
record_movie |
no_return_description |
Record a TOP to a movie file (.mov/.mp4) via a Movie File Out TOP — for exporting a clip or a loop, where render_output only saves a single frame. start begins recording (pass file, fps); pass `seconds` to auto-stop after a fixed length, or call stop to finish (stop also cleans up the recorder node). The file is written by TouchDesigner on the TD machine. For individual numbered frames, use render_output per frame. Returns the recording state: for start, confirmation that recording began with the target file, fps, and auto-stop seconds if set; for stop, the finished movie path and whether the recorder node was cleaned up. |
check_operator_availability |
no_return_description |
Reconcile the operator knowledge base against the RUNNING TouchDesigner's ground-truth creatable-optype list (GET /api/optypes). Returns the reconciliation result: which documented operators are actually creatable in this build vs deprecated/unavailable (or the status of a single operator when one is passed), and, when include_kb_gap is true, which live optypes the knowledge base doesn't yet document. Survives TDMCP_BRIDGE_ALLOW_EXEC=0. |
edit_dat_content |
no_return_description |
Surgically replace a substring inside a Text or Table DAT's `.text`, returning the edited DAT path and the number of replacements made, or an error when the match count is invalid. Without `replace_all`, requires exactly one match — 0 or >1 occurrences is an error, forcing the caller to add context or set `replace_all`. Use `set_dat_content` to overwrite an entire DAT's text in place; use this to make a targeted edit. |
set_dat_content |
no_return_description |
Overwrite a Text or Table DAT's entire `.text` with new content, returning the DAT path whose content was replaced and the new text, or an error when the write is refused. Unlike `edit_dat_content` (which makes a surgical find-and-replace), this replaces everything in one shot — use it to deploy a full script or template. Refuses to write empty/whitespace-only text unless `confirm_wipe:true` is passed, preventing silent data loss. |
manage_component_storage |
no_return_description |
CRUD operations on a COMP operator's .storage dictionary. Actions: 'list' returns all keys and their values, 'get' reads and returns the value stored under a single key, 'set' writes a JSON-serialisable value (string, number, bool, list, dict, null) under 'key' on the live COMP, 'delete' removes a key. No operators are created; the target COMP must already exist, and path + action are required (key is required for get/set/delete, value for set). Returns an operation result: for 'list' the full key/value map, for 'get' the requested value, and for 'set'/'delete' the updated storage entry so the caller can confirm the change. |
project_documentation_site |
no_return_description |
Compose a one-folder handoff/portfolio documentation PACKAGE for a network: a README.md (title, node count, per-family summary, how-to-load note), a topology.md with a Mermaid graph of the connections, and - when include_thumbnails is set - preview PNGs of output TOPs under thumbs/ linked from gallery.md, all written into out_dir. Unlike generate_readme (a single file), this assembles a small multi-file site folder for sharing or archiving a project. Returns the out_dir that was written and the list of files created (README.md, topology.md, gallery.md, thumbs/) so the caller can verify the package contents. |
focus_network_editor |
no_return_description |
Pan/zoom TouchDesigner's Network Editor to frame the given operators — a 'follow' move so the artist sees what the agent just built instead of hunting for it. UI-only: it points a Network Editor pane at the operators' parent, selects them, and homes on the selection with zoom. Changes nothing in the project graph. Returns the operator paths that were framed. |
set_parameters_batch |
no_return_description |
Update parameters on multiple nodes in a single batch request. Each update reports its own success; a failure does not roll back the others. Returns a per-update result for every { path, parameters } entry, stating which ones succeeded, which failed, and any error message. |
create_control_panel |
no_return_description |
Expose live controls on a COMP: append custom parameters (sliders, toggles, menus, RGB, pulse) and bind them to node parameters so the artist can drive a generated system in real time. Point `comp_path` at a system container and list the controls; use each control's `bind_to` to wire it to one or more 'nodePath.parName' targets. Returns the names of the controls created, the page they were added to, and any warnings (e.g. bind targets that could not be attached). |
create_control_surface |
no_return_description |
Build a playable performance panel (a Container COMP of visual widgets) for live use, beyond the parameter dialog: vertical faders that drive parameters, and buttons that recall or morph to named cues (from manage_cue). Open the container in Perform/Panel mode for a touchable surface — faders move their parameters, cue buttons fire scenes (instantly or with a crossfade). Returns the path of the created surface container together with the faders and cue buttons it exposes. |
animate_parameter |
no_return_description |
Drive one or more node parameters over time with an LFO (sine/triangle/ramp/square/pulse/random). Creates an LFO CHOP and binds each target so it oscillates between min and max with the given period — movement without manual keyframing. Returns the path of the created LFO CHOP and the target parameters it binds. |
bind_to_channel |
no_return_description |
Drive one or more node parameters from a CHOP channel by expression — the link that makes a visual react. Point it at an audio_features channel (bass/mid/treble/level) or a tempo_sync channel (ramp/pulse/beat) with a scale and offset, and each target parameter tracks that signal live. Optionally add attack/release smoothing (in seconds), or a single `smooth` time, to insert a Lag CHOP between the channel and the parameter. Returns the paths of the CHOPs created for the binding (including the Select+Lag smoothing CHOPs when smoothing is active) and the target parameters that were bound. |
manage_presets |
no_return_description |
Store, recall, list, or delete named snapshots of a COMP's parameter values — the live-performance preset system. Pair with create_control_panel: snapshot the knob positions and jump between looks. Snapshots are saved in the COMP's storage so they persist with the project. Returns the name of the preset stored/recalled/deleted (or the list of stored preset names for 'list') and any warnings. |
manage_checkpoint |
no_return_description |
Store / restore / list / delete a full snapshot of a sub-network — an 'undo point' to take before risky live edits. A checkpoint captures every node's constant parameters, the wiring, and node positions. Restoring reapplies parameters, recreates nodes that were deleted since (with their wiring), and prunes nodes that were created since. Unlike manage_presets (custom-parameter looks for performance), this captures the whole network for safe experimentation. Returns the name of the checkpoint stored/restored/deleted, or the list of checkpoint names for 'list'. |
manage_cue |
no_return_description |
Live-performance scene system: store / recall / morph / list / delete named cues (snapshots of a COMP's custom-parameter values). Unlike manage_presets, a cue can be reached with a timed `morph` that crossfades every numeric control from the current look to the cue over N seconds (eased), via a small Execute DAT. Recall and morph also take an optional `quantize` ('beat'/'bar') that defers the change to the next musical boundary. Returns the name of the cue stored/recalled/morphed/deleted (or the list of cue names for 'list'), and for morph the scheduled duration and quantize. |
scaffold_extension |
no_return_description |
Give a COMP a Python extension class: create a Text DAT holding the class (with optional method stubs), wire it into an extension slot, optionally promote it (so members are callable directly on the COMP), and reinitialize. The other half of making a generated network reusable — pair with `add_custom_parameters` (knobs) and `manage_component` (save as .tox). Returns the path of the created class DAT, the extension slot used, and whether the extension was promoted. |
randomize_controls |
no_return_description |
Randomize a COMP's numeric custom parameters within their slider ranges — an instant new variation for live improvisation. `amount` blends toward random (1 = fully random, low values nudge the current look). Non-numeric controls (toggles, menus) are left untouched, so it is always safe to fire. Pair with manage_presets/manage_cue to snapshot a happy accident. Returns the COMP path and the names of the parameters that were randomized. |
create_phone_remote |
no_return_description |
Serve a mobile-friendly web panel from a Web Server DAT so you can control a COMP's numeric custom parameters from a phone — just open the URL, no app to install. Each parameter becomes a touch slider that writes back live. SECURITY: like the bridge, this listens on all interfaces and accepts writes with no auth, so use it only on a trusted network. Pair with create_control_panel (the params to expose) and manage_cue (snapshot looks you dial in from the phone). Returns the URL to open on the phone and the path of the Web Server DAT serving the panel. |
create_clip_launcher |
no_return_description |
Build an Ableton-style clip launcher: a grid panel (Container COMP) of clip buttons, one per named cue (from manage_cue), for fast hands-on scene switching during a live set. Open the container in Perform/Panel mode and tap a clip to fire its cue — instantly, or (with morph_time) crossfading to it over N seconds (eased, the same engine manage_cue uses). Store the cues with manage_cue / create_control_panel first. Returns the path of the created launcher panel (comp_path/name) and the cue buttons it laid out. |
learn_control |
no_return_description |
EXPERIMENTAL two-step 'MIDI learn'. Call once with mode:'snapshot' (controls at rest) to record every channel of an input CHOP (a midiin/oscin CHOP or a Null fed by one); then wiggle one hardware knob/fader and call again with mode:'bind' — it diffs against the snapshot, finds the channel that moved the most, and binds your target parameter to it by expression (with optional scale/offset). The snapshot is kept in the parent COMP's storage between the two calls. This is live/stateful. Returns a report: for 'snapshot' the number of channels recorded; for 'bind' the matched channel, its normalized delta, and whether a binding was made (nothing is bound if the top channel's delta is below min_delta). |
scaffold_vj_deck |
no_return_description |
Compose a complete, playable VJ deck UI in one call: it builds a DJ-style A/B deck mixer (create_decks) with a crossfader, adds an on-screen fader control surface (create_control_surface) with crossfade + per-deck gain faders, and creates a midiinCHOP control surface (create_external_io) whose channels are bound to the same crossfader/gain parameters for hands-on MIDI control. Pass deck_a/deck_b source TOP paths (or omit for test sources), and an optional midi_map of channel→control bindings (defaults to ch1c1→crossfader, ch1c2→gain_a, ch1c3→gain_b). This is the deck-scaffold layer on top of the create_decks primitive — it wires the existing deck, surface, and I/O tools into one UI container. Returns the path of the scaffolded VJ-deck container (parent_path/name) and a summary of the deck, fader surface, and MIDI bindings it wired together. |
create_synesthesia_unreal_osc |
no_return_description |
Build a named OSC-out preset map for driving Synesthesia or Unreal Engine from TouchDesigner. Picks a preset ('synesthesia' → prefix '/syn', port 6448; 'unreal' → prefix '/unreal', port 8000), builds a Constant CHOP with one named channel per control (channel name = '<prefix>/<control>' so an oscoutCHOP emits the exact address the target app expects), and wires it into an oscoutCHOP aimed at host:port. Override the control names, prefix, host, or port as needed. Bind audio/analysis to the source channels (e.g. op('controls')['syn/Bass']) to make the receiving app react. Returns the path of the created OSC-out container (parent_path/name) and the source Constant CHOP (its channels are the OSC addresses, e.g. op('controls')) so you can drive/bind them. |
create_cue_sequencer |
no_return_description |
Build a bar-quantized cue timeline: a Beat CHOP (on the global tempo) + a CHOP Execute DAT that, on each bar (or beat) boundary, advances through an ordered list of steps and recalls — or morphs over morph_seconds — that step's cue on a target COMP. The deterministic, musically-timed counterpart to create_autopilot (which is random/cyclic). Reuses manage_cue's stored cues and the same cue_morph engine, so store the target's cues with manage_cue first. Live Active / Step / BarsPerStep controls let you pause, jump, or retune on stage. Returns the path of the created sequencer engine COMP (parent_path/name) and the names of its live Active/Step/BarsPerStep controls. |
create_stage_dashboard |
no_return_description |
Serve one unified live-performance cockpit from a Web Server DAT — a single responsive web page (phone + laptop) that combines a grid of cue-launch buttons (recall named cues from manage_cue on the target COMP), master faders bound to chosen parameters, a big PANIC button (toggles the target COMP's Blackout/Freeze safety pars, the create_panic mechanism), and a live readout strip (a beat indicator plus a VU bar reading an audio-features Null CHOP). Open the returned URL — no app to install — and the page POSTs every control change back to the server, which applies it. SECURITY: like the bridge and create_phone_remote, this listens on all interfaces and accepts writes with NO auth, so use it only on a trusted network. Store cues with manage_cue, expose params with create_control_panel, and run create_panic first so the Blackout/Freeze toggles exist. Returns the dashboard's browser URL (http://<host>:port using the chosen port) and the path of the created Web Server DAT (target/name). |
create_palette |
no_return_description |
Generate a reusable colour palette + gradient other tools can bind to. In 'harmony' mode it computes N swatches from a base hue and a colour-theory rule (complementary / analogous / triad / tetrad / monochrome); in 'from_source' mode it samples dominant colours from a source TOP. It builds a Ramp TOP gradient (key colours from a docked Table DAT) plus a Constant CHOP exposing each swatch as swatch{i}r/g/b channels — feed those into create_color_grade, generate_from_moodboard or bind_to_channel. Live BaseHue / Saturation / Value / Rule / Count controls are exposed on the parent. Builds standalone (a harmony palette needs no source). Returns the created palette container path, the Ramp TOP gradient path, and the swatch Constant CHOP path (one swatch{i}r/g/b per colour) ready to bind. |
create_led_mapper |
no_return_description |
Pixel-map a source TOP onto an LED fixture layout and send per-pixel colors out as DMX over Art-Net/sACN. Resizes the source to a tiny WxH grid (one texel = one fixture pixel), samples it into per-pixel r/g/b channels with a TOP-to-CHOP, and feeds those into a DMX Out CHOP — the pixel-mapping editor that artnet_out lacked. Defaults to a built-in moving test source so the chain cooks with no input. Exposes Brightness and Universe controls. Sending real Art-Net needs a fixture/node on the network; this validates the per-pixel color CHOP is correct. Returns the path of the created container (parent_path/name), the per-pixel r/g/b CHOP path, and the resolved DMX universe/channel footprint from start_universe/start_channel and the WxH grid for validation. |
manage_annotation |
no_return_description |
Self-document a network: create a titled annotation box, set an op's comment, list the annotations/comments in a network, or list the ops a box geometrically encloses. Makes generated networks legible. Returns a per-action result: for 'create' the annotation COMP path (default 'anno'); for 'comment' the op whose comment was set; for 'list' the annotations/comments found in parent_path; for 'enclosed' the ops the box geometrically encloses. |
set_perform_mode |
no_return_description |
Toggle perform mode — the one switch the artist flips before going live. When enabled, tdmcp stores an advisory flag that tools can read before doing nonessential compute; the built-in guard currently suppresses auto preview captures. The flag is stored on the TD root op (op('/').store('tdmcp_perform_mode', ...)). Advisory: this does not stop the TD timeline or kill audio/video processing. Call with enabled=false after the show to resume normal operation. Returns the resulting perform-mode state (the advisory flag now stored on the TD root) so callers can confirm the toggle took effect. |
create_replicator |
no_return_description |
Wire a Replicator COMP that clones a template COMP once per row of a Table DAT — TouchDesigner's idiomatic 'N copies from data' mechanism (menus, scoreboards, per-track decks, instanced panels). Resolves or creates the template COMP (omit template_path → a minimal container with a Text) and the driving Table DAT (omit table_path → a small example table; rows sets how many demo rows), creates the replicator under parent_path, points its driving-table and master parameters at them, sets the replication method to 'by table', and optionally drops an onReplicate callback DAT stub for per-clone setup. The Replicator's parameter names vary by TD build, so each is set probe-first and the report includes which parameter took plus the live parameter list. Then it pulses a re-replicate so the clones appear. Re-replicating is destructive to previously generated clones, which the replicator deletes and re-creates on cook. Returns the created Replicator COMP path, the template/table paths it resolved or created, the parameters that took effect with the live parameter list, and the resulting clone count. |
create_beat_grid_sequencer |
no_return_description |
Build a programmable step-grid sequencer driven by a Beat CHOP on the global TD tempo: a Table DAT holds the per-step pattern (values or 1/0 flags), and a CHOP Execute DAT fires on every beat boundary, reads the current step (count % steps) from the table, and dispatches — action=param sets a custom parameter to the step value; action=cue recalls the cue for active steps (cues stored with manage_cue). The deterministic, repeating-rhythm instrument between create_autopilot (random drift) and create_cue_sequencer (linear list): program a strobe on beats 1+3, a hue shift on the bar, etc. Reprogramme the grid live by editing the step_table DAT. NOTE: beat-callback timing is UNVERIFIED offline — check op().time.play if steps don't fire when the TD timeline is paused. Returns the path of the created sequencer COMP (parent_path/name) and the step_table DAT path for live reprogramming. |
create_midi_map |
no_return_description |
HARDWARE-GATED SCAFFOLD. Build a MIDI controller preset for a supported device (apc_mini / launchpad / midi_mix / nanokontrol / generic): creates a midiinCHOP + a labeled bind Table DAT, and optionally auto-binds faders/knobs to a target COMP's numeric custom parameters. Explicit bindings can override or supplement the preset. CC/note numbers are best-effort from published MIDI charts and MUST be validated with real hardware — actual assignments depend on device firmware. This tool is HELD FROM RELEASE until hardware validation is complete. For one-at-a-time MIDI learn of a single control, use learn_control instead. Returns the path of the created MIDI In CHOP (parent_path/name) and its bind Table DAT, plus the auto-bound fader/knob→parameter assignments to the target for validation. |
create_look_bank |
no_return_description |
A playable snapshot row: store N named 'looks' (snapshots of a control COMP's numeric/toggle/menu parameters) in a visible, editable Table DAT, with one momentary recall button per slot (snap or crossfade) plus a master A↔B morph knob that blends continuously between two chosen looks. Reuses manage_cue's morph engine (so a recall behaves exactly like a cue morph, with optional beat/bar quantize) and mirrors slots into the COMP's cues so they interoperate with manage_cue / create_control_surface. Pulses and strings are always skipped at capture. Build cues/params with create_control_panel first. Returns a per-action result: 'build' the look-bank panel path (comp_path/name); 'store' the slot saved; 'recall' the slot and morph target; 'set_ab' the assigned slot_a/slot_b and knob position; list/delete the affected slots. |
create_band_router |
no_return_description |
Split an audio signal into EQ bands and route each band to its own target parameter(s) — the musician-friendly 'bass -> this, highs -> that' patch. Builds a container with: a Select CHOP isolating the source audio by absolute path (no cross-container wire), N audiofilterCHOP band-pass slices tiling the spectrum in log-frequency space (the same audioFilter idiom extract_audio_features uses), an Analyze CHOP per band measuring its level via rmspower, a Merge + Lag smoothing the per-band envelope (release in seconds), and a Null 'bands_out' carrying one channel per band named band0..bandN-1 (band0 = lowest). Each target route binds a band's smoothed level to a parameter by expression (op('<bands_out>')['band<i>'] * scale + offset). The bands_out Null is also directly bind_to_channel-able for routes you add later. NOTE: the analyze 'rmspower' function value and the channel-rename pars are UNVERIFIED across TD builds — they are set in guarded tries with fallbacks, and per-item failures surface as warnings rather than failing the build. Returns the path of the created band-router container (parent_path/name), the bands_out Null CHOP path (one channel per band, band0 = lowest) for later bind_to_channel routes, and a report of the band→target bindings applied. |
create_xy_pad |
no_return_description |
Build a draggable 2D (XY) gesture pad — a Container COMP whose pointer drag drives an x/y CHOP of normalized control channels, optionally remapped into ranges and bound by expression to target parameters (e.g. an effect's two main knobs). Add a 3rd (Z) axis via z_target to also get a slider. Open the container in Perform/Panel mode and drag inside it to scrub X/Y live. The pad reads its drag through a Panel CHOP; the u/v drag-channel names are probed at build time (they vary by TD build) and any mismatch is reported as a warning. Leave the axis targets empty to just expose the x/y channels and bind them later with bind_to_channel. Returns the path of the created XY-pad container (parent_path/name) and its x/y (and optional z) control CHOP channels, ready for bind_to_channel. |
create_auto_montage |
no_return_description |
Point at a folder and build a self-running clip montage: scans the folder for clips/stills, builds one Movie File In TOP per file feeding a Switch TOP (fractional-index crossfade) → Null TOP, and adds an auto-advance brain on top — a Beat CHOP (clock='beat' or 'bar' with division) or LFO CHOP (clock='interval') drives a CHOP-Execute DAT that picks the next clip per `mode` (sequential / random / shuffle-no-repeat / weighted) and animates the Switch index with a crossfade. Exposes Play / Index / Next / Prev / Crossfade / Bpm / Division / Mode / Seed custom pars on the container; emits a state_out Null CHOP so bind_to_channel can read clip_index/beat. Folder is read inside TD. Missing folder → empty pointable montage instead of error. Returns the montage container COMP path, the Switch→Null TOP output chain path, and the state_out Null CHOP path. |
create_euclidean_sequencer |
no_return_description |
Build a Euclidean rhythm sequencer: given `pulses` evenly distributed across `steps` via Bjorklund's algorithm (with optional cyclic `rotation`), it writes the resulting on/off pattern to a Table DAT and fires one dispatch per active step on each beat boundary. The deterministic, mathematically-grounded sibling of create_beat_grid_sequencer — program rhythms by musical intent (e.g. E(3,8) tresillo, E(5,8) cinquillo, E(4,16) four-on-the-floor) rather than by hand-editing cells. Sweep the Pulses/Rotation custom parameters live and the table re-shapes in place. action=param sets a custom parameter to on_value/off_value per step; action=cue recalls a cue per active step (cues stored with manage_cue). NOTE: beat-callback timing is UNVERIFIED offline — check op().time.play if steps don't fire when the TD timeline is paused. Returns the sequencer COMP path, the on/off pattern Table DAT path, and the tempo (Beat CHOP) source path. |
create_preset_morph |
no_return_description |
Target-agnostic preset morph engine: snapshot any OP's animatable parameters into N named slots, then blend between them with a weight vector (or a single A↔B recall) through a Lag CHOP + Lookup curve, exposing the live blended values on a Null CHOP for bind_to_channel consumers. Unlike create_look_bank (which is scoped to a control COMP's custom pars with a 2-slot A↔B knob), this drives any OP and supports >2 simultaneous weights (normalized internally). Reuses manage_cue's MORPH_HOOK for beat/bar quantized recall. Note: Lag CHOP does not advance while the timeline is paused. Returns the morph container COMP path and the live blended-values Null CHOP path. |
create_scene_timeline |
no_return_description |
Build a scrubbable show timeline: a single Timer-CHOP playhead drives ordered scenes that recall cues on a target COMP. Sits above create_cue_sequencer (beat-quantized) and create_scheduler (event-firing) as the show's master clock. Exposes Play/Pause/Stop/Seek/Rate/Loop/Active_Scene custom pars + a playhead Null CHOP (t_seconds, t_norm, scene_idx, scene_t). Consumes the foundation setlist schema: when setlist_path is given, each scene's setlist_slot is mirrored into tdmcp_scenes for downstream tools. Bars→seconds conversion uses BPM 120 + 4 beats-per-bar at build time (no auto-rescale on tempo change). Returns the timeline engine COMP path and the playhead Null CHOP path. |
create_scheduler |
no_return_description |
Build a Timer-CHOP scheduler COMP: one or more named timers (seconds or beats), each with an optional ordered segment list, sharing a Callbacks DAT that fires a cue/param/script action on onDone and onSegmentEnter. Atomic timer primitive that create_scene_timeline and other automation rides on. Reuses manage_cue's tdmcp_cues storage for the default 'cue' action - store target cues first with manage_cue. Returns the scheduler COMP path, each timer's Timer CHOP + segment Table DAT, and the shared Callbacks DAT path. |
extend_data_source_fabric |
no_return_description |
Adds extra transports to the data-source fabric beyond create_data_source: 'mqtt' subscribes to a broker, 'ws-binary' streams binary frames over a WebSocket, 'midi-mmc' listens for MIDI Machine Control transport bytes (play/stop/record/locate). Same downstream shape as create_data_source — a Null DAT for the raw text/bytes and a Null CHOP whose channels are ready for bind_to_channel / create_data_visualization. Returns the created sub-network COMP path, the raw-data Null DAT path, and the output Null CHOP path. |
sync_timecode |
no_return_description |
Wire an external SMPTE/MTC/LTC/OSC timecode source into the TouchDesigner timeline. Creates the input op + Math CHOP normaliser + Null CHOP 'tc_out' (channels 'frame' and 'seconds'); optionally adds an Execute DAT that writes project.frame = tc_out['frame'] each cook so the timeline follows house clock. Requires the project to be playing — paused TD will not advance. LTC has no native TD decoder; the tool surfaces a warning and creates the audio input so the artist can attach an external decoder. MTC operator availability is build-dependent. Returns the timecode subsystem COMP path, the normalised 'tc_out' Null CHOP path, and the optional drive-timeline Execute DAT path. |
apply_lut |
no_return_description |
Apply a colour Look-Up Table (LUT) to an existing TOP inside a self-contained baseCOMP. Prefers an OpenColorIO TOP for `.cube`/`.3dl`/`.cc`/`.ccc` files; falls back to a Movie File In + Lookup TOP for image LUTs or when OCIO is unavailable. A `.cube` file with no OCIO is parsed in Python into a Script TOP ramp. Exposes Strength and Bypass controls on a custom page. Pass `source_path` to grade an existing TOP, or omit it for a standalone preview on a grey Constant TOP. Returns the LUT container COMP path, the graded output TOP path, and the custom-page Strength/Bypass control paths. |
post_passes_3d |
params_unexplained |
Compose a chain of 3D-aware post-processing passes (SSAO, SSR, DOF, motion blur) inside a new baseCOMP. Each pass is a glslTOP with companion textDAT that samples color + depth + (optional) normal/velocity AOVs from selectTOPs. Passes run in fixed order SSAO → SSR → DOF → MB and emit a final null TOP ('out1'). SSR is skipped with a warning when normal_top is empty; motion blur falls back to a directional blur when velocity_top is empty; if color_top points at a renderTOP and depth_top is empty, a sibling depthTOP is auto-created (best-effort). Per-pass controls: ssao_enable toggles the ambient-occlusion pass, ssao_radius its sampling radius (0.001–0.5) and ssao_intensity its darkening strength (0–4); ssr_enable/ssr_intensity toggle screen-space reflections and their blend amount (0–2); dof_enable toggles depth of field, dof_focus the normalized focus distance (0–1) and dof_aperture the blur size (0–0.1); motion_blur_enable toggles motion blur and motion_blur_amount its strength (0–1); resolution sets the output TOP size as [width, height] in pixels. Returns container/output paths, the resolved AOV paths, the enabled passes, and any warnings. |
create_flow_abstraction |
no_return_description |
Build a two-pass Kyprianidis-style flow abstraction: an edge-tangent-flow (ETF) bilateral smoother followed by a flow-based DoG (FDoG) line extractor — oil-painting smooth interiors with crisp coherent ink edges. Creates two glslTOPs + companion textDATs under parent_path, fed by a Select TOP from the source TOP and terminated by a Null TOP. Strength/Edge/Iterations are exposed as live parent-par-bound uniforms; blur radius, sigmas and tau are baked in at build time. Iterations boosts effective ETF strength in-shader (single-input pass, no ping-pong feedback). Returns the ETF and FDoG GLSL TOP paths, the companion fragment DAT paths, and the output Null TOP path. |
setup_face_tracking |
no_return_description |
One-shot face-landmark tracking from a webcam: loads the MediaPipe ENGINE (install first with `tdmcp install mediapipe-touchdesigner`), starts the timeline, and builds an adapter Script CHOP that emits a 468-sample (or 478 with iris) face-landmark CHOP (tx/ty/tz/confidence, centred on nose tip). Feeds directly into bind_to_channel and create_data_visualization. Returns the MediaPipe ENGINE path, the adapter COMP path, and the emitted face-landmark CHOP path. |
setup_segmentation |
no_return_description |
One-shot selfie segmentation via the MediaPipe TouchDesigner engine (install with `tdmcp install mediapipe-touchdesigner`). Loads the engine, enables Selfie Segmentation, and builds an adapter COMP with a clean alpha-mask Null TOP (optionally inverted and/or feathered) plus an optional pre-keyed RGBA Null TOP (person on transparent). Wire the mask into create_keyer, create_depth_silhouette, or any matte-consuming tool. The engine reuses an existing MediaPipe op if already loaded (idempotent). Keep the TD timeline PLAYING so the embedded browser captures the webcam; click Allow if macOS prompts for camera permission. Returns the adapter COMP path, the alpha-mask Null TOP path, and (when publish_prekeyed) the person_rgba Null TOP path. |
diagnose_tdableton_mapper |
no_return_description |
Inspect a TouchDesigner TDAbleton mapper COMP and its source CHOP without requiring AbletonMCP or a live Ableton connection. Detects common mapper symptoms such as an unexpected source CHOP, a Reorder channel list that does not match the expected value, or misconfigured Oscinputchop/Bypass/Min/Max parameters. Returns a diagnostic report of the symptoms found for each checked parameter, and when repair is true applies best-effort parameter repairs inside TouchDesigner and reports what was changed. |
create_audio_glsl_uniforms |
no_return_description |
Writes CHOP-reference expressions onto the seq.vec uniform slots of an existing glslTOP, so named channels (low/mid/high/rms etc.) drive shader uniforms every cook. Creates no operators — pure parameter binding. Idempotent and composable with create_glsl_shader. Returns a summary of the applied bindings (the slot assigned to each uniform and the channel/component wired into it) plus any warnings, such as channels missing from the source CHOP or an out-of-range slot skipped because expand_capacity was false. |
connect_daydream_cloud |
params_unexplained |
Create a Daydream cloud-hosted StreamDiffusion bridge in TD. A webclientDAT POSTs the encoded source TOP frame to Daydream's REST endpoint; the diffused result is pulled back via a Syphon/Spout/NDI receiver and exposed as a null TOP. API key is read from DAYDREAM_API_KEY in the TD process environment — never inlined. seed is optional: providing it seeds the diffusion RNG so the same prompt/strength/seed yields reproducible output, while omitting it lets Daydream pick a fresh random seed per frame. Live probe SKIPPED (requires Daydream account + outbound HTTPS). |
add_timecode_overlay |
no_return_description |
Overlay a running HH:MM:SS:FF timecode (or a countdown) onto an input TOP as VISUAL pixels — a Text TOP whose text expression re-evaluates every frame, composited 'over' the source with a Composite TOP. Modes: clock (show time since project start — NOT the OS wall clock — as HH:MM:SS:FF), count_up (elapsed time since this overlay was built, from zero), count_down (counts down from `target_seconds` to 00:00:00:00 and clamps there). The formatter lives in a Text DAT module (mod('fmt').tc(...)) so it re-cooks live inside TD. Distinct from sync_timecode, which syncs a CLOCK SIGNAL (no pixels) — this tool draws the timecode into the image. The chain ends with a Null TOP 'out'. Returns the overlay container path, the Null 'out' TOP path holding the composited result, and the FPS probed live for the timecode (me.time.rate -> project.cookRate -> 60). |
plan_visual |
no_return_description |
Turn a natural-language description of a visual you WANT into a build plan — a dry run that creates nothing. Returns the plan for the caller: the recommended tool/recipe, the nodes to create, and how they wire together, so an agent can hand it to a builder. Note: this does NOT inspect the current TouchDesigner project; to read existing nodes use get_td_nodes / get_td_topology / find_td_nodes. |
create_kinect_wall_harp |
params_unexplained |
Build a synthetic-safe Kinect v2 / FreenectTD projected wall harp in an isolated Base COMP. The network can create a FreenectTOP depth path when explicitly enabled, listen to an external OSC Kinect bridge with source='osc_kinect', or build a synthetic fallback. The normalized input frame can be cropped before tracking and projection mapping via crop_left/crop_right/crop_top/crop_bottom (each 0–1; the defaults 0/1/0/1 use the full frame) to exclude walls, limbs, or other unwanted regions. It extracts left/right hand centroids, divides the projection into configurable musical zones, triggers short electronic plucks on zone entry, renders a denser vibrating curtain of projected strings, and exposes depth/mask/hands/audio plus bridge-status diagnostics. If FreenectTD or Kinect hardware is unavailable, the tool returns warnings instead of throwing, so the visual/audio/trigger chain can still be tested offline. |
sync_external_clock |
no_return_description |
Lock the project tempo to a live source so beat-synced visuals follow the music. `mode` picks the source: 'tap' (default) gives a Bpm knob + Tap pulse you dial/tap by ear; 'ableton_link' locks to an Ableton Link session on the network; 'midi_clock' derives BPM from incoming MIDI timing-clock (24 PPQN). All modes write the global tempo (op('/').time.tempo), so create_tempo_sync clocks and create_autopilot follow. The Link/MIDI modes are hardware-gated — without that source present the manual Bpm knob still drives the clock. Returns the created 'tempo_clock' container path and the tempo source actually driving the clock. |
create_tempo_sync |
no_return_description |
Create a tempo clock (Beat CHOP driven by TouchDesigner's global tempo) exposing beat-synced channels on a Null CHOP: a per-beat 0→1 `ramp`, a `pulse` spike on each beat, integer `beat`/`bar` counters, and `bpm`. Bind any parameter to these to lock visuals to the beat. With emit_events on, it also broadcasts a `beat` event over the bridge WebSocket each beat, so `tdmcp-agent watch` and the AI can see the pulse live. Pair with extract_audio_features for full musical reactivity. Returns the created 'tempo_sync' container path, the features Null CHOP path, and the exposed channel names to bind. |
create_simulation |
no_return_description |
Build a GPU simulation: 'reaction_diffusion' grows Gray-Scott patterns (via the validated recipe), while 'slime' and 'fluid' run a feedback loop displaced by an evolving noise flow field — drifting trails and advected smears. Creates a self-contained simulation container under `parent_path` and exposes a live Decay knob (trail persistence) for slime/fluid, bound to the gain Level TOP. Returns the created container path and the output TOP path, the exposed controls, any node errors, and warnings. For more procedural techniques (cellular automata, flow fields, strange attractors) see create_generative_art. |
list_recipes |
no_return_description |
List the built-in recipe library — ready-made network templates (feedback tunnel, particle galaxy, reaction-diffusion, projection mapping, …). Offline. Returns a JSON array of the matching recipes, each with its `id`, `name`, `tags`, and `difficulty`. Pass `tag` to filter by tag or keyword (matches tags or name). Apply one with apply_recipe. |
create_spectrum |
no_return_description |
Build an FFT audio-spectrum analyzer that exposes N separate, ready-to-bind frequency-bin channels (band0..band{N-1}) on a Null CHOP. This is the per-band complement to extract_audio_features (which only gives overall level + bass/mid/treble): bind a row of parameters to op('.../spectrum/spectrum')['band0'], ['band1'], … to drive a bank of bars, or pick one frequency. A Sensitivity knob scales every band. Source can be the live device (mic/line — may prompt for macOS permission), an audio file, a synthetic oscillator (for testing), or an existing CHOP. Creates a self-contained 'spectrum' container under `parent_path` and returns a summary plus a JSON block with the container path, the Null CHOP path carrying band0..band{N-1}, exposed controls, any node errors, and warnings. Use extract_audio_features when you want coarse level/bass/mid/treble bands instead of N fine bins, create_audio_reactive for a ready-made spectrum visual, and feed this Null into bind_audio_reactive to drive a COMP. |
create_shader_lib |
no_return_description |
Instantiate a curated, ready-to-run full-screen GLSL shader (tunnel, raymarch_sphere, fractal, metaballs, plasma) into a GLSL TOP with live Speed / Scale / Color controls. Creates a self-contained 'shader_lib_<shader>' container under `parent_path` holding the GLSL TOP and a Null output, and returns a summary plus a JSON block with the container path, the output TOP path, exposed controls, any node errors, and warnings. High-value VJ eye-candy; unlike create_glsl_shader it ships robust built-in shaders rather than taking arbitrary code. |
create_shader_park |
no_return_description |
Compile Shader Park JavaScript sculpture code with shader-park-core and instantiate it as a self-contained TouchDesigner GLSL MAT scene with live controls. Creates a new baseCOMP under `parent_path` (named by `name`) holding the compiled GLSL MAT, rendered to a TOP for output, and returns a summary plus a JSON block with the container path, the render TOP path, exposed controls, any node errors, and warnings. Use the companion shader-park:tox script when you specifically want the official Shader Park .tox plugin workflow. |
create_geo_visualization |
no_return_description |
Turn GeoJSON (e.g. OpenStreetMap-derived) into a 3D city visualization. Reads Point / LineString / Polygon / Multi* features, projects lat/long via a Mercator projection normalized to a unit box, and builds a Script SOP that lays out point clouds for points and polylines for streets/building footprints — optionally extruded into 3D ribbon 'walls' using each feature's numeric 'height' property — all wrapped in a Geometry COMP under a camera+light Render TOP for instant preview. Creates a self-contained 'geo_viz' container under `parent_path` and returns a summary plus a JSON block with the container path, the render/output TOP path, exposed controls, any node errors, and warnings. NOTE: OpenStreetMap map data is © OpenStreetMap contributors and licensed under the Open Database License (ODbL); you must attribute it when visualizing OSM-derived data. |
detect_pitch |
no_return_description |
EXPERIMENTAL monophonic pitch tracker built entirely from stock CHOPs (the Pitch CHOP isn't createable in this build): an Audio Spectrum CHOP in 1-sample-per-Hz mode, trimmed to a [min_hz, max_hz] search band, then an Analyze CHOP argmax (highestpeakindex) whose index IS the frequency. Estimates the dominant musical pitch of live audio; creates a self-contained 'pitch' container under `parent_path` that outputs a Null CHOP with pitch_hz (frequency in Hz), note (MIDI note number), and confidence (peak magnitude) channels — bind a colour/parameter to op('.../pitch/pitch')['pitch_hz'] to drive visuals from a melody — and exposes live Sensitivity (magnitude gain) and Threshold (minimum peak magnitude below which the pitch is treated as silence) knobs. Source can be the live device (mic/line — may prompt for macOS permission), an audio file, a synthetic sine oscillator (for testing), or an existing CHOP. Caveats: ~1 Hz resolution, no harmonic/octave correction, monophonic only — approximate and best tuned live. Returns a summary plus a JSON block with the container path, created node paths, the pitch/output CHOP path, exposed controls, any node errors, and warnings (no preview image — the output is a data CHOP, not a TOP). |
create_raytk_scene |
no_return_description |
Build the minimal renderable RayTK node graph (sphereSdf → raymarchRender3D → Null TOP) from RayTK's real ROP COMP masters, copied at runtime — the node-graph-native complement to create_raymarch_scene (which stays the lightweight, no-dependency GLSL path). Creates a container COMP named by `name` (default 'raytk_scene_<sdf_primitive>') under `parent_path`, holding the copied graph. Optional flags union a second SDF (union_with), insert an inline basicMat (material), and add an explicit lookAtCamera (add_camera) / pointLight (add_light). Requires the RayTK toolkit staged + loaded (manage_packages install raytk, then load the .tox); RayTK 0.46 requires TouchDesigner 2025.30770+. Fails forward with 'stage & load RayTK first' guidance when the library is absent. Returns a summary plus a JSON block with the container path, created node paths, any node errors, and warnings. |
detect_tempo |
no_return_description |
EXPERIMENTAL automatic tempo (BPM) detection WITHOUT manual tapping. Detects beat onsets in live audio (kick band → RMS energy → moving-baseline threshold, reusing detect_onsets' primitive), measures the time between beats, and reduces the recent inter-onset intervals to a stable tempo (median → BPM = 60/interval). Creates a system container named by `name` (default 'detect_tempo') under `parent_path`, outputting a Null CHOP with a `bpm` channel — bind a parameter to op('.../detect_tempo/bpm')['bpm'] — and exposing live Threshold (onset sensitivity — lower fires on more beats) and Smoothing (how many recent intervals the median locks over — higher = steadier, slower to react) knobs. With drive_tempo on, it also writes the detected BPM to the project's global tempo (op('/').time.tempo) so every Beat CHOP downstream — create_tempo_sync, create_autopilot — follows the music automatically. Complements sync_external_clock (which is tap-tempo) and detect_onsets (which flags hits but derives no tempo). Source defaults to a synthetic gated tone (device capture can hang TD on a macOS permission modal); also accepts a file, an existing CHOP, or the live device. Caveats: time-dependent (reads 0 on a paused timeline), can lock to half/double time, and must be tuned live per source (Threshold + Smoothing knobs). Returns a summary plus a JSON block with the container path, created node paths, the bpm/output CHOP path, exposed controls, any node errors, and warnings (no preview image — the output is a data CHOP, not a TOP). |
create_hand_hologram |
params_unexplained no_return_description |
Build a palm-anchored hologram visual driven by create_hand_gesture_bus: a holographic object floats above a tracked hand, an open palm controls its visibility, and an opposite-hand pinch drives its scale, glow, and optional futuristic synth/device audio. Creates a container COMP named by `comp_name` (default 'hand_hologram') under `parent_path`, rendering the hologram at `resolution` (default 1280×720) and compositing it over `input_top_path` when provided. `source` defaults to 'synthetic' — a self-contained previewable mock that needs no camera or plugin; switch to 'mediapipe' (point `hand_chop_path` at the plugin's hand-landmarks CHOP) or 'existing_chop' for a hand CHOP you already have, optionally loading an asset .tox via `tox_path`. `preset` picks the visual — holo_cube (default), energy_orb, wireframe_hud, or particle_core — tinted `color` (default '#54f4ff') with `accent_color` (default '#b56cff'). `size` (default 1) scales it, `float_height` (default 1.15) sets the float height above the palm, `transparency` (default 0.46; 0 = opaque, 1 = invisible) fades it, `glow` (default 22) blooms it, `scanline_amount` (default 0.35) adds scanlines, `rotation_speed` (default 0.42 deg/s; negative reverses) spins it, and `pinch_scale_amount` (default 1.4) scales it during pinch. `audio_mode` is 'none' (default, silent), 'synth' (internal synth), or 'device_out' (synth sent to the device in `audio_device_hint`, default 'UMC202HD'). With `expose_controls` (default true) live knobs are exposed and with `capture_preview` (default true) an inline preview image is captured. Returns a summary plus a JSON block with the container path, created node paths, the output path, exposed controls, any node errors, and warnings. |
setup_body_tracking |
no_return_description |
One-shot body tracking from a webcam: loads the free mediapipe-touchdesigner ENGINE (install it first with `tdmcp install mediapipe-touchdesigner`) into the COMP at `parent_path` (default '/project1'), starts the timeline (the engine captures the webcam through an embedded browser that only runs while playing), and reads its pose JSON DAT through an adapter that emits a 33-landmark pose CHOP; with build_skeleton (default true) it also builds a live pose-skeleton visual wired to the tracked body so you only need to pick your webcam and enable Pose. `tox_path` points at the MediaPipe ENGINE .tox (defaults to the package staged by `tdmcp install mediapipe-touchdesigner`, falling back to the legacy ~/tdmcp-packages path). If the engine isn't installed yet, it returns install guidance rather than failing. Loading the engine will prompt for camera permission on macOS (click Allow). Returns a summary with the engine path, the adapter/pose-CHOP path, the skeleton path (when built), and any node errors or warnings. |
create_media_bin |
no_return_description |
Point at a folder on the TouchDesigner machine and build a clip BIN inside a new bin COMP: it scans the folder (filtered to the given extensions, capped at max_clips), creates one Movie File In TOP per file, feeds them through a Switch TOP, and ends on a Null TOP. Exposes Index (current clip), Next / Prev (pulse, wrapping), and Crossfade (seconds) controls — switching clips crossfades by ramping the Switch's fractional index (0s = hard cut). The folder is read inside TD (not the MCP server). If the folder is empty or missing you get an empty, pointable bin instead of an error. Use create_video_player for a hand-listed playlist; use create_media_bin to ingest a whole folder for clip-based VJing. Returns a summary plus a JSON block with the bin container path, the created Movie File In / Switch / Null node paths, the loaded clip count, exposed controls, node errors, warnings, and an inline preview image. |
create_feedback_tunnel |
params_unexplained |
Build a parameterized infinite-zoom/rotate feedback tunnel: a seed TOP is composited with its own fed-back, zoomed, rotated, and decayed frame each cook to produce a hypnotic inward-spiral tunnel. Four audio-bind-ready controls (Zoom, Rotate, HueShift, Decay) are exposed on the container for live performance. A built-in animated noise seed is used when no `source` TOP is given. The recipe-validated topology (noiseTOP → feedbackTOP + compositeTOP-maximum → transformTOP sx/sy → blurTOP → levelTOP brightness1/huerotate → nullTOP, loop closed by feedbackTOP.par.top) is created inside a new baseCOMP under `parent_path`. Returns a summary, the container + node paths, exposed controls, any node errors, and an inline preview image. This is the fixed zoom-and-rotate spiral preset; for a general feedback loop with a choice of seed type and an arbitrary ordered chain of effects (blur/displace/edge/…) use create_feedback_network instead. Parameters: `name` is the base name for the created container COMP (default 'feedback_tunnel'); `parent_path` is where it is created. |
create_set_navigator |
no_return_description |
Build a hands-light stage navigator (the QLab model) for stepping through an ordered scene/cue list: Next / Prev to move the pointer, Go to fire the current scene's cue on the target COMP, and an Index knob to jump directly. Optionally quantizes GO to the next beat. The navigator drives `manage_cue` recall on the target so cue morphs and beat-quantized changes all work. Use after building a control panel with `manage_cue` cues stored; then perform the show by hitting Next + Go instead of recalling by name. Returns a summary with the navigator container path, the created node paths, the exposed controls (Next/Prev/Go/Index), the target COMP, and any warnings. |
create_pop_geometry |
no_return_description |
Procedural Op Pattern (POP) geometry generator: build a SOP chain inside a Geometry COMP — primitive (box/sphere/tube/torus/grid/line/text) → Transform SOP (translate/rotate/scale) → optional Subdivide SOP → optional per-point Noise SOP displacement → Material SOP (Constant MAT) → Null SOP — then render through a Camera + Light + Render TOP to a Null TOP. Creates a new baseCOMP under `parent_path`. Exposes a RotateY control; NoiseAmount + NoisePeriod are exposed only when noise_amount > 0 (otherwise the Noise SOP is omitted and those knobs would be inert). Use build_sop_geometry for a fully declarative SOP chain without a render rig; use create_3d_scene for instanced primitives, create_pbr_scene for PBR shading. Returns a summary plus a JSON block with the container path, the created SOP/Geometry/Camera/Light/Render node paths, the render-output Null TOP path, exposed controls, node errors, warnings, and an inline preview image. |
create_midi_note_reactive |
no_return_description |
Build a MIDI note → per-note trigger/velocity chain that exposes bindable channels on a Null CHOP (note0…noteN-1). Unlike learn_control (which binds one CC), this creates a full note-event chain: midiinCHOP → eventCHOP (ADSR envelopes per note) → Null CHOP. Bind any parameter to op('…/notes_out')['note0'] and it pulses with each keypress. source='synthetic' (default) previews without hardware by generating a procedural note pattern — switch to source='device' when a MIDI keyboard is connected. The device path is HARDWARE-GATED (HELD FROM RELEASE until validated with real MIDI gear). Returns a summary with the container path, the created midiin/event/Null CHOP node paths, the exposed channel names (note0…noteN-1), and any warnings. |
compose_cue_list |
no_return_description |
Turn a natural-language show description into a validated cue list (SetlistSchema, scenes[] variant). Uses the local LLM when configured, falls back to a deterministic grammar parser otherwise. Optionally chains into create_cue_sequencer. Returns the validated cue list as a JSON block (scenes with cue names and morph times, plus the parsed bpm, bars, style, and title); when apply=true it also returns the created cue_sequencer container path. |
create_two_way_surface |
no_return_description |
Build a bidirectional OSC or MIDI control surface that drives TouchDesigner params from a controller AND echoes outgoing changes back to it (motor faders, RGB pads), with an oscillation guard so the device's own echo doesn't ping-pong. Each mapping pairs a device address with a TD parameter; a Script CHOP gates outbound sends by epsilon delta, rate limit, and a last_in cache. Exposes Bypass, Globaleps, Ratehz, Reseccache custom pars on the container. Returns a JSON block with the container path, the created In/Out + Script CHOP node paths, the active mapping list, exposed custom pars, and any warnings. |
create_automation_lane |
params_unexplained |
Build a per-parameter automation lane that records a live parameter sweep into a circular buffer over N bars, then loops the recording back into the parameter on a bar-phase clock. Two modes: record (sample the target param every cook into a ring buffer) or loop (read the buffer back via Lookup CHOP bound to the target param). Re-calling with the same name and a different mode flips the state without rebuilding the network. Uses Beat CHOP → Select CHOP (rampbar) → Lookup CHOP playback, with COMP storage tracking mode/write_head/armed state. Parameters: `bars` is the loop length in bars (must be 1, 2, 4, or 8; default 4); `bpm` sets the tempo for the bar clock (default 120); `mode` selects 'record' (sample into the buffer) or 'loop' (play the buffer back), default 'record', and re-calling with a different mode flips the state. Returns a summary plus a JSON block with container path, mode, samples count, target, and any warnings. |
create_chroma_reactive |
params_unexplained |
[experimental] Builds a 12-channel pitch-class chroma vector (chroma_0..chroma_11) from an audio bus via FFT bin → pitch-class fold. Outputs a Null CHOP ready for bind_to_channel. Shares audioSource convention with create_transient_reactive / create_energy_reactive. Parameters: `name` is the container COMP name (required); `parent` is the parent COMP path where it is created (default '/'). |
create_transient_reactive |
no_return_description |
Layer-1 audio splitter: differences a fast and a slow envelope follower to expose two normalized 0..1 channels — 'transient' (percussive onsets) and 'sustain' (tonal floor) — on a Null CHOP at {comp}/out. Pair with bind_to_channel to drive visuals from percussion vs sustain independently. Custom-par page 'Tune' on the parent COMP exposes Sensitivity + per-envelope attack/release for live tweaking. Returns a summary with the container path, the created envelope + Null CHOP node paths, the exposed channel names ('transient', 'sustain'), and any warnings. |
create_energy_structure |
no_return_description |
[experimental] Build a song-structure (build / drop / breakdown) edge detector COMP with adaptive thresholds. Listens to an existing audio CHOP (audioSource) or a freshly created Audio Device In, follows a long-window envelope, and runs a Script CHOP that maintains a rolling buffer (last windowSec seconds) to derive an adaptive mean (mu) and std (sigma). Emits a 5-channel Null CHOP `out` with: energy (smoothed RMS 0..1), state (0=breakdown, 1=build, 2=drop), and three 1-sample edge pulses build_edge / drop_edge / breakdown_edge. buildThreshold and dropThreshold are k-multipliers of sigma above mu (NOT absolute amplitudes), so the detector self-calibrates to the current mix loudness. Hysteresis (4 cooks above to step up, 30 below to fall back) stops chattering at thresholds. windowSec/Buildthreshold/Dropthreshold are exposed as custom params on the parent COMP so artists can tweak live. Default audio source builds an Audio Device In CHOP (may pop the macOS mic-permission dialog once — click Allow); pass audioSource to skip the device. Returns the path of the created container COMP (named `name` under `parent`); its `out` Null CHOP carries the energy, state, build_edge, drop_edge, and breakdown_edge channels for downstream binding. |
create_phone_gesture |
no_return_description |
Stream a phone's IMU (tilt + gyro + shake) and multitouch into TouchDesigner as CHOP channels you can bind to anything. Builds a Web Server DAT page the phone opens (any browser, no app) and a Null CHOP exposing tilt_x/y/z, gyro_x/y/z, shake, touch0..3_x/y/active, clients. Composable with create_phone_remote on the same COMP (different port). SECURITY: listens on all interfaces with no auth — trusted networks only. iOS Safari needs HTTPS for motion permission; falls back to touch-only on plain HTTP. Returns the path of the created container COMP (default 'phone_gesture' under `parent`), which hosts the Web Server DAT served on TCP `port` that the phone opens, and the binding-ready Null CHOP with the gesture + client channels. |
moodboard_to_system |
no_return_description |
Ingest 1..6 moodboard images and build a matching generative system in TouchDesigner. Uses the vision-capable local LLM when configured to extract palette + motion + generator pick (palette hint, generator from {audio_reactive, generative_art, particle_flock, feedback_tunnel, gpu_particle_field}, optional post-FX). Falls back to a deterministic style→generator grammar otherwise. Note: preview may read 0 on a paused timeline — press Play. Returns the path of the built generative system container in `parent_path`, the generator (and style) actually resolved from the LLM or the fallback grammar, and an inline preview of the result. |
setup_tdableton |
no_return_description |
Wire up an Ableton Live bridge inside a tdmcp-managed container. Auto mode probes for the official TDAbleton Palette COMP; if found, clones it and surfaces tempo/beat/track/device channels as binding-ready Null CHOPs. Falls back to a full OSC fabric (oscinCHOP + selectCHOP fan-out) if the Palette isn't available. Either branch exposes the same Null CHOP names at the container boundary so downstream bind_to_channel calls work regardless of which path was taken. Returns the created container path (named `name` under `parent_path`), the bridge mode actually used ('palette' or 'osc'), and the Null CHOP channel names exposed at the container boundary for bind_to_channel. |
create_chop_recorder |
no_return_description |
Build a CHOP recorder/player container that captures a source CHOP's channels over a fixed window using a Trail CHOP, snapshots the trail into a Table DAT on Stop, and plays the take back via a Datto CHOP indexed by a Timer CHOP–driven Lookup CHOP, terminating on a Null CHOP ready for bind_to_channel. Re-entrant: re-running with the same name updates controls without rebuilding. The last take is persisted in comp.store so it survives a .toe reload. Large takes (nchan × samples > 250k) are saved to disk instead of stored in the .toe. Note: time-dependent playback reads 0 when the TD timeline is paused — that is expected behavior. Returns the created container path (named `name` in `parent`) and its Null CHOP output carrying the captured, replayed take (persisted under `takeName`). |
import_shadertoy |
params_unexplained no_return_description |
Build a GLSL TOP from a Shadertoy URL, ID, or pasted source — supply exactly one of `url`, `shader_id`, or `raw_source`. Wires iChannels (defaulting to noise placeholders): `channels` maps each iChannel `index` to a source (an existing TOP path, or a generated noise/ramp/constant texture) with optional filter/extend settings. Creates a container named `name` under `parent_path` holding a GLSL TOP at `resolution` [width,height] with `pixel_format` (rgba8/16/32). Exposes a Speed control (and optional Mouse via `expose_mouse_control`); `expose_speed_control` toggles the Speed parameter and `capture_preview` saves a preview thumbnail. `provenance_override` replaces the recorded title/author/license/url metadata. First fetch on macOS may trigger an outgoing-connection permission prompt. Set TDMCP_SHADERTOY_KEY for reliable fetches; paste into raw_source to stay offline. Returns the created container path, the wired channel list, and the captured preview (when enabled). |
import_isf_shader |
params_unexplained no_return_description |
Import an ISF (.fs) shader into TouchDesigner as a GLSL TOP with auto-generated controls. Accepts raw source, a local file path, or an http(s) URL via `source` (with `source_kind` overriding the source sniffer; 'raw' skips IO). Creates a container named `name` under `parent_path` holding a GLSL TOP at `resolution` [width,height] and `pixel_format` (rgba8/16/32). `channel_overrides` substitute real TOP paths for the default placeholder noise on ISF image/audio inputs; `control_defaults` override any ISF DEFAULT value at build time. `expose_controls` auto-generates the container control panel for ISF inputs, `capture_preview` saves a preview thumbnail, and `fetch_timeout_ms` bounds the time spent fetching a URL source. Returns the created container path and the list of auto-generated controls. |
create_chrome_blobs |
no_return_description |
Builds a liquid-chrome / Y2K metaball generator: an animated Noise TOP (or external source) is blurred, thresholded into soft blobs, then a GLSL TOP renders a procedural environment-map chrome look (greyscale ramp + moving specular highlight) with 5 metal tints and 4 background modes. Yields a self-contained baseCOMP under parent_path containing the rendered chrome-blobs output TOP, with Speed, Blob_Count, Metal_Color, and Background controls exposed on the container. |
create_voxel_stack |
no_return_description |
Isometric voxel-stack renderer driven by any TOP. Builds a single instanced Geometry COMP (boxSOP, N=cols·rows instances up to 256×256) with a CHOP chain sampling luminance for column height and per-instance color. Color modes: source_color (sample TOP directly), palette (Monument-Valley pastel ramp), height_ramp (same palette, height-based). Isometric ortho cam (rx=-35.264°, ry=45°) by default; perspective available. Yields the voxel-stack renderTOP output inside a new container under parent_path at output_resolution, with HeightScale, VoxelSize, and RotateY controls exposed on the container. If source_top_path is omitted, an animated noiseTOP drives the stack. |
apply_glsl_top_mapping |
no_return_description |
Build a self-contained GLSL TOP network from a pre-translated mapping (fragment + uniforms + channels + controls). Foundation primitive used by Shadertoy and ISF importers; also reachable directly for power users with a hand-translated fragment. Creates a container COMP under parent_path (named by `name`), optionally exposes the mapping's controls, and captures a preview when capture_preview is true. Returns a summary plus a JSON block with the created container path, node paths, exposed controls, node errors, warnings, and an inline preview image. |
browse_library |
params_unexplained |
Browse built-in/vault recipes and optional local component packages, filtered by an optional text `query` and/or `tags`; pass `package_dir` to also scan a local package directory, and set `include_recipes` / `include_packages` to control whether recipes, packages, or both are returned. Read-only discovery step before instantiating a recipe (apply_recipe) or installing a package (install_library_package); returns the matching recipes and packages so an agent can pick one by name. |
inspect_component_manifest |
params_unexplained no_return_description |
Read and validate a tdmcp component/library manifest from the package folder or file at `path`. Read-only: use it to check a package's metadata, declared assets, and docs before install_library_package or make_portable_tox. Returns the parsed manifest (metadata, declared assets, docs) plus any validation problems and warnings, reported instead of throwing. |
export_recipe_bundle |
params_unexplained |
Write selected recipes to a portable JSON bundle on disk at `out_file`: pass `recipe_ids` to pick specific recipes, or set `include_all` true to export the whole library. Use it to hand recipes to another machine or to CI; re-import the bundle with import_recipe_bundle, or produce a signed/versioned artifact with publish_recipe_bundle. Writes a file (destructive). Returns the written bundle path plus counts of exported and missing recipe ids. |
import_recipe_bundle |
params_unexplained no_return_description |
Import recipes from the portable JSON bundle at `bundle_file` into the recipe directory `out_dir`, replacing existing recipe files only when `overwrite` is true. The inverse of export_recipe_bundle: each recipe is validated before it is written, so a malformed bundle fails loudly instead of corrupting the directory. Writes files (destructive). Returns the number of recipes imported, the paths written, and any validation failures. |
validate_library_asset |
params_unexplained |
Check that the local library asset at `path` exists on disk and is referenced by the optional manifest at `manifest_path`. Read-only pre-flight for packaging: catches missing or unreferenced files before make_portable_tox / install_library_package and returns the specific problem rather than failing later. |
scaffold_recipe_template |
params_unexplained no_return_description |
Write a minimal but valid recipe JSON template to disk at `out_file`, carrying the given `id` and `name`, and replacing an existing file only when `overwrite` is true. Use it to bootstrap a hand-authored recipe that already passes RecipeSchema; fill in nodes/connections, then instantiate with apply_recipe. Writes a file (destructive). Returns the path of the written template. |
attach_docs_as_assets |
params_unexplained no_return_description |
Copy the files in `docs` into a package and register them in the manifest at `manifest_path`'s docs list, placing them under the `asset_dir` subfolder (default 'docs'). Use after make_portable_tox to bundle a README or usage notes with a component so they travel with it; writes into the package folder (destructive). Returns the updated manifest path and the list of registered doc paths. |
local_marketplace_index |
params_unexplained no_return_description |
Scan the local package directory `package_dir` and write an index of installable tdmcp packages to `out_file`. Use it to make a folder of components browsable and installable as a simple local marketplace; the written index is what browse_library and install_library_package consume. Writes a file (destructive). Returns the index file path and the number of packages indexed. |
component_link_health |
params_unexplained no_return_description |
Probe live COMPs in the running project for externaltox paths and report missing or broken linked component files. When `paths` is empty the root `parent_path` COMP is searched. Read-only diagnostic: run it when externally-linked .tox components may have moved or gone stale, before relying on them in a build. Returns per-probed-node link status (ok / missing / broken), the referenced externaltox paths, and warnings. |
import_recipe_from_url |
no_return_description |
Fetch, validate, and import a recipe or recipe-bundle JSON from the HTTPS `url` into the local recipes directory `out_dir`, overwriting existing recipe files when `overwrite` is true and capping the download at `max_bytes` (default 1 MiB, hard cap 10 MiB). Returns a summary listing the imported recipe files and any that were skipped or rejected. |
export_palette_component |
no_return_description |
Save the COMP at `comp_path` as a .tox into TouchDesigner's native Palette folder so it appears in the Palette browser for drag-and-drop reuse. The file stem comes from `name` (defaults to the COMP basename), it is grouped under the `category` subfolder (default 'tdmcp'), and `palette_dir`, when non-empty, explicitly resolves the palette folder instead of TouchDesigner's user palette. Returns the absolute path of the saved .tox. |
provenance_stamp |
no_return_description |
Write a `.provenance.json` sidecar next to the saved artifact at `artifact_path`, recording the sha256 checksum, file size, mtime, source COMP path, originating tdmcp tool, toolchain versions, best-effort git metadata, author, tags, and notes; set `overwrite` false to refuse replacing an existing sidecar. Offline — no TD bridge required. Returns the sidecar path and the recorded provenance entries. |
checksum_and_verify_pack |
params_unexplained no_return_description |
Compute or verify SHA-256 checksums for tdmcp artifacts (.tox, .recipe.json, bundles). `action`='compute' walks `path` and writes a tdmcp-checksums.json manifest to `manifest_out`, restricted by `include_globs`, `exclude_globs`, `follow_symlinks`, and `max_file_bytes`; `action`='verify' re-hashes files against the supplied `manifest` and reports ok/mismatch/missing/extra per file, failing where `strict` is true. No TD bridge required. Returns the manifest path and per-file status results, plus any warnings. |
curated_collection_pack |
params_unexplained no_return_description |
Bundle a curated, hand-picked set of vault assets (recipes, components, looks, raw assets) into a single portable, shareable pack with provenance and integrity. `action`='pack' gathers the `items` into a `<name>.pack/` tree under `out_dir` with a JSON manifest and checksum manifest; `action`='unpack' restores that tree (reading `pack_path`, resolving relative item paths against `vault_path`, copying `.provenance.json` sidecars when `include_provenance` is true, and re-verifying checksums when `verify_on_unpack` is true). Fully offline — no TD bridge required. Returns the pack directory path, created artifact paths, checksum entries, and warnings. |
component_changelog_trail |
no_return_description |
Maintains an append-only per-component revision history as a JSONL trail (`<component>.trail.jsonl`) inside the Obsidian vault, next to the .tox and its provenance sidecar. Three actions: append a new revision entry (with optional sha256 of the .tox, changed-param list, author, and timestamp); read all entries back as JSON; export the trail as a human-readable markdown changelog note rendered into the vault. Returns the stored entry (append), the full JSON array of entries (read), or the vault path of the rendered markdown note (export). Offline — no TD bridge required. Pairs with save_component_to_vault and provenance_stamp. |
save_component_to_vault |
no_return_description |
Save a live TouchDesigner COMP as a reusable .tox component file inside the Obsidian vault (at <folder>/<name>.tox) and write a companion markdown note with frontmatter, a description, and load instructions — completing the build→parameterize→script→package-to-library loop. The saved .tox can later be loaded back with manage_component (load action). Requires a configured TDMCP_VAULT_PATH. The target COMP must exist and be a COMP (not a non-COMP operator). Returns the saved .tox path, the companion note path, and whether a thumbnail image was captured. |
capture_to_vault |
no_return_description |
Captures a preview still from a TOP and appends it to a dated gallery note in the Obsidian vault, building a visual look-book over time. Each call writes the PNG image under <gallery>/images/ and appends a new section to <gallery>/<note>.md (defaulting to today's date so all daily captures land in one note). Use this to document looks, reference frames, or build a browsable gallery of your session's visuals. Requires a configured TDMCP_VAULT_PATH. Returns the saved PNG path and the gallery note path to which the capture section was appended. |
export_setlist_to_vault |
no_return_description |
Serialize the current cues stored on a COMP (manage_cue snapshots, keyed 'tdmcp_cues') into a setlist note in the Obsidian vault, so a live-built show can be round-tripped into the vault library as a git-diffable setlist. The note frontmatter `tracks` array matches what import_setlist expects — each cue becomes a track with its title and optional bpm, ready for a recipe id to be added by hand. Re-import the note later with import_setlist to rebuild the visuals. Requires a configured TDMCP_VAULT_PATH. Returns the written setlist note path and the count of cues/tracks serialized. |
generate_library_index |
no_return_description |
Write one Markdown contact-sheet note of the whole vault library — recipes, shaders, presets, components, and setlists — as a grid of cards, each with its thumbnail (the <stem>.png sibling written by save_recipe_to_vault / save_component_to_vault), title, tags, and a copy-paste load snippet (e.g. `apply_recipe id=…`). No TouchDesigner connection required: it reads the local vault on disk and writes the index note. Filter by category (kinds) and/or a substring query. Requires a configured TDMCP_VAULT_PATH. Returns the written note path and the per-category counts of items indexed. |
auto_tag_library_asset |
no_return_description |
Inspect a captured library asset (a vault recipe/component note, or a live TD COMP) and return a suggested tag set, difficulty, and one-line description from a deterministic operator-family heuristic; with write:true, merge the suggestion into the note's frontmatter (preserving '*'-pinned user tags) and return the resulting suggestion. Use this to backfill consistent tags across a library so browse_vault_library can find by category. Requires a configured TDMCP_VAULT_PATH; target='td_comp' additionally requires the bridge. |
morph_pack |
no_return_description |
Export an existing create_preset_morph container's slots ('looks') to a portable, sha256-verified JSON file in the Obsidian vault (action=pack), or re-hydrate a pack file back into a (newly built if missing) create_preset_morph container (action=unpack). Reuses the create_preset_morph engine — does not invent a new morph topology. Requires TDMCP_VAULT_PATH unless inline 'looks' are supplied on unpack. Returns the written pack file path and the number of slots serialized (pack), or the rebuilt container path and the hydrated slot ids (unpack). |
merge_vaults |
params_unexplained no_return_description |
Merge the contents of a source Obsidian vault into a target vault (defaulting to TDMCP_VAULT_PATH). Walks Recipes/, Shaders/, Presets/, Components/, Setlists/, and Memory/ folders. sha256-hashes each file pair and resolves conflicts with your chosen strategy: 'theirs' overwrites target, 'ours' keeps target, 'rename' writes a side-by-side copy, 'skip' logs and skips. kinds filters which folder categories participate in the merge ('all' includes every category). dryRun=true plans the merge and reports what would change without writing any files. Note: LF/CRLF differences count as conflicts. Returns per-file merge results (source path, action taken, final target path) and per-strategy totals. |
vault_repo_sync |
no_return_description |
Read-mostly git wrapper for the configured Obsidian vault directory. Lets an artist see what's changed (status), fetch/fast-forward-only pull, push, or read recent history (log). Never auto-resolves conflicts. Never uses --force. Never invokes a shell. Conflicts are surfaced as structured data for manual resolution. Requires TDMCP_VAULT_PATH or the vault_path argument. Returns structured results: status and log return the changed-file/commit data, while pull and push return the outcome with any conflicts or rejections reported as structured data. |
variant_pack |
no_return_description |
Generate N perturbed variants around an anchor parameter look and write the whole pack to the Obsidian vault as a morph_pack-compatible JSON. Probes the target COMP's customPars for slider ranges to clamp + integer-round per param, then perturbs each variant uniformly within ±delta_range × (normMax − normMin). The resulting file is consumed directly by morph_pack (action=unpack). Requires TDMCP_VAULT_PATH. Returns the written pack file path, the generated variant slot ids, and the per-parameter clamp/perturbation ranges used. |
learn_from_my_corpus |
no_return_description |
Offline companion to `learn_conventions`: walks the Obsidian vault corpus (Recipes/, Components/, Looks/, Setlists/, Moodboards/) and distils palette, naming, recipe-shape, and param-default preferences into Memory/corpus_style.md (and optionally merges palettes/naming/favorite_generators into Memory/style.md). Returns the extracted findings for the requested `observe` families as structured content; with dry_run=false it also writes the distilled notes to the vault. No TouchDesigner required — pure filesystem read. Requires TDMCP_VAULT_PATH (or pass `vault_path`). |
version_library_asset |
no_return_description |
Apply a SemVer patch/minor/major bump to a vault recipe or component note, recording the change in a sidecar `<asset>.versions.json` (asset_path + current + history list with version/bump/note/timestamp) and writing the new version into the note's frontmatter `version` field. Returns the asset_path, the current version, and the full version history — after applying the bump, or unchanged when read_only=true. Pass `read_only:true` to inspect the sidecar without bumping. Pure vault I/O — no TouchDesigner bridge required. Requires TDMCP_VAULT_PATH. |
export_look_tox |
no_return_description |
Save a COMP as a `.tox` inside `<vault>/<folder>/<slug>.tox` and write a sibling Markdown note (id/type=look + name + tags + assets + created + source_path). Defaults `folder` to `Looks`. The artist-publishing primitive for portable looks; integrates with `browse_vault_library` and `tag_and_search_library` via the note frontmatter. Returns the vault paths of the exported .tox and the sibling note it wrote. Requires TDMCP_VAULT_PATH and a running TouchDesigner bridge. |
tutorial_companion_pack |
params_unexplained |
Build a teaching/selling companion for a network: snapshot the COMP's topology, capture preview PNGs of its output TOPs, scaffold an N-step lesson plan in Markdown, and emit a documentary network snapshot. Writes into `<vault>/<folder>/<slug>/` as `tutorial.md` + `topology.json` + `network_snapshot.json` + `previews/*.png`. `preview_width` and `preview_height` set the pixel dimensions of the captured preview PNGs. The snapshot captures nodes + connections by TD path for reference only — it is not a `RecipeSchema`-compatible installable recipe. Composes existing read-only bridge calls — the artist edits the lesson body afterwards. Requires TDMCP_VAULT_PATH and a running TouchDesigner bridge. |
macro_recorder |
params_unexplained no_return_description |
Record the sequence of MCP tool calls to a portable JSON macro file, then list or load it back for replay. `action` selects the operation: 'start' begins recording, 'stop' ends it and persists the macro, 'list' enumerates saved macro files, 'load' reads a macro file. `name` is the macro name to save/list under, `file` is an explicit path to the macro JSON file, and `redactSensitive` controls whether sensitive argument values are scrubbed from the recorded calls (setting it to false requires `allowUnsafeRecording` since raw scripts/secrets may be persisted). Writes or reads the macro JSON file and returns the recording status plus the macro file path. Replay ships separately as `run_macro_script`. |
run_macro_script |
params_unexplained no_return_description |
Replay a `MacroRecord` JSON file by dispatching each entry through the in-process tool handlers. `macroPath` is the path to the macro JSON file to replay. Use `dryRun` to plan without invoking, `stopOnError` to halt on first failure, `argsOverrides` to shallow-merge per-tool arg replacements, and `allowRawPython` to opt-in to raw-Python entries (still subject to the server-side ctx gate). Returns the dispatch result for each replayed entry (or the plan when dryRun=true) plus any errors encountered. Redacted args from a recording may fail at the tool boundary; do not un-redact. |
Selection evidence
Confusable tool pairs.
21 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.
| Tool A | Tool B | Confidence | Why they collide |
|---|---|---|---|
create_audio_reactive |
create_3d_audio_reactive |
medium | Both build audio-reactive visuals and cross-reference each other in their descriptions; a task like 'build something that reacts to the music' (2D vs 3D unspecified) can plausibly pick either. |
create_interactive_projection_mapping |
create_projection_mapping |
medium | A request to 'set up projection mapping' or 'warp my projection' maps to both names; only 'interactive' distinguishes them, and the base tool's corner-pin scope is easy to choose first for an ambiguous task. |
create_particle_system |
create_pop_particle_system |
medium | Near-identical names and descriptions that point at each other; 'create a particle system' (or 'get particle sim going') has no unique cue, so an agent may pick the CPU or POP-variant arbitrarily. |
create_pop_field |
create_depth_pop_field |
medium | Both build POP point fields with very similar schemas; a depth/mask source is a single optional parameter, so 'create a pop field (of points)' is ambiguous as to whether depth drives it. |
get_td_nodes |
get_td_node_errors |
medium | Shared get_td_node* prefix; a diagnostic task like 'check my network for problems' could select the generic node-listing tool instead of the error reader when only names are weighed. |
get_td_nodes |
get_td_node_flags |
medium | Both sound like generic node inspection; 'find why my node shows nothing' plausibly picks the generic lister (get_td_nodes) over the flags/health scanner the task actually needs. |
get_td_nodes |
get_td_node_parameters |
medium | All are get_td_node* readers; an agent reasoning by name alone for 'inspect this node' may grab the listing tool rather than the parameter reader the task implies. |
browse_library |
browse_vault_library |
high | Names differ only by 'vault' and both descriptions cover recipes/components; 'browse the library for a recipe' is genuinely ambiguous and either tool would seem to satisfy it. |
get_inline_preview |
get_preview |
high | Both are one-shot TOP preview tools whose descriptions overlap; a vague 'show me the output' has no cue for thumbnail-vs-delivery frame, so either can be plausibly selected. |
manage_component_storage |
manage_component |
medium | Both start 'manage_component*'; 'manage this component' could mean its .storage dict OR saving/loading it as a .tox, so a bare management request is ambiguous. |
create_data_source |
create_data_source_http_ws |
medium | Descriptions present one as the 'simple sibling' of the other; 'ingest live data' maps to both when no transport is named, since the ws variant is just the fuller-featured version. |
get_td_node_errors |
get_td_node_flags |
medium | Both diagnose a node/network and share the get_td_node* prefix; 'what's wrong with this node' could route to either the error reader or the flag/health scanner. |
get_td_node_parameters |
get_td_node_errors |
medium | Same get_td_node* family; 'debug this node' or 'read this node' is ambiguous between reading its parameters and checking its errors when only names are considered. |
get_td_node_parameters |
get_td_node_flags |
medium | Both are per-node readers under the same prefix; 'inspect this node to see its state' plausibly selects either the parameter dump or the flags scan. |
update_td_node_parameters |
get_td_node_parameters |
medium | Identical parameter-related phrasing; 'set/read this node's parameters' can go to the wrong member when the direction (write vs read) is implied rather than explicit. |
create_3d_scene |
create_pbr_scene |
medium | The simple vs PBR distinction is one shading-choice deep in the descriptions; 'create a 3D scene with a metallic/glossy look' can plausibly land on the basic scene tool. |
create_data_reactive |
create_data_visualization |
medium | Both are 'data' creators producing reactive/binding outputs; 'make a data-reactive visual' is ambiguous between building the chart visual and binding data onto a COMP's knobs. |
create_depth_displacement |
create_depth_from_2d |
medium | Both are depth-creation tools with similar schemas; 'create depth (relief) from my picture' could pick the 2D-to-depth map converter or the displacement generator. |
create_blob_reactive |
create_chrome_blobs |
medium | Name similarity ('blob') plus both answering 'make a blobs visual' — blob-tracking reactivity vs the chrome metaball look — makes a generic blob request genuinely ambiguous. |
create_cue_sequencer |
create_prob_sequencer |
medium | Both are beat-sequencer builders with nearly identical schema shape; 'build a step sequencer for my show' has no cue for cue-timeline vs Markov-probabilistic without reading details. |
setup_face_tracking |
setup_hand_tracking |
medium | Both are MediaPipe webcam setup tools with the same input shape and overlapping descriptions; 'set up webcam landmark tracking' with body part unspecified can plausibly select either. |
Compare the field