Skip to main content

MCP tool for assembling multiple source media files into a single OTIO timeline (multi-source sequence builder).

Project description

clipwright-sequence

MCP tool that assembles multiple source media files into a single multi-source OTIO timeline for concatenation by clipwright-render.

Overview

clipwright-sequence accepts an ordered list of clip specifications and emits a single OTIO timeline file (one V1 video track; A1 audio track left empty for BGM or mixing by the calling agent). The timeline is consumed unchanged by clipwright-render, which concatenates the clips into a single output video.

This fills the gap between single-source tools and multi-clip programs: every other clipwright tool starts from one media file. clipwright-sequence is the authoring primitive that builds a multi-source program OTIO before the final render pass.

Design principle (M3 — separation of annotation and realisation): clipwright-sequence writes only the OTIO; it does not transcode or touch media files. All media processing is deferred to clipwright-render.

Prerequisites

  • Python 3.11 or later
  • clipwright core package (shared types, envelope, OTIO utils)
  • CLIPWRIGHT_FFPROBE environment variable (or ffprobe on PATH) — used to probe each source's duration and confirm video stream presence before building the timeline

No FFmpeg is needed at sequence-build time; FFmpeg is only invoked by clipwright-render at realisation time.

MCP Tool: clipwright_build_sequence

Parameters

Name Type Default Description
clips list[SequenceClip] required Ordered list of clip specifications to assemble. Maximum 1000 entries per call (DC-GP-003).
clips[].media string required Path to the source media file. Must be co-located under the output directory (see Co-location Constraint).
clips[].start_sec float | null null0.0 Start of the clip in seconds from the beginning of the source. Must be ≥ 0.
clips[].end_sec float | null null → full duration End of the clip in seconds from the beginning of the source. Must be > 0 and ≤ source duration.
output string required Output OTIO timeline file path (.otio extension required). The parent directory must exist.

Return value

{
  "ok": true,
  "summary": "Assembled a 3-clip sequence (approx total 45.2s) from 2 source(s). Generated sequence.otio. Pass it to clipwright-render to concatenate into a single video.",
  "data": {
    "clip_count": 3,
    "total_duration_sec": 45.2,
    "unique_source_count": 2
  },
  "artifacts": [{"role": "timeline", "path": "sequence.otio", "format": "otio"}],
  "warnings": []
}

Note on total_duration_sec: This value is an approximate estimate computed as the sum of the input clip ranges (DC-AM-003). The rendered output duration may differ slightly after per-frame normalisation in clipwright-render.

Error codes

Code Cause
INVALID_INPUT clips is empty, exceeds 1000 entries, contains an invalid range (start_sec >= end_sec, end_sec > source duration), or output has a non-.otio extension
INVALID_INPUT output parent directory does not exist
INVALID_INPUT A source file has no video stream (audio-only file)
INVALID_INPUT A source file's frame rate is undetermined (e.g. still-image stream or unusual capture device)
FILE_NOT_FOUND A source media path does not exist
PATH_NOT_ALLOWED A source file is located outside the output directory tree (co-location violation)
PATH_NOT_ALLOWED output path and a source media path resolve to the same file
PROBE_FAILED ffprobe could not determine a source's duration (corrupted file)
DEPENDENCY_MISSING ffprobe binary not found (CLIPWRIGHT_FFPROBE unset and not on PATH)

Co-location Constraint

All source media files must be located under the same directory as the output .otio file (or in a recursive subdirectory of it).

Why this mirrors clipwright-render's rule — not a relaxation of it: clipwright-render enforces a PATH_NOT_ALLOWED boundary: every source referenced in an OTIO timeline must be co-located with the timeline file. If clipwright-sequence were to accept sources from outside that boundary, the produced .otio would be valid at build time but would fail immediately when passed to clipwright-render.

By enforcing the same co-location rule at sequence-build time, clipwright-sequence guarantees that any .otio it produces will round-trip through clipwright-render without a PATH_NOT_ALLOWED error. The constraint is a forward-compatibility guarantee, not an arbitrary restriction.

Recursive subdirectories are permitted: sources may live anywhere inside the tree rooted at the output's parent directory.

project/
  intro.mp4          ← allowed (same directory)
  footage/
    main.mp4         ← allowed (subdirectory)
    broll.mp4        ← allowed (subdirectory)
  sequence.otio      ← output
