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 +27 -3
- package/package.json +1 -1
- package/src/tools/editorTools.mjs +136 -20
- package/src/tools/systemTools.mjs +1 -1
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.
|
|
58
|
+
creavit-studio v1.3.9
|
|
54
59
|
|
|
55
|
-
✓
|
|
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`, `
|
|
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
|
@@ -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(
|
|
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({
|
|
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({
|
|
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: "
|
|
123
|
-
command: "editor.
|
|
130
|
+
name: "creavit_editor_perspective_poses",
|
|
131
|
+
command: "editor.listPerspectivePoses",
|
|
124
132
|
description:
|
|
125
|
-
"
|
|
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
|
-
{
|
|
128
|
-
|
|
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({
|
|
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")
|
|
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:
|
|
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:
|
|
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:
|
|
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") }, [
|
|
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
|
-
{
|
|
308
|
-
|
|
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(
|
|
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(
|
|
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.",
|