creavit-studio-mcp 1.3.7 → 1.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,6 +7,11 @@ and **see the canvas** to verify the result.
7
7
 
8
8
  macOS only (Creavit Studio is a macOS app). Requires Node 18+.
9
9
 
10
+ > This MCP server is client-agnostic — any MCP client can drive the app.
11
+ > That is separate from the **in-app Agent panel**, which shells out to a CLI
12
+ > installed on your Mac and detects only Claude Code and Codex
13
+ > (see `electron/aiAgent/agentCatalog.cjs`).
14
+
10
15
  ## Install
11
16
 
12
17
  ### Claude Code
@@ -50,9 +55,9 @@ npx creavit-studio-mcp --doctor
50
55
  ```
51
56
 
52
57
  ```
53
- creavit-studio v1.2.0
58
+ creavit-studio v1.3.9
54
59
 
55
- 50 MCP tools defined
60
+ 104 MCP tools defined
56
61
  ✓ Offline project reading available (.crvt files readable without the app)
57
62
  ✓ Connected to the app (v3.0.5, pid 61068)
58
63
  Open windows: 2
@@ -106,7 +111,8 @@ files directly and work with the app closed.
106
111
  `creavit_editor_set_settings`, `creavit_editor_list_zooms`,
107
112
  `creavit_editor_add_zoom`, `creavit_editor_update_zoom`,
108
113
  `creavit_editor_remove_zoom`, `creavit_editor_segments`,
109
- `creavit_editor_set_segments`, `creavit_editor_seek`,
114
+ `creavit_editor_set_segments`, `creavit_editor_timeline`,
115
+ `creavit_editor_canvas_elements`, `creavit_editor_seek`,
110
116
  `creavit_editor_playback`, `creavit_editor_screenshot`,
111
117
  `creavit_editor_export`, `creavit_editor_history`
112
118
 
@@ -162,6 +168,24 @@ Timeline & assets: `creavit_motion_segments`, `creavit_motion_library`,
162
168
  **Recording** — `creavit_devices_list`, `creavit_recording_status`,
163
169
  `creavit_recording_start`, `creavit_recording_stop`
164
170
 
171
+ `creavit_recording_start` treats `cameraEnabled`, `micEnabled`, and
172
+ `systemAudioEnabled` as authoritative. Passing `false` updates both capture and
173
+ the recorder UI; disabling the camera also stops and hides its live window.
174
+
175
+ ### Every timeline track and canvas element
176
+
177
+ `creavit_editor_segments` remains the compact clip/cut API. For the complete
178
+ editor use `creavit_editor_timeline action=list`: it discovers clips, steps,
179
+ zooms, layouts, perspectives, titles, sounds, shortcuts, masks, motion scenes,
180
+ code snippets, media/GIFs, subtitles, and manual-cursor segments. Pass
181
+ `detail=full` to read complete objects, then use get/add/update/remove/replace on
182
+ one returned track type.
183
+
184
+ `creavit_editor_canvas_elements action=list` returns every transformable item on
185
+ the main canvas. Each item advertises its exact `supports` array and coordinate
186
+ units. Updating the advertised fields can move, resize/scale, rotate, change
187
+ opacity, or hide an element without guessing its internal state shape.
188
+
165
189
  **Browser walkthrough** — `creavit_browser_open`, `creavit_browser_inspect`,
166
190
  `creavit_browser_focus`, `creavit_browser_interact`, `creavit_browser_scroll`,
167
191
  `creavit_browser_close`, `creavit_record_url_walkthrough`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "creavit-studio-mcp",
3
- "version": "1.3.7",
3
+ "version": "1.3.9",
4
4
  "description": "MCP server that lets AI coding agents (Claude Code, Codex, Cursor) drive the Creavit Studio screen recording app",
5
5
  "keywords": [
6
6
  "mcp",
@@ -69,7 +69,9 @@ export function editorTools() {
69
69
  }),
70
70
  color: S.string("CSS color for a solid background"),
