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 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`, `creavit_editor_camera_get`,
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`, adds
213
- scroll-highlight zooms, optionally covers the whole video with a perspective
214
- preset, mutes it, and saves it.
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "creavit-studio-mcp",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
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",
@@ -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.2.0";
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, adds zooms, optional perspective, and optionally mutes it.",
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 section destinations (default true)"),
244
- replaceZooms: S.bool("Remove recorder-created zooms first (default true)"),
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
- const autoZoom = args.autoZoom !== false;
263
- const replaceZooms = args.replaceZooms !== false;
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 = { muted: false, zooms: [], perspective: null, saved: false, trimmedTo: null };
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 local path"),
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"),
@@ -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
+ }