Skip to main content
Glama

Kdenlive MCP Server

A Model Context Protocol (MCP) server wrapping cli-anything-kdenlive for LLM-driven video editing workflows via Kdenlive.

Overview

This FastMCP server enables AI models to perform complex video editing tasks on Kdenlive projects through a set of 75 tools. The server uses the Python API of cli-anything-kdenlive directly (not subprocess) to maintain a persistent session state, ensuring modifications are immediately available to subsequent tool calls.

Key Features

  • Persistent Session State: Uses CLI's in-memory session API, auto-saves after every mutation

  • Gen 5 XML Export: Kdenlive-compatible XML output with proper bin references and version metadata

  • Robust Error Handling: All exceptions caught and returned as structured JSON payloads

  • Auto-Project Tracking: Globally tracks project path; all tools automatically target the active project

  • 75 MCP Tools: Comprehensive coverage of Kdenlive operations

Related MCP server: Cutible MCP Server

Installation

Prerequisites

# Python 3.10+
# Ensure uv is installed for dependency management
pip install uv

Install Dependencies

cd kdenlive-mcp-server
uv sync

Usage

As an MCP Server

The server runs as a FastMCP server compatible with any LLM platform that supports MCP (e.g., Claude Code, Pi, OpenCode).

Command Line

# Run the MCP server
uv run kdenlive-mcp

# Or directly via Python
uv run python3 -m kdenlive_mcp_server.server

Python Integration

from kdenlive_mcp_server.server import (
    project_new, bin_import_clip, timeline_add_clip, export_xml
)

# Create project
result = project_new(output_path="my_project.kdenlive-cli.json", profile="hd1080p30")

# Import media
result = bin_import_clip(clip_path="video.mp4", name="Interview", duration=120.0)

# Add to timeline
result = timeline_add_clip(clip_id="clip0", track=0, position=0.0)

# Export XML
result = export_xml(output_path="output.kdenlive")

Project Structure

kdenlive-mcp-server/
├── kdenlive_mcp_server/
│   ├── __init__.py           # Empty package init
│   └── server.py             # FastMCP server with 75 tools
├── main.py                   # Entry point delegating to server module
├── pyproject.toml            # Project configuration and dependencies
├── uv.lock                   # Dependency lock file
└── README.md                 # This file

Tools

Project (5 tools)

Tool

Description

project_new()

Create a new Kdenlive project with optional profile override

project_open()

Load an existing .kdenlive-cli.json project

project_save()

Persist the current project state to disk

project_get_info()

Get project metadata (resolution, FPS, track layout, clip counts)

project_list_profiles()

List all available video output profiles (hd1080p30, 4k60, sd_pal, etc.)

Bin (4 tools)

Tool

Description

bin_import_clip()

Ingest media files (video, audio, image) into the project bin

bin_remove_clip()

Delete a clip from the bin by ID

bin_list_clips()

List all assets in the project bin

bin_get_clip_details()

Fetch detailed properties of a clip (duration, type, source)

Timeline (8 tools)

Tool

Description

timeline_add_track()

Append a video or audio track to the timeline

timeline_remove_track()

Delete a track and all its clips

timeline_add_clip()

Place a bin clip on a track at a specific position

timeline_remove_clip()

Remove a clip from a track

timeline_move_clip()

Reposition a clip on the same track

timeline_trim_clip()

Adjust clip in/out crop handles

timeline_split_clip()

Cut a clip into two pieces at a precise offset

timeline_list()

List all tracks with clip counts and status

Filters (5 tools)

Tool

Description

filter_add()

Attach a video/audio effect (blur, brightness, frei0r.opacity, volume)

filter_remove()

Remove an effect from a clip

filter_set_param()

Update a single filter parameter (radius, opacity, level)

filter_list()

List all active filters on a clip

filter_list_available()

Discover all available filters by category

Transitions (4 tools)

Tool

Description

transition_add()

Create blend transitions (dissolve, wipe, slide, composite, affine)

transition_remove()

Delete a transition by ID

transition_set()

Update a transition parameter

transition_list()

List all transitions on the timeline

Guides (3 tools)

Tool

Description

guide_add()

Add timeline markers/chapters

guide_remove()

Remove a guide by ID

guide_list()

List all guide markers

Export (3 tools)

Tool

Description

export_xml()

Generate Kdenlive/MLT XML for the project

export_list_presets()

List available render presets

export_render()

Render project to video via melt CLI

Session (4 tools)

