creavit-studio-mcp 1.3.4 → 1.3.6

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
@@ -120,6 +120,20 @@ files directly and work with the app closed.
120
120
  > `creavit_editor_add_zoom` only when the user asks for a zoom at a specific
121
121
  > moment.
122
122
 
123
+ **Sensitive content** — `creavit_editor_video_frame`,
124
+ `creavit_editor_sensitive_areas`, `creavit_editor_add_sensitive`,
125
+ `creavit_editor_update_sensitive`, `creavit_editor_remove_sensitive`,
126
+ `creavit_editor_sensitive_visibility`
127
+
128
+ > To cover a password field, an email or an API key: scan the recording with
129
+ > `creavit_editor_video_frame` (pass several `times` in one call) until you see
130
+ > it, read its pixel box off that frame, then pass the box as `rectPx` together
131
+ > with the frame's `frameWidth`/`frameHeight` as `refWidth`/`refHeight`. The
132
+ > region is anchored to the video content, so it follows zoom, perspective and
133
+ > crop. Use `creavit_editor_video_frame` — **not** `creavit_editor_screenshot` —
134
+ > for measuring: the screenshot is the composed canvas and its pixels do not map
135
+ > onto the mask.
136
+
123
137
  **Perspective** — `creavit_editor_perspectives`,
124
138
  `creavit_editor_add_perspective`, `creavit_editor_update_perspective`,
125
139
  `creavit_editor_remove_perspective`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "creavit-studio-mcp",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
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",
package/src/protocol.mjs CHANGED
@@ -1,12 +1,20 @@
1
1
  // MCP sunucusu — köprü protokolü sabitleri.
2
2
  // electron/agentBridge/protocol.cjs ile eşleşmeli.
3
3
 
4
+ import { createRequire } from "node:module";
5
+
6
+ const require = createRequire(import.meta.url);
7
+ const packageMetadata = require("../package.json");
8
+
4
9
  export const BRIDGE_PROTOCOL_VERSION = 1;
5
10
  export const ENDPOINT_FILENAME = "agent-bridge.json";
6
11
 
7
12
  export const MCP_PROTOCOL_VERSION = "2024-11-05";
8
13
  export const SERVER_NAME = "creavit-studio";
9
- export const SERVER_VERSION = "1.3.2";
14
+ // package.json is the single version source used by npm, the CLI and the MCP
15
+ // initialize response. Keeping a second literal here made 1.3.4 report itself
16
+ // as 1.3.2 even though npx had installed the correct package.
17
+ export const SERVER_VERSION = packageMetadata.version;
10
18
 