71
71
  image: S.string("Image URL, local path, or a CMS wallpaper name"),
72
- wallpaper: S.string("CMS wallpaper name (see creavit_editor_wallpapers)"),
72
+ wallpaper: S.string(
73
+ "CMS wallpaper name (see creavit_editor_wallpapers)",
74
+ ),
73
75
  blur: S.number("Image blur amount"),
74
76
  gradient: S.object(
75
77
  "Gradient configuration: {type, direction, colors:[{color,position}]}.",
@@ -79,7 +81,10 @@ export function editorTools() {
79
81
  ["type"],
80
82
  ),
81
83
  mapResult: (result) =>
82
- textResult({ ...result, note: "Applied. Call creavit_project_save to persist." }),
84
+ textResult({
85
+ ...result,
86
+ note: "Applied. Call creavit_project_save to persist.",
87
+ }),
83
88
  }),
84
89
 
85
90
  bridgeTool({
@@ -108,7 +113,10 @@ export function editorTools() {
108
113
  }),
109
114
  timeoutMs: 60_000,
110
115
  mapResult: (result) =>
111
- textResult({ ...result, note: "Applied. Call creavit_project_save to persist." }),
116
+ textResult({
117
+ ...result,
118
+ note: "Applied. Call creavit_project_save to persist.",
119
+ }),
112
120
  }),
113
121
 
114
122
  bridgeTool({
@@ -119,16 +127,65 @@ export function editorTools() {
119
127
  }),
120
128
 
121
129
  bridgeTool({
122
- name: "creavit_editor_camera_set",
123
- command: "editor.setCamera",
130
+ name: "creavit_editor_perspective_poses",
131
+ command: "editor.listPerspectivePoses",
124
132
  description:
125
- "Partially updates camera overlay settings: visible, size, radius, shadow, position crop, cropZoom, followMouse, oscillationMovement, mirror, aspectRatio, border, background removal, mergeWithCursor, lockSizeOnZoom and sizeOnZoom. Call creavit_project_save afterwards.",
133
+ "Lists the balanced perspective poses (flat, desk, hero, peek-up, lean/iso/float left-right) with their angles. Read this before setting a pose so you pick a real one.",
134
+ inputSchema: schema(),
135
+ }),
136
+
137
+ bridgeTool({
138
+ name: "creavit_editor_perspective_pose",
139
+ command: "editor.setPerspectivePose",
140
+ description:
141
+ "Gives a perspective range a balanced camera angle and computes its pivot from a focus point — prefer this over writing raw tiltX/tiltY/skew, which is how lopsided angles happen. `pose` picks the look, `strength` (0..2) makes it subtle or dramatic, `focus` is the canvas point the tilt pivots around as {x,y} in 0..1 (e.g. the UI element the viewer should look at). Add `endPose`/`focusEnd` to animate from one angle/pivot to another across the range. Call creavit_project_save afterwards.",
142
+ inputSchema: schema({
143
+ id: S.string("Perspective range id"),
144
+ index: S.number("Range index when id is unknown (default 0)"),
145
+ pose: S.string("flat | desk | hero | peek-up | lean-left | lean-right | iso-left | iso-right | float-left | float-right"),
146
+ endPose: S.string("Pose the range animates towards"),
147
+ strength: S.number("0..2, default 1"),
148
+ focus: S.object("Pivot point {x,y} normalized 0..1"),
149
+ focusEnd: S.object("Pivot point the origin travels to"),
150
+ scale: S.number("Plane scale at the start"),
151
+ scaleEnd: S.number("Plane scale at the end"),
152
+ }),
153
+ }),
154
+
155
+ bridgeTool({
156
+ name: "creavit_editor_reframe",
157
+ command: "editor.reframe",
158
+ description:
159
+ "Re-frames the whole composition for another aspect ratio in ONE call — use this for \"make it vertical / for mobile / a story\" requests instead of setting the ratio and then nudging padding, camera and zooms by hand. Ask the user which format they want first (9:16 story, 4:5 or 1:1 feed, 3:4) when they did not say. It sets the ratio, refits padding/radius so the content stays as large as possible, enlarges the camera and anchors it bottom-center so it reads on a narrow frame, and scales the cursor. Existing zooms are preserved untouched unless tightenZooms is true. Call creavit_project_save afterwards.",
126
160
  inputSchema: schema(
127
- { settings: S.object("Camera settings to update") },
128
- ["settings"],
161
+ {
162
+ ratio: S.string("16:9, 9:16, 1:1, 4:3, 3:4, or empty string for auto", {
163
+ enum: ["", "16:9", "9:16", "1:1", "4:3", "3:4"],
164
+ }),
165
+ cameraPlacement: S.string("bottom | top | keep", {
166
+ enum: ["bottom", "top", "keep"],
167
+ }),
168
+ tightenZooms: S.bool(
169
+ "Raise low zoom scales so text stays readable on a phone (default false)",
170
+ ),
171
+ },
172
+ ["ratio"],
129
173
  ),
174
+ }),
175
+
176
+ bridgeTool({
177
+ name: "creavit_editor_camera_set",
178
+ command: "editor.setCamera",
179
+ description:
180
+ "Partially updates camera overlay settings: visible, size, radius, shadow, position crop, cropZoom, followMouse, oscillationMovement, mirror, aspectRatio, border, background removal, mergeWithCursor, lockSizeOnZoom and sizeOnZoom. Background removal is a real toggle: pass removeBackground (or optimizedBackgroundRemoval) true/false and the app loads the segmentation engine and starts the pipeline, exactly like the settings panel does — optionally tune it with optimizedBackgroundRemovalSettings. Call creavit_project_save afterwards.",
181
+ inputSchema: schema({ settings: S.object("Camera settings to update") }, [
182
+ "settings",
183
+ ]),
130
184
  mapResult: (result) =>
131
- textResult({ ...result, note: "Applied. Call creavit_project_save to persist." }),
185
+ textResult({
186
+ ...result,
187
+ note: "Applied. Call creavit_project_save to persist.",
188
+ }),
132
189
  }),
133
190
 
134
191
  {
@@ -144,7 +201,8 @@ export function editorTools() {
144
201
  ["action"],
145
202
  ),
146
203
  run: async ({ action }) => {
147
- if (action === "status") return textResult(await callCommand("editor.getAudio", {}));
204
+ if (action === "status")
205
+ return textResult(await callCommand("editor.getAudio", {}));
148
206
  if (action !== "mute" && action !== "unmute") {
149
207
  throw new Error("`action` must be status, mute, or unmute");
150
208
  }
@@ -207,7 +265,8 @@ export function editorTools() {
207
265
  bridgeTool({
208
266
  name: "creavit_editor_perspectives",
209
267
  command: "editor.listPerspectives",
210
- description: "Lists all perspective (3D animation) ranges on the timeline.",
268
+ description:
269
+ "Lists all perspective (3D animation) ranges on the timeline.",
211
270
  inputSchema: schema(),
212
271
  }),
213
272
 
@@ -228,7 +287,8 @@ export function editorTools() {
228
287
  bridgeTool({
229
288
  name: "creavit_editor_update_perspective",
230
289
  command: "editor.updatePerspective",
231
- description: "Updates an existing perspective range by id or zero-based index.",
290
+ description:
291
+ "Updates an existing perspective range by id or zero-based index.",
232
292
  inputSchema: schema(
233
293
  {
234
294
  id: S.string("Perspective range ID"),
@@ -242,7 +302,8 @@ export function editorTools() {
242
302
  bridgeTool({
243
303
  name: "creavit_editor_remove_perspective",
244
304
  command: "editor.removePerspective",
245
- description: "Deletes a perspective range by id/index, or all perspective ranges with all=true.",
305
+ description:
306
+ "Deletes a perspective range by id/index, or all perspective ranges with all=true.",
246
307
  inputSchema: schema({
247
308
  id: S.string("Perspective range ID"),
248
309
  index: S.number("Perspective range index"),
@@ -269,12 +330,56 @@ export function editorTools() {
269
330
  ),
270
331
  }),
271
332
 
333
+ bridgeTool({
334
+ name: "creavit_editor_timeline",
335
+ command: "editor.timelineSegments",
336
+ description:
337
+ "Unified access to EVERY editor timeline track, not just video clips: clips, steps, zooms, layouts, perspectives, titles, sound effects, shortcuts, sensitive masks, motion scenes, code snippets, media/GIFs, subtitles and manual-cursor segments. action='list' discovers track types/counts; use detail='full' to read complete objects. get/add/update/remove/replace target one `type`. Updates are deep-merged so nested transform/style objects are preserved. Call creavit_project_save afterwards.",
338
+ inputSchema: schema({
339
+ action: S.string("list, get, add, update, remove or replace (default list)", {
340
+ enum: ["list", "get", "add", "update", "remove", "replace"],
341
+ }),
342
+ types: S.array("Track types to include when listing", { type: "string" }),
343
+ type: S.string("Target track type for get/add/update/remove/replace"),
344
+ id: S.string("Segment id"),
345
+ index: S.number("Zero-based segment index when it has no id"),
346
+ segment: S.object("Complete segment object to add"),
347
+ patch: S.object("Fields to update; nested objects are deep-merged"),
348
+ segments: S.array("Complete replacement list", { type: "object" }),
349
+ detail: S.string("summary or full (list only)", {
350
+ enum: ["summary", "full"],
351
+ }),
352
+ }),
353
+ }),
354
+
355
+ bridgeTool({
356
+ name: "creavit_editor_canvas_elements",
357
+ command: "editor.canvasElements",
358
+ description:
359
+ "Lists or transforms every editable element on the MAIN editor canvas: screen, camera, captured windows, GIF/image/video overlays, code snippets, titles, motion scenes and sensitive masks. action='list' returns each element's id, transform, units and exact `supports` fields. action='update' can move (x/y), resize (width/height/size/scale), rotate and change opacity where that element advertises support. Motion Studio's internal layers remain available through creavit_motion_elements / creavit_motion_element_update.",
360
+ inputSchema: schema({
361
+ action: S.string("list, get or update (default list)", {
362
+ enum: ["list", "get", "update"],
363
+ }),
364
+ type: S.string(
365
+ "screen, camera, window, gif, media, codeSnippet, title, motion or sensitive",
366
+ ),
367
+ id: S.string("Canvas element id"),
368
+ index: S.number("Index among elements of that type"),
369
+ patch: S.object(
370
+ "Transform fields advertised by the element's supports array, e.g. {x,y,width,height,scale,size,rotation,opacity,visible}",
371
+ ),
372
+ }),
373
+ }),
374
+
272
375
  bridgeTool({
273
376
  name: "creavit_editor_seek",
274
377
  command: "editor.seek",
275
378
  description:
276
379
  "Moves the playhead to the given time and renders that frame. Combine with creavit_editor_screenshot to inspect a specific moment.",
277
- inputSchema: schema({ time: S.number("Target time in seconds") }, ["time"]),
380
+ inputSchema: schema({ time: S.number("Target time in seconds") }, [
381
+ "time",
382
+ ]),
278
383
  }),
279
384
 
280
385
  {
@@ -304,8 +409,15 @@ export function editorTools() {
304
409
  timeoutMs: 120_000,
305
410
  mapResult: (result) => ({
306
411
  content: [
307
- { type: "image", data: result.base64, mimeType: result.mimeType || "image/png" },
308
- { type: "text", text: `Canvas frame @ ${Number(result.atTime || 0).toFixed(2)}s` },
412
+ {
413
+ type: "image",
414
+ data: result.base64,
415
+ mimeType: result.mimeType || "image/png",
416
+ },
417
+ {
418
+ type: "text",
419
+ text: `Canvas frame @ ${Number(result.atTime || 0).toFixed(2)}s`,
420
+ },
309
421
  ],
310
422
  }),
311
423
  }),
@@ -314,7 +426,7 @@ export function editorTools() {
314
426
  name: "creavit_editor_export",
315
427
  command: "editor.export",
316
428
  description:
317
- "Exports the video idempotently; concurrent retries share one render. This takes a LONG time (minutes). Follow progress with creavit_events (export.started / export.finished / export.failed), then use creavit_file_open when the user asks to open/play it. If filePath is omitted, the export is written beside the open .crvt project.",
429
+ "Exports the video idempotently; concurrent retries share one render. This takes a LONG time (minutes). Follow progress with creavit_events (export.started / export.finished / export.failed), then use creavit_file_open when the user asks to open/play it. If filePath is omitted, the export is written beside the open .crvt project. Exporting requires an active Creavit Studio license, or a remaining free export credit. When neither is available the export is REFUSED before any rendering starts and the error explains why (expired license / free credits used up); relay that message to the user in their own language and point them at the purchase page instead of retrying.",
318
430
  inputSchema: schema({
319
431
  filePath: S.string("Target file path (.mp4)"),
320
432
  format: S.string("mp4 or gif", { enum: ["mp4", "gif"] }),
@@ -329,14 +441,18 @@ export function editorTools() {
329
441
  name: "creavit_editor_export_start",
330
442
  command: "editor.export.start",
331
443
  description:
332
- "Starts one export in the background and returns immediately. Use this when tool latency matters. Progress/completion is reported by creavit_events; set openWhenFinished=true to open/play the result automatically without showing export UI.",
444
+ "Starts one export in the background and returns immediately. Use this when tool latency matters. Progress/completion is reported by creavit_events; set openWhenFinished=true to open/play the result automatically without showing export UI. Exporting requires an active Creavit Studio license, or a remaining free export credit. When neither is available the export is REFUSED before any rendering starts and the error explains why (expired license / free credits used up); relay that message to the user in their own language and point them at the purchase page instead of retrying.",
333
445
  inputSchema: schema({
334
- filePath: S.string("Target file path (.mp4); omit to export beside the project"),
446
+ filePath: S.string(
447
+ "Target file path (.mp4); omit to export beside the project",
448
+ ),
335
449
  format: S.string("mp4 or gif", { enum: ["mp4", "gif"] }),
336
450
  resolution: S.string("e.g. 720p, 1080p, 4k"),
337
451
  fps: S.number("Frame rate, e.g. 30 or 60"),
338
452
  quality: S.string("compact | high | max"),
339
- openWhenFinished: S.bool("Open the exported file automatically when rendering completes"),
453
+ openWhenFinished: S.bool(
454
+ "Open the exported file automatically when rendering completes",
455
+ ),
340
456
  }),
341
457
  timeoutMs: 30_000,
342
458
  }),
@@ -74,7 +74,7 @@ export function systemTools() {
74
74
  name: "creavit_recording_start",
75
75
  command: "recording.start",
76
76
  description:
77
- "Starts a screen recording idempotently: retries while starting share the same native operation, and calling it while active does not restart. Get source IDs from creavit_devices_list first. For a multi-step website recording, use ONE creavit_record_url_walkthrough call instead of this manual tool.",
77
+ "Starts a screen recording idempotently: retries while starting share the same native operation, and calling it while active does not restart. cameraEnabled, micEnabled and systemAudioEnabled are authoritative booleans: false also updates the recorder UI/state and cameraEnabled:false stops/hides the live camera window before capture. Get source IDs from creavit_devices_list first. For a multi-step website recording, use ONE creavit_record_url_walkthrough call instead of this manual tool.",
78
78
  inputSchema: schema({
79
79
  options: S.object(
80
80
  "Recording options: {sourceType:'display'|'window'|'area', sourceId, cameraEnabled, micEnabled, systemAudioEnabled, delayMs, area:{x,y,width,height}}. cameraEnabled:false also turns the camera off and hides its window, so it does not appear in a screen recording; cameraEnabled:true opens and starts it.",