Skip to main content
Glama
touchdesigner-agent-mcp

touchdesigner-agent-mcp

by axysar

πŸŽ›οΈ touchdesigner-agent-mcp

License: MIT Status: Stable Python: 3.10+ MCP: 1.0

A premium, open-source Model Context Protocol (MCP) server that empowers LLMs (like Claude) to directly control, introspect, and build TouchDesigner networks in real-time.

With this server, an AI coding agent can create and connect operators, query parameters, capture the viewport to see what it built, automatically fix compile errors, and stream real-time data from TouchDesigner CHOPs.


πŸ—οΈ Architecture

This repository uses a zero-dependency, dual-process architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Claude / MCP Host           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
                 β”‚ MCP (stdio)
                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     touchdesigner-agent-mcp (Python Client) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
                 β”‚ HTTP (POST /mcp)
                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  TouchDesigner Web Server DAT   β”‚ (Installed via td/install.py)
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     TouchDesigner Operators     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The TouchDesigner side is built completely in plain Python (exposed via a Web Server DAT), meaning no binary .tox files or opaque components. You can read, audit, and diff every single line of code running in your project.


Related MCP server: touch-mcp

✨ Features

πŸ”„ Dual-Directional Integration

  • 25 Tools: Full CRUD for nodes, wiring, force-cooking, viewport rendering, and GLSL editing.

  • 4 Prompt Templates: Guiding instructions that teach LLMs the best tool combinations for node finding, error handling, operator connections, and network repairs.

  • 4 Resource Templates: Native MCP td:// resources that let the LLM stream live data from CHOP channels, node parameters, and project metadata.

πŸ›‘οΈ Undo Safety (Ctrl+Z)

Every single tool invocation that mutates TouchDesigner is automatically wrapped in a transaction block (ui.undo). If the agent makes a mistake, deletes a critical node, or wires something incorrectly, you can instantly revert it by pressing Ctrl+Z inside TouchDesigner.

⚑ Progress Tracking

Long-running operations (like scene scaffolding, viewport captures, and force-cooking) report real-time progress to the MCP client via the report_progress API, showing you exactly what the server is doing.

πŸ”’ Zero-Config Security

On first installation, the installer auto-generates a secure, random Auth Token (secrets.token_urlsafe(32)) and binds it to the component. The token is preserved across reinstalls, keeping your TouchDesigner instance secure from unauthorized remote code execution (RCE).


πŸŽ›οΈ Tool Matrix

Category

Tools

Description

System Info

get_td_info, describe_td_tools

Inspect TouchDesigner build, OS, and available tool schemas.

Node CRUD

get_td_nodes, create_td_node, update_td_node_parameters, delete_td_node

Create, read, update, and delete operators.

Parameters & Errors

get_td_node_parameters, get_td_node_errors, exec_node_method

Read parameters, query errors, or trigger pulses/methods.

Python RCE

execute_python_script

Run arbitrary Python scripts directly inside the TouchDesigner execution context.

Introspection

get_td_classes, get_td_class_details, get_td_module_help

Let the LLM search TouchDesigner's Python API, docs, and help pages.

Visual Vision

td_viewport

Captures any TOP/COMP or the active network pane as an image (Base64 or file path).

Scene Scaffold

td_scaffold

Scaffold complete pipelines (Feedback Loop, Instancing, Render Setup) in one click.

Advanced Wiring

td_connect, td_layout

Family-validated operator wiring and automatic positioning without node overlaps.

GLSL & Files

td_glsl, td_save_tox, td_load_tox, td_save_project

Author GLSL shaders, import/export .tox assets, and save the .toe project.

Media Assets

td_list_media_assets

Scan local project directories for video, audio, images, and geometry assets.


πŸ“‘ Resources

MCP Clients can read or subscribe to real-time resources using the td:// URI scheme:

URI Template

Resource Type

Description

td://chop/{path}

Dynamic CHOP Stream

