integration-test-guard
Ensure MCP-server / API changes in the touchdesigner-mcp repo ship with integration-test…
A generic workflow for self-starting TouchDesigner via computer-use (or an already-running instance), loading mcp_webserver_base.tox, and verifying any TD-side Python change (td/modules/**) directly from the Textport — reading back real TD runtime values and reconciling them.
$ npx -y skills add 8beeeaaat/touchdesigner-mcp --skill touchdesigner-self-debug --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/touchdesigner-self-debugContext preview
The summary Claude sees to decide when to auto-load this skill.
A generic workflow for self-starting TouchDesigner via computer-use (or an already-running instance), loading mcp_webserver_base.tox, and verifying any TD-side Python change (td/modules/**) directly from the Textport — reading back real TD runtime values and reconciling them.
name: touchdesigner-self-debug description: > A generic workflow for self-starting TouchDesigner via computer-use (or an already-running instance), loading mcp_webserver_base.tox, and verifying any TD-side Python change (td/modules/**) directly from the Textport — reading back real TD runtime values and reconciling them. Use after changing TD-side code in the touchdesigner-mcp repo when E2E verification on a real TD is needed, or when told to "start TD and check," "verify on the actual machine," or "import and run the .tox." Includes the shortcut of calling api_service directly, bypassing the HTTP WebServer / OpenAPI schema.
A **general technique** for verifying any TD-side Python change (e.g. anything in `td/modules/**`) inside **real TouchDesigner**. Calling functions directly from the Textport, without standing up the HTTP WebServer, is the shortest path.
> **This skill is feature-agnostic.** The worked example in Steps 4–5 happens to > verify *node auto-alignment* (the PR that produced this skill), but that is > **illustration only**. The reusable shape is: **create/modify via the real code > path → read back the TD runtime value you actually care about → reconcile > against an invariant.** Swap the alignment-specific bits (grid, overlap area, > `node_layout.py`) for whatever your change touches. Do **not** assume alignment, > grids, or overlap have anything to do with your task.
1. **The `.tox` reads `td/modules/` from disk at runtime.** Re-authoring the `.tox` is **not** required for `.py` changes; reload modules or restart TD. 2. **`loadTox()` leaves `externaltox` empty** → `import_modules.setup()` fails with `No module named 'mcp'`. Replicate setup manually (Step 3). 3. **A fresh worktree lacks generated artifacts** → empty OpenAPI schema / missing `node_modules` breaks HTTP routing. Bypass it by **calling the Textport directly** (Step 4). Only run `npm install && npm run gen` if you specifically need the HTTP path (e.g. running the vitest integration suite). 4. **Computer-use screenshots go black** when TD loses frontmost focus → recover with `open_application("TouchDesigner")` + `switch_display`. 5. **Multi-line pastes into the REPL break on line boundaries** → always wrap in `exec("""...""")` to submit as one statement. 6. **To pick up a later `.py` edit** in an already-running TD, drop the module from `sys.modules` so the next import reloads from disk (Step 3c). If the WebServer is already up you can do this via `execute_python_script` — no computer-use needed.
computer-use: request_access(["TouchDesigner"])
computer-use: open_application("TouchDesigner") # wait a few seconds
computer-use: screenshot # confirmIf a WebServer is already listening on 9981 (`lsof -nP -iTCP:9981 -sTCP:LISTEN`) and `get_td_info` succeeds, you can drive everything via `execute_python_script` and skip the computer-use / Textport steps entirely.
Menu bar **Dialogs → "Textport and DATs"**. (`Alt+T` toggles the Palette and is unreliable; use the menu.)
# 3a. Load
p = op('/project1').loadTox('<ABS_REPO>/td/mcp_webserver_base.tox'); print('LOADED', p)
# 3b. externaltox is empty after loadTox — replicate import_modules.setup()
exec("""
import sys, os, yaml
b = op('/project1/mcp_webserver_base')
b.par.externaltox = '<ABS_REPO>/td/mcp_webserver_base.tox'
mp = '<ABS_REPO>/td/modules'; tsp = os.path.join(mp, 'td_server')
[sys.modules.pop(m) for m in list(sys.modules) if m.split('.',1)[0] in ('mcp','utils')]
[sys.path.remove(x) for x in (tsp, mp) if x in sys.path]
sys.path.insert(0, mp); sys.path.insert(0, tsp)
import mcp
sp = os.path.join(mp, 'td_server', 'openapi_server', 'openapi', 'openapi.yaml')
mcp.openapi_schema = yaml.safe_load(open(sp)) if os.path.exists(sp) else {}
print('SETUP_OK', mcp.__file__, 'schema', bool(mcp.openapi_schema))
""")
# 3c. Reload just your edited modules to pick up later .py edits (targeted, safe)
import sys
for m in ('mcp.services.api_service',): # list the modules you changed
sys.modules.pop(m, None)`SETUP_OK .../td/modules/mcp/__init__.py` means `mcp` imported from the local tree. (`schema False` is fine for the Textport-direct path.)
**Generic template — this is the part to reuse.** Drive the code you changed through its real entry point, then read back the runtime value and reconcile:
exec("""
from mcp.services.<your_module> import <entry_point> # the code you changed
# 1. exercise it via the real call path
<result> = <entry_point>(<args>)
# 2. read back the ACTUAL TD runtime value(s) you care about
<observed> = <read from op(...), node attrs, cook state, errors, ...>
# 3. reconcile against an invariant (prefer a numeric/boolean check over "looks right")
print('JUDGE', 'PASS' if <invariant holds> else 'FAIL', <observed>)
""")Notes that generalize:
<details> <summary><b>Worked example (align-nodes PR — illustration, not the procedure)</b></summary>
Verifying that `create_node` places
This is an implementation of an MCP (Model Context Protocol) server for TouchDesigner. Its goal is to enable AI agents to control and operate TouchDesigner projects. English / 日本語
Repo: 8beeeaaat/touchdesigner-mcp
Ensure MCP-server / API changes in the touchdesigner-mcp repo ship with integration-test…
Prepare a new touchdesigner-mcp release: inspect the unreleased diff since the last tag,…
Audit whether the unreleased touchdesigner-mcp diff (since the last tag) is adequately…
This skill should be used when the user runs /touchdesigner:debug or asks to debug,…
This skill should be used when working with TouchDesigner through the touchdesigner-mcp tools…
This skill should be used when the user runs /touchdesigner:launch or asks to "start…