Tool

Description

session_undo()

Revert the most recent operation (up to 50 history entries)

session_redo()

Redo the last undone operation

session_status()

Inspect session state (project loaded, modified flag, history depth)

session_history()

List all undo/redo history entries

Batch Editing & Vertical Video (new in 0.2.0)

Tool

Description

timeline_build_from_segments()

Place many keep-segments of one bin clip back to back in a single, single-undo call

clip_reframe_vertical()

Center-crop a 16:9 clip to fill a 9:16 frame, with a horizontal pan

timeline_build_from_segments(clip_id, segments, track=0, start=0.0, gap=0.0, include_audio=True, audio_track=None)

Cutting a long take with timeline_split_clip / timeline_remove_clip is fragile because every removal shifts the clip_index of the clips after it. Instead, compute the ranges you want to keep and place them all at once:

timeline_add_track()  # video track 0
timeline_build_from_segments(
    clip_id="clip0",
    segments=[{"start": 0.5, "end": 1.5}, {"start": 3.0, "end": 4.5}, {"start": 6.0, "end": 8.0}],
)
# -> {"placed": 3, "timeline_duration": 4.5, "kept_seconds": 4.5, "track": 0, "audio_track": 1, ...}
  • segments is a list of {start, end} in source seconds, or a path to a JSON file containing {"segments": [...]}.

  • Segments are sorted, clamped to the clip's duration, merged where they overlap or touch, and dropped if shorter than 0.05 s. An empty result is an error.

  • Segments are laid out from start, separated by gap seconds.

  • Clips on a video track render without sound, so when the source has an audio stream the same segments are mirrored onto an audio track (the first existing one, or a new A1). Pass include_audio=False to skip this, or audio_track=<id> to choose the track.

  • The whole build, including any auto-created audio track, is one undo step: a single session_undo() reverts it.

clip_reframe_vertical(track_id, clip_index, x_offset=0.0)

For Shorts/Reels/TikTok, start the project with a vertical profile (vertical1080p30 or vertical1080p60, both 1080x1920), then reframe each landscape clip:

project_new("short.kdenlive-cli.json", profile="vertical1080p30")
# ... import + timeline_build_from_segments ...
clip_reframe_vertical(track_id=0, clip_index=0)                 # center
clip_reframe_vertical(track_id=0, clip_index=1, x_offset=-0.5)  # pan left

