Agent-first video cutting library — declarative JSON edits powered by FFmpeg
Project description
CutAgent
Agent-first video cutting library — declarative JSON edits powered by FFmpeg.
CutAgent is designed from the ground up for AI agents and programmatic video editing. Every CLI command outputs structured JSON. Every operation is composable through a declarative Edit Decision List (EDL) format. No GUI, no human-formatted text — just clean machine-readable interfaces for professional video cutting.
Why CutAgent?
- Agent-first: Every command returns structured JSON — built for LLM tool use, not human eyes
- Declarative EDL: Describe your edit as a JSON document, execute it in one call
- Zero runtime dependencies: Pure Python + FFmpeg — nothing else to install
- Content intelligence: Scene detection, silence detection, audio levels, keyframe analysis
- Professional operations: Trim, split, concat, reorder, extract, fade with crossfade transitions
- Structured errors: Error codes, recovery hints, and context in every failure response
Requirements
- Python 3.10+
- FFmpeg and FFprobe on
$PATH
Installation
From GitHub:
pip install git+https://github.com/DaKev/cutagent.git
From source (development):
git clone https://github.com/DaKev/cutagent.git
cd cutagent
pip install -e ".[dev]"
Quick Start
Python API
from cutagent import probe, trim, execute_edl
# Inspect a video
info = probe("interview.mp4")
print(info.duration, info.width, info.height)
# Trim a segment
result = trim("interview.mp4", start="00:02:15", end="00:05:40", output="clip.mp4")
# Execute a full edit decision list
edl = {
"version": "1.0",
"inputs": ["interview.mp4"],
"operations": [
{"op": "trim", "source": "interview.mp4", "start": "00:02:15", "end": "00:05:40"},
{"op": "trim", "source": "interview.mp4", "start": "00:12:00", "end": "00:14:30"},
{"op": "concat", "segments": ["$0", "$1"]}
],
"output": {"path": "highlight.mp4", "codec": "copy"}
}
result = execute_edl(edl)
CLI (AI-Native — all output is JSON)
# Discover capabilities (returns machine-readable schema)
cutagent capabilities
# Probe a video
cutagent probe interview.mp4
# Get keyframe positions
cutagent keyframes interview.mp4
# Detect scene boundaries
cutagent scenes interview.mp4 --threshold 0.3
# Build a full content summary (scenes + silence + audio levels)
cutagent summarize interview.mp4
# Trim
cutagent trim interview.mp4 --start 00:02:15 --end 00:05:40 -o clip.mp4
# Split at multiple points
cutagent split interview.mp4 --at 00:05:00,00:10:00 --prefix segment
# Concatenate
cutagent concat clip1.mp4 clip2.mp4 -o merged.mp4
# Extract audio
cutagent extract interview.mp4 --stream audio -o audio.aac
# Validate an EDL without executing
cutagent validate edit.json
# Execute an EDL
cutagent execute edit.json
EDL Format
The Edit Decision List is a declarative JSON format for multi-step edits. Operations run sequentially; $N references the output of operation N:
{
"version": "1.0",
"inputs": ["interview.mp4", "broll.mp4"],
"operations": [
{"op": "trim", "source": "interview.mp4", "start": "00:01:00", "end": "00:03:00"},
{"op": "trim", "source": "broll.mp4", "start": "00:00:10", "end": "00:00:20"},
{"op": "fade", "source": "$1", "fade_in": 0.5, "fade_out": 0.5},
{"op": "concat", "segments": ["$0", "$2"], "transition": "crossfade", "transition_duration": 0.5}
],
"output": {"path": "final.mp4", "codec": "libx264"}
}
Available operations: trim, split, concat, reorder, extract, fade
Architecture
┌──────────────────────────────────────────────────────────────────┐
│ cutagent (CLI / Python API) │
├──────────────────┬─────────────────┬─────────────────────────────┤
│ cli.py │ engine.py │ validation.py │
│ JSON output │ EDL execution │ Dry-run validation │
├──────────────────┼─────────────────┼─────────────────────────────┤
│ probe.py │ operations.py │ models.py │
│ Media analysis │ Video ops │ Typed dataclasses │
├──────────────────┴─────────────────┴─────────────────────────────┤
│ ffmpeg.py (subprocess wrappers) │ errors.py (error codes) │
└──────────────────────────────────────────────────────────────────┘
ffmpeg.pyis the only module that spawns subprocessesmodels.pyanderrors.pyhave zero internal dependencies- All public functions return typed dataclasses, never raw dicts
- The CLI outputs JSON exclusively — designed for machine consumption
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Validation error (bad input, invalid EDL) |
| 2 | Execution error (FFmpeg failed) |
| 3 | System error (FFmpeg not found, permissions) |
Error Handling
Every error includes a code, message, and recovery suggestions:
{
"error": true,
"code": "TRIM_BEYOND_DURATION",
"message": "End time 01:00:00 (3600.000s) exceeds duration (120.500s)",
"recovery": [
"Source duration is 120.500s — set end to 120.500 or less",
"Run 'cutagent probe <file>' to check the actual duration"
],
"context": {"source": "clip.mp4", "duration": 120.5, "end": "01:00:00"}
}
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines on:
- Setting up the development environment
- Architecture principles and code style
- Adding new operations
- The JSON output contract
License
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
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 cutagent-0.1.0.tar.gz.
File metadata
- Download URL: cutagent-0.1.0.tar.gz
- Upload date:
- Size: 37.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02b6ea340734833631c30a6fdd92b2cacdbb241fe7153f6c3308582a16aa4361
|
|
| MD5 |
8583680ed0ee7f5af9347deac99959a2
|
|
| BLAKE2b-256 |
5b6067e3434798a524c9ff1c14e96909d67507f10a3a79ac83530d68c6c83a55
|
Provenance
The following attestation bundles were made for cutagent-0.1.0.tar.gz:
Publisher:
publish.yml on DaKev/cutagent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cutagent-0.1.0.tar.gz -
Subject digest:
02b6ea340734833631c30a6fdd92b2cacdbb241fe7153f6c3308582a16aa4361 - Sigstore transparency entry: 953596150
- Sigstore integration time:
-
Permalink:
DaKev/cutagent@a165b325749b5ae0ea77bc092d376fd8b3ef35d5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/DaKev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a165b325749b5ae0ea77bc092d376fd8b3ef35d5 -
Trigger Event:
release
-
Statement type:
File details
Details for the file cutagent-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cutagent-0.1.0-py3-none-any.whl
- Upload date:
- Size: 32.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1891562d2f8e02136e500460b8a655fda75385c4be0fae393b9d3c1f598ef37a
|
|
| MD5 |
427f4b4e8146c9a643d5ff5e248b8282
|
|
| BLAKE2b-256 |
a47135549055aeb60a485c65e86ecae2fbb24ccee06e2a0631be3a9671f8c912
|
Provenance
The following attestation bundles were made for cutagent-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on DaKev/cutagent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cutagent-0.1.0-py3-none-any.whl -
Subject digest:
1891562d2f8e02136e500460b8a655fda75385c4be0fae393b9d3c1f598ef37a - Sigstore transparency entry: 953596153
- Sigstore integration time:
-
Permalink:
DaKev/cutagent@a165b325749b5ae0ea77bc092d376fd8b3ef35d5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/DaKev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a165b325749b5ae0ea77bc092d376fd8b3ef35d5 -
Trigger Event:
release
-
Statement type: