Embody - MCP Server for TouchDesigner
70-tool MCP server for TouchDesigner: build, wire and debug live networks from an AI agent.
Connector by dylanroscover · GitHub account verified by the MCP Registry
Install
Pick your client. Read the repository before you give any tool access to your data.
No install instructions from the source yet. Check the repository for setup steps.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this server can do and what it asks for, from its tool list, install config and code. Checked Oct 25, 2026.
- Tools
- 44 read · 31 write · 4 delete · 15 not yet classified
- Secrets
- None asked for
- Install scripts
- None found
Tools by what they do 94
Read from the source code; the running server may list different tools.
Read 44 · Look things up without changing anything.
capture_opcapture_topconvoy_get_artifactconvoy_get_jobconvoy_list_controllersconvoy_list_nodesconvoy_pingdescribe_op_typediff_tdndiff_tdxnfind_childrenget_annotations
Show 32 more tools
get_chop_dataget_connectionsget_convoy_statusget_dat_contentget_docsget_enclosed_opsget_externalization_statusget_externalizationsget_focusget_guidanceget_job_statusget_logsget_module_helpget_network_layoutget_opget_op_errorsget_op_flagsget_op_performanceget_op_positionget_parameterget_pop_dataget_project_performanceget_sessionsget_td_class_detailsget_td_classesget_td_infoget_td_statuslist_dialogspreflight_landingquery_networkread_tdnread_tdxn
Write 31 · Create, change, send or run things.
batch_operationsconvoy_batchconvoy_callconvoy_cancel_jobconvoy_restart_nodeconvoy_save_artifactconvoy_select_nodeconvoy_send_fileconvoy_start_nodeconvoy_update_embodycreate_annotationcreate_extension
Show 19 more tools
create_opedit_dat_contentexec_op_methodexternalize_opimport_networkrelease_scoperename_oprestart_tdrun_soak_testrun_testssave_externalizationsave_projectset_annotationset_dat_contentset_op_flagsset_op_positionset_parameterupdate_embodyupdate_task
Delete 4 · Delete, drop, revoke or wipe things.
convoy_forget_nodedelete_opexecute_pythonremove_externalization_tag
Not yet classified 15 · We could not tell from the name and description.
announce_taskclaim_scopeconnect_opsconvoy_ack_jobconvoy_lifecycle_quitconvoy_lifecycle_stateconvoy_owlettecook_opcopy_opdisconnect_opdismiss_dialogexport_network
Show 3 more tools
launch_tdlayout_childrenswitch_instance
Network hosts it talks to 30
::1· found in codeantigravity.google· found in codeapi.github.com· found in codeapi.resend.com· found in codeapple.com· found in codeattacker.invalid· found in codechallenges.cloudflare.com· found in codechatgpt.com· found in codeclaude.ai· found in codecode.claude.com· found in codecode.visualstudio.com· found in codecursor.com· found in codederivative.ca· found in codedev.owlette.app· found in codedevelopers.openai.com· found in codedocs.astral.sh· found in codedocs.derivative.ca· found in codedylanroscover.github.io· found in codeembody.tools· found in codeevil.invalid· found in codeexample.invalid· found in codeexample.test· found in codefonts.googleapis.com· found in codegeminicli.com· found in codegithub.com· found in codegithub.com.helper· found in codeopencode.ai· found in codeowlette.app· found in codeschemas.microsoft.com· found in codewindsurf.com· found in code
Files it touches
/dev/console/etc/passwd/etc/passwd.tox/home/dev/c.tox/home/u/Git/Proj/home/x/home/x/.local/state/home/x/.local/state/embody-convoy/home/x/.state/home/x/.state/embody-convoy/Library/Developer/Library/Developer/CommandLineTools/opt/derivative/opt/homebrew/bin/opt/homebrew/bin/python3/private/show-b.toe/srv/builds/Release.toe/sys/sys/class/net/sys/quiet/sys/quiet/envoy_describe_tmp/sys/quiet/thing/sys/TDTox/defaultCOMPs/sys/y/tmp/.embody/envoy.json/tmp/a/tmp/b/tmp/c.json/tmp/custom.tdn/tmp/embody-cfg/tmp/envoy.json/tmp/fake-project.toe/tmp/helper/tmp/it/tmp/nowhere/tmp/test_file.tdn/tmp/test.json/Users/a/Users/a/Library/Caches/Embody/Convoy/artifacts/Users/rosco/Desktop/e1/.venv/lib/python3.11/site-packages
Tools (94)
Read from the source code; the running server may differ. Descriptions are the server’s own words; hidden characters are shown as [U+…].
announce_taskAnnounce a unit of work to the shared task ledger. The ledger (.embody/tasks.json) is how parallel AI sessions know what is being worked on and -- crucially -- what is FINISHED but not yet committed. Claims (claim_scope) expire the moment a session goes quiet; ledger entries persist, so a session arriving later still sees the state of the work instead of guessing it from dirty files and timestamps. Announce at the START of substantive work (a feature, a fix, a refactor -- not single-tool edits), then keep it honest with update_task: done_uncommitted when the work is finished but sitting in t…
batch_operationsExecute multiple operations in a single request. Combines several tool calls into one round-trip, reducing latency and token overhead. Stops on first error by default. Args: operations: List of dicts, each with 'tool' (str) and 'params' (dict). Example: [{"tool": "set_op_position", "params": {"op_path": "/project1/noise1", "x": 400}}, {"tool": "connect_ops", "params": {"source_path": "/project1/noise1", "dest_path": "/project1/null1"}}] Returns: Dict with 'results' (list in same order), 'count', and 'success' (false if any failed)
capture_opCapture any operator's current output as a temp image file. A TOP is read natively (same pixels as capture_top). Every other family -- CHOP, SOP, POP, DAT, COMP, MAT -- is rendered through a transient OP Viewer TOP, the picture the network editor's viewer shows, created inside the Embody COMP for this call and destroyed after. The capture waits a few frames for the viewer to render; the returned text says when a viewer was used. Use capture_top when you need TOP-only features (sample grids). File path is returned by default; inline=True embeds a small preview. The text carries the same Quali…
capture_topCapture a TOP as a temp image file or sampled RGBA grid. TOP only -- for any other family (CHOP, SOP, POP, DAT, COMP, MAT) use capture_op, which renders through an OP Viewer TOP. File path is returned by default; inline=True embeds a small preview. sample_grid>=2 returns an NxN RGBA grid instead, clamped 2..32 with row 0 at image top-left; image format args are ignored. The returned text carries a Quality verdict computed from the raw pixels (luminance stats, alpha coverage): a FAIL flags a black / flat / fully-transparent frame so you can tell an empty render from a real one WITHOUT readin…
claim_scopeClaim a cooperative write lease so peer sessions avoid a scope. Overlapping claims and destructive ops are refused while the lease is live; own writes renew it and silence/TTL expires it. Args: scope: Op path prefix, file:<repo-relative>, or project:<name> note: Short intent shown to peers ttl: Lease seconds, 30-3600 (default 300). Returns: {'granted': True, ...} or {'granted': False, 'holder': {...}}
connect_opsConnect two operators with a wire. Args: source_path: Path to source operator (output) dest_path: Path to destination operator (input) source_index: Output connector index (default 0) dest_index: Input connector index (default 0) comp: If True, use COMP connectors (top/bottom) instead of operator connectors (left/right) Returns: Dict with success status
convoy_ack_jobAcknowledge that this controller has safely observed one terminal Convoy delivery. This idempotent call lets the target release protected result artifacts and eventually reap the job. Verified artifact downloads and successful artifact saves acknowledge automatically; use this tool for other terminal results or to retry an indeterminate acknowledgement.
convoy_batchRun one ordered Envoy batch on each explicit Convoy target. Targets execute independently and may run concurrently; the result preserves input order and reports partial success. This does not promise distributed atomicity or rollback.
convoy_callRelay one Envoy operation to an explicit Embody node. The target is always identified by host_id and node_id; Convoy never silently falls back to a local TouchDesigner instance.
convoy_cancel_jobRequest cancellation from the exact host that owns a durable delivery. Queued work cancels definitively; an active host subprocess receives best-effort process-tree cancellation. TouchDesigner work already past its host boundary is reported as non-cancellable, never simulated. Cancellation never wakes TouchDesigner.
convoy_forget_nodeDelete a stale node row (the row a renamed, moved, or deleted project left behind). Without host_id it acts on THIS machine's Convoy host app; with host_id (the owning host from convoy_list_nodes) the request is relayed to that host over its live session and its rules decide. Refuses while the node still has a delivery that has not FINISHED, and names the blocking delivery ids so they can be cancelled; a finished result never holds a row, because results are fetched by delivery id and outlive it; an online row is never forgotten. Rows unseen for a week are evicted automatically; this is the im…
convoy_get_artifactMaterialize one private Convoy artifact from its owning host onto this client machine. Images are returned as MCP image content; other files are verified and returned as a local temporary path. Use the artifact reference returned by a Convoy job rather than copying a remote filesystem path.
convoy_get_jobRead a previously relayed Convoy delivery from its owning peer. Use the target_host_id, convoy_id, and delivery_id returned by convoy_call.
convoy_lifecycle_quitHost-private CAS-guarded quit for exact-node restart.
convoy_lifecycle_stateHost-private clean/unsaved snapshot for exact-node restart.
Show 79 more tools
convoy_list_controllersList live controller sessions, selected targets, leases, and active work across reachable Convoy hosts. Read-only and never wakes TouchDesigner.
convoy_list_nodesList the local and reachable remote Embody nodes known to this machine's Convoy host. Returns stable host/node/runtime identities, connection state, address, and version metadata. Local nodes carry a capabilities field (td_python, full_shell); remote nodes deliberately do not -- absent means unknown, never allowed.
convoy_owletteUse Convoy's optional, host-private consumer of Owlette's published API for site/machine inventory, online detail, and command status. Command submission requires a separate local host opt-in and an idempotency key. Owlette is not the Convoy LAN transport and mcp_tool_call is always refused here.
convoy_pingMeasure Convoy reachability to one explicit node through the host-native ping operation. It reports the node's known online state without starting or waking TouchDesigner.
convoy_restart_nodeRestart one exact running TouchDesigner node. The default require_clean policy refuses dirty, unsaved, or unverifiable state; save_then_restart explicitly saves first. Destructive restart policies are not exposed by this build.
convoy_save_artifactVerify one Convoy artifact and explicitly save it in this bridge project's .embody/convoy/artifacts directory. The project is derived from this Envoy bridge's own configuration; remote paths and caller-selected project roots are never used. Existing files are preserved unless overwrite is true.
convoy_select_nodePin this MCP session's ordinary Envoy tool calls to one exact Convoy node. The selection survives peer dropouts and never falls back to local TouchDesigner. Call with no arguments to inspect the selection, or clear=true to restore direct local routing.
convoy_send_fileSend one file from this bridge's project to a Convoy node. The source must resolve inside this project. By default it lands in the target project's .embody/convoy/inbox/; with worktree=<name> at dest inside the target's sibling <project>-wt-<name> worktree (create one with convoy_call convoy_git worktree_add); with live=true at dest inside the live project, which needs Allow Execute TD Python on the target because a synced .py reloads into TouchDesigner. dest defaults to the file name for the inbox and to the file's own project-relative path otherwise. Existing files are kept unless overwrite …
convoy_start_nodeStart one exact, previously registered offline TouchDesigner node from its host-pinned launch profile. No executable, path, argv, or environment is accepted from the caller.
convoy_update_embodySelf-update Embody on Convoy nodes to the latest GitHub release -- one node or the whole fleet -- without the TD Python grant. Dispatches the bounded update_embody operation (sha256-pinned manifest, downgrade-refusing) as a durable job per node and returns the handles; poll convoy_get_job. Nodes must run Embody >= 6.0.257 to serve the operation.
cook_opCook (evaluate) an operator. Args: op_path: Path to the operator force: Force cook even if not dirty (default True) recurse: Recursively cook children (default False) Returns: Dict with success status
copy_opCopy an operator to a new location. Prerequisite: load the /create-operator skill before first use in a session (same placement + verify workflow as create_op). Auto-positions the copy clear of siblings and re-hugs its docked companions below it (docks_placed in the result). Args: source_path: Path to operator to copy dest_parent: Path to destination parent COMP new_name: Optional new name for the copy Returns: Dict with path to new operator
create_annotationCreate a Comment, Network Box, or Annotate in the network editor. Prerequisite: load the /manage-annotations skill first -- coordinate math (nodeX/nodeY is the bottom-left corner) and sizing rules live there. The annotation is created utility=True (matching TD UI-drawn annotations), so it appears in get_annotations but NOT in query_network/find_children unless include_utility=True. All op-path tools (set_annotation, delete_op, set_parameter, ...) still resolve it by path. Args: parent_path: Path to parent COMP mode: "annotate" (default), "comment", or "networkbox" text: Body tex…
create_extensionCreate or attach a TouchDesigner extension COMP and code DAT. Prerequisite: load the /create-extension skill before first use -- required parameters, lifecycle methods, and wiring steps. Args: parent_path: Parent COMP path, or target COMP when existing_comp=True class_name: Python class name name: New COMP name; ignored when existing_comp=True code: Full class code; omitted generates boilerplate promote: Promote capitalized methods to COMP level ext_name: Custom extension name ext_index: Extension slot 0-3; omitted auto-detects existing_comp: True attaches to …
create_opCreate a new operator in TouchDesigner. Prerequisite: load the /create-operator skill before first use in a session -- group placement, wiring direction, and the mandatory verify pass live there. Auto-positions the new op clear of siblings, and snaps any docked companions it spawns (callback/shader/info DATs) into a tight row hugging the host's bottom edge (docks_placed in the result). A textDAT is created with language 'python' unless `language` says otherwise. Pass it whenever the DAT will hold anything but Python: it is set before auto-externalize picks the file type, so a shader lands i…
delete_opDelete an operator. Refuses the Embody COMP, its ancestors, '/' and Envoy's own extension DAT (error_code envoy.embody.host_destroy_refused); override does not bypass that check. Args: op_path: Full path to the operator (e.g., "/project1/base1") override: Bypass the multi-session gate when another live session claimed this scope or wrote it very recently. Returns: Dict with success status
describe_op_typeParameter names, labels, styles, defaults and menu values for an operator TYPE -- before the operator exists. The look-before-you-guess read: TD abbreviates parameter names unpredictably (blurTOP blur amount is `size`, lagCHOP has `lag1`/ `lag2`, rectanglePOP sizes are `sizeu`/`sizev`), so call this once per unfamiliar type instead of guessing into set_parameter. Read off a throwaway instance in /sys/quiet (cooking disabled, outside the project), then cached per type for the session. Args: op_type: TD class name of the type (noiseTOP, lfoCHOP, baseCOMP, gridPOP) pattern: Glob or subs…
diff_tdnDEPRECATED alias for diff_tdxn -- prefer diff_tdxn. Kept for the same reason as read_tdn: the name is published. Identical behaviour.
diff_tdxnDiff live in-memory TDXN state against on-disk .tdxn files. Empty target (or "/" / "project") returns a project summary; a COMP path or .tdn filename returns that COMP in detail. Read-only. Args: target: Empty for whole project, else COMP path or .tdn file max_changed_ops: Cap reported changed operators max_bytes: Soft response cap; changed_keys remain when trimmed Returns: Diff envelope, project summary, or {'error': ...}
disconnect_opDisconnect an operator's input. Args: op_path: Path to the operator input_index: Input connector index to disconnect (default 0) comp: If True, disconnect a COMP connector (top/bottom) instead of operator connector (left/right) Returns: Dict with success status
dismiss_dialogDismiss a modal dialog that is blocking a TouchDesigner instance, then verify it is gone. Default action=auto runs the ladder close (WM_CLOSE) -> escape -> enter until the window disappears; the main TouchDesigner window is never a target. Use list_dialogs (with screenshot=true) first so you know what you are dismissing: close/escape decline a question, enter accepts its default.
edit_dat_contentReplace text in a DAT without sending the whole DAT. Prerequisite when writing TD Python into the DAT: load the /td-api-reference skill first. Text DATs only. old_string must appear exactly once unless replace_all=True. Refuses wipes without confirm_wipe=True. Args: op_path: Path to the DAT operator old_string: Text to find; non-empty and unique by default new_string: Replacement text; must differ from old_string replace_all: True replaces every occurrence confirm_wipe: Required when the edit would leave the DAT empty Returns: Dict with success, path, replacements, …
exec_op_methodCall a method on a TouchDesigner operator. Example: exec_op_method("/project1/table1", "appendRow", args=[["a", "b", "c"]]) destroy/reload/changeType/progressiveUnload on the Embody COMP, an ancestor, '/' or Envoy's extension DAT are refused (envoy.embody.host_destroy_refused). Args: op_path: Path to the operator method: Method name to call (e.g., "appendRow", "clear", "cook") args: Positional arguments as a list (default []) kwargs: Keyword arguments as a dict (default {}) Returns: Dict with method result
execute_pythonExecute arbitrary Python code in TouchDesigner. Use with caution - code runs on main thread with full TD access. Prerequisite: load the /td-api-reference skill before writing TD Python. Ops created here bypass auto-layout: position them per the network-layout rule or a LAYOUT WARNING rides back in _logs. Refused before anything runs (envoy.embody.host_destroy_refused) when the code would destroy or reload the Embody COMP, an ancestor, '/' or Envoy's extension DAT in this call -- me and parent() ARE the Embody COMP here; the refusal says how to defer. Args: code: Python code to execute …
export_networkExport a TouchDesigner network as a TDXN document (a dict over MCP; YAML in a .tdxn/.tdn file on disk). Only non-default properties are included, keeping output minimal. Args: root_path: Root COMP to export from (default "/" for entire project) include_dat_content: Include DAT text/table content (default None = use Embeddatsintdxns toggle) output_file: File path to write the TDXN to. Use "auto" to generate name. None returns dict only. An output_file that is NOT the COMP's tracked file is a snapshot: the tracking row and the canonical file are left alone. max_d…
externalize_opTag an operator for Embody externalization and write it to disk. Prerequisite: load the /externalize-operator skill before first use in a session -- the required workflow steps live there. Args: op_path: Path to the operator tag_type: Tag type - "tox" for COMPs, "py"/"txt"/"tsv"/"json" etc for DATs If None, will auto-detect based on operator type Unattended sessions: a TDXN operation that meets a TD palette component can raise the Black-Box-vs-Full-Export dialog. Decide programmatically BEFORE the call: set the Tdxnpalettehandling parameter on the Embody COMP ('blackbox…
find_childrenSearch for operators inside a COMP using TouchDesigner's findChildren. Much more powerful than query_network for targeted searches. Args: op_path: Path to the parent COMP to search in name: Name pattern to match (e.g., "noise*", "*filter*") type: Operator type to filter (e.g., "baseCOMP", "textDAT", "noiseTOP", "annotateCOMP") depth: Exact depth to search at (1 = direct children only) tags: List of tags to match (operator must have all tags) text: Search DAT text content for this string comment: Search operator comments for this string include_utility: If True,…
get_annotationsList all annotations (Comments, Network Boxes, Annotates) in a COMP. Args: parent_path: Path to the COMP to search for annotations Returns: Dict with list of annotations and their properties including text, mode, position, and enclosed operators
get_chop_dataRead a CHOP as per-channel STATISTICS, never a blind dump. A 4x600 CHOP is 2400 raw floats; this returns min/max/mean/std + first/last per channel instead. Pass samples>0 only when the raw values matter. Args: op_path: Path to the CHOP operator channels: Glob on channel name (e.g. "chan*"); omit for all (capped at 32 channels, with channelsOmitted reported) samples: Head/tail raw values per channel (0 = stats only) compare_to: Another CHOP path -- adds a 'diff' block of per-channel min/max/mean deltas. The "what did this chain actually do to my data" r…
get_connectionsGet all input and output connections for an operator. Args: op_path: Path to the operator Returns: Dict with inputs and outputs lists. 'inputs' has ONE ENTRY PER INPUT CONNECTOR: {'index': i, 'connected_to': path-or-null}, so index is the REAL connector index and a sparse wire (input 2 wired, 0-1 empty) reads exactly that -- never compacted. Dynamic multi-input ops show one trailing empty connector. 'outputs' entries carry a LIST per connector (outputs fan out).
get_convoy_statusReport this machine's Convoy host presence and, when it is running, its realm, peer, queue, and identity status. This is a host-only read and never wakes TouchDesigner. Explicit convoy_* tools use this host for remote routing; ordinary Envoy tools remain local until convoy_select_node explicitly pins this session to a Convoy node.
get_dat_contentGet the content of a DAT operator (text or table data). Args: op_path: Path to the DAT operator format: "text" for raw text, "table" for row/column data, "auto" to detect based on DAT type, "stats" to reduce a table to per-column min/max/mean (numeric) or distinct counts (text) plus head/tail rows -- use it instead of dumping a large table into context Returns: Dict with DAT content (text string or table rows/cols)
get_docsLook up official TouchDesigner documentation (docs.derivative.ca). Resolves operator pages ("Movie File In TOP", "moviefileinTOP"), Python class pages ("CHOP Class"), and concept articles. Prefers the local offline help mirror when the TD installation has one (version-exact, instant); falls back to the live docs.derivative.ca wiki API. Args: query: Page name or topic (e.g. "noiseTOP", "Timer CHOP", "Instancing") section: Optional section heading from a previous call's sections_available -- returns just that section source: 'auto' (offline then web), 'offline', or 'web' …
get_enclosed_opsGet the relationship between an annotation and operators. If op_path is an annotation: returns the operators enclosed by it. If op_path is a regular operator: returns the annotations enclosing it. Args: op_path: Path to an annotation or regular operator Returns: Dict with enclosed_ops or enclosing_annotations depending on operator type
get_externalization_statusGet externalization status for an operator (dirty state, build info). Args: op_path: Path to the operator Returns: Dict with dirty state, build number, timestamp, file path
get_externalizationsGet list of all externalized operators tracked by Embody. Returns: Dict with list of externalized operators and their status
get_focusReport what the USER is currently looking at in TouchDesigner. Call this to resolve conversational references -- "fix this operator", "add a blur here", "what's wrong with that node" -- before guessing a path or calling query_network. DISAMBIGUATION RULE: "this operator" / "that node" means the SELECTED (or current) operator. It does NOT mean the rollover operator -- rollover is just whatever the mouse happens to be hovering over and is incidental. Use `target` when it is set; fall back to `selected`/`current`. Only mention `rollover` if the user explicitly talks about hovering. Returns: …
get_guidanceRead this project's TouchDesigner rules and workflow skills. These are the project's own doctrine -- the same documents Claude Code loads from .claude/rules and .claude/skills. Every other client (Codex, Cursor, opencode, ...) only sees them through this tool. Call it with no argument once per session to list the topics, then read the relevant one BEFORE acting: - before creating or moving operators -> 'create-operator', 'network-layout' - before writing TD Python (execute_python, DAT content) -> 'td-python', 'td-api-reference' - before creating or editing annotations -> 'manag…
get_job_statusStatus of background jobs (run_tests background=True, save_project, run_soak_test). Jobs are disk-backed (.embody/jobs/), so they survive server restarts and extension reinits -- the failure mode that severs a long synchronous call. Poll with the job_id the starting tool returned; omit it to list recent jobs. A finished run_tests job carries the summary (counts + the failing tests); a finished save_project job carries version_before/version_after. It also carries warnings: the WARNING/ERROR lines logged during the save (ERRORs first, then oldest first, repeats collapsed, at most 8 plus a '(+N…
get_logsGet recent log entries from Embody's ring buffer. Useful for debugging operations or understanding what happened. Args: level: Filter by log level ("INFO", "WARNING", "ERROR", "SUCCESS", "DEBUG") count: Maximum number of entries to return (default 50, max 200) since_id: Only return entries with id > since_id (for polling new logs) source: Filter by source/caller pattern (substring match) Returns: Dict with log entries and metadata
get_module_helpGet Python help text for a TouchDesigner module or class. Supports dotted names like "td.tdu" or simple names like "OP". Args: module_name: Module or class name (e.g., "td", "td.tdu", "OP", "Par") Returns: Dict with module name and help text
get_network_layoutGet compact positions and sizes for all children in a COMP. Args: comp_path: Path to the parent COMP include_annotations: Whether to include annotation positions (default True) Returns: Dict with operator path/type/nodeX/nodeY/nodeWidth/nodeHeight; centers are nodeX+nodeWidth/2 and nodeY+nodeHeight/2. Docked companions carry dockedTo (their host's name) so the Verify step can confirm every dock hugs its host.
get_opGet operator info; parameters are non-default only by default. Args: op_path: Full path to the operator include_defaults: True returns all parameters Returns: Dict with type, family, parameters, inputs, outputs, children. 'inputs' has ONE ENTRY PER INPUT CONNECTOR (null = that connector is empty), so a wire on input 2 with inputs 0-1 unwired reads [null, null, path] -- entry position IS the real connector index. Dynamic multi-input ops (Switch, Composite) always show one trailing null (their growth connector). 'outputs' is the compacted connected-outpu…
get_op_errorsGet error and warning messages for an operator and optionally its children. Useful for debugging TD networks -- covers all three surfaces TD reports red: cook errors, Python tracebacks from callbacks/DAT scripts/expressions (OP.scriptErrors, tagged kind='script' in errors[]), and GLSL compile failures (shaderErrors key). Args: op_path: Path to the operator to check recurse: If True, also check children (default True) Returns: Dict with structured error and warning lists
get_op_flagsGet all flags/properties for an operator (bypass, lock, display, etc.). Args: op_path: Path to the operator Returns: Dict with all flag states
get_op_performanceGet performance/profiling data for an operator. Args: op_path: Path to the operator include_children: Include aggregate children performance data Returns: Dict with CPU/GPU cook times in MILLISECONDS (same unit as get_project_performance's frameTimeMs -- frame budget is 16.7ms at 60fps), memory usage in bytes, cook counts
get_op_positionGet an operator's position and size in the network editor. Args: op_path: Path to the operator Returns: Dict with nodeX, nodeY, nodeWidth, nodeHeight, color, comment
get_parameterRead one parameter compactly, or search parameters by glob/substring. Single-parameter mode is compact by default; details=True restores full metadata. Search mode ignores details. search_in='value' evaluates scanned values; search_in='any' evaluates constants only. Args: op_path: Full path to the operator par_name: Parameter name for single-parameter mode search: Glob or substring pattern for search mode search_in: Field to search: name, value, expr, or any depth: Child search depth max_results: Maximum search hits to return details: True returns full metadata in…
get_pop_dataRead a POP: attribute metadata always, point values on request. Metadata (numPoints + point/prim/vert attribute names, sizes and types) costs ~0.02ms regardless of point count. Reading actual point VALUES is a GPU->CPU readback that stalls the main thread: measured ~9.5ms at 16k points and ~69ms at 160k (~4 frames at 60fps) on 2025.33070. Sampling is therefore opt-in and gated on the operator's TOTAL point count, not on how many you ask for -- POP.points(count=N) does not bound the readback. Args: op_path: Path to the POP operator attributes: Glob on attribute name (e.g. "P"); omit f…
get_project_performanceGet project-level performance metrics: FPS, frame time, GPU/CPU memory, dropped frames, active operators, and more. Uses a Perform CHOP for accurate real-time measurements. The first call creates the monitor operator (negligible overhead). Args: include_hotspots: Return the top N most expensive COMPs by cook time. 0 (default) skips hotspot analysis. Recommended: 5-10. Returns: Dict with timing (fps, frameTimeMs, cookRate), memory (gpuMemUsedMB, totalGpuMemMB, cpuMemUsedMB), frame health (droppedFrames, activeOps, totalOps), GPU info (gpuTemp), performance mode status…
get_sessionsList AI client sessions currently connected to this Envoy server. Each session is one AI client window (e.g. one Claude Code session) connected through its own bridge process. Check this at session start and before large or destructive operations (import_network with clear_first, delete_op on a COMP, project save, test runs) so concurrent sessions don't clobber each other's work. Returns: Dict with 'sessions' (newest-activity first: sid, label, pid, first_seen, last_seen, idle_s, requests, last_tool, recent_scopes = op paths/files this session recently modified, claims = scop…
get_td_class_detailsGet detailed information about a specific TouchDesigner Python class. Shows methods, properties, and descriptions. Args: class_name: Name of the class in the td module (e.g., "OP", "COMP", "Par") Returns: Dict with class methods, properties, and descriptions
get_td_classesList all Python classes and modules available in the TouchDesigner td module. Useful for discovering TD's Python API. Returns: Dict with list of class names and descriptions
get_td_infoGet information about the TouchDesigner environment and Envoy server. Returns: Dict with TD version, build, OS info, and Envoy/Embody versions
get_td_statusCheck if TouchDesigner is running and Envoy is reachable. Returns connection state, crash detection, process liveness, and project config. Works even when TD is down. envoy_unresponsive / main_thread_stalled flag a TouchDesigner that is alive but frozen.
import_networkImport a TDXN network into a TouchDesigner COMP, recreating all operators. Args: target_path: Destination COMP path to import into tdn: The TDXN document as a dict (full document, or a dict holding just an 'operators' array) clear_first: If True, delete all existing children before importing override: Bypass the multi-session gate when another live session claimed this COMP or wrote it very recently (applies only with clear_first=True) Unattended sessions: a TDXN operation that meets a TD palette component can raise the Black-Box-vs-Full-Export dialog.…
launch_tdLaunch TouchDesigner with this session's pinned instance's .toe (unpinned: the registry default's). Use to start TD for the first time or restart after a crash. Waits for Envoy to become reachable before returning.
layout_childrenAuto-layout all children in a COMP using TouchDesigner's built-in layout. Args: op_path: Path to the parent COMP Returns: Dict with success status
list_dialogsList the modal dialogs a TouchDesigner instance currently shows (ui.messageBox, missing-file and save-changes prompts, the license box, file pickers). Runs on the bridge, so it works while TD's main thread is blocked by the dialog and every Envoy tool is timing out. TD draws its own dialogs, so their text is not readable through the OS: pass screenshot=true to save a PNG of each one and Read it. Returns blocked=true when a dialog is up.
preflight_landingCheck whether a worktree's diff can land safely in the main tree. Read-only and TD-free (answered on the worker thread). Reports three collision classes BEFORE any file moves: landing files also dirty in the MAIN tree (a running TD re-exports externalized files -- blind overwrite is the classic landing failure), landing files claimed or recently written by PEER sessions, and landing files whose live TDXN/DAT state is UNSAVED (dirty in externalizations.tsv). Run it before porting any worktree diff; a 'conflicts' verdict means reconcile first. Args: worktree_path: The worktree directory --…
query_networkList operators in a network/container. Args: parent_path: Path to parent COMP to search in (default "/") recursive: If True, search recursively into child COMPs op_type: Filter by operator type (e.g., "baseCOMP", "TOP", "annotateCOMP") include_utility: If True, include utility operators like annotations (default False) Returns: Dict with operator path/type/family/depth; name = last path segment
read_tdnDEPRECATED alias for read_tdxn -- prefer read_tdxn. Kept because the old name is published: it is in shipped rule files, saved agent prompts and third-party integrations, and removing it would break them silently. Identical behaviour.
read_tdxnRead live authored state under comp_path as a compact TDXN dict. This is authored-state, not runtime: use runtime probes for evaluated values, cook errors, output pixels/data, timing, or flags. Args: comp_path: Root COMP to read (default "/" for entire project) include_dat_content: Include DAT text/table content max_depth: Maximum recursion depth (None = unlimited) embed_all: Recurse into TDXN-tagged COMPs instead of skipping Returns: Dict with the TDXN document under 'tdn', or {'error': ...}
release_scopeRelease a scope you claimed with claim_scope. Args: scope: The exact scope string you claimed. Returns: {'released': bool} plus a reason when not released.
remove_externalization_tagRemove Embody externalization tracking from an operator (tag, table row, and TDXN breadcrumb). Args: op_path: Path to the operator delete_file: Also delete the externalized file on disk (best-effort; safety checks may keep it). Default False keeps the file. Returns: Dict with success, removed_tags (operator tags stripped), removed_rows (registry rows dropped, including descendants), removed_anything, and a human-readable summary. An operator can have a tracked row but no tag (a pre-guard annotation artifact), so removed_tags alone cannot confirm cl…
rename_opRename an operator. Args: op_path: Full path to the operator new_name: New name for the operator Returns: Dict with success status and new path
restart_tdQuit this session's pinned TouchDesigner gracefully and relaunch its .toe (unpinned: the registry default's). Other TD instances are never touched. Waits for the process to exit before relaunching. Use when TD is running but needs a fresh start.
run_soak_testRun a low-overhead performance soak as a background job. Testing a show means watching it run for minutes to hours, not reading one frame. This samples Envoy's Perform CHOP on the frame hook -- three channel reads per frame (microseconds), memory and op counts once per interval, nothing cooked, captured or created -- so the instrument does not move the needle it reads. Returns a job_id immediately; poll get_job_status(job_id): a running record carries `progress` (elapsed_s, last_sample, summary_so_far, verdict_so_far), the finished record a `result` with per-metric first/last/min/max/mean/slo…
run_testsRun Embody test suites and return results. Prerequisite: load the project's /run-tests skill (when present). A FULL run (no suite_name) is REFUSED when the saved .toe is missing or over an hour old -- it mutates the live network for ~25 minutes and that file is the only recovery point. Call save_project first, or pass confirm_saved=True to accept losing anything since the last save. Every response reports the recovery point's age; a single-suite run is never refused. background=True is the RESILIENT mode -- recommended for full runs: the run starts and this call returns a job id IMMEDIATELY…
save_externalizationForce save an externalized operator. Prerequisite: load the /externalize-operator skill before first use in a session. Args: op_path: Path to the externalized operator Returns: Dict with success status and file path
save_projectSave the TouchDesigner project as a tracked background job. A DEVELOPMENT TOOL, NOT FOR SHOWS: a save blocks TouchDesigner's main thread for 15+ seconds (no frames render) and restarts the Envoy server. Never run it against a machine running a show. The node refuses it while Embody's Perform Mode or TD's perform window is on ({'error', 'code': 'perform_mode'}, no job started). Convoy relays it to remote nodes without the TD Python grant; the same refusal applies. project.save() blocks TD's main thread for many seconds (the TDXN strip/restore cycle plus the release-tox export) and reinitializ…
set_annotationModify properties of an existing annotation. Prerequisite: load the /manage-annotations skill first -- coordinate math (nodeX/nodeY is the bottom-left corner) and sizing rules live there. Args: op_path: Path to the annotation operator text: New body text content title: New title bar text color: Background color as [r, g, b] floats (0.0-1.0) opacity: Opacity (0.0-1.0) width: New width height: New height x: New X position y: New Y position Returns: Dict with updated annotation properties
set_dat_contentReplace a DAT's entire text or table content. Prerequisite when writing TD Python into the DAT: load the /td-api-reference skill first. Refuses no-content calls and any wipe unless confirm_wipe=True. Args: op_path: Path to the DAT operator text: Full text replacement; text="" is a wipe rows: Full table replacement; rows=[] is a wipe clear: Empty the DAT; redundant when text/rows is provided confirm_wipe: Required when the result would be empty Returns: Dict with success status, or {'error': ...} if a guard trips
set_op_flagsSet one or more flags/properties on an operator. Args: op_path: Path to the operator bypass: Bypass flag lock: Lock flag display: Display flag render: Render flag viewer: Viewer flag current: Current flag (yellow flag) expose: Expose flag allowCooking: Allow cooking flag selected: Selected flag in network editor cloneImmune: The operator survives a clone re-sync componentCloneImmune: The COMP and everything inside it survive a clone re-sync (COMPs only) showCustomOnly: The parameter dialog shows only custom pages showDocked: This…
set_op_positionSet an operator's position, size, color, or comment in the network editor. Moving an op carries its docked companions along: they are re-hugged in a tight row below the new position (docks_moved in the result). Position the host FIRST if you also plan to place a dock explicitly. Args: op_path: Path to the operator x: X position (horizontal, from left) y: Y position (vertical, from bottom) width: Node tile width height: Node tile height color: RGB color as [r, g, b] floats (0.0-1.0) comment: Comment text annotation Returns: Dict with success status and new pos…
set_parameterSet a parameter value, expression, bind expression, or mode on an operator. Invalid Menu values are rejected with the valid menuNames because TD would otherwise silently coerce them to index 0. Sequence-block parameters auto-grow their sequence, e.g. const5name grows numBlocks to 6. A Pulse parameter is pulsed instead of assigned (any value; the result carries pulsed: true). A reload or clone pulse (enableexternaltoxpulse, reinitnet, enablecloningpulse) on the Embody COMP, an ancestor, '/' or Envoy's extension DAT is refused (envoy.embody.host_destroy_refused). Args: op_path: Full path t…
switch_instanceSwitch THIS session's TouchDesigner instance or list all registered instances. Omit the instance parameter to list available instances with their status. Provide an instance name (toe basename) to re-pin this session's bridge to that instance -- other sessions' routing is untouched unless all_sessions=true.
update_embodySelf-update Embody to the latest GitHub release, as a job. Bounded and non-interactive: the node's own updater fetches the official release, verifies the sha256-pinned manifest, refuses downgrades and TD-build-floor violations, then swaps the component in place (no caller code or URL is involved -- this never needs the TD Python grant). Returns a job id immediately; poll get_job_status(job_id). A finished record carries version_before/version_after; an up-to-date node finishes 'done' with versions equal. The install restarts the MCP server, so expect one reconnect blip. Args: idempotency…
update_taskUpdate a shared-ledger task's status, note, or commit sha. Transitions (see announce_task): -> done_uncommitted when the work is complete but uncommitted -- the state peers MUST see before touching the same files; -> committed once it lands (pass commit=<sha>; a sha alone implies the transition); -> abandoned when dropped. Any session may update any task -- marking a dead session's stale entry abandoned is cooperative hygiene -- and the ledger records updated_by when the writer is not the owner. Args: task_id: The id announce_task returned (tsk_...) status: New lifecycle status n…
Signals
- Stars
- 208
- Forks
- 10
- Open issues
- 6
- Last commit
- Oct 19, 2026 (10 days ago)
- Last release
- Oct 19, 2026 (10 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- Registry name
io.github.dylanroscover/embody- Version
- 6.2.67
- License
- MIT
- Repository
- github.com/dylanroscover/Embody
- Website
- embody.tools
- First seen
- Oct 24, 2026
- Last checked
- Oct 25, 2026
Cite this page
Embody - MCP Server for TouchDesigner. Agent Mart. https://agentmart.dev/connectors/dylanroscover-embody (last updated 2026-10-25)