The source is scaled so its height fills the frame, then shifted horizontally: x_offset -1 shows the left edge, 0 the center, 1 the right edge. It adds an affine filter (Kdenlive's Transform effect) with a transition.rect; calling it again on the same clip updates that filter instead of stacking another. Center crop only, no face tracking.

Example Workflows

Create a Simple Video Project

from kdenlive_mcp_server.server import (
    project_new, bin_import_clip, timeline_add_track,
    timeline_add_clip, export_xml, project_save
)

# 1. Create project
result = project_new(
    output_path="intro_video.kdenlive-cli.json",
    profile="hd1080p30",
    name="Introduction"
)

# 2. Import media
result = bin_import_clip(
    clip_path="interview.mp4",
    name="Interview",
    duration=120.0
)

# 3. Add track and place clip
result = timeline_add_track(track_type="video", track_name="V1")
result = timeline_add_clip(
    clip_id="clip0",  # From bin_import_clip response
    track=0,
    position=0.0
)

# 4. Export
result = export_xml(output_path="intro.kdenlive")

Apply Effects to Clips

from kdenlive_mcp_server.server import (
    project_new, bin_import_clip, timeline_add_track,
    timeline_add_clip, filter_add, filter_set_param, filter_list
)

# Setup
result = project_new(output_path="effects_demo.kdenlive-cli.json", profile="hd720p60")
result = bin_import_clip(clip_path="movie.mp4", name="Movie", duration=300.0)
result = timeline_add_track(track_type="video")
result = timeline_add_clip(clip_id="clip0", track=0, position=0.0)

# Add brightness filter
result = filter_add(
    track_id=0,
    clip_index=0,
    filter_type="brightness",
    params=["level=0.8"]
)

# Update brightness
result = filter_set_param(
    track_id=0,
    clip_index=0,
    filter_index=0,
    parameter="level",
    value="1.2"
)

# List filters
result = filter_list(track_id=0, clip_index=0)

Add Chapter Markers

from kdenlive_mcp_server.server import (
    project_new, bin_import_clip, timeline_add_track,
    timeline_add_clip, guide_add, guide_list, project_save
)

# Setup
result = project_new(output_path="documentary.kdenlive-cli.json", profile="4k30")
result = bin_import_clip(clip_path="documentary.mp4", name="Doc", duration=900.0)
result = timeline_add_track(track_type="video")
result = timeline_add_clip(clip_id="clip0", track=0, position=0.0)

# Add chapter markers
result = guide_add(position=60.0, label="Chapter 1: Introduction", guide_type="chapter")
result = guide_add(position=180.0, label="Chapter 2: Main Content", guide_type="chapter")
result = guide_add(position=300.0, label="Chapter 3: Conclusion", guide_type="chapter")

# List guides
result = guide_list()

# Save
result = project_save()

Error Handling

All tools return consistent response formats:

# Success
{
    "success": True,
    "data": {...}
}

# Error
{
    "success": False,
    "error": "Error message describing the failure"
}

Configuration

pyproject.toml

[project]
name = "kdenlive-mcp-server"
version = "0.1.0"
description = "MCP server for Kdenlive video editing via cli-anything-kdenlive"
requires-python = ">=3.10"
dependencies = [
    "mcp>=1.28.0",
    "cli-anything-kdenlive>=1.0.0",
]

[project.scripts]
kdenlive-mcp = "kdenlive_mcp_server.server:main"

[tool.uv.sources]
cli-anything-kdenlive = { git = "https://github.com/HKUDS/CLI-Anything.git", subdirectory = "kdenlive/agent-harness" }

uv.lock

Auto-generated by uv sync. Contains locked dependency versions.

Dependencies

Troubleshooting

Kdenlive XML Compatibility Issues

If Kdenlive reports "Version of the project file cannot be read" or "Timeline clip without bin reference found":

  1. Cause: Using PyPI v1.0.0 (Gen 4 format) which lacks proper Kdenlive metadata

  2. Fix: The package now installs from GitHub HEAD with Gen 5 format that includes:

    • kdenlive:docproperties.version="1.1"

    • Chain-based clip structure with kdenlive:id linking to main_bin

    • Proper bin reference handling

Project Not Saving

The server auto-saves to disk after every mutation. If changes aren't persisting:

  1. Verify the project path is set via project_new() or project_open()

  2. Check that session_status() shows has_project: true

  3. Ensure the output directory is writable

FastMCP Server Not Starting

  1. Verify MCP version: uv run python3 -c "import mcp; print(mcp.__version__)"

  2. Check FastMCP: uv run python3 -c "from mcp.server.fastmcp import FastMCP; print('FastMCP OK')"

  3. Review logs for detailed error messages

Development

Testing

Run the test suite:

# Run all integration tests
uv run python3 test_integration.py

# Test with zero-duration edge case
uv run python3 test_edge_cases.py

Code Style

The project follows PEP 8 style guidelines. Use uv run ruff check . to lint.

Adding New Tools

To add a new MCP tool:

  1. Add the tool function to server.py decorated with @server.tool()

  2. Import the corresponding CLI API module if needed

  3. Include comprehensive docstrings with Args and Returns sections

  4. Implement error handling with try/except

  5. Call _save() after mutations to persist changes

Example:

@server.tool()
def my_new_tool(param1: str, param2: int) -> dict[str, Any]:
    """Brief description of what the tool does.

    Args:
        param1: Description of param1.
        param2: Description of param2.

    Returns:
        Success response format.
    """
    err = _require_project()
    if err:
        return err

    try:
        # Do something with the project
        result = some_api_function(param1, param2)
        _save()
        return _ok(result)
    except Exception as e:
        return _err(str(e))

Contributing

  1. Fork the repository

  2. Create a feature branch

  3. Add tests for new functionality

  4. Ensure all tests pass: uv run pytest

  5. Submit a pull request

References

Available Tools

73 tools
bin_create_folderC

Create folder in project bin.

Inputs: name (required), parent. Returns: object

bin_get_clip_detailsB

Get detailed properties of a bin clip (length, aspect ratio, media info).

Args: clip_id: The clip identifier from the bin.

Inputs: clip_id (required). Returns: object

bin_import_clipA

Ingest a media file into the project bin for later timeline use.

Args: clip_path: Path to the media file (video, audio, or image). name: Optional display name. Defaults to the filename. duration: Optional duration override in seconds (useful for images). If None, auto-probed via ffprobe. clip_type: Media type hint: video, audio, image, color, title.

Inputs: clip_path (required), name, duration, clip_type. Returns: object

bin_list_clipsA

List every asset in the project bin with ID, name, type, and duration.

Inputs: no named parameters. Returns: object

bin_move_clipA

Move clip to folder (or root if folder None).

Inputs: clip_id (required), folder. Returns: object

bin_remove_clipA

Delete a clip from the media bin by its ID.

Args: clip_id: The clip identifier from bin_list_clips or bin_import_clip.

Inputs: clip_id (required). Returns: object

bin_renameC

Rename bin clip.

Inputs: clip_id (required), new_name (required). Returns: object

clip_add_noteC

Add / update note for bin clip.

Inputs: note (required), clip_id (required). Returns: object

clip_get_propertiesA

Get timeline clip properties: in/out, duration, speed, opacity, reverse.

Inputs: track_id (required), clip_index (required). Returns: object

clip_reverseB

Reverse playback direction of a timeline clip (toggles).

Inputs: track_id (required), clip_index (required). Returns: object

clip_set_colorA

Set color label for bin clip (hex or named).

Inputs: color (required), clip_id (required). Returns: object

clip_set_opacityC

Set opacity of a timeline clip (0.0 transparent .. 1.0 opaque).

Inputs: opacity (required), track_id (required), clip_index (required). Returns: object

clip_set_speedB

Set playback speed of a timeline clip (1.0=normal, 2.0=2x, 0.5=half, negative=reverse).

Inputs: speed (required), track_id (required), clip_index (required). Returns: object

export_list_presetsA

List all available render presets for final video output.

Inputs: no named parameters. Returns: object

export_renderA

Render the project to a video file via melt.

Generates MLT XML from the current project then pipes it through melt. Requires 'melt' on the system (apt install melt).

Args: output_path: Destination video file (e.g. output.mp4). preset: Optional render preset name (see export_list_presets).

Inputs: output_path (required), preset. Returns: object

export_xmlA

Generate Kdenlive/MLT XML for the current project.

Args: output_path: Optional file path to write the XML to (e.g. ~/Downloads/myproj.kdenlive). If None, no file is written and XML is returned in data.xml for you to copy.

Inputs: output_path. Returns: object

filter_addA

Attach a video/audio effect to a timeline clip.

Args: track_id: Track containing the clip. clip_index: 0-based clip index on that track. filter_type: Filter name (e.g. blur, brightness, frei0r.opacity, volume). Run filter_list_available for all options. params: 'key=value' parameter strings (e.g. ['radius=5.0', 'opacity=0.8']).

Inputs: track_id (required), clip_index (required), filter_type (required), params. Returns: object

filter_listA

List all active filters on a specific timeline clip.

Args: track_id: Track containing the clip. clip_index: 0-based clip index.

Inputs: track_id (required), clip_index (required). Returns: object

filter_list_availableB

Discover all filters the Kdenlive runtime exposes.

Args: category: Optional category filter (e.g. blur, color, audio).

Inputs: category. Returns: object

filter_removeA

Detach an effect from a clip.

Args: track_id: Track containing the clip. clip_index: 0-based clip index. filter_index: 0-based filter index (see filter_list).

Inputs: track_id (required), clip_index (required), filter_index (required). Returns: object

filter_set_paramA

Update a single parameter on an active filter.

Args: track_id: Track containing the clip. clip_index: 0-based clip index. filter_index: 0-based filter index. parameter: Parameter name (e.g. radius, opacity, level). value: New value (auto-converted to int/float if numeric).

Inputs: value (required), track_id (required), parameter (required), clip_index (required), +1 more. Returns: object

guide_addA

Place a navigation guide marker along the timeline.

Args: position: Time position in seconds. label: Short label for the guide. guide_type: 'default', 'chapter', or 'segment'. comment: Optional longer description.

Inputs: position (required), label, comment, guide_type. Returns: object

guide_getA

Get single guide by ID.

Inputs: guide_id (required). Returns: object

guide_listA

Return all guide markers on the timeline.

Inputs: no named parameters. Returns: object

guide_removeB

Delete a guide marker by its ID.

Args: guide_id: Numeric guide identifier.

Inputs: guide_id (required). Returns: object

guide_updateC

Update guide properties.

Inputs: guide_id (required), label, comment, position, +1 more. Returns: object

marker_addB

Add timeline or clip marker (markers separate from guides).

Inputs: position (required), label, comment, track_id, +2 more. Returns: object

marker_listA

List all markers.

Inputs: no named parameters. Returns: object

marker_removeB

Remove marker by ID.

Inputs: marker_id (required). Returns: object

project_get_infoA

Return project metadata: FPS, resolution, track layout, bin clip count.

Inputs: no named parameters. Returns: object

project_get_profileA

Get the current project's video profile (resolution, FPS, aspect ratio).

Inputs: no named parameters. Returns: object

project_get_render_profilesA

Alias for project_list_profiles - get available render presets.

Inputs: no named parameters. Returns: object

project_list_profilesA

Enumerate all available video output profiles (hd1080p30, 4k60, sd_pal, etc.).

Inputs: no named parameters. Returns: object

project_newA

Create a brand new Kdenlive project session.

After this call the project path is stored so subsequent tools automatically target this project.

Args: output_path: Path where the project JSON will be saved (.kdenlive-cli.json). profile: Preset profile (hd1080p30, hd1080p25, hd720p60, 4k30, 4k60, sd_pal, sd_ntsc). Overrides width/height/fps if set. name: Human-readable project name. width: Video width in pixels (ignored when profile is set). height: Video height in pixels (ignored when profile is set). fps_num: FPS numerator (ignored when profile is set). fps_den: FPS denominator (ignored when profile is set).

Inputs: output_path (required), name, width, height, +3 more. Returns: object

project_openB

Load an existing .kdenlive-cli.json project into the session.

Args: project_path: Path to an existing project file.

Inputs: project_path (required). Returns: object

project_saveA

Persist the current project state to a file.

Args: output_path: Optional path to write to. Defaults to the original project path.

Inputs: output_path. Returns: object

project_set_profileB

Set or update the project's video profile.

Args: profile: Preset profile name (hd1080p30, hd1080p25, hd720p60, 4k30, 4k60, sd_pal, sd_ntsc). Overrides width/height/fps if set. width: Video width in pixels. height: Video height in pixels. fps_num: FPS numerator. fps_den: FPS denominator. progressive: Whether video is progressive. dar_num: Display aspect ratio numerator. dar_den: Display aspect ratio denominator.

Inputs: width, height, dar_den, dar_num, +4 more. Returns: object

render_queue_addC

Add job to render queue.

Inputs: output_path (required), preset, in_point, out_point. Returns: object

render_queue_listB

List render queue jobs.

Inputs: no named parameters. Returns: object

render_queue_startA

Start processing render queue (renders sequentially via melt).

Inputs: no named parameters. Returns: object

render_queue_statusA

Get render queue status.

Inputs: no named parameters. Returns: object

render_queue_stopA

Stop render queue (marks running as stopped).

Inputs: no named parameters. Returns: object

session_historyA

List all undo/redo history entries with descriptions.

Inputs: no named parameters. Returns: object

session_redoB

Reapply the last undone operation.

Inputs: no named parameters. Returns: object

session_redo_stepB

Redo N steps (granular).

Inputs: steps. Returns: object

session_statusA

Inspect session state: project loaded, modified flag, history depth.

Inputs: no named parameters. Returns: object

session_undoA

Revert the most recent state change (up to 50 history entries).

Inputs: no named parameters. Returns: object

session_undo_stepC

Undo N steps (granular).

Inputs: steps. Returns: object

timeline_add_clipA

Place a bin clip onto a specific track at a given time position.

Args: clip_id: Bin clip identifier to place (from bin_list_clips). track: Target track number. position: Start time on the timeline in seconds. in_point: Media trim-in (where to start playback inside source) in seconds. out_point: Media trim-out (where to end playback inside source) in seconds. Defaults to full bin duration. Use timeline_trim_clip to adjust after placement.

Inputs: track (required), clip_id (required), position (required), in_point, +1 more. Returns: object

timeline_add_trackA

Append a video or audio track to the timeline.

Args: track_type: 'video' or 'audio'. track_name: Optional name (auto-generated if omitted). mute: Start muted. hide: Start hidden. locked: Prevent edits on this track.

Inputs: hide, mute, locked, track_name, +1 more. Returns: object

timeline_get_durationA

Get total timeline duration in seconds (max end time).

Inputs: no named parameters. Returns: object

timeline_get_infoA

Get comprehensive timeline info: tracks+clips, duration, position, zoom, guides, markers, profile.

Inputs: no named parameters. Returns: object

timeline_get_positionA

Get current playhead position.

Inputs: no named parameters. Returns: object

timeline_get_zoomB

Get timeline zoom level.

Inputs: no named parameters. Returns: object

timeline_listA

Return all timeline tracks with clip counts, IDs, mute/lock status.

Inputs: no named parameters. Returns: object

timeline_move_clipA

Reposition a clip on the same track to a new time position.

Args: track_id: Track containing the clip. clip_index: 0-based index of the clip within the track. new_position: New timeline position in seconds.

Inputs: track_id (required), clip_index (required), new_position (required). Returns: object

timeline_remove_clipA

Delete a clip from the timeline.

Args: track_id: Track containing the clip. clip_index: 0-based index of the clip within the track.

Inputs: track_id (required), clip_index (required). Returns: object

timeline_remove_trackA

Delete a track and all its clips from the timeline.

Args: track_id: Numeric track identifier (from timeline_list).

Inputs: track_id (required). Returns: object

timeline_seekA

Seek playhead to position (seconds).

Inputs: position (required). Returns: object

timeline_set_zoomA

Set timeline zoom level (0.1 .. 10.0).

Inputs: zoom (required). Returns: object

timeline_split_clipA

Cut a clip into two independent pieces at a precise time offset.

Args: track_id: Track containing the clip. clip_index: 0-based index of the clip within the track. offset: Time offset in seconds from the clip's start (0 < offset < clip duration).

Inputs: offset (required), track_id (required), clip_index (required). Returns: object

timeline_trim_clipA

Adjust the in/out trim handles of a timeline clip (not the crop filter).

Args: track_id: Track containing the clip. clip_index: 0-based index of the clip within the track. in_point: New trim-in in seconds. None = leave unchanged. out_point: New trim-out in seconds. None = leave unchanged.

Inputs: track_id (required), clip_index (required), in_point, out_point. Returns: object

track_get_infoB

Get detailed info for a single track (including clips).

Inputs: track_id (required). Returns: object

track_move_downA

Move track down one position (swap with next).

Inputs: track_id (required). Returns: object

track_move_upB

Move track up one position (swap with previous).

Inputs: track_id (required). Returns: object

track_set_hiddenB

Hide/show a track (video visibility).

Inputs: hidden (required), track_id (required). Returns: object

track_set_lockedC

Lock/unlock a track.

Inputs: locked (required), track_id (required). Returns: object

track_set_mutedB

Mute/unmute a track (audio).

Inputs: muted (required), track_id (required). Returns: object

track_set_nameC

Rename a track.

Inputs: name (required), track_id (required). Returns: object

transition_addB

Create a blend transition (crossfade, wipe, etc.) between two track layers.

Args: transition_type: Transition name (e.g. crossfade, luma, mix). track_a: Upper track index. track_b: Lower track index. position: Start time on the timeline in seconds. duration: Transition length in seconds. params: 'key=value' parameter strings.

Inputs: track_a (required), track_b (required), transition_type (required), params, +2 more. Returns: object

transition_listA

List all transitions on the timeline.

Inputs: no named parameters. Returns: object

transition_removeA

Delete a transition by its numeric ID.

Args: transition_id: Transition identifier.

Inputs: transition_id (required). Returns: object

transition_setC

Modify a parameter on an existing transition.

Args: transition_id: Transition identifier. param_name: Parameter name. value: New value (auto-converted to numeric if applicable).

Inputs: value (required), param_name (required), transition_id (required). Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3/5.0

    Scored across 73 tools

    Disambiguation2/5

    Multiple tools have unclear boundaries: timeline_get_info overlaps timeline_get_zoom/position/duration, project_get_render_profiles is an alias for project_list_profiles and also overlaps export_list_presets, and the clip_ prefix is used for both bin clips and timeline clips. session_undo vs session_undo_step also creates ambiguity.

    Naming Consistency4/5

    Tool names are mostly consistent snake_case with a clear domain prefix and verb_noun pattern (timeline_add_clip, guide_remove, filter_set_param). Minor deviations like project_new, session_undo_step, and the duplicate alias project_get_render_profiles keep it from being fully consistent.

    Tool Count1/5

    73 tools is an extreme count for an MCP server and exceeds any reasonable scope. Many tools are granular variants, aliases, or single-purpose getters that inflate the surface without adding meaningful capability.

    Completeness4/5

    The core video editing workflow is well covered: project management, bin operations, timeline editing, filters, transitions, guides, markers, and rendering all have solid CRUD/lifecycle coverage. Minor gaps exist such as no marker update tool and no way to list available transition types.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers