Skip to content
Automation
Skill

/ltx-director

Drive the LTX Director (Timeline) node. Its Add Image/Text/Audio buttons are DOM-only and cannot be clicked by an agent; edit the hidden timeline_data JSON widget instead. Load when a workflow contains LTXDirector / LTXDirectorGuide / PromptRelayEncodeTimeline, or when asked to

From plugin
comfyui-mcp
88442 skills4 agents11 commands1 MCP

Claude Code

$ npx -y skills add artokun/comfyui-mcp --skill ltx-director --agent claude-code

SKILL.md

ltx-director.SKILL.md
name: ltx-director
description: Drive the LTX Director (Timeline) node. Its Add Image/Text/Audio buttons are DOM-only and cannot be clicked by an agent; edit the hidden timeline_data JSON widget instead. Load when a workflow contains LTXDirector / LTXDirectorGuide / PromptRelayEncodeTimeline, or when asked to add, move, retime, or remove timeline segments (image / text / audio / motion).

LTX Director (Timeline)

`LTXDirector` (pack: **WhatDreamsCost-ComfyUI**, category `WhatDreamsCost`) is a video *timeline editor* node. Its on-canvas UI has **Add Image**, **Add Text** and **Add Audio** buttons.

You cannot click those buttons. Don't try.

They are not node inputs. The pack builds them as raw DOM elements with JS handlers:

addTextBtn.addEventListener("click", () => this.addTextSegmentFreeSpace());

Panel/MCP tools drive the LiteGraph **node model** (widgets + inputs). They cannot invoke arbitrary DOM handlers, so "click Add Text" is impossible. This is a hard limitation, not flakiness. Say so plainly rather than retrying.

The real control surface: `timeline_data`

Everything those buttons do is serialized into ONE string widget, `timeline_data`. The pack's own code treats it as *"the absolute source of truth"*. Set it and the editor renders it.

It is listed in the pack's `HIDDEN_WIDGET_NAMES`, so it does **not** appear in the node's visible widget list, but it is an ordinary input and is settable:

create_workflow(action="modify", workflow=<the graph>, operations=[
  { op: "set_input", node_id: "42",
    input_name: "timeline_data", value: "<json string>" },
])

The value is a JSON **string**, not an object. Empty state is `"{}"`.

Sibling hidden widgets: `local_prompts`, `segment_lengths`, `guide_strength`, `audio_data`, `use_custom_audio`, `inpaint_audio`, `use_custom_motion`, `override_audio`.

Schema (verified against a real production workflow)

{
  // TRACK GATES — a track's segments are IGNORED unless its gate is true.
  "mainTrackEnabled": true,
  "audioTrackEnabled": false,
  "motionTrackEnabled": false,

  // must mirror the node's start_frame / duration_frames widgets (see Edges)
  "normalStartFrame": 0,
  "normalDurationFrames": 4393,

  "global_prompt": "",
  "overrideAudio": false,
  "inpaint_audio": false,

  // retake mode
  "retakeMode": false, "retakeStart": 24, "retakeLength": 48,
  "retakePrompt": "", "retakeStrength": 1, "retakeVideo": null,
  "retake_global_prompt": "",

  // display-only
  "propHeight": 90, "globalPropHeight": 60, "showFilenames": true,

  "segments": [],        // main track: image AND text segments
  "motionSegments": [],
  "audioSegments": []
}

Text segment (`segments`)

{ "id": "seg1", "start": 0, "length": 48, "prompt": "wide shot, neon city", "type": "text" }

Image segment (`segments`)

{
  "id": "1784657553220x4fxu",
  "start": 0,
  "length": 241.68,
  "prompt": "",
  "type": "image",
  "imageFile": "whatdreamscost/Nintendo_ZeldaUrbosaHotspringKF_00002_.png",
  "imageB64": "/api/view?filename=Nintendo_ZeldaUrbosaHotspringKF_00002_.png&type=input&subfolder=whatdreamscost"
}

**`imageB64` is a misnomer. It holds a `/api/view` URL, not base64.** So an image segment points at a file already in ComfyUI's **input** dir. Full agent-drivable recipe:

1. `upload_image (action:"image")` → puts the file in the input dir (note its `subfolder`/name) 2. `imageFile` = `"<subfolder>/<name>.png"` 3. `imageB64` = `"/api/view?filename=<name>.png&type=input&subfolder=<subfolder>"`

Audio segment (`audioSegments`)

