com um clique
multi-instance
Workflow for running multiple TD instances with Envoy, switching between them, and understanding the instance registry.
Menu
Workflow for running multiple TD instances with Envoy, switching between them, and understanding the instance registry.
MUST READ before first MCP tool call in a session. Complete Envoy tool catalog with parameters and usage.
Run Embody's test suite and write new tests (Embody development)
MUST READ before calling create_op. Contains required verification, positioning, and error-checking steps.
MUST READ before writing TD Python via execute_python, set_dat_content, or edit_dat_content. API reference for parameters, storage, operators, threading.
MUST READ before calling externalize_op or save_externalization. Required workflow steps.
MUST READ before calling create_extension. Required parameters, lifecycle methods, and wiring steps.
| name | multi-instance |
| description | Workflow for running multiple TD instances with Envoy, switching between them, and understanding the instance registry. |
Envoy supports multiple TouchDesigner instances running simultaneously in the same git repo. Each instance gets its own port, and the bridge can switch between them on demand.
Claude Code <--> STDIO Bridge <--> Envoy (TD instance A, port 9870)
|
+---switch---> Envoy (TD instance B, port 9871)
activeswitch_instance redirects the bridge's HTTP target in-memory.embody/envoy.json)Each Envoy instance registers itself in .embody/envoy.json at the git root on startup:
{
"active": "Embody-5.257",
"td_executable": "/Applications/TouchDesigner.app",
"instances": {
"Embody-5.257": {
"toe_path": "dev/Embody-5.257.toe",
"port": 9870,
"td_pid": 12345
},
"MySecondProject": {
"toe_path": "MySecondProject.toe",
"port": 9871,
"td_pid": 67890
}
}
}
| Field | Purpose |
|---|---|
active | Instance the bridge currently targets |
td_executable | Path to TD app (used by launch_td) |
instances.<name>.toe_path | Relative path to the .toe file |
instances.<name>.port | Envoy HTTP port for this instance |
instances.<name>.td_pid | OS process ID of the TD process |
Instances are added on Envoy startup and removed on graceful shutdown (onDestroyTD).
Each instance picks a port from a 10-port range starting at the configured Envoyport parameter (default: 9870):
base+1 through base+9This means up to 10 simultaneous instances per base port.
.toe fileLaunch TD normally or via launch_td. Envoy starts on its configured port and registers in .embody/envoy.json.
.toe filesOpen them in separate TD instances (File > Open or double-click). Each Embody/Envoy auto-starts and claims the next available port.
Call switch_instance with no parameters to see all registered instances and their status:
switch_instance()
Returns each instance's name, port, PID, reachability (PID alive + port responding), and whether it's the active target.
switch_instance(instance="MySecondProject")
The bridge immediately redirects to the target instance's port. All subsequent MCP calls go to that TD process.
switch_instance(instance="Embody-5.257")
An instance is reachable only when:
kill -0 / process table check)Both conditions must be true. A dead PID with an open port means another instance reused that port — the entry is stale.
get_td_status includes the full instance registry with reachability in its response.
Instances are deregistered on graceful TD shutdown. If TD crashes:
.embody/envoy.json but are filtered by reachability checks.toe overwrites the stale entryPreferred: Close TD instances via Envoy by calling execute_python with project.quit(). This prompts the user to save unsaved changes, then triggers onDestroyTD for clean deregistration and port release. Works reliably across platforms.
To close a specific instance, switch_instance to it first, then send the quit command:
switch_instance(instance="MySecondProject") # target the instance
execute_python(code="project.quit()") # user gets save prompt in TD
Never use project.quit(force=True) unless the user has explicitly asked — it skips the save dialog and risks losing unsaved work.
Avoid: osascript -e 'quit app "TouchDesigner"' and similar OS-level approaches are unreliable — they may not target the correct instance and don't guarantee clean Envoy shutdown.
| Scenario | Action |
|---|---|
Test code in two .toe files side by side | Open both, switch_instance between them |
Test code in a secondary .toe | Open it, switch to it, perform work, switch back |
| Check if a second TD is still running | switch_instance() (list mode) or get_td_status |
| One instance crashed, want the other | switch_instance to the surviving instance |
| Close a specific instance | switch_instance to it, then execute_python with project.quit() |
When you open the same .toe file in multiple TD instances, Envoy auto-suffixes the registry key to avoid collisions. The first instance registers as MyProject, the second as MyProject-2, etc. Stale entries (dead PIDs) are automatically reclaimed.
.embody/envoy.json is per git root — instances in different repos have separate registrieslaunch_td always launches the .toe configured in .embody/envoy.json top-level toe_path — use TD directly to open additional files.toe file in multiple instances auto-suffixes keys (MyProject-2, -3, etc.)