Streams active float values for all channels in the target CHOP (e.g. td://chop/project1/lfo1).

td://node/{path}

Node Parameters

Lightweight read endpoint for parameters and operator metadata.

td://errors/{path}

Error State

Inspects compilation or wiring errors for the target node and its children.

td://project/info

Static Project Info

Metadata including project name, folder path, and the TouchDesigner app build.


πŸš€ Quick Start

1. Set Up TouchDesigner Side

  1. Copy the td/ folder somewhere stable on your disk.

  2. In TouchDesigner, open the Textport (Alt+T) and run the installer:

    import sys
    sys.path.append('/ABSOLUTE/PATH/TO/td')
    import install
    install.install()
  3. This creates /project1/td_agent_mcp with a Web Server DAT running on port 9981.

  4. Note the secure Auth Token printed in the Textportβ€”you will need this for step 3.

TIP

If you make changes to the scripts in thetd/ directory, you can reload and reinstall them instantly using: import importlib; importlib.reload(install); install.install()


2. Install the MCP Server

Build and run the server using uv (recommended):

# To run locally
uv sync
uv run touchdesigner-agent-mcp --stdio

3. Register the Server with Your Client

Claude Desktop

Add the server configuration to your claude_desktop_config.json:

{
  "mcpServers": {
    "touchdesigner-agent-mcp": {
      "command": "uv",
      "args": [
        "run", 
        "--directory", 
        "/ABSOLUTE/PATH/TO/touchdesigner-agent-mcp", 
        "touchdesigner-agent-mcp", 
        "--stdio"
      ],
      "env": {
        "TD_AUTH_TOKEN": "YOUR_AUTO_GENERATED_TOKEN_HERE"
      }
    }
  }
}

Claude Code (CLI)

Install the bundled marketplace plugin:

/plugin marketplace add axysar/touchdesigner-agent-mcp

βš™οΈ Configuration Reference

You can configure the client using environment variables or command-line flags:

Environment Variable

CLI Flag

Default

Description

TD_HOST

--td-host

127.0.0.1

The hostname/IP of the machine running TouchDesigner.

TD_PORT

--td-port

9981

The port of the Web Server DAT.

TD_AUTH_TOKEN

--td-token

(empty)

Security token matching the Authtoken parameter.

TD_TIMEOUT

--timeout

30

Request timeout in seconds.


πŸ”’ Security Hardening

Because the server allows arbitrary Python execution inside TouchDesigner (giving the LLM full RCE capabilities on your local system), security is critical:

  • Token Auth: All incoming HTTP requests require a valid Authorization: Bearer <token> header.

  • Auto-Generation: If a token isn't manually specified, the installer automatically generates a cryptographically secure 32-character token.

  • CORS Protection: The TouchDesigner Web Server DAT strictly rejects requests from arbitrary browser origins.

  • Traversals: Asset scanning is restricted to a maximum depth of 5 levels to prevent system performance issues or directory leaks.


πŸ› οΈ Development & Contributing

See CLAUDE.md for quick-start development guidelines.

Running Tests

To run registration, schema validation, and resource-binding checks without requiring TouchDesigner to be active:

uv run pytest

Code Style

We use ruff to enforce linting and formatting standards:

uv run ruff check .
uv run ruff format .

πŸ“„ License & Attribution

This project is licensed under the MIT License β€” see LICENSE.

It synthesizes and extends two outstanding prior open-source works:

TouchDesigner is a registered trademark of Derivative.

Available Tools

25 tools
create_td_nodeA

Create a new operator under a parent.

Returns the created node summary. TD auto-increments the name on collision, so check the returned name/path.

Inputs: parent (required), node_type (required), node_name, parameters, +1 more. Returns: result

delete_td_nodeA
DestructiveIdempotent

Delete an operator by path.

Destructive and not undoable through this tool. Returns {deleted: true, node: {...}} on success.

Inputs: path (required), response_format. Returns: result

describe_td_toolsA
Read-onlyIdempotent

List the tools this server exposes, with names, descriptions, and schemas.

A manifest for code-execution agents that want to discover the available TouchDesigner tool surface. Introspected locally; does not contact TouchDesigner. Returns {count, tools: [{name, description, [inputSchema, annotations]}]}.

Inputs: filter, detail_level, response_format. Returns: result

exec_node_methodA
Destructive

Call a method on an operator (e.g. cook, pulse, reset).

Returns {result: <serialized return value>}. Use for operator actions that are not parameter writes.

Inputs: path (required), method (required), args, kwargs, +1 more. Returns: result

execute_python_scriptA
Destructive

Execute a Python script in TouchDesigner's interpreter and capture output.

Runs with the TouchDesigner API in scope plus the bundled tdapi helpers. Returns {result, stdout, stderr}.

This runs arbitrary, un-sandboxed code in the user's TouchDesigner process β€” prefer the dedicated node tools for routine edits; use this for logic the other tools do not cover.

Inputs: script (required), response_format. Returns: result

get_td_class_detailsA
Read-onlyIdempotent

Get methods, properties, and docstrings for a TouchDesigner class.

Returns {name, type, description, methods, properties}.

Inputs: class_name (required), response_format. Returns: result

get_td_classesA
Read-onlyIdempotent

List the Python classes and modules available in the td module.

Returns {classes: [{name, description}]}. Pair with get_td_class_details to drill in.

Inputs: response_format. Returns: result

get_td_infoA
Read-onlyIdempotent

Get TouchDesigner build, version, OS, and the touchdesigner-agent-mcp API version.

Use this first to confirm connectivity to TouchDesigner. Returns {server, version, osName, osVersion, mcpApiVersion}.

Inputs: response_format. Returns: result

get_td_module_helpA
Read-onlyIdempotent

Capture Python help() output for a TouchDesigner module or class.

Returns {moduleName, helpText} with terminal control codes stripped.

Inputs: module_name (required), response_format. Returns: result

get_td_node_errorsA
Read-onlyIdempotent

Collect error messages for an operator and its descendants.

Returns {nodePath, nodeName, opType, errorCount, hasErrors, errors}. TD updates its error cache on frame boundaries β€” prefer checking errors in a request separate from the mutation that may have caused them.

Inputs: path (required), response_format. Returns: result

get_td_node_parametersA
Read-onlyIdempotent

Get an operator's parameters and current values.

Call this before updating parameters β€” TD names rarely match labels. Returns {id, name, path, opType, properties}.

Inputs: path (required), response_format. Returns: result

get_td_nodesA
Read-onlyIdempotent

List child operators under a path, optionally filtered by a name pattern.

Returns {nodes: [{id, name, path, opType, properties}]}. Set include_properties=true only when you need values β€” the light default is faster for large networks.

Inputs: parent, pattern, response_format, include_properties. Returns: result

td_connectA
Idempotent

Wire one operator's outlet to another's inlet, validating compatibility.

TouchDesigner only connects same-family operators via connectors; a cross-family attempt (e.g. TOP -> SOP) returns a descriptive error rather than failing silently.

Inputs: to_path (required), from_path (required), to_inlet, from_outlet, +1 more. Returns: result

td_cookA
Idempotent

Force-cook an operator (and optionally its descendants).

TouchDesigner does not always re-cook operators inside a nested baseCOMP referenced indirectly, so a stale buffer can make a correct edit look broken. Call this on the parent COMP whenever results look stale before debugging anything else. Returns {cooked, totalCookTimeMs, errors}.

Inputs: path (required), recurse, response_format. Returns: result

td_glslA
Idempotent

Read or write a GLSL shader stage, resolving the correct docked DAT.

A GLSL TOP keeps its source in _pixel_shader / _vertex_shader DATs docked to the parent β€” never guess that DAT's name or set .text on it directly. Omit code to read; pass code to write (set return_compiled=true to re-cook and surface compile errors). Returns {stage, docked_dat_path, code, errors}.

Inputs: path (required), code, stage, response_format, +1 more. Returns: result

td_layoutA

Layout intelligence: find an empty area, test overlap, or chain operators.

  • find_empty_area (needs base): returns {x, y} for a non-overlapping widthxheight block.

  • check_overlap (needs path): returns {overlaps: bool}.

  • chain (needs ops): connects operators in order, laid out left-to-right with spacing.

Inputs: action (required), ops, base, path, +7 more. Returns: result

td_list_media_assetsA
Read-onlyIdempotent

Scan a directory for usable TouchDesigner media files (video, audio, images, geometry).

Returns a list of relative file paths that can be loaded into moviefileinTOP, fileinSOP, audiofileinCHOP, etc.

Inputs: folder. Returns: result

td_load_toxA
Destructive

Load an external .tox file into a target Component (COMP).

Inputs: base (required), filepath (required). Returns: result

td_paneA
Read-onlyIdempotent

Return the current network-editor pane: path, pan, zoom, viewport size.

Use this to learn where the user is looking before editing there. Returns {path, tx, ty, zoom, viewportSize} (or {pane: null}).

Inputs: response_format. Returns: result

td_save_projectA

Save the TouchDesigner project (.toe). Use this to checkpoint your work.

Inputs: filepath. Returns: result

td_save_toxB

Save a Component (COMP) operator to an external .tox file.

Inputs: path (required), filepath (required). Returns: result

td_scaffoldA

Create a complete, pre-wired network from a template.

Prefer this over hand-wiring common setups: each template handles creation, connector compatibility, naming, layout, and the first force-cook. Returns {template, createdOps, wiring, entryPoint, description}.

Inputs: template (required), base, name_prefix, response_format. Returns: result

td_selectionA
Read-onlyIdempotent

Return operators currently selected in the active pane.

Returns {count, ops: [{path, name, type, opType, family, x, y}]}.

Inputs: response_format. Returns: result

td_viewportA
Read-only

Capture a TOP/COMP viewer or the network editor pane as an image.

Use this to actually see the result of edits instead of guessing. target is a TOP/COMP path, or 'pane' for the current network editor. Small inline captures are returned as a viewable image; large captures (or return_as='path') return a temp-file path string.

Inputs: target (required), width, format, height, +2 more.

update_td_node_parametersA
Idempotent

Set parameter values on an operator.

Returns {path, updated, failed: [{name, reason}], message}. Unknown names go to failed rather than raising β€” everything in failed means the names were wrong.

Inputs: path (required), parameters (required), response_format. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 25 tools

    Disambiguation5/5

    Each tool targets a distinct operation (e.g., create vs. delete node, connect vs. layout, viewport capture vs. pane info). Overlap is minimal and well-explained in descriptions.

    Naming Consistency5/5

    Tools follow a consistent verb_noun pattern with 'td_' prefix for common actions and 'get_td_' for queries. Exceptions like 'exec_node_method' and 'describe_td_tools' are still clear and fit the pattern.

    Tool Count4/5

    25 tools is on the higher end but justified by the breadth of TouchDesigner capabilities covered. No tool seems superfluous, though a few could potentially be combined (e.g., get_td_classes and get_td_class_details).

    Completeness5/5

    Covers the full lifecycle: create, read, update, delete nodes; parameter management; connections; cooking; layout; file I/O; scripting; and inspection. Gaps are minor (e.g., timeline control) but not essential for core automation.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      A
      maintenance
      A Model Context Protocol server that enables AI agents to control and operate TouchDesigner projects through creation, modification, and querying of nodes and project structures.
      14
      4,246 npm
      613
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      MCP server for controlling TouchDesigner from AI coding agents like Claude Code and Codex CLI, enabling operator manipulation, parameter control, and screenshot capture.
      12
      14 PyPI
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      An MCP server for TouchDesigner that lets AI agents inspect, build, wire, optimize, and stabilize live TD networks with 106 tools, plus a technique memory system for reusable patterns.
      100
      16
      MIT