{
  "id": "17846562234967gjvk", "type": "audio",
  "start": 0, "length": 4393, "trimStart": 0, "audioDurationFrames": 4393,
  "audioFile": "whatdreamscost/Intergalactic Hip Hop.mp3",
  "fileName": "Intergalactic Hip Hop.mp3",
  "waveformPeaks": [0.047, 0.274, 0.537, "…~200 floats…"]
}

`waveformPeaks` is the rendered waveform. It is cosmetic. Omit it or pass `[]` if you're writing a segment programmatically; the audio still plays. Don't fabricate plausible-looking peaks and imply they were measured.

Edges (get these wrong and it silently does nothing)

1. **Track gates.** Pushing into `audioSegments` does nothing while `audioTrackEnabled` is `false`. Set the gate in the same edit. (The reference workflow ships an audio segment with the track OFF, which is easy to misread as broken.) 2. **Frame bookkeeping must agree.** `normalDurationFrames` == `duration_frames` widget == `segment_lengths` widget (observed: all `4393`), and `normalStartFrame` == `start_frame`. Change the timeline length and you must update all of them. 3. **Frames, not seconds.** `start` / `length` are pixel-space frames and may be fractional (`241.68`). `duration_seconds` / `frame_rate` / `time_units` are display concerns. 4. **`global_prompt` exists twice**, inside `timeline_data` and as a `forceInput` socket on the node. In the reference workflow the socket is wired from a `PrimitiveStringMultiline`; prefer the wired source and keep them consistent. 5. **`guide_data` must go somewhere.** `LTXDirector.guide_data` → `LTXDirectorGuide`. That partner node is what injects the keyframes. 6. **Unsupported by the pack.** The widget tooltip says *"auto-managed; do not edit by hand"*. Well-formed blobs load fine; malformed JSON will break the editor. Round-trip and re-read after writing, and tell the user this is unofficial.

Reference wiring (from a working LTX 2.3 Director graph)

Power Lora Loader (rgthree) ─ model ─┐
DualCLIPLoader ──────────── clip ────┤
VAELoaderKJ ───────────── audio_vae ─┤   LTXDirector #42
PrimitiveStringMultiline ─ global_prompt ─┘
        │ model         → LTX2_NAG
        │ positive      → ConditioningZeroOut, LTXVConditioning
        │ audio_latent  → LTXVConcatAVLatent
        │ guide_data    → LTXDirectorGuide   ← required partner
        │ frame_rate    → AudioToFrameCount, VHS_VideoCombine
        └ comb
Read more
@artokun
Ships withcomfyui-mcp

<img src="docs/images/demo-poster.jpg" width="760" alt="The Agent panel driving ComfyUI end to end. Click to watch the demo"> The Agent panel driving ComfyUI end to end. It reads what is installed locally, wires the graph, frees VRAM, and runs the render.

88442 skills4 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
884
Star history of artokun/comfyui-mcp on GitHub, a chart by star-history.com

Other skills on comfyui-mcp.

ai-toolkit-trainer

ai-toolkit-trainer

Train custom LoRAs with ostris AI-Toolkit. Covers WAN 2.2/2.1 (people, styles, video motion) and Z-Image (Turbo & Base, low-VRAM…

@artokun@artokunInstall Skill
anima-base

anima-base

Anime/illustration text-to-image (ANIMA 1.0, ~2B Cosmos DiT). Use for anime, manga, illustrated characters; accepts Danbooru tags…

@artokun@artokunInstall Skill
anima-lora-trainer

anima-lora-trainer

Train a custom anime LoRA on the ANIMA base model with Citron's local Gradio trainer (kohya sd-scripts), <6GB VRAM,…

@artokun@artokunInstall Skill
civitai

civitai

Discover Civitai models with the BUILT-IN download_model action:"search_civitai" and install/generate them locally. Find a…

@artokun@artokunInstall Skill
color-correction

color-correction

Diagnose and fix video/image color OBJECTIVELY with the get_image (action:"analyze_color") tool (scopes/stats such as black/white…

@artokun@artokunInstall Skill
comfyui-core

comfyui-core

Core ComfyUI knowledge covering workflow format, node types, pipeline patterns, and MCP tool usage

@artokun@artokunInstall Skill

More skills from other plugins.

agent-builder

agent-builder

Load immediately after an Agent intent, before the first agent_builder_* call. Governs how you create, configure, test, and…

n8n11d209k
@n8n-io@n8n-ioInstall Skill
browser-use

browser-use

Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…

@browser-use@browser-useInstall Skill
agent-browser

agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…

@vercel-labs-2@vercel-labs-2Install Skill
add-anydoc

add-anydoc

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when…

@nanocoai@nanocoaiInstall Skill

Questions about ltx-director.

Which coding agents can use ltx-director?
ltx-director installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.