11
19
  export const JSONRPC_ERRORS = {
12
20
  PARSE_ERROR: -32700,
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { projectTools } from "./projectTools.mjs";
4
4
  import { editorTools } from "./editorTools.mjs";
5
+ import { sensitiveTools } from "./sensitiveTools.mjs";
5
6
  import { motionTools } from "./motionTools.mjs";
6
7
  import { systemTools } from "./systemTools.mjs";
7
8
  import { browserTools } from "./browserTools.mjs";
@@ -18,6 +19,7 @@ function buildRegistry() {
18
19
  ...systemTools(),
19
20
  ...projectTools(),
20
21
  ...editorTools(),
22
+ ...sensitiveTools(),
21
23
  ...motionTools(),
22
24
  ...browserTools(),
23
25
  ...inputTools(),
@@ -0,0 +1,135 @@
1
+ // MCP araçları — hassas içerik maskeleri (blur / pixelate / solid).
2
+ // Editör penceresinin açık olmasını gerektirir (creavit_project_open).
3
+
4
+ import { bridgeTool, schema, S, textResult } from "./defineTool.mjs";
5
+
6
+ const RECT_PROPS = {
7
+ rectPx: S.object(
8
+ "Region measured in PIXELS on a creavit_editor_video_frame image: {x, y, width, height}. This is the easy way — look at the frame, read the box off it.",
9
+ ),
10
+ refWidth: S.number(
11
+ "Width of the image the rectPx was measured on (the `frameWidth` reported by creavit_editor_video_frame). Required whenever that frame was downscaled.",
12
+ ),
13
+ refHeight: S.number(
14
+ "Height of the image the rectPx was measured on (the `frameHeight` reported by creavit_editor_video_frame).",
15
+ ),
16
+ x: S.number("Left edge, normalized 0-1 (alternative to rectPx)"),
17
+ y: S.number("Top edge, normalized 0-1"),
18
+ width: S.number("Width, normalized 0-1"),
19
+ height: S.number("Height, normalized 0-1"),
20
+ effect: S.string("blur (default), pixelate, or solid", {
21
+ enum: ["blur", "pixelate", "solid"],
22
+ }),
23
+ intensity: S.number("How strongly the region is obscured, 0-100 (default 55)"),
24
+ radius: S.number("Corner rounding percentage, 0-50 (default 12)"),
25
+ solidColor: S.string("Fill color when effect is 'solid', e.g. '#111114'"),
26
+ };
27
+
28
+ export function sensitiveTools() {
29
+ return [
30
+ bridgeTool({
31
+ name: "creavit_editor_video_frame",
32
+ command: "editor.videoFrame",
33
+ description:
34
+ "Returns the RAW source video frame — no background, padding, zoom or perspective, just what was recorded. This is the coordinate reference for sensitive-content masks: a pixel you see here maps directly onto the mask region. Use it to FIND something in the recording (a password field, an email, an API key) and to work out WHEN it is on screen: pass `times` with up to 8 timestamps to scan the video in one call, then narrow down. Do not use creavit_editor_screenshot for this — that one is the composed canvas and its pixels do not map onto the mask.",
35
+ inputSchema: schema({
36
+ time: S.number("Single timestamp in seconds"),
37
+ times: S.array("Up to 8 timestamps in seconds, scanned in one call", {
38
+ type: "number",
39
+ }),
40
+ maxWidth: S.number(
41
+ "Downscale the returned image to this width (default: full source width). Whatever comes back, pass its frameWidth/frameHeight as refWidth/refHeight when you measure on it.",
42
+ ),
43
+ }),
44
+ timeoutMs: 120_000,
45
+ mapResult: (result) => {
46
+ const frames = Array.isArray(result?.frames) ? result.frames : [];
47
+ const content = [];
48
+ for (const frame of frames) {
49
+ content.push({
50
+ type: "image",
51
+ data: frame.base64,
52
+ mimeType: frame.mimeType || "image/png",
53
+ });
54
+ const at =
55
+ frame.atTime === null || frame.atTime === undefined
56
+ ? "current playhead"
57
+ : `${Number(frame.atTime).toFixed(2)}s`;
58
+ content.push({
59
+ type: "text",
60
+ text: `Source frame @ ${at} — image is ${frame.frameWidth}x${frame.frameHeight}, video content is ${frame.contentWidth}x${frame.contentHeight}. Measuring a region on this image? pass refWidth=${frame.frameWidth} refHeight=${frame.frameHeight} together with rectPx.`,
61
+ });
62
+ }
63
+ if (content.length === 0) {
64
+ return textResult({ ...result, note: "No frame could be captured." });
65
+ }
66
+ return { content };
67
+ },
68
+ }),
69
+
70
+ bridgeTool({
71
+ name: "creavit_editor_sensitive_areas",
72
+ command: "editor.listSensitiveAreas",
73
+ description:
74
+ "Lists the sensitive-content masks on the timeline: id, start/end in seconds, the region both normalized (0-1) and in video pixels, effect, intensity and corner radius. Also reports the video content size and whether masks are currently hidden.",
75
+ inputSchema: schema(),
76
+ }),
77
+
78
+ bridgeTool({
79
+ name: "creavit_editor_add_sensitive",
80
+ command: "editor.addSensitiveArea",
81
+ description:
82
+ "Covers a region of the screen with a blur / pixelate / solid mask for a time range — for passwords, emails, API keys, names and the like. The region is anchored to the VIDEO CONTENT, so it follows zoom, perspective and crop and never uncovers what is underneath. Workflow: call creavit_editor_video_frame (with several `times`) to find the moment the thing is visible and read its pixel box off the frame, then call this with `rectPx` plus the frame's refWidth/refHeight and the start/end of the interval it is on screen. Pad the box a few pixels beyond the element. Verify afterwards with creavit_editor_screenshot, and call creavit_project_save to persist.",
83
+ inputSchema: schema(
84
+ {
85
+ start: S.number("Start time in seconds"),
86
+ end: S.number("End time in seconds, greater than start"),
87
+ ...RECT_PROPS,
88
+ },
89
+ ["start", "end"],
90
+ ),
91
+ mapResult: (result) =>
92
+ textResult({
93
+ ...result,
94
+ note: "Added. Check it with creavit_editor_screenshot, then creavit_project_save to persist.",
95
+ }),
96
+ }),
97
+
98
+ bridgeTool({
99
+ name: "creavit_editor_update_sensitive",
100
+ command: "editor.updateSensitiveArea",
101
+ description:
102
+ "Updates an existing sensitive-content mask — move or resize the region, change the time range, the effect or its intensity. Target it by id (from creavit_editor_sensitive_areas) or by zero-based index. Put the changed fields in `patch`; the same rectPx/refWidth/refHeight or normalized x/y/width/height forms are accepted there.",
103
+ inputSchema: schema(
104
+ {
105
+ id: S.string("ID of the mask"),
106
+ index: S.number("Or its position in the list (0-based)"),
107
+ patch: S.object(
108
+ "Fields to change: start, end, rectPx (+refWidth/refHeight), x, y, width, height, effect, intensity, radius, solidColor",
109
+ ),
110
+ },
111
+ ["patch"],
112
+ ),
113
+ }),
114
+
115
+ bridgeTool({
116
+ name: "creavit_editor_remove_sensitive",
117
+ command: "editor.removeSensitiveArea",
118
+ description:
119
+ "Deletes a sensitive-content mask by id or zero-based index, or every mask with all=true.",
120
+ inputSchema: schema({
121
+ id: S.string("ID of the mask"),
122
+ index: S.number("Or its position in the list (0-based)"),
123
+ all: S.bool("Delete every mask"),
124
+ }),
125
+ }),
126
+
127
+ bridgeTool({
128
+ name: "creavit_editor_sensitive_visibility",
129
+ command: "editor.setSensitiveHidden",
130
+ description:
131
+ "Shows or hides every sensitive-content mask at once — the same switch as 'Hide masks' in the settings panel. Hiding does not delete anything; use it only to peek at what is underneath.",
132
+ inputSchema: schema({ hidden: S.bool("true hides all masks") }, ["hidden"]),
133
+ }),
134
+ ];
135
+ }