| name | mcp-tools-reference |
| description | MUST READ before first MCP tool call in a session. Complete Envoy tool catalog with parameters and usage. |
Envoy MCP Tool Reference
Mutating TD-authoring operations are wrapped in TD undo blocks (one batch_operations call = one Ctrl+Z step); read-only tools, run_tests, cook_op, and disk-only ops (export_network, save_externalization) are not.
Operator Management
| Tool | Parameters | Description |
|---|
create_op | parent_path, op_type, name? | Create a new operator (e.g., baseCOMP, noiseTOP, textDAT, gridPOP). Auto-positions it and hugs any docked companions below it (docks_placed) |
create_extension | parent_path, class_name, name?, code?, promote?, ext_name?, ext_index?, existing_comp? | Create a TD extension: baseCOMP + text DAT + extension wiring |
delete_op | op_path | Delete an operator |
copy_op | source_path, dest_parent, new_name? | Copy operator to new location. Auto-positions the copy and hugs its docked companions (docks_placed) |
rename_op | op_path, new_name | Rename an operator |
get_op | op_path, include_defaults? | Returns NON-DEFAULT parameters by default (include_defaults=True for all); parameter-heavy COMPs are expensive (~3k+ tokens full) -- prefer read_tdn for structure reads |
query_network | parent_path?, recursive?, op_type?, include_utility? | Compact operator list: path/type/family/depth; name = last path segment. Set include_utility=True to include annotations |
find_children | op_path, name?, type?, depth?, tags?, text?, comment?, include_utility? | Advanced search using TD's findChildren |
cook_op | op_path, force?, recurse? | Force-cook an operator |
Parameter Control
| Tool | Parameters | Description |
|---|
set_parameter | op_path, par_name, value?, mode?, expr?, bind_expr? | Set value, expression, bind expression, or mode; rejects invalid Menu values with valid menuNames; sequence-block names auto-grow (const5name -> 6 blocks) |
get_parameter | op_path, par_name?, search?, search_in?, depth?, max_results?, details? | Single-parameter mode is compact by default (path, parameter, value, mode, label, mode-specific refs, menuNames); details=True restores default/style/range/menuLabels/menuIndex. Search ignores details |
DAT Content
| Tool | Parameters | Description |
|---|
get_dat_content | op_path, format? | Get DAT text or table data ("text", "table", "auto") |
set_dat_content | op_path, text?, rows?, clear?, confirm_wipe? | Full-replace DAT content. Refuses no-action calls and wipes (text="", rows=[], or clear=True with no content) unless confirm_wipe=True. For partial text edits prefer edit_dat_content; use this for tables, full rewrites, or intentional wipes. |
edit_dat_content | op_path, old_string, new_string, replace_all?, confirm_wipe? | Surgical text edit on a text DAT. old_string must appear exactly once by default; widen with context or pass replace_all=True. Refuses empty/identical strings and wipes unless confirm_wipe=True; not-found errors include diagnostics. Tables go through set_dat_content(rows=...). |
Operator Flags
| Tool | Parameters | Description |
|---|
get_op_flags | op_path | Get all flags |
set_op_flags | op_path, bypass?, lock?, display?, render?, viewer?, current?, expose?, allowCooking?, selected? | Set one or more flags |
Operator Positioning & Layout
| Tool | Parameters | Description |
|---|
get_op_position | op_path | Get position, size, color, and comment |
get_network_layout | comp_path, include_annotations? | Compact layout for all children in a COMP: path/type/nodeX/nodeY/nodeWidth/nodeHeight plus bounding_box; docked ops carry dockedTo (host name). Centers are nodeX+nodeWidth/2; annotation text is capped at 160 chars. Use instead of repeated get_op_position calls |
set_op_position | op_path, x?, y?, width?, height?, color?, comment? | Set position, size, color ([r,g,b] 0-1), or comment. Moving a host re-hugs its docked companions below the new spot (docks_moved); position the host before any explicitly-placed dock |
layout_children | op_path | Auto-layout all children in a COMP |
Annotations
| Tool | Parameters | Description |
|---|
create_annotation | parent_path, mode?, text?, title?, x?, y?, width?, height?, color?, opacity?, name? | Create annotation ("annotate", "comment", "networkbox") |
get_annotations | parent_path | List all annotations with properties and enclosed operators |
set_annotation | op_path, text?, title?, color?, opacity?, width?, height?, x?, y? | Modify annotation properties |
get_enclosed_ops | op_path | Get ops enclosed by annotation, or annotations enclosing an op |
Performance Monitoring
| Tool | Parameters | Description |
|---|
get_op_performance | op_path, include_children? | Get CPU/GPU cook times, memory, cook counts |
get_project_performance | include_hotspots? | Get project-level FPS, frame time, GPU/CPU memory, dropped frames, active ops, GPU temp. Optional hotspot ranking of top N COMPs by cook time |
Connections
| Tool | Parameters | Description |
|---|
connect_ops | source_path, dest_path, source_index?, dest_index?, comp? | Wire two operators. comp=True for COMP connectors |
disconnect_op | op_path, input_index?, comp? | Disconnect an input |
get_connections | op_path | Get all input/output connections |
Code Execution
| Tool | Parameters | Description |
|---|
execute_python | code | Execute Python in TD. Set result variable to return values |
Introspection & Diagnostics
| Tool | Parameters | Description |
|---|
get_td_info | (none) | TD version, build, OS, Envoy version |
get_op_errors | op_path, recurse? | Get error and warning messages for op and children |
exec_op_method | op_path, method, args?, kwargs? | Call a method on an operator |
get_td_classes | (none) | List all Python classes in td module |
get_td_class_details | class_name | Get methods, properties, docs for a TD class |
get_module_help | module_name | Python help text for a module |
get_docs | query, section?, source?, max_chars? | Look up official TD docs; offline mirror preferred, docs.derivative.ca fallback; normal responses return title, source, sections_available, content; ambiguous offline lookups return matches instead of a page |
get_guidance | topic? | Read THIS project's checked-in TouchDesigner doctrine (.claude/rules/*.md, .claude/skills/*/SKILL.md). Bare call lists topics; topic returns one document. Matching ignores case/punctuation. Answered worker-side (no TD round-trip). Complements get_docs: get_docs is official Derivative documentation, get_guidance is how this project wants the work done -- and it is the ONLY way non-Claude-Code clients (Codex, Cursor, opencode) see these rules |
get_focus | (none) | What the user is looking at: network (current pane), , , , plus / and a . Call it to resolve "this operator" / "fix this" before guessing a path. DISAMBIGUATION: "this" means the SELECTED/current op, NEVER the rollover (rollover is incidental mouse position). Headless TD returns with nulls |
MCP Prompts
| Prompt | Parameters | Description |
|---|
search_op | op_name, op_type? | Guide for searching operators |
check_op_errors | op_path | Guide for inspecting/resolving errors and warnings |
connect_ops | (none) | Guide for wiring operators |
create_extension_guide | (none) | Guide for creating extensions |
Embody Integration
| Tool | Parameters | Description |
|---|
externalize_op | op_path, tag_type? | Tag and externalize operator to disk (one step) |
remove_externalization_tag | op_path, delete_file? | Remove externalization tracking (tag + row + TDN breadcrumb); delete_file=True also deletes the file (best-effort). Returns removed_tags, removed_rows, removed_anything, summary -- an operator can have a tracked row but NO tag, so check removed_anything, not removed_tags, to confirm cleanup |
get_externalizations | (none) | List all externalized operators |
save_externalization | op_path | Force re-export an already-externalized operator |
get_externalization_status | op_path | Get dirty state, build, timestamp, path |
TDN Network Format
| Tool | Parameters | Description |
|---|
read_tdn | comp_path?, include_dat_content?, max_depth?, embed_all? | Preferred for reading ≥3 operators. Returns live network as a TDN dict. ~20-90x fewer tokens than get_op+query_network walks thanks to default-omission, type_defaults, and par_templates. |
export_network | root_path?, include_dat_content?, output_file?, max_depth? | Write .tdn to disk. With output_file set, returns a compact summary (op/annotation counts + file path), NOT the full document -- Read the file for details. Without output_file, returns the full dict like read_tdn. |
import_network | target_path, tdn, clear_first? | Recreate network from a parsed TDN document (on-disk .tdn is YAML in v2.0; reads legacy JSON) |
diff_tdn | target?, max_changed_ops?, max_bytes? | What's UNSAVED in TDN networks (live vs on-disk .tdn) -- the view git can't give. Omit target -> whole project (every live TDN COMP, summarized); target = a COMP path OR a .tdn file path/bare filename -> that one COMP in full detail (old=disk, new=live). For committed/history diffs use plain git diff (Embody's .tdn diff driver keeps those clean). Read-only. |
When to prefer read_tdn: exploring or auditing ≥3 operators, checking structure and parameters-as-authored, mapping connections, reading annotations. Scope cost with comp_path; cap with max_depth on large roots.
When NOT to use read_tdn: evaluated-expression runtime values (get_parameter), cook errors (get_op_errors), DAT/CHOP/TOP output data (get_dat_content, capture_top), cook timing (get_op_performance), flag state after runtime mutation (get_op_flags). read_tdn is an authored-state snapshot, not a runtime probe.
When to use diff_tdn: whenever the user asks "what's changed / unsaved?" for TDN networks. It shows what is UNSAVED -- the live in-memory network vs the on-disk .tdn -- which git cannot see (git only reads disk, never TD's live state). Omit target (or pass ""/"project") for a whole-project summary (every live TDN COMP: which changed + counts); pass a target (a COMP path OR a .tdn file path/bare filename, resolved to its COMP) for one COMP in full detail (old=disk, new=live). For committed/history diffs use plain git diff -- Embody installs a .tdn git diff driver so those are clean (the volatile export header is stripped). Read-only, non-interactive. Requires TD running.
TOP Capture
| Tool | Parameters | Description |
|---|
capture_top | op_path, format?, quality?, max_resolution?, inline?, sample_grid? | Capture a TOP output. Returns a temp file path by default; inline=True embeds a small preview. sample_grid>=2 returns numeric NxN RGBA cells + channel stats instead of an image, clamped 2..32 with origin at top-left. The returned text carries a Quality verdict from the raw pixels (luminance + alpha stats): a Quality: FAIL flags a black / flat / fully-transparent frame so you can tell an empty render from a real one WITHOUT reading the image. Never declare a visual task done on a FAIL. |
For visual work, success is verified by capturing and judging the output TOP, not by a clean network alone; see /visual-aesthetics.
Logging
| Tool | Parameters | Description |
|---|
get_logs | level?, count?, since_id?, source? | Get recent log entries from ring buffer |
Auto-piggybacked logs: A _logs field rides along only when a WARNING or ERROR was logged during the call (capped at ~8) -- routine INFO/DEBUG/SUCCESS history is omitted to keep responses token-lean. Warning cursors are per session (from the bridge's identity headers), so concurrent sessions each receive their own copy of a warning -- one session polling first no longer consumes it for the others.
Auto-piggybacked peer advisories: a _peers field rides along when your request touches territory another session modified recently (last ~10 min) -- one entry per peer: {label, scope, tool, age_s, conflict}. conflict: true means a peer WROTE an overlapping scope within the last minute AND your operation is also a write -- treat it as a hard stop: check get_sessions, coordinate (or divide work by COMP subtree), and only then proceed. Non-conflict advisories are informational and deduped per (peer, scope) for ~5 min; conflicts always ride.
Destructive-op gate: delete_op, import_network with clear_first=True, run_tests, and batches containing them are REFUSED (MULTI-SESSION GATE error naming the holder/peer) while a live peer session claims the scope or wrote it within the last minute. Pass override=True only when certain, and say so. Call get_logs for the full history, or read the log files in Embody's logs directory (see the Logfolder parameter on the Embody COMP).
Auto-attached recovery hints: when a tool returns an error, a recovery_hints list may ride along -- each entry is {cause, action, next_tools} keyed off the error message (path-not-found, wrong family, empty capture, thread conflict, timeout, ...). It tells you the likely cause and which tool to call next, so recover by following it rather than retrying the same failing call verbatim.
Testing
| Tool | Parameters | Description |
|---|
run_tests | suite_name?, test_name?, override?, background? | Run Embody unit-test suites (all, one suite, or one test; 300s timeout). Destructive and agent tiers are excluded -- they run only via their dedicated entry points. Gated by the multi-session destructive-op gate; override bypasses it (say so when you do). background=True (recommended for full runs) returns a job id immediately -- poll get_job_status; the synchronous mode is severed by the watchdog suites' server restart |
get_job_status | job_id? | Status of background jobs (run_tests background=True, save_project). Disk-backed (.embody/jobs/), so results survive server restarts and extension reinits; omit job_id to list recent jobs. Finished run_tests jobs carry the summary + failing tests |
save_project | (none) | Save the project as a tracked job: returns a job id immediately, the save runs a few frames later (a synchronous call is severed by the save's own main-thread block + extension reinit). Finished record carries version_before/version_after |
Bridge Meta-Tools
These run locally on the STDIO bridge — they work even when TD is not running.
| Tool | Parameters | Description |
|---|
get_td_status | (none) | Check if TD is running, Envoy reachable, crash detection, process liveness. Includes instance registry and live bridge sessions (from heartbeat files -- works even with TD down) |
launch_td | timeout? | Launch TD with the project's .toe file, wait for Envoy (default: 120s) |
restart_td | timeout? | Gracefully quit TD and relaunch, wait for Envoy (default: 120s) |
switch_instance | instance?, all_sessions? | List all registered TD instances (omit instance) or re-pin THIS session's bridge to a different running instance (provide toe basename without .toe); peers are untouched unless all_sessions=true (writes the registry default and bumps active_epoch, moving every session). See /multi-instance skill for workflow |
Convoy Tools (LAN work relay)
Sixteen additional meta-tools drive Convoy, relaying work to Convoy-enabled Embody nodes on the trusted LAN through the local per-user host app. Status and inventory calls (get_convoy_status, convoy_list_nodes, convoy_list_controllers, convoy_ping) never wake TouchDesigner.
convoy_select_node pins THIS session to one exact node -- ordinary Envoy tools then run there until convoy_select_node with clear=true.
convoy_call / convoy_batch run registered operations on explicit one-off targets; pass a unique idempotency_key per intended action so a retry reconciles instead of double-running.
convoy_get_job / convoy_ack_job / convoy_cancel_job reconcile durable deliveries; acknowledge a finished delivery you have safely observed so the target can release its protected result artifacts.
convoy_forget_node deletes a stale node row on THIS machine's host app (a renamed, moved, or deleted project's leftover). It refuses only while the node has a delivery that has not FINISHED, and names the blocking delivery ids in its refusal (a finished-but-unacknowledged result never holds a row -- results are fetched by delivery id and outlive it); dead and long-unseen rows are also evicted automatically by the host's retention sweep.
convoy_get_artifact / convoy_save_artifact fetch results BY ARTIFACT REFERENCE and verify them locally -- never open a remote C:\... or /Users/... path as if it were local.
convoy_start_node / convoy_restart_node manage node lifecycle; restarts require the node's CURRENT runtime id (from convoy_list_nodes) plus a unique idempotency_key, and the default policy refuses dirty or unverifiable project state.
convoy_owlette is an optional read-mostly site bridge that fails closed without credentials.
Batch Operations
| Tool | Parameters | Description |
|---|
batch_operations | operations | Execute multiple operations in a single request. Reduces latency and token overhead |
operations is a list of {"tool": str, "params": dict} objects. Each entry maps to an existing tool name and its parameters. Stops on first error.
When to use: 3+ calls to the same tool type (positioning, connecting, parameter setting, flags). Use execute_python instead when you need conditionals, loops, or computed values between operations.
Example — position 4 operators + connect them in one call:
{"operations": [
{"tool": "set_op_position", "params": {"op_path": "/project1/noise1", "x": 400, "y": 0}},
{"tool": "set_op_position", "params": {"op_path": "/project1/comp1", "x": 800, "y": 0}},
{"tool": "set_op_position", "params": {"op_path": "/project1/level1",