creavit-studio-mcp 1.3.0 → 1.3.2
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 +17 -6
- package/package.json +1 -1
- package/src/bridgeClient.mjs +3 -0
- package/src/protocol.mjs +1 -1
- package/src/tools/browserTools.mjs +17 -6
- package/src/tools/editorTools.mjs +33 -3
- package/src/tools/index.mjs +2 -0
- package/src/tools/inputTools.mjs +134 -0
package/README.md
CHANGED
|
@@ -111,9 +111,15 @@ files directly and work with the app closed.
|
|
|
111
111
|
`creavit_editor_export`, `creavit_editor_history`
|
|
112
112
|
|
|
113
113
|
**Appearance** — `creavit_editor_background_get`,
|
|
114
|
-
`creavit_editor_background_set`, `
|
|
114
|
+
`creavit_editor_background_set`, `creavit_editor_wallpapers`,
|
|
115
|
+
`creavit_editor_wallpaper_set`, `creavit_editor_camera_get`,
|
|
115
116
|
`creavit_editor_camera_set`, `creavit_editor_audio`
|
|
116
117
|
|
|
118
|
+
> Zoom ranges are normally **not** something you add. Creavit Studio records the
|
|
119
|
+
> real mouse clicks and builds its own auto-zoom segments in the editor; use
|
|
120
|
+
> `creavit_editor_add_zoom` only when the user asks for a zoom at a specific
|
|
121
|
+
> moment.
|
|
122
|
+
|
|
117
123
|
**Perspective** — `creavit_editor_perspectives`,
|
|
118
124
|
`creavit_editor_add_perspective`, `creavit_editor_update_perspective`,
|
|
119
125
|
`creavit_editor_remove_perspective`
|
|
@@ -175,6 +181,9 @@ Use the typed tools instead of guessing generic setting keys:
|
|
|
175
181
|
```text
|
|
176
182
|
creavit_editor_background_set type=solid color=#10131a
|
|
177
183
|
creavit_editor_background_set type=gradient gradient={type, direction, colors}
|
|
184
|
+
creavit_editor_wallpapers categories + sample names
|
|
185
|
+
creavit_editor_wallpapers category=macos that category's full list
|
|
186
|
+
creavit_editor_wallpaper_set name=sonoma-dark ready-made CMS wallpaper
|
|
178
187
|
creavit_editor_camera_set settings={visible,size,radius,shadow,mirror,...}
|
|
179
188
|
creavit_editor_audio action=mute
|
|
180
189
|
creavit_project_save
|
|
@@ -209,9 +218,13 @@ the URL in a frameless site-only capture window (`16:9`, `4:3`, `1:1`, `9:16`,
|
|
|
209
218
|
or another requested ratio) and waits for the DOM, fonts, and images before
|
|
210
219
|
recording. It then executes ordered semantic actions with the real macOS mouse,
|
|
211
220
|
so the normal Creavit custom-cursor track receives authentic move/click events.
|
|
212
|
-
It trims the timeline to `durationMs`,
|
|
213
|
-
|
|
214
|
-
|
|
221
|
+
It trims the timeline to `durationMs`, optionally covers the whole video with a
|
|
222
|
+
perspective preset, mutes it, and saves it.
|
|
223
|
+
|
|
224
|
+
It does **not** add zoom ranges: the app records the real clicks and generates
|
|
225
|
+
its own auto-zoom segments in the editor, which land on the actual click times.
|
|
226
|
+
`autoZoom: true` (plus `replaceZooms: true` to wipe the app's own ones) is
|
|
227
|
+
opt-in, for when the user explicitly wants scripted zooms.
|
|
215
228
|
|
|
216
229
|
When the calling agent has inspected the page, it can pass ordered `steps`
|
|
217
230
|
(`scrollPages`, `dwellMs`, `zoom`, `scale`, `x`, `y`, and optionally
|
|
@@ -232,8 +245,6 @@ Example input:
|
|
|
232
245
|
{ "action": "click", "text": "Get Started", "dwellMs": 3000 }
|
|
233
246
|
],
|
|
234
247
|
"controlSystemMouse": true,
|
|
235
|
-
"autoZoom": true,
|
|
236
|
-
"zoomScale": 1.8,
|
|
237
248
|
"perspective": true,
|
|
238
249
|
"perspectiveTemplate": "minimal-tilt",
|
|
239
250
|
"mute": true
|
package/package.json
CHANGED
package/src/bridgeClient.mjs
CHANGED
|
@@ -12,6 +12,9 @@ import { ensureAppRunning, isAutoLaunchEnabled } from "./appLauncher.mjs";
|
|
|
12
12
|
const DEFAULT_ENDPOINT_DIRS = [
|
|
13
13
|
path.join(os.homedir(), "Library", "Application Support", "creavit-studio"),
|
|
14
14
|
path.join(os.homedir(), "Library", "Application Support", "Creavit Studio"),
|
|
15
|
+
// `npm run electron:dev` paketlenmemiş çalıştığı için userData "Electron"
|
|
16
|
+
// altına düşer. Bu olmadan MCP dev build'i hiç göremez.
|
|
17
|
+
path.join(os.homedir(), "Library", "Application Support", "Electron"),
|
|
15
18
|
];
|
|
16
19
|
|
|
17
20
|
export class BridgeUnavailableError extends Error {
|
package/src/protocol.mjs
CHANGED
|
@@ -6,7 +6,7 @@ export const ENDPOINT_FILENAME = "agent-bridge.json";
|
|
|
6
6
|
|
|
7
7
|
export const MCP_PROTOCOL_VERSION = "2024-11-05";
|
|
8
8
|
export const SERVER_NAME = "creavit-studio";
|
|
9
|
-
export const SERVER_VERSION = "1.
|
|
9
|
+
export const SERVER_VERSION = "1.3.1";
|
|
10
10
|
|
|
11
11
|
export const JSONRPC_ERRORS = {
|
|
12
12
|
PARSE_ERROR: -32700,
|
|
@@ -220,7 +220,7 @@ export function browserTools() {
|
|
|
220
220
|
{
|
|
221
221
|
name: "creavit_record_url_walkthrough",
|
|
222
222
|
description:
|
|
223
|
-
"Records a site in a clean configurable-ratio window after real page readiness. It can execute ordered semantic steps using the real system mouse, trims to an exact duration,
|
|
223
|
+
"Records a site in a clean configurable-ratio window after real page readiness. It can execute ordered semantic steps using the real system mouse, trims to an exact duration, applies optional perspective, and optionally mutes it. Zooms are NOT added: Creavit Studio records the real clicks and generates its own auto-zoom segments in the editor. Only pass autoZoom=true when the user explicitly asks for extra scripted zooms.",
|
|
224
224
|
inputSchema: schema(
|
|
225
225
|
{
|
|
226
226
|
url: S.string("http(s) page to record"),
|
|
@@ -240,8 +240,8 @@ export function browserTools() {
|
|
|
240
240
|
tailMs: S.number("Still time after the last scroll (default 800)"),
|
|
241
241
|
controlSystemMouse: S.bool("Move/click the real macOS mouse so Creavit records native cursor data (default true)"),
|
|
242
242
|
mute: S.bool("Disable recording audio and mute export clips (default true)"),
|
|
243
|
-
autoZoom: S.bool("Add zooms around
|
|
244
|
-
replaceZooms: S.bool("
|
|
243
|
+
autoZoom: S.bool("Add scripted zooms around step destinations (default FALSE — the app already creates zooms from the real clicks; only enable when the user asks for it)"),
|
|
244
|
+
replaceZooms: S.bool("Delete the app's own click-based zooms before adding scripted ones (default false; only meaningful with autoZoom=true)"),
|
|
245
245
|
zoomScale: S.number("Automatic zoom scale (default 1.7)"),
|
|
246
246
|
perspective: S.bool("Apply perspective to the complete result"),
|
|
247
247
|
perspectiveTemplate: S.string("Perspective template id (default minimal-tilt)"),
|
|
@@ -259,8 +259,12 @@ export function browserTools() {
|
|
|
259
259
|
const scrollIntervalMs = Math.max(300, Math.min(15_000, Number(args.scrollIntervalMs) || 1400));
|
|
260
260
|
const tailMs = Math.max(200, Math.min(30_000, Number(args.tailMs) || 800));
|
|
261
261
|
const muted = args.mute !== false;
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
// Zoom'ları KENDİMİZ eklemiyoruz: Creavit Studio gerçek tıklamaları
|
|
263
|
+
// kaydedip editörde otomatik zoom segmentlerini kendi üretiyor. Bizim
|
|
264
|
+
// tahmini zamanlamayla eklediğimiz zoom'lar onların üstüne yanlış oturuyordu.
|
|
265
|
+
// Sadece kullanıcı açıkça isterse (autoZoom=true) devreye girer.
|
|
266
|
+
const autoZoom = args.autoZoom === true;
|
|
267
|
+
const replaceZooms = autoZoom && args.replaceZooms === true;
|
|
264
268
|
const controlSystemMouse = args.controlSystemMouse !== false;
|
|
265
269
|
const zoomScale = Math.max(1, Math.min(5, Number(args.zoomScale) || 1.7));
|
|
266
270
|
const requestedSteps = Array.isArray(args.steps) && args.steps.length ? args.steps : args.sections;
|
|
@@ -385,7 +389,14 @@ export function browserTools() {
|
|
|
385
389
|
recordingStarted = false;
|
|
386
390
|
|
|
387
391
|
const editorState = await waitForEditor(previousEditor?.projectFilePath, 600_000);
|
|
388
|
-
const applied = {
|
|
392
|
+
const applied = {
|
|
393
|
+
muted: false,
|
|
394
|
+
zooms: [],
|
|
395
|
+
zoomSource: autoZoom ? "scripted (autoZoom=true)" : "editor auto-zoom from the recorded clicks",
|
|
396
|
+
perspective: null,
|
|
397
|
+
saved: false,
|
|
398
|
+
trimmedTo: null,
|
|
399
|
+
};
|
|
389
400
|
let finalDuration = Number(editorState.duration);
|
|
390
401
|
if (durationMs) {
|
|
391
402
|
const targetDuration = durationMs / 1000;
|
|
@@ -61,14 +61,15 @@ export function editorTools() {
|
|
|
61
61
|
name: "creavit_editor_background_set",
|
|
62
62
|
command: "editor.setBackground",
|
|
63
63
|
description:
|
|
64
|
-
"Sets the canvas background. For solid use type='solid' and color. For gradient pass at least two stops as {type:'linear'|'radial', direction:'to-right', colors:[{color:'#...',position:0},...]}. Call creavit_project_save afterwards.",
|
|
64
|
+
"Sets the canvas background. For solid use type='solid' and color. For gradient pass at least two stops as {type:'linear'|'radial', direction:'to-right', colors:[{color:'#...',position:0},...]}. For a ready-made wallpaper use type='image' with `wallpaper` (name from creavit_editor_wallpapers) — or use creavit_editor_wallpaper_set directly. Call creavit_project_save afterwards.",
|
|
65
65
|
inputSchema: schema(
|
|
66
66
|
{
|
|
67
67
|
type: S.string("Background type", {
|
|
68
68
|
enum: ["solid", "color", "gradient", "image", "dynamic"],
|
|
69
69
|
}),
|
|
70
70
|
color: S.string("CSS color for a solid background"),
|
|
71
|
-
image: S.string("Image URL or
|
|
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
73
|
blur: S.number("Image blur amount"),
|
|
73
74
|
gradient: S.object(
|
|
74
75
|
"Gradient configuration: {type, direction, colors:[{color,position}]}.",
|
|
@@ -81,6 +82,35 @@ export function editorTools() {
|
|
|
81
82
|
textResult({ ...result, note: "Applied. Call creavit_project_save to persist." }),
|
|
82
83
|
}),
|
|
83
84
|
|
|
85
|
+
bridgeTool({
|
|
86
|
+
name: "creavit_editor_wallpapers",
|
|
87
|
+
command: "editor.listWallpapers",
|
|
88
|
+
description:
|
|
89
|
+
"Lists the ready-made wallpapers (background images from the Creavit CMS) grouped by category. Without arguments it returns the categories with a small sample of names — pass `category` for that category's complete list, or `search` to look a name up. Feed the name to creavit_editor_wallpaper_set.",
|
|
90
|
+
inputSchema: schema({
|
|
91
|
+
category: S.string("Only this category, e.g. 'macos'"),
|
|
92
|
+
search: S.string("Find wallpapers whose name contains this text"),
|
|
93
|
+
limit: S.number("Maximum number of names to return"),
|
|
94
|
+
}),
|
|
95
|
+
}),
|
|
96
|
+
|
|
97
|
+
bridgeTool({
|
|
98
|
+
name: "creavit_editor_wallpaper_set",
|
|
99
|
+
command: "editor.setWallpaper",
|
|
100
|
+
description:
|
|
101
|
+
"Sets the canvas background to a CMS wallpaper — exactly what picking one in the UI does. Select it by `name` (from creavit_editor_wallpapers), by `category` + `index`, or with random=true. Call creavit_project_save afterwards.",
|
|
102
|
+
inputSchema: schema({
|
|
103
|
+
name: S.string("Wallpaper name, e.g. 'sonoma-dark'"),
|
|
104
|
+
category: S.string("Category to pick from, e.g. 'macos'"),
|
|
105
|
+
index: S.number("Zero-based position inside the category"),
|
|
106
|
+
random: S.bool("Pick a random wallpaper"),
|
|
107
|
+
blur: S.number("Background blur amount (optional)"),
|
|
108
|
+
}),
|
|
109
|
+
timeoutMs: 60_000,
|
|
110
|
+
mapResult: (result) =>
|
|
111
|
+
textResult({ ...result, note: "Applied. Call creavit_project_save to persist." }),
|
|
112
|
+
}),
|
|
113
|
+
|
|
84
114
|
bridgeTool({
|
|
85
115
|
name: "creavit_editor_camera_get",
|
|
86
116
|
command: "editor.getCamera",
|
|
@@ -136,7 +166,7 @@ export function editorTools() {
|
|
|
136
166
|
name: "creavit_editor_add_zoom",
|
|
137
167
|
command: "editor.addZoom",
|
|
138
168
|
description:
|
|
139
|
-
"Adds a zoom range. start/end are in seconds and end must be greater than start. scale defaults to 2 (1 means no zoom), x/y default to 0.5 (center). Get the video duration from creavit_editor_state.",
|
|
169
|
+
"Adds a zoom range MANUALLY. Do NOT use this to 'zoom on the clicks' after a recording — Creavit Studio records the real mouse clicks and builds its own auto-zoom segments in the editor, and hand-added ranges land on estimated times instead. Only call it when the user explicitly asks for a zoom at a specific moment. start/end are in seconds and end must be greater than start. scale defaults to 2 (1 means no zoom), x/y default to 0.5 (center). Get the video duration from creavit_editor_state.",
|
|
140
170
|
inputSchema: schema(
|
|
141
171
|
{
|
|
142
172
|
start: S.number("Start time in seconds"),
|
package/src/tools/index.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { editorTools } from "./editorTools.mjs";
|
|
|
5
5
|
import { motionTools } from "./motionTools.mjs";
|
|
6
6
|
import { systemTools } from "./systemTools.mjs";
|
|
7
7
|
import { browserTools } from "./browserTools.mjs";
|
|
8
|
+
import { inputTools } from "./inputTools.mjs";
|
|
8
9
|
import { escapeTools } from "./escapeTools.mjs";
|
|
9
10
|
import { errorResult } from "./defineTool.mjs";
|
|
10
11
|
import { BridgeUnavailableError } from "../bridgeClient.mjs";
|
|
@@ -19,6 +20,7 @@ function buildRegistry() {
|
|
|
19
20
|
...editorTools(),
|
|
20
21
|
...motionTools(),
|
|
21
22
|
...browserTools(),
|
|
23
|
+
...inputTools(),
|
|
22
24
|
...escapeTools(),
|
|
23
25
|
];
|
|
24
26
|
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// MCP araçları — sistem faresi ve klavyesi.
|
|
2
|
+
// browser_* araçlarından farkı: izole capture penceresine bağlı değiller,
|
|
3
|
+
// ekrandaki herhangi bir uygulamayı sürerler.
|
|
4
|
+
|
|
5
|
+
import { bridgeTool, schema, S } from "./defineTool.mjs";
|
|
6
|
+
|
|
7
|
+
const STEP_SCHEMA = S.object(
|
|
8
|
+
"One step: {action:'move',x,y,durationMs} | {action:'click',clickCount} | {action:'down'|'up'} | {action:'type',text,perCharMs} | {action:'key',key,modifiers} | {action:'wait',ms}",
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
export function inputTools() {
|
|
12
|
+
return [
|
|
13
|
+
bridgeTool({
|
|
14
|
+
name: "creavit_input_click",
|
|
15
|
+
command: "input.click",
|
|
16
|
+
description:
|
|
17
|
+
"Moves the real system mouse to a screen coordinate and clicks. For a point inside a window use creavit_input_window_click instead — it does the coordinate math for you.",
|
|
18
|
+
inputSchema: schema(
|
|
19
|
+
{
|
|
20
|
+
x: S.number("Screen X"),
|
|
21
|
+
y: S.number("Screen Y"),
|
|
22
|
+
durationMs: S.number("Travel time for the move (default 450)"),
|
|
23
|
+
clickCount: S.number("1 = click, 2 = double-click"),
|
|
24
|
+
},
|
|
25
|
+
["x", "y"],
|
|
26
|
+
),
|
|
27
|
+
timeoutMs: 30_000,
|
|
28
|
+
}),
|
|
29
|
+
|
|
30
|
+
bridgeTool({
|
|
31
|
+
name: "creavit_input_move",
|
|
32
|
+
command: "input.moveMouse",
|
|
33
|
+
description: "Moves the real system mouse to a screen coordinate, without clicking.",
|
|
34
|
+
inputSchema: schema(
|
|
35
|
+
{
|
|
36
|
+
x: S.number("Screen X"),
|
|
37
|
+
y: S.number("Screen Y"),
|
|
38
|
+
durationMs: S.number("Travel time (default 450)"),
|
|
39
|
+
},
|
|
40
|
+
["x", "y"],
|
|
41
|
+
),
|
|
42
|
+
timeoutMs: 30_000,
|
|
43
|
+
}),
|
|
44
|
+
|
|
45
|
+
bridgeTool({
|
|
46
|
+
name: "creavit_input_window_click",
|
|
47
|
+
command: "input.windowClick",
|
|
48
|
+
description:
|
|
49
|
+
"Clicks inside a window from creavit_devices_list, using window-relative coordinates (or 0-1 with normalized:true). Brings the window's owner app to the front first — this is the click to use while recording a window.",
|
|
50
|
+
inputSchema: schema(
|
|
51
|
+
{
|
|
52
|
+
windowId: S.number("Window id from creavit_devices_list"),
|
|
53
|
+
x: S.number("Window-relative X (px, or 0-1 when normalized)"),
|
|
54
|
+
y: S.number("Window-relative Y"),
|
|
55
|
+
normalized: S.bool("Treat x/y as 0-1 fractions of the window (default false)"),
|
|
56
|
+
durationMs: S.number("Travel time (default 450)"),
|
|
57
|
+
clickCount: S.number("1 = click, 2 = double-click"),
|
|
58
|
+
activate: S.bool("Bring the owner app to the front first (default true)"),
|
|
59
|
+
},
|
|
60
|
+
["windowId", "x", "y"],
|
|
61
|
+
),
|
|
62
|
+
timeoutMs: 60_000,
|
|
63
|
+
}),
|
|
64
|
+
|
|
65
|
+
bridgeTool({
|
|
66
|
+
name: "creavit_input_type",
|
|
67
|
+
command: "input.type",
|
|
68
|
+
description:
|
|
69
|
+
"Types text into whatever is focused. Click the field first. perCharMs types character by character, which looks natural in a recording.",
|
|
70
|
+
inputSchema: schema(
|
|
71
|
+
{
|
|
72
|
+
text: S.string("Text to type (UTF-8; Turkish characters are fine)"),
|
|
73
|
+
perCharMs: S.number("Delay per character, 0 = all at once (default 0)"),
|
|
74
|
+
pressEnter: S.bool("Press Return afterwards (default false)"),
|
|
75
|
+
},
|
|
76
|
+
["text"],
|
|
77
|
+
),
|
|
78
|
+
timeoutMs: 120_000,
|
|
79
|
+
}),
|
|
80
|
+
|
|
81
|
+
bridgeTool({
|
|
82
|
+
name: "creavit_input_key",
|
|
83
|
+
command: "input.key",
|
|
84
|
+
description:
|
|
85
|
+
"Presses a single key with optional modifiers. Keys: return, tab, space, delete, escape, left/right/up/down, home, end, pageup, pagedown. Modifiers: cmd, shift, alt, ctrl.",
|
|
86
|
+
inputSchema: schema(
|
|
87
|
+
{
|
|
88
|
+
key: S.string("Key name"),
|
|
89
|
+
modifiers: S.array("Modifiers held down", S.string("cmd|shift|alt|ctrl")),
|
|
90
|
+
},
|
|
91
|
+
["key"],
|
|
92
|
+
),
|
|
93
|
+
timeoutMs: 30_000,
|
|
94
|
+
}),
|
|
95
|
+
|
|
96
|
+
bridgeTool({
|
|
97
|
+
name: "creavit_record_walkthrough",
|
|
98
|
+
command: "recording.walkthrough",
|
|
99
|
+
description:
|
|
100
|
+
"Records a walkthrough in ONE call: starts recording, runs the input steps, stops. USE THIS to record an interaction — the recorded length is leadMs + steps + tailMs and nothing else. Driving it by hand (start, then sequence, then stop) adds your own round-trip time to the video; measured, an 8.7s scenario became a 22.5s recording. With sourceType 'window' the step coordinates are window-relative by default.",
|
|
101
|
+
inputSchema: schema(
|
|
102
|
+
{
|
|
103
|
+
options: S.object(
|
|
104
|
+
"Recording options, same as creavit_recording_start: {sourceType:'display'|'window'|'area', sourceId, cameraEnabled, micEnabled, systemAudioEnabled, area}",
|
|
105
|
+
),
|
|
106
|
+
steps: S.array("Input steps, executed in order", STEP_SCHEMA),
|
|
107
|
+
leadMs: S.number("Idle time before the first step (default 800)"),
|
|
108
|
+
tailMs: S.number("Idle time after the last step (default 1200)"),
|
|
109
|
+
normalized: S.bool("Treat move x/y as 0-1 fractions of the window (default false)"),
|
|
110
|
+
windowRelative: S.bool("Step coordinates are window-relative (default true for window recordings)"),
|
|
111
|
+
},
|
|
112
|
+
["options", "steps"],
|
|
113
|
+
),
|
|
114
|
+
timeoutMs: 900_000,
|
|
115
|
+
}),
|
|
116
|
+
|
|
117
|
+
bridgeTool({
|
|
118
|
+
name: "creavit_input_sequence",
|
|
119
|
+
command: "input.sequence",
|
|
120
|
+
description:
|
|
121
|
+
"Runs a whole input scenario inside the app in ONE native process, so its wall-clock duration is exactly what you asked for. USE THIS WHILE RECORDING — driving a recording with separate click/type calls adds each round-trip to the recorded video. Pass windowId to write move steps in window-relative coordinates.",
|
|
122
|
+
inputSchema: schema(
|
|
123
|
+
{
|
|
124
|
+
steps: S.array("Steps, executed in order", STEP_SCHEMA),
|
|
125
|
+
windowId: S.number("Window id — makes move steps window-relative"),
|
|
126
|
+
normalized: S.bool("Treat move x/y as 0-1 fractions of the window (default false)"),
|
|
127
|
+
activate: S.bool("Bring the owner app to the front first (default true)"),
|
|
128
|
+
},
|
|
129
|
+
["steps"],
|
|
130
|
+
),
|
|
131
|
+
timeoutMs: 600_000,
|
|
132
|
+
}),
|
|
133
|
+
];
|
|
134
|
+
}
|