DaVinci Resolve MCP

An MCP server integration for the DaVinci Resolve video editing software.

DaVinci Resolve MCP Server

Version API Coverage Tools Tested DaVinci Resolve Python License

A Model Context Protocol (MCP) server providing complete coverage of the DaVinci Resolve Scripting API. Connect AI assistants (Claude, Cursor, Windsurf) to DaVinci Resolve and control every aspect of your post-production workflow through natural language.

What's New in v2.3.3

Granular layer hardening — closing exposure gaps and dropped-dict-key bugs surfaced by an exhaustive parity audit of every documented Resolve scripting method against both server layers.

Cloud project helper rewritten (Critical): src/utils/cloud_operations.py was calling pm.CreateCloudProject(project_name, folder_path) with positional arguments — but the documented Resolve API signature is CreateCloudProject({cloudSettings}), a single dict. Same bug affected ImportCloudProject and RestoreCloudProject. Helper now builds proper {cloudSettings} dicts and exposes all 5 documented keys (PROJECT_NAME, PROJECT_MEDIA_PATH, IS_COLLAB, SYNC_MODE, IS_CAMERA_ACCESS) per docs lines 576-594. Granular wrappers (create_cloud_project_tool, import_cloud_project_tool, restore_cloud_project_tool) updated to expose the full settings surface; load_cloud_project_tool added (was missing entirely from granular).

Silent-drop bugs fixed (Critical):

  • render_with_quick_export() (granular) previously dropped the documented {param_dict} (TargetDir, CustomName, VideoQuality, EnableUpload). Now forwards all four keys per docs line 179.
  • timeline_create_compound_clip() (granular) previously dropped the documented {clipInfo} dict (name, startTimecode). Now exposes both keys per docs line 369.

Missing granular tools added:

  • append_to_timeline — both simple clip_ids form and positioned clip_infos form (MediaPool.AppendToTimeline was completely absent from granular layer; only compound had it).
  • auto_sync_audio — with proper {audioSyncSettings} dict mapping per docs lines 600-614 (sync_mode, channel_number with 'automatic'/'mix' aliases, retain_embedded_audio, retain_video_metadata).
  • load_cloud_project_tool — was missing entirely; compound had it.
  • rename_color_group — wraps ColorGroup.SetName (compound had it via color_group(action="set_name") but no granular tool).

Removed 4 undocumented cloud method wrappers:

  • get_cloud_projects resource → GetCloudProjectList not in API docs
  • export_project_to_cloud_toolExportToCloud/ExportProjectToCloud not in API docs
  • add_user_to_cloud_project_toolAddUserToCloudProject not in API docs
  • remove_user_from_cloud_project_toolRemoveUserFromCloudProject not in API docs

Removed 9 legacy granular gallery tools that wrapped undocumented or renamed methods (gallery.GetAlbums(), gallery.CreateAlbum(), still.GetTimecode(), still.IsGrabbed(), etc.). The proper documented Gallery and GalleryStillAlbum wrappers (lines 743+ of the previous gallery.py — all 14 of those, e.g. get_gallery_still_albums, create_gallery_still_album, import_stills_to_album, export_stills_from_album, get_album_stills, set_still_label) cover the documented API surface and remain. Removed: get_color_presets, save_color_preset, apply_color_preset, delete_color_preset, create_color_preset_album, delete_color_preset_album, export_lut, get_lut_formats, export_all_powergrade_luts.

Removed 2 granular project optimized-media tools that wrapped undocumented Resolve methods (Project.GenerateOptimizedMedia, Project.DeleteOptimizedMedia, MediaPool.SetClipSelection — none in API docs). Removed: generate_optimized_media, delete_optimized_media. Use the Resolve UI for optimized-media generation; set_optimized_media_mode (which uses the documented Project.SetSetting("OptimizedMediaMode", ...)) is preserved.

Deprecated method call fixed: timeline(action="get_items_in_track") was calling the deprecated tl.GetItemsInTrack() form (docs line 989, marked deprecated) instead of the supported tl.GetItemListInTrack() (line 350). Every other call site already used the correct form.

New: API parity CI guard at scripts/audit_api_parity.py. Parses docs/resolve_scripting_api.txt and verifies (1) no from api.X broken imports remain, (2) every documented Resolve method appears somewhere in src/, (3) wrappers calling undocumented methods are flagged for review. Includes an allowlist for legitimate undocumented-but-real Resolve API surface (Fusion compositing API, UIManager methods like OpenProjectSettings/LoadUILayout/SaveUILayout, internal type-discrimination helpers like TimelineItem.GetType/GetMediaType). Run with python3 scripts/audit_api_parity.py — currently passes all three checks cleanly.

Tool count: 328 granular tools (was 354 before v2.3.2; net change since v2.3.1 is −26 broken/duplicate/undocumented tools removed and +4 missing tools added). 20 new unit tests against Resolve stubs covering the cloud settings builder, audio sync settings builder, and AppendToTimeline clipInfo builder. All 41 tests pass without a live Resolve connection.

Live disposable Resolve validation: every new and changed v2.3.3 granular tool was exercised against DaVinci Resolve Studio 20.3.2.9 in a disposable project with synthetic temp media via tests/live_v233_validation.py. 10/10 checks passed: append_to_timeline (simple + positioned + failure path), auto_sync_audio (settings dict + invalid input rejection), import_media image-sequence form, timeline_create_compound_clip (info dict forwarded — compound clip created with explicit name), rename_color_group (renamed a real color group), render_with_quick_export (params dict forwarded — Resolve's structured {JobStatus, Error} response confirms the dict reached it), and the compound-side GetItemListInTrack deprecated→supported fix.

v2.3.2

API parity sweep — closing documented overloads and dropped parameters that the v2.3.1 audit surfaced.

  • Positioned CreateTimelineFromClips via clip_infosmedia_pool(action="create_timeline_from_clips", params={"clip_infos": [...]}) and the granular create_timeline_from_clips(clip_infos=[...]) now expose the documented MediaPool.CreateTimelineFromClips(name, [{clipInfo}, ...]) overload (4 keys: mediaPoolItem, startFrame, endFrame, recordFrame)
  • Image-sequence ImportMedia via clip_infos — both layers now expose MediaPool.ImportMedia([{FilePath, StartIndex, EndIndex}, ...]) for DPX/EXR/etc. sequence imports. PascalCase keys preserved per Resolve docs
  • Positioned AddItemListToMediaPool via item_infosmedia_storage(action="import_to_pool", params={"item_infos": [{media, startFrame, endFrame}, ...]}) and granular add_items_to_media_pool_from_storage(item_infos=[...]) now expose the documented MediaStorage.AddItemListToMediaPool([{itemInfo}, ...]) overload
  • Timeline.AddTrack dict form — replaced the legacy bare-string sub_type argument with the documented newTrackOptions dict (audio_type, index). Granular timeline_add_track(track_type, audio_type=, index=) and compound timeline(action="add_track", params={"track_type", "options": {audio_type, index}})
  • CreateSubtitlesFromAudio actually wired up — granular timeline_create_subtitles_from_audio previously advertised language and preset parameters then silently dropped them. Now maps user strings (e.g. "korean", "netflix", "double") to resolve.AUTO_CAPTION_* constants per docs lines 720-761, and exposes the missing chars_per_line, line_break, gap keys
  • Granular import_media no longer crashes — the granular import_media tool was importing from a deleted api.media_operations module and would throw ModuleNotFoundError on first call. Rewritten to call MediaPool.ImportMedia directly and to share the new clip_infos overload
  • SetRenderSettings docstring completeness — granular set_render_settings now documents all 27 keys per docs lines 765-799 (previously omitted EncodingProfile, MultiPassEncode, AlphaMode, NetworkOptimization, PixelAspectRatio, ClipStartFrame, TimelineStartTimecode, ReplaceExistingFilesInPlace)
  • Removed 18 broken granular tools (+ 7 broken resources) that imported from a deleted api.* namespace and would crash with ModuleNotFoundError on first call. All 25 had working equivalents elsewhere or wrapped undocumented Resolve methods. Granular tool count is now 336 (was 354). Migration map for any caller that was hitting them:
    • delete_mediamedia_pool(action="delete_clips")
    • move_media_to_binmedia_pool(action="move_clips")
    • auto_sync_audio (granular tool) → media_pool(action="auto_sync_audio")
    • unlink_clipsmedia_pool(action="unlink")
    • relink_clipsmedia_pool(action="relink")
    • create_binmedia_pool(action="add_subfolder")
    • list_media_pool_bins (resource) → folder(action="get_subfolders")
    • get_media_pool_bin_contents (resource) → folder(action="get_clips")
    • get_timeline_tracks (resource) → timeline(action="get_track_count") + timeline(action="get_items_in_track")
    • create_empty_timelinemedia_pool(action="create_timeline")
    • delete_timelinemedia_pool(action="delete_timelines")
    • add_marker (granular timeline tool) → timeline_markers(action="add")
    • add_clip_to_timelinemedia_pool(action="append_to_timeline")
    • apply_lut (granular graph tool) → graph(action="set_lut")
    • copy_gradetimeline_item_color(action="copy_grades")
    • get_render_presets (resource) → render(action="list_presets")
    • add_to_render_queuerender(action="add_job")
    • start_render (granular project tool) → render(action="start")
    • get_render_queue_status (resource) → render(action="list_jobs") + render(action="get_job_status")
    • clear_render_queue (granular project tool) → render(action="delete_all_jobs")
    • create_sub_clip, get_current_color_node, get_color_wheel_params, set_color_wheel_param, add_node: removed — these wrapped undocumented Resolve methods that were never exposed in the official scripting API. No replacement exists; use the Resolve UI for now.

v2.3.1

  • Positioned AppendToTimeline via clip_infosmedia_pool(action="append_to_timeline", params={"clip_infos": [...]}) now exposes the documented MediaPool.AppendToTimeline([{clipInfo}, ...]) overload, accepting per-entry clip_id/media_pool_item_id, start_frame, end_frame, record_frame, track_index, and optional media_type. Each appended item returns its timeline_item_id for follow-up Fusion ops
  • Positioned append failure reporting — the same call now returns {"error": ...} when Resolve fails to produce valid timeline items, including falsey AppendToTimeline() results and returned item handles without a timeline item id
  • Live disposable Resolve validation — verified the fix against DaVinci Resolve Studio 20.3.2 with synthetic temp media in a disposable project: valid clip_infos append returned success, count=1, and timeline_item_id; invalid clip_infos calls returned errors

v2.3.0

  • Resolve 20.2.2 API sync — added the 12 scripting methods introduced across Resolve 20.0-20.2.2, with compatibility guards so older Resolve builds return clear "requires Resolve 20.x" errors instead of crashing
  • Resolve 20 live validation — revalidated the new API surface against DaVinci Resolve Studio 20.3.2, bringing live-tested coverage to 331/336 methods (98.5%)
  • Official scripting docs refresheddocs/resolve_scripting_api.txt now tracks the Resolve 20 scripting README bundled with the installed 20.3.2 developer package
  • AI skill reference updated — merged PR #30's docs/SKILL.md and updated it for the Resolve 20 method count, 354-tool granular server, version guards, and source media integrity guidance
  • Stale Resolve handle recovery — both server modes now validate cached Resolve handles and reconnect cleanly after Resolve restarts or Project Manager transitions

v2.2.0

  • Granular server modularized internallysrc/resolve_mcp_server.py is now a thin entrypoint, with the 354-tool implementation split across src/granular/resolve_control.py, project.py, timeline.py, timeline_item.py, media_pool.py, folder.py, media_pool_item.py, gallery.py, graph.py, and media_storage.py
  • Installer now emits env blocks for every generated stdio config — standard .mcp.json, VS Code .vscode/mcp.json, Zed context_servers, and manual snippets now include RESOLVE_SCRIPT_API, RESOLVE_SCRIPT_LIB, and PYTHONPATH
  • Windows Resolve 20.3 hardening — on Windows, the installer also emits PYTHONHOME derived from the selected interpreter's base install so Resolve binds against the intended Python instead of a newer globally registered one
  • Windows stdio transport hardening — server entrypoints now run FastMCP through strict LF-only stdio wrappers to avoid client disconnects caused by platform newline translation in Windows pipes
  • set_cdl accepts arrays cleanly — both compound and granular servers now normalize JSON array, tuple, and numeric CDL values into Resolve's required string form like "1.0 1.0 1.0"
  • fusion_comp can target timeline item comps — node graph actions can now operate on a clip's Fusion comp via clip_id, timeline_item_id, or timeline_item, and bulk_set_inputs applies scoped input changes across multiple timeline comps
  • python src/server.py --full now stays intact — the compound entrypoint now correctly launches the granular server instead of importing it and exiting

v2.1.0

  • New fusion_comp tool — 20-action tool exposing the full Fusion composition node graph API. Add/delete/find nodes, wire connections, set/get parameters, manage keyframes, control undo grouping, set render ranges, and trigger renders — all on the currently active Fusion page composition
  • timeline_item_fusion cache actions — added get_cache_enabled and set_cache actions for Fusion output cache control directly on timeline items
  • Fusion node graph reference — docstring includes common tool IDs (Merge, TextPlus, Background, Transform, ColorCorrector, DeltaKeyer, etc.) for discoverability

v2.0.9

  • Cross-platform sandbox path redirect_resolve_safe_dir() now handles macOS (/var/folders, /private/var), Linux (/tmp, /var/tmp), and Windows (AppData\Local\Temp) sandbox paths that Resolve can't write to. Redirects to ~/Documents/resolve-stills instead of Desktop
  • Auto-cleanup for grab_and_export — exported files are read into the response (DRX as inline text, images as base64) then deleted from disk automatically. Zero file accumulation. Pass cleanup: false to keep files on disk
  • Both servers in syncserver.py and resolve_mcp_server.py now share the same version and both use _resolve_safe_dir() for all Resolve-facing temp paths (project export, LUT export, still export)

v2.0.8

  • New grab_and_export action on gallery_stills — combines GrabStill() + ExportStills() in a single atomic call, keeping the live GalleryStill reference for reliable export. Returns a file manifest with exported image + companion .drx grade file
  • Format fallback chain — if the requested format fails, automatically retries with tif then dpx
  • macOS sandbox path redirect/var/folders and /private/var paths are redirected to ~/Desktop/resolve-stills since Resolve's process can't write to sandboxed temp directories
  • Key finding documentedExportStills requires the Gallery panel to be visible on the Color page. All 9 supported formats (dpx, cin, tif, jpg, png, ppm, bmp, xpm, drx) produce a companion .drx grade file alongside the image

v2.0.7

  • Security: path traversal protection for layout preset toolsexport_layout_preset, import_layout_preset, and delete_layout_preset now validate that resolved file paths stay within the expected Resolve presets directory, preventing path traversal via crafted preset names
  • Security: document destructive tool risk — added Security Considerations section noting that quit_app/restart_app tools can terminate Resolve; MCP clients should require user confirmation before invoking

v2.0.6

  • Fix color group operations crashtimeline_item_color unpacked _check() as (proj, _, _) but _check() returns (pm, proj, err), so proj got the ProjectManager instead of the Project, crashing assign_color_group and remove_from_color_group

v2.0.5

  • Lazy connection recovery — full server (--full mode) now auto-reconnects and auto-launches Resolve, matching the compound server behavior
  • Null guards on all chained API callsGetProjectManager(), GetCurrentProject(), GetCurrentTimeline() failures now return clear errors instead of NoneType crashes
  • Helper functionsget_resolve(), get_project_manager(), get_current_project() replace 178 boilerplate blocks

v2.0.4

  • Fix apply_grade_from_drx parameter — renamed mode to grade_mode to match Resolve API; corrected documentation from replace/append to actual keyframe alignment modes (0=No keyframes, 1=Source Timecode aligned, 2=Start Frames aligned)
  • Backward compatible — still accepts mode for existing clients, grade_mode takes precedence

v2.0.3

  • Fix GetNodeGraph crashGetNodeGraph(0) returns False in Resolve; now calls without args unless layer_index is explicitly provided
  • Falsy node graph check — guard checks not g instead of g is None to catch False returns

v2.0.2

  • Antigravity support — Google's agentic AI coding assistant added as 10th MCP client
  • Alphabetical client ordering — MCP_CLIENTS list sorted for easier maintenance

v2.0.1

  • 26-tool compound server — all 324 API methods grouped into 26 context-efficient tools (default)
  • Universal installer — single python install.py for macOS/Windows/Linux, 10 MCP clients
  • Dedicated timeline_item actions — retime/speed, transform, crop, composite, audio, keyframes with validation
  • Lazy Resolve connection — server starts instantly, connects when first tool is called
  • Bug fixes — CreateMagicMask param type, GetCurrentClipThumbnailImage args, Python 3.13+ warning

Key Stats

MetricValue
MCP Tools27 compound (default) / 328 granular
API Methods Covered336/336 (100%)
Methods Live Tested331/336 (98.5%)
Live Test Pass Rate331/331 (100%)
API Object Classes13
Tested AgainstDaVinci Resolve 19.1.3 Studio + Resolve 20.3.2 Studio
Compatibility NoteResolve 19.1.3 remains the compatibility baseline; Resolve 20.x scripting calls are additive, version-guarded, and live-tested on 20.3.2; Resolve 21 beta APIs are intentionally deferred until stable

API Coverage

Every non-deprecated method in the DaVinci Resolve Scripting API is covered. The default compound server exposes 27 tools that group related operations by action parameter, keeping LLM context windows lean. The full granular server provides 328 individual tools for power users. Both modes cover all 13 API object classes:

ClassMethodsToolsDescription
Resolve2222App control, pages, layout presets, render/burn-in presets, keyframe mode
ProjectManager2525Project CRUD, folders, databases, cloud projects, archive/restore
Project4343Timelines, render pipeline, settings, LUTs, color groups
MediaStorage99Volumes, file browsing, media import, mattes
MediaPool2727Folders, clips, timelines, metadata, stereo, sync
Folder88Clip listing, export, transcription
MediaPoolItem3636Metadata, markers, flags, properties, proxy, transcription
Timeline5858Tracks, markers, items, export, generators, titles, stills, stereo
TimelineItem8080Properties, markers, Fusion comps, versions, takes, CDL, AI tools
Gallery88Albums, stills, power grades
GalleryStillAlbum66Stills management, import/export, labels
Graph1122Node operations, LUTs, cache, grades (timeline + clip graph variants)
ColorGroup510Group management, pre/post clip node graphs

Requirements

  • DaVinci Resolve Studio 18.5+ (macOS, Windows, or Linux) — the free edition does not support external scripting
  • Python 3.10–3.12 recommended (3.13+ may have ABI incompatibilities with Resolve's scripting library)
  • DaVinci Resolve running with Preferences > General > "External scripting using" set to Local

Validated live coverage is based on DaVinci Resolve 19.1.3 Studio for the original API surface, plus DaVinci Resolve 20.3.2 Studio for the Resolve 20.0-20.2.2 scripting additions. Resolve 21 beta APIs are intentionally deferred until a stable release.

Quick Start

# Clone the repository
git clone https://github.com/samuelgursky/davinci-resolve-mcp.git
cd davinci-resolve-mcp

# Make sure DaVinci Resolve is running, then:
python install.py

The universal installer auto-detects your platform, finds your DaVinci Resolve installation, creates a virtual environment, and configures your MCP client — all in one step.

Supported MCP Clients

The installer can automatically configure any of these clients:

ClientConfig Written To
Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.json (macOS)
Claude Code.mcp.json (project root)
Cursor~/.cursor/mcp.json
VS Code (Copilot).vscode/mcp.json (workspace)
Windsurf~/.codeium/windsurf/mcp_config.json
ClineVS Code global storage
Roo CodeVS Code global storage
Zed~/.config/zed/settings.json
Continue~/.continue/config.json
JetBrains IDEsManual (Settings > Tools > AI Assistant > MCP)

You can configure multiple clients at once, or use --clients manual to get copy-paste config snippets.

Installer Options

python install.py                              # Interactive mode
python install.py --clients all                # Configure all clients
python install.py --clients cursor,claude-desktop  # Specific clients
python install.py --clients manual             # Just print the config
python install.py --dry-run --clients all      # Preview without writing
python install.py --no-venv --clients cursor   # Skip venv creation

Server Modes

The MCP server comes in two modes:

ModeFileToolsBest For
Compound (default)src/server.py27Most users — fast, clean, low context usage
Fullsrc/resolve_mcp_server.py354Power users who want one tool per API method

The compound server's timeline_item tool includes dedicated actions for common workflows:

CategoryActionsParameters
Retimeget_retime, set_retimeprocess (nearest, frame_blend, optical_flow), motion_estimation (0-6)
Transformget_transform, set_transformPan, Tilt, ZoomX/Y, RotationAngle, AnchorPointX/Y, Pitch, Yaw, FlipX/Y
Cropget_crop, set_cropCropLeft, CropRight, CropTop, CropBottom, CropSoftness, CropRetain
Compositeget_composite, set_compositeOpacity, CompositeMode
Audioget_audio, set_audioVolume, Pan, AudioSyncOffset
Keyframesget_keyframes, add_keyframe, modify_keyframe, delete_keyframe, set_keyframe_interpolationproperty, frame, value, interpolation (Linear, Bezier, EaseIn, EaseOut, EaseInOut)

The installer uses the compound server by default. To use the full server:

python src/server.py --full    # Launch full 354-tool server
# Or point your MCP config directly at src/resolve_mcp_server.py

Manual Configuration

If you prefer to set things up yourself, add to your MCP client config:

{
  "mcpServers": {
    "davinci-resolve": {
      "command": "/path/to/venv/bin/python",
      "args": ["/path/to/davinci-resolve-mcp/src/server.py"],
      "env": {
        "RESOLVE_SCRIPT_API": "/path/to/DaVinci Resolve/Developer/Scripting",
        "RESOLVE_SCRIPT_LIB": "/path/to/fusionscript.so-or-dll",
        "PYTHONPATH": "/path/to/DaVinci Resolve/Developer/Scripting/Modules"
      }
    }
  }
}

On Windows, installer-generated configs also include PYTHONHOME. That scopes Resolve's Python binding to the selected interpreter and avoids the Resolve 20.3 multi-Python crash reported in Issue #26.

Platform-specific paths:

PlatformAPI PathLibrary Path
macOS/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scriptingfusionscript.so in DaVinci Resolve.app
WindowsC:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\Scriptingfusionscript.dll in Resolve install dir
Linux/opt/resolve/Developer/Scripting/opt/resolve/libs/Fusion/fusionscript.so

Usage Examples

Once connected, you can control DaVinci Resolve through natural language:

"What version of DaVinci Resolve is running?"
"List all projects and open the one called 'My Film'"
"Create a new timeline called 'Assembly Cut' and add all clips from the media pool"
"Add a blue marker at the current playhead position with note 'Review this'"
"Set up a ProRes 422 HQ render for the current timeline"
"Export the timeline as an EDL"
"Switch to the Color page and grab a still"
"Create a Fusion composition on the selected clip"

Test Results

Baseline testing was performed against DaVinci Resolve 19.1.3 Studio on macOS with live API calls (no mocks). Resolve 20 additions were revalidated live against DaVinci Resolve 20.3.2 Studio.

PhaseTestsPass RateScope
Phase 1204/204100%Safe read-only operations across all classes
Phase 279/79100%Destructive operations with create-test-cleanup patterns
Phase 320/20100%Real media import, sync, transcription, database switching, Resolve.Quit
Phase 410/10100%AI/ML methods, Fusion clips, stereo, gallery stills
Phase 56/6100%Scene cuts, subtitles from audio, graph node cache/tools/enable
Resolve 20 delta12/12100%Resolve 20.0-20.2.2 scripting additions live-tested on 20.3.2
Total331/331100%98.5% of current API methods tested live

Untested Methods (5 of 336)

MethodReasonHelp Wanted
PM.CreateCloudProjectRequires DaVinci Resolve cloud infrastructureYes
PM.LoadCloudProjectRequires DaVinci Resolve cloud infrastructureYes
PM.ImportCloudProjectRequires DaVinci Resolve cloud infrastructureYes
PM.RestoreCloudProjectRequires DaVinci Resolve cloud infrastructureYes
TL.AnalyzeDolbyVisionRequires HDR/Dolby Vision contentYes

Complete API Reference

Every method in the DaVinci Resolve Scripting API and its test status. Methods are listed by object class.

Status Key:

  • ✅ = Tested live, returned expected result
  • ⚠️ = Tested live, API accepted call (returned False — needs specific context to fully execute)
  • ☁️ = Requires cloud infrastructure (untested)
  • 🔬 = Requires specific content/hardware (untested — PRs welcome)

Resolve

#MethodStatusTest Result / Notes
1Fusion()Returns Fusion object
2GetMediaStorage()Returns MediaStorage object
3GetProjectManager()Returns ProjectManager object
4OpenPage(pageName)Switches Resolve page
5GetCurrentPage()Returns current page name (e.g. "edit")
6GetProductName()Returns "DaVinci Resolve Studio"
7GetVersion()Returns [19, 1, 3, 7, '']
8GetVersionString()Returns "19.1.3.7"
9LoadLayoutPreset(presetName)Loads saved layout
10UpdateLayoutPreset(presetName)Updates existing preset
11ExportLayoutPreset(presetName, presetFilePath)Exports preset to file
12DeleteLayoutPreset(presetName)Deletes preset
13SaveLayoutPreset(presetName)⚠️API accepts; returns False when preset name conflicts
14ImportLayoutPreset(presetFilePath, presetName)Imports preset from file
15Quit()Quits DaVinci Resolve
16ImportRenderPreset(presetPath)⚠️API accepts; needs valid preset file
17ExportRenderPreset(presetName, exportPath)⚠️API accepts; needs valid preset name
18ImportBurnInPreset(presetPath)⚠️API accepts; needs valid preset file
19ExportBurnInPreset(presetName, exportPath)⚠️API accepts; needs valid preset name
20GetKeyframeMode()Returns keyframe mode
21SetKeyframeMode(keyframeMode)⚠️API accepts; mode must match valid enum
22GetFairlightPresets()Resolve 20.3.2 live test returns preset map

ProjectManager

#MethodStatusTest Result / Notes
1ArchiveProject(projectName, filePath, ...)⚠️API accepts; archiving is slow
2CreateProject(projectName, mediaLocationPath)Creates new project; optional media location added in Resolve 20.2.2
3DeleteProject(projectName)⚠️Returns False if project is open
4LoadProject(projectName)Returns Project object
5GetCurrentProject()Returns current Project
6SaveProject()Saves current project
7CloseProject(project)Closes project
8CreateFolder(folderName)Creates project folder
9DeleteFolder(folderName)Deletes project folder
10GetProjectListInCurrentFolder()Returns project name list
11GetFolderListInCurrentFolder()Returns folder name list
12GotoRootFolder()Navigates to root
13GotoParentFolder()Returns False at root (expected)
14GetCurrentFolder()Returns current folder name
15OpenFolder(folderName)Opens folder
16ImportProject(filePath, projectName)Imports .drp file
17ExportProject(projectName, filePath, ...)Exports .drp file
18RestoreProject(filePath, projectName)⚠️API accepts; needs backup archive
19GetCurrentDatabase()Returns {DbType, DbName}
20GetDatabaseList()Returns list of databases
21SetCurrentDatabase({dbInfo})Switches database
22CreateCloudProject({cloudSettings})☁️Requires cloud infrastructure
23LoadCloudProject({cloudSettings})☁️Requires cloud infrastructure
24ImportCloudProject(filePath, {cloudSettings})☁️Requires cloud infrastructure
25RestoreCloudProject(folderPath, {cloudSettings})☁️Requires cloud infrastructure

Project

#MethodStatusTest Result / Notes
1GetMediaPool()Returns MediaPool object
2GetTimelineCount()Returns integer count
3GetTimelineByIndex(idx)Returns Timeline object
4GetCurrentTimeline()Returns current Timeline
5SetCurrentTimeline(timeline)Sets active timeline
6GetGallery()Returns Gallery object
7GetName()Returns project name
8SetName(projectName)⚠️Returns False on open project
9GetPresetList()Returns preset list with dimensions
10SetPreset(presetName)⚠️API accepts; preset must exist
11AddRenderJob()Returns job ID string
12DeleteRenderJob(jobId)Deletes render job
13DeleteAllRenderJobs()Clears render queue
14GetRenderJobList()Returns job list
15GetRenderPresetList()Returns preset names
16StartRendering(...)Starts render
17StopRendering()Stops render
18IsRenderingInProgress()Returns False when idle
19LoadRenderPreset(presetName)Loads render preset
20SaveAsNewRenderPreset(presetName)Creates render preset
21DeleteRenderPreset(presetName)Deletes render preset
22SetRenderSettings({settings})Applies render settings; Resolve 20.2 adds ExportSubtitle and SubtitleFormat keys
23GetRenderJobStatus(jobId)Returns {JobStatus, CompletionPercentage}
24GetQuickExportRenderPresets()Returns preset names
25RenderWithQuickExport(preset, {params})Initiates quick export
26GetSetting(settingName)Returns project settings dict
27SetSetting(settingName, settingValue)Sets project setting
28GetRenderFormats()Returns format map
29GetRenderCodecs(renderFormat)Returns codec map
30GetCurrentRenderFormatAndCodec()Returns {format, codec}
31SetCurrentRenderFormatAndCodec(format, codec)Sets format and codec
32GetCurrentRenderMode()Returns mode integer
33SetCurrentRenderMode(renderMode)Sets render mode
34GetRenderResolutions(format, codec)Returns resolution list
35RefreshLUTList()Refreshes LUT list
36GetUniqueId()Returns UUID string
37InsertAudioToCurrentTrackAtPlayhead(...)⚠️Tested; needs Fairlight page context
38LoadBurnInPreset(presetName)⚠️API accepts; preset must exist
39ExportCurrentFrameAsStill(filePath)⚠️API accepts; needs valid playhead position
40GetColorGroupsList()Returns color group list
41AddColorGroup(groupName)Returns ColorGroup object
42DeleteColorGroup(colorGroup)Deletes color group
43ApplyFairlightPresetToCurrentTimeline(presetName)⚠️Resolve 20.3.2 live test accepts call; returns False without a named preset

MediaStorage

#MethodStatusTest Result / Notes
1GetMountedVolumeList()Returns mounted volume paths
2GetSubFolderList(folderPath)Returns subfolder paths
3GetFileList(folderPath)Returns file paths
4RevealInStorage(path)Reveals path in Media Storage
5AddItemListToMediaPool(...)Imports media, returns clips
6AddClipMattesToMediaPool(item, [paths], eye)Adds clip mattes
7AddTimelineMattesToMediaPool([paths])Returns MediaPoolItem list

MediaPool

#MethodStatusTest Result / Notes
1GetRootFolder()Returns root Folder
2AddSubFolder(folder, name)Creates subfolder
3RefreshFolders()Refreshes folder list
4CreateEmptyTimeline(name)Creates timeline
5AppendToTimeline(...)Appends clips, returns TimelineItems
6CreateTimelineFromClips(name, ...)Creates timeline from clips
7ImportTimelineFromFile(filePath, {options})Imports AAF/EDL/XML
8DeleteTimelines([timeline])Deletes timelines
9GetCurrentFolder()Returns current Folder
10SetCurrentFolder(folder)Sets current folder
11DeleteClips([clips])Deletes clips
12ImportFolderFromFile(filePath)Imports DRB folder
13DeleteFolders([subfolders])Deletes folders
14MoveClips([clips], targetFolder)Moves clips
15MoveFolders([folders], targetFolder)Moves folders
16GetClipMatteList(item)Returns matte paths
17GetTimelineMatteList(folder)Returns matte items
18DeleteClipMattes(item, [paths])Deletes clip mattes
19RelinkClips([items], folderPath)⚠️API accepts; needs offline clips
20UnlinkClips([items])Unlinks clips
21ImportMedia([items])Imports media files
22ExportMetadata(fileName, [clips])Exports metadata CSV
23GetUniqueId()Returns UUID string
24CreateStereoClip(left, right)Creates stereo pair
25AutoSyncAudio([items], {settings})⚠️Tested; needs matching A/V clips
26GetSelectedClips()Returns selected clips
27SetSelectedClip(item)Selects clip

Folder

#MethodStatusTest Result / Notes
1GetClipList()Returns clip list
2GetName()Returns folder name
3GetSubFolderList()Returns subfolder list
4GetIsFolderStale()Returns False
5GetUniqueId()Returns UUID string
6Export(filePath)Exports DRB file
7TranscribeAudio()Starts audio transcription
8ClearTranscription()Clears transcription

MediaPoolItem

#MethodStatusTest Result / Notes
1GetName()Returns clip name
2GetMetadata(metadataType)Returns metadata dict
3SetMetadata(type, value)Sets metadata
4GetThirdPartyMetadata(type)Returns third-party metadata
5SetThirdPartyMetadata(type, value)Sets third-party metadata
6GetMediaId()Returns media UUID
7AddMarker(frameId, color, name, note, duration, customData)Adds marker
8GetMarkers()Returns marker dict
9GetMarkerByCustomData(customData)Finds marker by data
10UpdateMarkerCustomData(frameId, customData)Updates marker data
11GetMarkerCustomData(frameId)Returns custom data string
12DeleteMarkersByColor(color)Deletes markers by color
13DeleteMarkerAtFrame(frameNum)⚠️Returns False if no marker at frame
14DeleteMarkerByCustomData(customData)⚠️Returns False if no match
15AddFlag(color)Adds flag
16GetFlagList()Returns flag colors
17ClearFlags(color)Clears flags
18GetClipColor()Returns clip color
19SetClipColor(colorName)Sets clip color
20ClearClipColor()Clears clip color
21GetClipProperty(propertyName)Returns property dict
22SetClipProperty(propertyName, value)⚠️API accepts; some properties read-only
23LinkProxyMedia(proxyMediaFilePath)Links proxy media
24UnlinkProxyMedia()Unlinks proxy media
25ReplaceClip(filePath)Replaces clip source
26GetUniqueId()Returns UUID string
27TranscribeAudio()Starts audio transcription
28ClearTranscription()Clears transcription
29GetAudioMapping()Returns JSON audio mapping
30GetMarkInOut()Returns mark in/out dict
31SetMarkInOut(in, out, type)Sets mark in/out
32ClearMarkInOut(type)Clears mark in/out
33SetName(clipName)Resolve 20.3.2 live test renames clip
34LinkFullResolutionMedia(filePath)⚠️Resolve 20.3.2 live test accepts call; full-res relink returns False without a matching proxy/full-res fixture
35ReplaceClipPreserveSubClip(filePath)Resolve 20.3.2 live test replaces clip while preserving subclip metadata
36MonitorGrowingFile()Resolve 20.3.2 live test enables growing-file monitoring

Timeline

#MethodStatusTest Result / Notes
1GetName()Returns timeline name
2SetName(timelineName)⚠️Returns False on active timeline
3GetStartFrame()Returns start frame
4GetEndFrame()Returns end frame
5SetStartTimecode(timecode)Sets start timecode
6GetStartTimecode()Returns "01:00:00:00"
7GetTrackCount(trackType)Returns track count
8AddTrack(trackType, subTrackType)Adds track
9DeleteTrack(trackType, trackIndex)Deletes track
10GetTrackSubType(trackType, trackIndex)Returns sub-type (e.g. "stereo")
11SetTrackEnable(trackType, trackIndex, enabled)Enables/disables track
12GetIsTrackEnabled(trackType, trackIndex)Returns enabled state
13SetTrackLock(trackType, trackIndex, locked)Locks/unlocks track
14GetIsTrackLocked(trackType, trackIndex)Returns lock state
15DeleteClips([timelineItems], ripple)Deletes clips from timeline
16SetClipsLinked([timelineItems], linked)Links/unlinks clips
17GetItemListInTrack(trackType, index)Returns items on track
18AddMarker(frameId, color, name, note, duration, customData)Adds timeline marker
19GetMarkers()Returns marker dict
20GetMarkerByCustomData(customData)Finds marker by data
21UpdateMarkerCustomData(frameId, customData)Updates marker data
22GetMarkerCustomData(frameId)Returns custom data
23DeleteMarkersByColor(color)Deletes markers by color
24DeleteMarkerAtFrame(frameNum)⚠️Returns False if no marker at frame
25DeleteMarkerByCustomData(customData)⚠️Returns False if no match
26GetCurrentTimecode()Returns timecode string
27SetCurrentTimecode(timecode)⚠️Returns False if playback not active
28GetCurrentVideoItem()Returns item at playhead
29GetCurrentClipThumbnailImage()Returns thumbnail data
30GetTrackName(trackType, trackIndex)Returns track name
31SetTrackName(trackType, trackIndex, name)Sets track name
32DuplicateTimeline(timelineName)Duplicates timeline
33CreateCompoundClip([items], {clipInfo})Returns compound clip item
34CreateFusionClip([timelineItems])Returns Fusion clip item
35ImportIntoTimeline(filePath, {options})⚠️Tested; result depends on file format
36Export(fileName, exportType, exportSubtype)Exports EDL/XML/AAF
37GetSetting(settingName)Returns settings dict
38SetSetting(settingName, settingValue)⚠️API accepts; some settings read-only
39InsertGeneratorIntoTimeline(name)Inserts generator
40InsertFusionGeneratorIntoTimeline(name)Inserts Fusion generator
41InsertFusionCompositionIntoTimeline()Inserts Fusion composition
42InsertOFXGeneratorIntoTimeline(name)⚠️API accepts; needs valid OFX plugin
43InsertTitleIntoTimeline(name)Inserts title
44InsertFusionTitleIntoTimeline(name)Inserts Fusion title
45GrabStill()Returns GalleryStill object
46GrabAllStills(stillFrameSource)Returns list of GalleryStill objects
47GetUniqueId()Returns UUID string
48CreateSubtitlesFromAudio({settings})Returns True — creates subtitles from audio
49DetectSceneCuts()Returns True — detects scene cuts in timeline
50ConvertTimelineToStereo()Converts timeline to stereo 3D
51GetNodeGraph()Returns Graph object
52AnalyzeDolbyVision([items], analysisType)🔬Requires HDR/Dolby Vision content
53GetMediaPoolItem()Returns MediaPoolItem for timeline
54GetMarkInOut()Returns mark in/out dict
55SetMarkInOut(in, out, type)Sets mark in/out
56ClearMarkInOut(type)Clears mark in/out
57GetVoiceIsolationState(trackIndex)Resolve 20.3.2 live test returns voice isolation state
58SetVoiceIsolationState(trackIndex, {state})Resolve 20.3.2 live test sets voice isolation state

TimelineItem

#MethodStatusTest Result / Notes
1GetName()Returns item name
2GetDuration(subframe_precision)Returns duration
3GetEnd(subframe_precision)Returns end frame
4GetSourceEndFrame()Returns source end frame
5GetSourceEndTime()Returns source end time
6GetFusionCompCount()Returns comp count
7GetFusionCompByIndex(compIndex)Returns Fusion composition
8GetFusionCompNameList()Returns comp names
9GetFusionCompByName(compName)Returns Fusion composition
10GetLeftOffset(subframe_precision)Returns left offset
11GetRightOffset(subframe_precision)Returns right offset
12GetStart(subframe_precision)Returns start frame
13GetSourceStartFrame()Returns source start
14GetSourceStartTime()Returns source start time
15SetProperty(propertyKey, propertyValue)Sets item property
16GetProperty(propertyKey)Returns property dict
17AddMarker(frameId, color, name, note, duration, customData)Adds marker to item
18GetMarkers()Returns marker dict
19GetMarkerByCustomData(customData)Finds marker by data
20UpdateMarkerCustomData(frameId, customData)Updates marker data
21GetMarkerCustomData(frameId)Returns custom data
22DeleteMarkersByColor(color)Deletes markers by color
23DeleteMarkerAtFrame(frameNum)⚠️Returns False if no marker at frame
24DeleteMarkerByCustomData(customData)⚠️Returns False if no match
25AddFlag(color)Adds flag
26GetFlagList()Returns flag colors
27ClearFlags(color)Clears flags
28GetClipColor()Returns clip color
29SetClipColor(colorName)Sets clip color
30ClearClipColor()Clears clip color
31AddFusionComp()Creates Fusion composition
32ImportFusionComp(path)Imports .comp file
33ExportFusionComp(path, compIndex)Exports .comp file
34DeleteFusionCompByName(compName)⚠️Returns False if comp not found
35LoadFusionCompByName(compName)Loads composition
36RenameFusionCompByName(oldName, newName)Renames composition
37AddVersion(versionName, versionType)Adds grade version
38GetCurrentVersion()Returns version info
39DeleteVersionByName(versionName, versionType)⚠️Returns False if version not found
40LoadVersionByName(versionName, versionType)Loads grade version
41RenameVersionByName(oldName, newName, type)Renames version
42GetVersionNameList(versionType)Returns version names
43GetMediaPoolItem()Returns source MediaPoolItem
44GetStereoConvergenceValues()Returns stereo keyframes
45GetStereoLeftFloatingWindowParams()Returns stereo params
46GetStereoRightFloatingWindowParams()Returns stereo params
47SetCDL([CDL map])Sets CDL values
48AddTake(mediaPoolItem, startFrame, endFrame)Adds take
49GetSelectedTakeIndex()Returns selected take index
50GetTakesCount()Returns take count
51GetTakeByIndex(idx)Returns take info
52DeleteTakeByIndex(idx)Deletes take
53SelectTakeByIndex(idx)Selects take
54FinalizeTake()⚠️Returns False when no take selected
55CopyGrades([tgtTimelineItems])⚠️API accepts; needs matching items
56SetClipEnabled(enabled)Enables/disables clip
57GetClipEnabled()Returns enabled state
58UpdateSidecar()⚠️Returns False for non-BRAW clips
59GetUniqueId()Returns UUID string
60LoadBurnInPreset(presetName)⚠️API accepts; preset must exist
61CreateMagicMask(mode)⚠️Tested; needs DaVinci Neural Engine + Color page context
62RegenerateMagicMask()⚠️Tested; needs existing mask
63Stabilize()Returns True on supported clips
64SmartReframe()⚠️Tested; needs specific aspect ratio setup
65GetNodeGraph(layerIdx)Returns Graph object
66GetColorGroup()Returns ColorGroup
67AssignToColorGroup(colorGroup)Assigns to group
68RemoveFromColorGroup()⚠️Returns False if not in group
69ExportLUT(exportType, path)Exports LUT file
70GetLinkedItems()Returns linked items
71GetTrackTypeAndIndex()Returns [trackType, trackIndex]
72GetSourceAudioChannelMapping()Returns audio mapping
73GetIsColorOutputCacheEnabled()Returns cache state
74GetIsFusionOutputCacheEnabled()Returns cache state
75SetColorOutputCache(cache_value)⚠️Tested; needs active color pipeline
76SetFusionOutputCache(cache_value)⚠️Tested; needs active Fusion pipeline
77SetName(clipName)Resolve 20.3.2 live test renames timeline item
78GetVoiceIsolationState()Resolve 20.3.2 live test returns voice isolation state
79SetVoiceIsolationState({state})Resolve 20.3.2 live test sets voice isolation state
80ResetAllNodeColors()Resolve 20.3.2 live test resets node colors

Gallery

#MethodStatusTest Result / Notes
1GetAlbumName(galleryStillAlbum)Returns album name
2SetAlbumName(galleryStillAlbum, albumName)Sets album name
3GetCurrentStillAlbum()Returns GalleryStillAlbum
4SetCurrentStillAlbum(galleryStillAlbum)Sets current album
5GetGalleryStillAlbums()Returns album list
6GetGalleryPowerGradeAlbums()Returns power grade albums
7CreateGalleryStillAlbum()Creates still album
8CreateGalleryPowerGradeAlbum()Creates power grade album

GalleryStillAlbum

#MethodStatusTest Result / Notes
1GetStills()Returns list of GalleryStill objects
2GetLabel(galleryStill)Returns label string
3SetLabel(galleryStill, label)⚠️API accepts; may not persist in all versions
4ImportStills([filePaths])Imports DRX still files (requires Color page)
5ExportStills([stills], folderPath, prefix, format)Exports stills as image + companion .drx grade file. Requires Color page with Gallery panel visible. Supported formats: dpx, cin, tif, jpg, png, ppm, bmp, xpm, drx.
6DeleteStills([galleryStill])Deletes stills from album

Note (v2.0.8+): The compound server's gallery_stills tool includes a grab_and_export action that combines GrabStill() + ExportStills() in a single call — more reliable than calling them separately since it keeps the live GalleryStill reference. Returns the list of exported files (image + .drx grade data). Requires the Color page with the Gallery panel open.

Graph

#MethodStatusTest Result / Notes
1GetNumNodes()Returns node count (via ColorGroup pre/post graphs)
2SetLUT(nodeIndex, lutPath)Sets LUT on node
3GetLUT(nodeIndex)Returns LUT path
4SetNodeCacheMode(nodeIndex, cache_value)Returns True
5GetNodeCacheMode(nodeIndex)Returns -1 (no cache mode set)
6GetNodeLabel(nodeIndex)Returns node label string
7GetToolsInNode(nodeIndex)Returns None (no OFX tools in node)
8SetNodeEnabled(nodeIndex, isEnabled)Returns True
9ApplyGradeFromDRX(path, gradeMode)Applies grade from DRX file
10ApplyArriCdlLut()Applies ARRI CDL LUT
11ResetAllGrades()Resets all grades

ColorGroup

#MethodStatusTest Result / Notes
1GetName()Returns group name
2SetName(groupName)Sets group name
3GetClipsInTimeline(timeline)Returns clips in group
4GetPreClipNodeGraph()Returns Graph object
5GetPostClipNodeGraph()Returns Graph object

Contributing

We welcome contributions! The following areas especially need help:

Help Wanted: Untested API Methods

5 methods (1.5%) remain untested against a live DaVinci Resolve instance. If you have access to the required infrastructure or content, we'd love a PR with test confirmation:

  1. Cloud Project Methods (4 methods) — Need DaVinci Resolve cloud infrastructure:

    • ProjectManager.CreateCloudProject
    • ProjectManager.LoadCloudProject
    • ProjectManager.ImportCloudProject
    • ProjectManager.RestoreCloudProject
  2. HDR Analysis (1 method) — Needs specific content:

    • Timeline.AnalyzeDolbyVision — needs HDR/Dolby Vision content

How to Contribute

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-contribution)
  3. Run the existing test suite to ensure nothing breaks
  4. Add your test results or fixes
  5. Submit a pull request

Other Contribution Ideas

  • Windows testing — All tests were run on macOS; Windows verification welcome
  • Linux testing — DaVinci Resolve supports Linux; test coverage needed
  • Resolve version compatibility — Test against Resolve 18.x, 19.0, or newer versions
  • Bug reports — If a tool returns unexpected results on your setup, file an issue
  • Documentation — Improve examples, add tutorials, translate docs

Platform Support

PlatformStatusResolve Paths Auto-DetectedNotes
macOS✅ Tested/Library/Application Support/Blackmagic Design/...Primary development and test platform
Windows✅ SupportedC:\ProgramData\Blackmagic Design\...Community-tested; installer now emits env + PYTHONHOME for Resolve 20.3 multi-Python setups
Linux⚠️ Experimental/opt/resolve/...Should work — testing and feedback welcome

Security Considerations

This MCP server controls DaVinci Resolve via its Scripting API. Some tools perform actions that are destructive or interact with the host filesystem:

ToolRiskMitigation
quit_app / restart_appTerminates the Resolve process — can cause data loss if unsaved changes exist or a render is in progressMCP clients should require explicit user confirmation before calling these tools. Subprocess calls use hardcoded command lists (no shell injection possible).
export_layout_preset / import_layout_preset / delete_layout_presetRead/write/delete files in the Resolve layout presets directoryPath traversal protection validates all resolved paths stay within the expected presets directory (v2.0.7+).
save_projectCreates and removes a temporary .drp file in the system temp directoryPath is constructed server-side with no LLM-controlled input.

Recommendations for MCP client developers:

  • Enable tool-call confirmation prompts for destructive tools (quit_app, restart_app, delete_layout_preset)
  • Do not grant blanket auto-approval to all tools in this server

Project Structure

davinci-resolve-mcp/
├── install.py                    # Universal installer (macOS/Windows/Linux)
├── src/
│   ├── server.py                # Compound MCP server — 27 tools (default)
│   ├── resolve_mcp_server.py    # Thin full-server entrypoint — 354 tools
│   ├── granular/                # Modular full-server implementation
│   └── utils/                   # Platform detection, Resolve connection helpers
├── tests/                       # 5-phase live API test suite + Resolve 20 delta (331/331 pass)
├── docs/
│   └── resolve_scripting_api.txt # Official Resolve Scripting API reference
└── examples/                    # Getting started, markers, media, timeline examples

License

MIT

Author

Samuel Gursky ([email protected])

Acknowledgments

  • Blackmagic Design for DaVinci Resolve and its scripting API
  • The Model Context Protocol team for enabling AI assistant integration
  • Anthropic for Claude Code, used extensively in development and testing

Server Terkait

NotebookLM Web Importer

Impor halaman web dan video YouTube ke NotebookLM dengan satu klik. Dipercaya oleh 200.000+ pengguna.

Instal Ekstensi Chrome