/other/path/clip.mp4  ← PATH_NOT_ALLOWED

Symlink Sources

Symlink sources are not supported (DC-AS-005). Resolve symlinks to their real paths before passing them to this tool.

Two-Phase Workflow

clipwright_build_sequence(clips, output)     # Phase 1 — build OTIO
        │
        ▼  OTIO timeline with ordered V1 clips
clipwright_render(timeline, output_media)    # Phase 2 — concatenate and encode
        │
        ▼  single output video (intro + main + outro, or any sequence)

clipwright-sequence can be combined with other directive tools before the final render:

clipwright_build_sequence → clipwright_detect_color → clipwright_reduce_noise → clipwright_render

MCP Client Registration

Register clipwright-sequence as a standalone MCP server in your client configuration (.mcp.json / claude_desktop_config.json). CLIPWRIGHT_FFPROBE is required.

{
  "mcpServers": {
    "clipwright-sequence": {
      "command": "clipwright-sequence",
      "env": {
        "CLIPWRIGHT_FFPROBE": "/path/to/ffprobe"
      }
    }
  }
}

clipwright-render (which materialises the OTIO into a video) still requires CLIPWRIGHT_FFMPEG.

Usage Examples

Assemble intro + main + outro

# Via MCP call_tool
result = await session.call_tool("clipwright_build_sequence", {
    "clips": [
        {"media": "/project/intro.mp4"},
        {"media": "/project/main.mp4", "start_sec": 10.0, "end_sec": 130.0},
        {"media": "/project/outro.mp4"}
    ],
    "output": "/project/sequence.otio"
})
# Then render
render_result = await session.call_tool("clipwright_render", {
    "timeline": "/project/sequence.otio",
    "output": "/project/final.mp4"
})

Splice two gameplay segments

result = await session.call_tool("clipwright_build_sequence", {
    "clips": [
        {"media": "/project/gameplay.mp4", "start_sec": 60.0, "end_sec": 180.0},
        {"media": "/project/gameplay.mp4", "start_sec": 300.0, "end_sec": 420.0}
    ],
    "output": "/project/highlights.otio"
})

The same source file may appear multiple times (with different ranges). Each unique source is probed exactly once.

B-roll interleave

result = await session.call_tool("clipwright_build_sequence", {
    "clips": [
        {"media": "/project/interview.mp4", "start_sec": 0.0, "end_sec": 30.0},
        {"media": "/project/broll/cityscape.mp4"},
        {"media": "/project/interview.mp4", "start_sec": 30.0, "end_sec": 60.0}
    ],
    "output": "/project/edited.otio"
})

Installation

Within a uv workspace:

uv run --package clipwright-sequence clipwright-sequence

Or install from PyPI:

pip install clipwright-sequence
clipwright-sequence

License

MIT — See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clipwright_sequence-0.2.1.tar.gz (11.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

clipwright_sequence-0.2.1-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

File details

Details for the file clipwright_sequence-0.2.1.tar.gz.

File metadata

  • Download URL: clipwright_sequence-0.2.1.tar.gz
  • Upload date:
  • Size: 11.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for clipwright_sequence-0.2.1.tar.gz
Algorithm Hash digest
SHA256 c7533e5c81e73a0fc9080f0282e56aac66c9ab164fde81a2df772169de5674ef
MD5 35655cf7dad9a3716c5cf94933a5e64a
BLAKE2b-256 9fe8d1710947d3358adfbe983930c07b5ac46b8243bfd89a8df33033e35f8630

See more details on using hashes here.

Provenance

The following attestation bundles were made for clipwright_sequence-0.2.1.tar.gz:

Publisher: publish.yml on satoh-y-0323/clipwright

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file clipwright_sequence-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for clipwright_sequence-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d3c1643438430d868140e20a67e8ce698fda0f9b14f66e4439f3cb5ef9f3148d
MD5 5ab40b79bc3c7efb78ead1778e3a669c
BLAKE2b-256 46f144b72600561c2d7453aeeacad61100d488b31a20e2aea7c091b5ae85adca

See more details on using hashes here.

Provenance

The following attestation bundles were made for clipwright_sequence-0.2.1-py3-none-any.whl:

Publisher: publish.yml on satoh-y-0323/clipwright

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page