MCP tool for adding transition directives (fade, dissolve, fadeblack, fadewhite) to an OTIO timeline for realisation by clipwright-render.
Project description
clipwright-transition
MCP tool that adds transition directives (fade, dissolve, fadeblack, fadewhite) to an
OTIO timeline for realisation by clipwright-render.
Overview
clipwright-transition accepts an OTIO timeline (typically produced by
clipwright-sequence) and annotates it with transition directives at clip boundaries.
The directives are stored in metadata["clipwright"]["transition"] and consumed by
clipwright-render, which materialises them as xfade/acrossfade filter chains during
the final encoding pass.
Design principle (separation of annotation and realisation):
clipwright-transition writes only the OTIO directive; it does not transcode or touch
media files. All media processing is deferred to clipwright-render.
No FFmpeg or FFprobe is needed at transition-annotation time.
Prerequisites
- Python 3.11 or later
clipwrightcore package (shared types, envelope, OTIO utils)- An OTIO timeline with two or more video clips on a single V1 track (e.g. produced by
clipwright-sequence)
MCP Tool: clipwright_add_transition
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
timeline |
string |
required | Path to the input OTIO timeline file (.otio extension required). |
output |
string |
required | Output OTIO timeline file path (.otio extension required, must differ from timeline). The parent directory must exist. |
options |
AddTransitionOptions |
required | Transition mode: either uniform (apply the same transition to all internal boundaries) or per_boundary (specify per-boundary transitions). Exactly one must be provided. |
options.uniform |
TransitionSpec | null |
null |
Apply a single transition spec to every internal clip boundary. |
options.uniform.type |
string |
required | Transition type: "fade", "dissolve", "fadeblack", or "fadewhite". |
options.uniform.duration_sec |
float |
required | Transition duration in seconds (0 < duration ≤ 5.0). |
options.per_boundary |
list[BoundaryTransition] | null |
null |
Per-boundary transition list (max 1000 entries). All internal boundaries must be covered (no partial/gapped specification in v1). |
options.per_boundary[].after_clip_index |
int |
required | Zero-based index of the clip before the boundary (≥ 0). |
options.per_boundary[].type |
string |
required | Transition type (same allowlist as uniform.type). |
options.per_boundary[].duration_sec |
float |
required | Transition duration in seconds (same constraint as uniform.duration_sec). |
Return value
{
"ok": true,
"summary": "Applied dissolve transition (0.5s) to 2 boundary(ies) [uniform mode]. Generated output.otio. Pass it to clipwright-render to materialise the transitions.",
"data": {
"boundary_count": 2,
"mode": "uniform"
},
"artifacts": [{"role": "timeline", "path": "output.otio", "format": "otio"}],
"warnings": []
}
Error codes
| Code | Cause |
|---|---|
INVALID_INPUT |
output has a non-.otio extension |
INVALID_INPUT |
output parent directory does not exist |
INVALID_INPUT |
output resolves to the same path as timeline |
INVALID_INPUT |
The timeline has fewer than two video clips |
INVALID_INPUT |
The timeline has no video track or two or more video tracks |
INVALID_INPUT |
The timeline already contains an OTIO Transition object |
INVALID_INPUT |
A per_boundary index is out of range [0, n_clips-2] |
INVALID_INPUT |
per_boundary contains duplicate after_clip_index values |
UNSUPPORTED_OPERATION |
per_boundary does not cover all internal boundaries (partial/gapped specification is unsupported in v1; use uniform or specify all n_clips-1 boundaries) |
FILE_NOT_FOUND |
The timeline path does not exist |
Three-Phase Workflow
clipwright_build_sequence(clips, output) # Phase 1 — build multi-clip OTIO
│
▼ OTIO timeline with ordered V1 clips
clipwright_add_transition(timeline, output, opts) # Phase 2 — annotate transitions
│
▼ OTIO timeline with transition directives
clipwright_render(timeline, output_media) # Phase 3 — encode with transitions
│
▼ single output video with crossfades
MCP Client Registration
Register clipwright-transition as a standalone MCP server in your client configuration
(.mcp.json / claude_desktop_config.json). No environment variables are required at
annotation time.
{
"mcpServers": {
"clipwright-transition": {
"command": "clipwright-transition"
}
}
}
clipwright-render (which materialises the transitions into a video) requires
CLIPWRIGHT_FFMPEG.
Usage Examples
Apply a uniform dissolve between all clips
# Via MCP call_tool
result = await session.call_tool("clipwright_add_transition", {
"timeline": "/project/sequence.otio",
"output": "/project/with_transitions.otio",
"options": {
"uniform": {"type": "dissolve", "duration_sec": 0.5}
}
})
# Then render
render_result = await session.call_tool("clipwright_render", {
"timeline": "/project/with_transitions.otio",
"output": "/project/final.mp4"
})
Apply per-boundary transitions
result = await session.call_tool("clipwright_add_transition", {
"timeline": "/project/sequence.otio",
"output": "/project/with_transitions.otio",
"options": {
"per_boundary": [
{"after_clip_index": 0, "type": "fade", "duration_sec": 1.0},
{"after_clip_index": 1, "type": "fadeblack", "duration_sec": 0.5}
]
}
})
Note: All internal boundaries must be covered in v1. For a 3-clip timeline (
after_clip_indexvalues0and1are the two internal boundaries), both must be specified. Partial/gapped specification will returnUNSUPPORTED_OPERATION.
Non-Destructive Guarantee
clipwright-transition never modifies the input timeline file. It always writes a
new OTIO file to output. Existing metadata["clipwright"] keys (from other tools)
are preserved; only the "transition" key is added.
Installation
Within a uv workspace:
uv run --package clipwright-transition clipwright-transition
Or install from PyPI:
pip install clipwright-transition
clipwright-transition
License
MIT — See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file clipwright_transition-0.1.0.tar.gz.
File metadata
- Download URL: clipwright_transition-0.1.0.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51af26a8806d878bf977baa7bff0284d3e89d5fe6b16c6fff2ffe6d8393d56de
|
|
| MD5 |
5241f9789bacefefb0d555c14a57e5fa
|
|
| BLAKE2b-256 |
b481646dfd4efd185e95eb83687b95884903f9f36dd1a2570b68042a8e828a20
|
Provenance
The following attestation bundles were made for clipwright_transition-0.1.0.tar.gz:
Publisher:
publish.yml on satoh-y-0323/clipwright
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
clipwright_transition-0.1.0.tar.gz -
Subject digest:
51af26a8806d878bf977baa7bff0284d3e89d5fe6b16c6fff2ffe6d8393d56de - Sigstore transparency entry: 1929163452
- Sigstore integration time:
-
Permalink:
satoh-y-0323/clipwright@756002a76bfceae2fc823881f0db4ad0ac9fa6a7 -
Branch / Tag:
refs/tags/v0.16.0 - Owner: https://github.com/satoh-y-0323
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@756002a76bfceae2fc823881f0db4ad0ac9fa6a7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file clipwright_transition-0.1.0-py3-none-any.whl.
File metadata
- Download URL: clipwright_transition-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e48283b143a14f5445f67734908ccab59f9e78aa670e1c24566e47cd4f71619
|
|
| MD5 |
91092f8151877d1d70c6af6157fd2389
|
|
| BLAKE2b-256 |
e87611e0bb83486a9e7dc40997c08ab70e2ef9112687ee0f06f33e581c568956
|
Provenance
The following attestation bundles were made for clipwright_transition-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on satoh-y-0323/clipwright
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
clipwright_transition-0.1.0-py3-none-any.whl -
Subject digest:
4e48283b143a14f5445f67734908ccab59f9e78aa670e1c24566e47cd4f71619 - Sigstore transparency entry: 1929163978
- Sigstore integration time:
-
Permalink:
satoh-y-0323/clipwright@756002a76bfceae2fc823881f0db4ad0ac9fa6a7 -
Branch / Tag:
refs/tags/v0.16.0 - Owner: https://github.com/satoh-y-0323
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@756002a76bfceae2fc823881f0db4ad0ac9fa6a7 -
Trigger Event:
push
-
Statement type: