Repository navigation
MCP: reach every editor feature (settings, captions, regions, clips, media, export) #1180
Description
Decision
The MCP must be able to do everything the editor can: an agent connected over MCP discovers and acts on every project feature, the look included (frames, 3D, webcam cutout, cursor, captions and translations), not only the timeline. App-level secrets (LLM keys, MCP token) stay out.
Follows #1174 (one server, two transports), whose PR 3 brings record and export to the in-app server.
Audited at origin/main @ b4b2890. Paths relative to the repo root. R = readable by MCP, W = tool that writes it.
Exposed today:
- Document tools (
electron/ai-edition/deep-agent/service.ts:393-421), on both servers: getCurrentDocument, getTranscript, getTranscriptWords, getCursorTrack, setWordText, removeWords, addTrim(s), setTrim, setClipRange, moveClip, replaceTimeline, addZoom(s), setZoom, addSpeed, setSpeed, addAnnotation, setAnnotation, addCameraFullscreen, setCameraFullscreen, addAudio, setAudio, removeTrim, removeModifier, removeClip, setAspectRatio. - Both servers also add listProjects, createCheckpoint, restoreCheckpoint.
- Stdio only (
electron/mcp/media-tools.ts): listSources, startRecording, stopRecording, setPointerTrack, exportVideo, getFrames. PR 3 of MCP: one server, two transports — the app is the authority when it runs #1174 brings these to the in-app server.
Headline
- The MCP edits the timeline only: clips, trims, zooms, speed, text annotations, camera-fullscreen regions, audio tracks, transcript words, aspect ratio. Almost all of the project's LOOK is unreachable.
- Every
legacyEditorsetting is invisible to getCurrentDocument exceptautoFocusAll, and none is writable except aspectRatio. That covers wallpaper, padding, roundness, shadow, blur, frame, motion blur, depth of field, the whole webcam layout, cursor, master gain, format fill, captions and translations. The snapshot omits evenaspectRatio. - Captions: nothing is readable or writable, although
service.ts:113(also the MCP instructions) andeditor.json:270,275promise "add captions".editor.json:276promises "split a clip", which exists nowhere. - The CLI
openscreen captions(src/cli/CliCaptionsRunner.tsx) writes legacy v1auto-captionannotations. The v2 CaptionsPane treats those as legacy and offers to clear them, so the CLI is obsolete as well.
1. Background, frame, composition (legacyEditor, typed by src/lib/ai-edition/store/editorSettings.ts:88-134)
| Feature | Where | R | W | Notes |
|---|---|---|---|---|
| Wallpaper (bundled, colour, gradient, upload) | wallpaper; RightPanes.tsx:393-414 |
no | no | parseStylePresetWallpaper (stylePresets.ts:247) validates safely. Bundled list lib/wallpaper.ts:4 not discoverable |
| Wallpaper motion | wallpaperMotion; RightPanes.tsx:418-431 |
no | no | only when wallpaperAcceptsMotion (native/sceneDescription.ts:618) |
| Background blur | backgroundBlur |
no | no | [0,1] |
| Padding | padding; RightPanes.tsx:2574 |
no | no | [0,100] |
| Rounded corners | borderRadius; RightPanes.tsx:2603 |
no | no | [0,64] px |
| Shadow | shadowIntensity; RightPanes.tsx:2563 |
no | no | |
| Device frame | frame; RightPanes.tsx:2530 |
no | no | RECORDING_FRAMES (projectDefaults.ts:17) |
| Frame theme | frameTheme; RightPanes.tsx:2551 |
no | no | |
| Aspect ratio | aspectRatio |
partial | setAspectRatio | not in getCurrentDocument |
Aspect "Original" native formats (W:H) |
RightPanes.tsx:2475; collectNativeFormats (document/outputFormat.ts:329) |
no | no | setAspectRatioArgs (agent-tools.ts:535) lacks them |
| Format fill: follow cursor | formatFollowCursor; RightPanes.tsx:2502 |
no | no | gated by formatFillAvailability (outputFormat.ts:231) |
| Motion blur | motionBlurAmount; RightPanes.tsx:2629 |
no | no | |
| Depth of field (3D zooms) | depthOfField; RightPanes.tsx:2650 |
no | no | offered only when a zoom has rotationPreset |
| Per-clip crop | timeline.clips[].cropRegion (schema/index.ts:226); useTimeline.ts:1216 |
no | no | missing from clip snapshot (agent-tools.ts:1035) |
2. 3D and camera
| Feature | Where | R | W | Notes |
|---|---|---|---|---|
| Zoom 3D camera (left/right/orbit) | zoomRanges[].rotationPreset |
yes | addZoom, setZoom | covered |
| Zoom focus mode manual/auto | zoomRanges[].focusMode; FloatingInspector.tsx:890 |
yes | no | snapshot reports it (agent-tools.ts:1076), no setter |
| Auto-focus all zooms | autoFocusAll |
yes | no | an EditorSettingsPatch key |
| Zoom custom scale | zoomRanges[].customScale; useTimeline.ts:887 |
yes | partial | setZoom can only clear it. Bounds timeline/zoom-scale.ts:32, zoomScaleLimit (native/sceneDescription.ts:708) |
| Zoom hide cursor | zoomRanges[].hideCursor; FloatingInspector.tsx:904 |
no | no | |
| Cursor 3D model | cursorModel3d; RightPanes.tsx:3796 |
no | no |
3. Webcam (LayoutPane, RightPanes.tsx:2804-3141)
| Feature | Where | R | W | Notes |
|---|---|---|---|---|
| Layout preset (PiP, side by side, stack, none) | webcamLayoutPreset |
no | no | |
| Mirror | webcamMirrored |
no | no | |
| Shrink on zoom | webcamReactiveZoom |
no | no | |
| Shape | webcamMaskShape |
no | no | moves an untouched roundness to the shape default |
| Roundness | webcamRoundness |
no | no | |
| Size | webcamSizePreset |
no | no | [15,60] |
| Position | webcamAnchor |
no | no | WEBCAM_ANCHORS (projectDefaults.ts:74) |
| Background removal / cutout | webcamBackgroundMode; :3042 |
no | no | gated by useCanSegmentCamera() (native/hooks/useSegmentationSupport.ts:58) |
| Cutout blur amount | webcamBlurIntensity |
no | no | |
| Cutout custom background | webcamWallpaper |
no | no | |
| Webcam framing | webcamCropRegion + webcamCropPan |
no | no | |
| Camera fullscreen regions | yes | add/setCameraFullscreen | covered |
4. Cursor (CursorPane, RightPanes.tsx:3680-3996)
cursorShow, cursorAutoHide, cursorTheme (CURSOR_THEME_IDS, lib/cursor/cursorThemes.ts:290), cursorAsArrow (CURSOR_KIND_IDS, :119), cursorSize [1.5,6], cursorSmoothing, cursorMotionBlur, cursorClickBounce [0,2], cursorClickImpact, cursorClickSound, cursorClickSoundGainDb: all R no, W no. The pointer track is covered by getCursorTrack and setPointerTrack. Check the cursor style modes as well (e.g. Glass Lens).
5. Timeline
| Feature | Where | R | W | Notes |
|---|---|---|---|---|
| Re-run auto zooms on an existing project | useTimeline.ts:373 |
— | no | collectAutoZoomSuggestionsForDocument + appendAutoZoomSuggestions already imported in media-tools.ts:19 |
| Insert another asset's clip | useTimeline.ts:1332, op insert_asset_clip (schema/index.ts:374) |
yes | no | the hint at agent-tools.ts:2630 ("use replaceTimeline") is misleading |
| Duplicate clip | document/timeline.ts:1012 |
— | no | |
| Clear edit regions | clearEditRegions (document/timeline.ts:1191) |
— | no | |
| Split clip | none | — | — | promised by editor.json:276 |
6. Annotations (FloatingInspector.tsx:962-1266)
| Feature | Where | R | W | Notes |
|---|---|---|---|---|
| Text annotation style and position | annotations[] |
partial (id, span, type, text) | add/setAnnotation | written but never read back |
| Type switch (text, image, arrow, blur) | convertAnnotationKind (annotations/placement.ts:251) |
type | no | addAnnotation hard-codes text (agent-tools.ts:2405) |
| Arrow | figureData, figureDataSchema (schema/index.ts:406) |
no | no | |
| Blur / mosaic privacy region | blurData, blurDataSchema (schema/index.ts:393) |
no | no | privacy gap |
| Image annotation | data URL | no | no | needs a file read |
7. Audio
- Master gain
audioGainDb±12 dB: no / no. - Track fade in and out
audioTracks[].fadeInMs/fadeOutMs(max 5000): no / no. - Import audio or record a voiceover (
DocumentService.addAsset,document-service.ts:533): no.
8. Captions (legacyEditor.captions, src/lib/ai-edition/captions/settings.ts:50-127; CaptionsPane.tsx)
- Nothing here is readable or writable:
- enabled;
- style (
CAPTION_STYLES,settings.ts:182); - font, weight, size, colour;
- plate and opacity (
captionPlatePatch,:152); - anchors and insets;
- words per line;
- lane (
resolveCaptionLane,:638); - display language and translation layers (
legacyEditor.captionTranslations,translations.ts).
- Translation exists only through the app LLM (
electron/ai-edition/caption-translate.ts, IPCcaptions.translate). The MCP client can translate itself and store the result withputCaptionTranslation(translations.ts:85).
9. Transcription
- Transcription is only triggered in the renderer when the editor opens:
transcriptionStore.ts,document/transcribe.ts:43,v4/MediaStage.tsx:463. A stdio project from stopRecording has NO transcript until the user opens it, so getTranscript and removeWords fail. - No tool triggers it, redoes it or forces a language.
- The project vocabulary (
project.vocabulary, max 600 chars) andassets[].transcriptionFailureare neither readable nor writable.
10. Export (dialog state)
exportVideopasses null for GIF fps and size (media-tools.ts:508-509) although the CLI supports them.- It has no mp4 fps (60 is fixed in
lib/cliContracts.ts) and no GIF loop. - autoZoom and the voiceover mix are hardcoded off (
media-tools.ts:510-513).
11. Projects and media
- Rename the project (
project.title): no tool. - Import or remove media (
DocumentService.addAsset:533,removeAsset:587): no tool. - Create a project (
:464): only through stopRecording. - Delete a project: none. It is destructive; leave it out.
12. Recording
startRecordingcannot record the webcam (CliRecordRequesthas no camera fields).- The cursor mode is forced to
editable-overlay(media-tools.ts:345).
13. App-level (outside the project)
- Style presets (
electron/ai-edition/style-preset-service.ts:115-215; applied withstylePresetPatch,src/lib/ai-edition/stylePresetsEditor.ts:90): list, apply, save, and the preset for new projects. - LLM keys, MCP token and port, locale, theme, shortcuts: these stay out of the MCP.
Promises no tool keeps
service.ts:113: "add captions". It is also the MCP instructions (openscreen-mcp-server.ts:230).editor.json:270,275,276: "add captions", "split a clip".agent-tools.ts:2630: "to place footage use replaceTimeline", but that uses the primary asset only.- The snapshot reports
focusMode, and setters accept annotation style and position, yet nothing reads those back or sets focusMode.
Proposed batches
- A.
setEditorSettings+ asettingsread block in getCurrentDocument.- A partial patch named after
EditorSettingsPatch(store/editorSettings.ts:343), applied withapplySettingsPatch(store/settingsPatch.ts:15) like setAspectRatio (agent-tools.ts:1478). - Zod bounds from
SETTING_BOUNDS(src/lib/projectDefaults.ts:295) and the enum lists. Wallpapers go throughparseStylePresetWallpaper: that is the security boundary, no file:// and no URLs. - Read side:
getEditorSettings(doc)(editorSettings.ts:213), with data-URL wallpapers elided, plus the gating context (formatFillAvailability, tilted zoom present, bundled wallpapers, segmentation capability if reachable). - Optional: listStylePresets and applyStylePreset.
- Covers §1, the webcam part of §3, §4, autoFocusAll and audioGainDb.
- A partial patch named after
- B. Captions and transcription.
setCaptionSettingsthroughpatchCaptionSettings(captions/settings.ts:657), with a style shortcut.- Translations: read units with
captionTranslationUnits/untranslatedUnits, write withputCaptionTranslation, remove withremoveCaptionTranslation; the client translates itself. transcribe(assetId, language?)against the main-process STT. When the app runs, use or wait for its transcription.- Project vocabulary.
- Align the CLI
captionscommand on the v2 model, and fix the prompts.
- C. Fill in the region tools.
- setZoom: focusMode, hideCursor, customScale.
- setAudio: fades.
- add/setAnnotation: type, figureData, blurData.
- Snapshot: annotation style, position and type data.
- D. Clip structure.
- New tools: insertClip, duplicateClip, addAutoZooms.
- setClipRange gains cropRegion.
- Fix the replaceTimeline hint and the "split a clip" promise.
- E. Projects and media: setProjectInfo (title), importMedia, removeMedia, createProject.
- F. Export and record:
- exportVideo gains gifFrameRate, gifSizePreset, autoZoom, mp4 fps and GIF loop;
- startRecording gains the webcam.
Plan
One PR per batch A to F above, each adding tools to both transports and keeping instructions, tool descriptions, technical-documentation/architecture/mcp-server.md, website/docs/ai-editing.md (+ translations) and the openscreen-demo skill true.
Activity
fix(mcp): offer auto only while the timeline holds one composition, k…
feat(agent): region tools set and read every zoom, annotation and aud…
docs: region tools reach arrows, blurs, zoom settings and audio fades
feat(mcp): setEditorSettings and a settings block in getCurrentDocument
docs(mcp): document setEditorSettings and the settings read
fix(mcp): offer auto only while the timeline holds one composition, k…
fix(mcp): refuse a camera crop and pan that place the framing in two …
feat(mcp): rename a project, import and remove its media, create one
docs(mcp): the project and media tools, and why deleting a project is…
fix(mcp): let the editor read an imported .oga, keep a created projec…
feat(mcp): setEditorSettings and a settings block in getCurrentDocument
docs(mcp): document setEditorSettings and the settings read
fix(mcp): offer auto only while the timeline holds one composition, k…
fix(mcp): refuse a camera crop and pan that place the framing in two …
refactor(timeline): share the editor's insert-clip and crop writes as…
33 remaining items
feat(mcp): read, style and translate the captions through the agent t…
feat(cli): openscreen captions writes a transcript and turns captions on
docs: captions, translation and transcription over MCP and in the CLI
docs(website): carry the captions and transcription changes into the …
fix(mcp): caption a transcript only the legacy mirror holds, say tran…
fix(mcp): read the project again when a waiting transcription starts
Cliftonz commentedon Oct 13, 2026
A concrete case for the annotations row in section 6: I edit short feature demos through the MCP, and every label needs a fixed text size (72) to match our other videos. addAnnotation and setAnnotation only take text, span and x/y, so the size has to be set by hand in the inspector after each agent edit. Being able to set and read back an annotation’s text size as part of batch C would remove that manual step.
EtienneLescot commentedon Oct 14, 2026
@Cliftonz this landed in #1182 (batch C), merged on main.
addAnnotationandsetAnnotationtakefontSize(8 to 200; 72 is fine), pluscolor,background,boldandanimation.getCurrentDocumentreads each text annotation's look back,fontSizeincluded, so the agent can check what it wrote.It ships in the next release; until then, a build from
mainhas it.feat(mcp): transcribe an asset over MCP with the on-device Whisper
feat(mcp): read, style and translate the captions through the agent t…
feat(cli): openscreen captions writes a transcript and turns captions on
docs: captions, translation and transcription over MCP and in the CLI
docs(website): carry the captions and transcription changes into the …
fix(mcp): caption a transcript only the legacy mirror holds, say tran…
fix(mcp): read the project again when a waiting transcription starts