screenslick-mcp 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vlad
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # ScreenSlick MCP Server
2
+
3
+ Local MCP server for controlling the ScreenSlick browser editor from Codex,
4
+ Claude Code, Claude Desktop, Cursor, and other MCP clients.
5
+
6
+ The server runs locally over stdio and opens a localhost bridge at:
7
+
8
+ ```text
9
+ ws://127.0.0.1:32117/screenslick-agent
10
+ ```
11
+
12
+ Open ScreenSlick, enter the editor, click **Agent**, then ask your MCP client to
13
+ call `screenslick_bridge_status`.
14
+
15
+ ## Install
16
+
17
+ No ScreenSlick source checkout is required. Use the npm package from your MCP
18
+ client:
19
+
20
+ ```json
21
+ {
22
+ "mcpServers": {
23
+ "screenslick": {
24
+ "type": "stdio",
25
+ "command": "npx",
26
+ "args": ["-y", "screenslick-mcp"]
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ If your client uses form fields:
33
+
34
+ | Field | Value |
35
+ | --- | --- |
36
+ | Name | `screenslick` |
37
+ | Transport | `stdio` |
38
+ | Command | `npx` |
39
+ | Arguments | `-y`, `screenslick-mcp` |
40
+
41
+ ## Claude Code
42
+
43
+ Project-scoped `.mcp.json`:
44
+
45
+ ```json
46
+ {
47
+ "mcpServers": {
48
+ "screenslick": {
49
+ "type": "stdio",
50
+ "command": "npx",
51
+ "args": ["-y", "screenslick-mcp"]
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ Restart Claude Code, approve the MCP server, then run `/mcp` to confirm the
58
+ `screenslick` server is connected.
59
+
60
+ ## Codex CLI
61
+
62
+ Add a stdio server entry to your Codex config:
63
+
64
+ ```toml
65
+ [mcp_servers.screenslick]
66
+ command = "npx"
67
+ args = ["-y", "screenslick-mcp"]
68
+ startup_timeout_sec = 10
69
+ tool_timeout_sec = 120
70
+ ```
71
+
72
+ ## Cursor
73
+
74
+ Create `.cursor/mcp.json` in a project, or `~/.cursor/mcp.json` globally:
75
+
76
+ ```json
77
+ {
78
+ "mcpServers": {
79
+ "screenslick": {
80
+ "command": "npx",
81
+ "args": ["-y", "screenslick-mcp"]
82
+ }
83
+ }
84
+ }
85
+ ```
86
+
87
+ ## Available tools
88
+
89
+ - `screenslick_bridge_status`
90
+ - `screenslick_get_project`
91
+ - `screenslick_get_capabilities`
92
+ - `screenslick_list_voices`
93
+ - `screenslick_list_music`
94
+ - `screenslick_list_sound_effects`
95
+ - `screenslick_list_effects`
96
+ - `screenslick_remove_silences`
97
+ - `screenslick_generate_transcript`
98
+ - `screenslick_generate_script`
99
+ - `screenslick_generate_voiceover`
100
+ - `screenslick_add_transcript_voiceover_to_timeline`
101
+ - `screenslick_preview_voiceover`
102
+ - `screenslick_toggle_voiceover`
103
+ - `screenslick_apply_commands`
104
+ - `screenslick_capture_frame`
105
+ - `screenslick_export_video`
106
+
107
+ ## Environment variables
108
+
109
+ | Variable | Default | Purpose |
110
+ | --- | --- | --- |
111
+ | `SCREEN_SLICK_AGENT_PORT` | `32117` | Local bridge port |
112
+ | `SCREEN_SLICK_AGENT_HOST` | `127.0.0.1` | Must remain localhost |
113
+ | `SCREEN_SLICK_AGENT_LOG` | package `.tmp/screenslick-agent-mcp.log` | Debug log path |
114
+
115
+ The bridge is intentionally localhost-only. Remote hosts are rejected.
116
+
117
+ ## Verify
118
+
119
+ 1. Start ScreenSlick and open the editor.
120
+ 2. Click **Agent** in the editor.
121
+ 3. Ask the MCP client to call:
122
+
123
+ ```text
124
+ screenslick_bridge_status
125
+ ```
126
+
127
+ Healthy response:
128
+
129
+ ```json
130
+ {
131
+ "ok": true,
132
+ "connected": true,
133
+ "port": 32117,
134
+ "path": "/screenslick-agent",
135
+ "session": {
136
+ "hasVideo": true,
137
+ "timelineDuration": 62.63
138
+ }
139
+ }
140
+ ```
141
+
142
+ ## Development
143
+
144
+ ```bash
145
+ npm install
146
+ npm run build
147
+ npm run dev
148
+ ```
149
+
150
+ Use development mode from this repo:
151
+
152
+ For live source changes:
153
+
154
+ ```json
155
+ {
156
+ "mcpServers": {
157
+ "screenslick": {
158
+ "type": "stdio",
159
+ "command": "npx",
160
+ "args": ["tsx", "src/index.ts"],
161
+ "cwd": "/path/to/screenslick-mcp"
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ For testing the built package:
168
+
169
+ ```json
170
+ {
171
+ "mcpServers": {
172
+ "screenslick": {
173
+ "type": "stdio",
174
+ "command": "node",
175
+ "args": ["dist/index.js"],
176
+ "cwd": "/path/to/screenslick-mcp"
177
+ }
178
+ }
179
+ }
180
+ ```
181
+
182
+ ## Best-practice notes
183
+
184
+ - Uses the official MCP TypeScript SDK over stdio.
185
+ - Keeps editor bridge traffic on `127.0.0.1`.
186
+ - Does not require the ScreenSlick source repo on the user's machine.
187
+ - Uses structured input schemas for every tool.
188
+ - Routes editor actions through ScreenSlick's native editor APIs instead of
189
+ processing video files directly.
190
+ - Treats premium voice generation as a consent boundary: agents should ask
191
+ before using premium/Gemini voices because they can consume credits.
package/SECURITY.md ADDED
@@ -0,0 +1,31 @@
1
+ # Security
2
+
3
+ ScreenSlick MCP is a local stdio MCP server. It starts a localhost-only bridge so
4
+ the ScreenSlick browser editor can connect to the MCP process.
5
+
6
+ ## Trust boundary
7
+
8
+ - The bridge binds to `127.0.0.1`.
9
+ - Non-local HTTP and WebSocket requests are rejected.
10
+ - `SCREEN_SLICK_AGENT_HOST` must remain `127.0.0.1`.
11
+ - The server does not process media files directly.
12
+ - Editor mutations go through ScreenSlick's existing editor command layer.
13
+
14
+ ## User consent
15
+
16
+ Agents should ask before using premium/Gemini voice generation because it can
17
+ consume ScreenSlick credits.
18
+
19
+ Agents should also ask before destructive broad edits, such as deleting many
20
+ clips or removing large timeline ranges, unless the user explicitly requested
21
+ that action.
22
+
23
+ ## Reporting issues
24
+
25
+ Open a GitHub issue with:
26
+
27
+ - MCP client name and version
28
+ - Operating system
29
+ - Node.js version
30
+ - ScreenSlick URL/build
31
+ - Relevant `.tmp/screenslick-agent-mcp.log` lines, with private data removed
@@ -0,0 +1,9 @@
1
+ export declare function getBridgeStatus(): {
2
+ ok: boolean;
3
+ connected: boolean;
4
+ port: number;
5
+ path: string;
6
+ session: unknown;
7
+ };
8
+ export declare function callEditor(method: string, params: unknown): Promise<unknown>;
9
+ export declare function ensureBridge(): Promise<unknown>;
package/dist/bridge.js ADDED
@@ -0,0 +1,356 @@
1
+ import { createHash } from "node:crypto";
2
+ import { createServer } from "node:http";
3
+ import { getConfig, WS_PATH } from "./config.js";
4
+ import { debugLog } from "./log.js";
5
+ // Editor calls (export, capture, generation) can run long; keep the WS and HTTP
6
+ // fallback paths on the same ceiling. The status probe is a quick liveness check.
7
+ const EDITOR_CALL_TIMEOUT_MS = 120_000;
8
+ const BRIDGE_PROBE_TIMEOUT_MS = 5_000;
9
+ let serverPromise = null;
10
+ let activeEditor = null;
11
+ let editorSession = null;
12
+ let editorRequestCounter = 0;
13
+ const pendingEditorRequests = new Map();
14
+ function isLocalRequest(request) {
15
+ const address = request.socket.remoteAddress;
16
+ return (address === "127.0.0.1" ||
17
+ address === "::1" ||
18
+ address === "::ffff:127.0.0.1");
19
+ }
20
+ function createAcceptKey(key) {
21
+ return createHash("sha1")
22
+ .update(`${key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`)
23
+ .digest("base64");
24
+ }
25
+ function sendJsonResponse(response, status, body) {
26
+ const payload = JSON.stringify(body);
27
+ response.writeHead(status, {
28
+ "content-type": "application/json",
29
+ "content-length": Buffer.byteLength(payload),
30
+ });
31
+ response.end(payload);
32
+ }
33
+ async function readJsonBody(request) {
34
+ const chunks = [];
35
+ for await (const chunk of request) {
36
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
37
+ }
38
+ if (chunks.length === 0)
39
+ return {};
40
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
41
+ }
42
+ class WebSocketConnection {
43
+ socket;
44
+ buffer = Buffer.alloc(0);
45
+ fragments = [];
46
+ fragmentOpcode = 0;
47
+ closed = false;
48
+ constructor(socket) {
49
+ this.socket = socket;
50
+ socket.on("data", (chunk) => this.read(chunk));
51
+ socket.on("close", () => this.close());
52
+ socket.on("error", (error) => {
53
+ debugLog(`editor socket error ${error.message}`);
54
+ this.close();
55
+ });
56
+ }
57
+ sendJson(value) {
58
+ this.sendText(JSON.stringify(value));
59
+ }
60
+ close() {
61
+ if (this.closed)
62
+ return;
63
+ this.closed = true;
64
+ debugLog("editor disconnected");
65
+ if (activeEditor === this) {
66
+ activeEditor = null;
67
+ editorSession = null;
68
+ for (const [id, pending] of pendingEditorRequests) {
69
+ clearTimeout(pending.timer);
70
+ pending.reject(new Error("ScreenSlick editor disconnected."));
71
+ pendingEditorRequests.delete(id);
72
+ }
73
+ }
74
+ this.socket.destroy();
75
+ }
76
+ sendText(text) {
77
+ if (this.closed)
78
+ return;
79
+ const payload = Buffer.from(text);
80
+ let header;
81
+ if (payload.length < 126) {
82
+ header = Buffer.from([0x81, payload.length]);
83
+ }
84
+ else if (payload.length <= 0xffff) {
85
+ header = Buffer.alloc(4);
86
+ header[0] = 0x81;
87
+ header[1] = 126;
88
+ header.writeUInt16BE(payload.length, 2);
89
+ }
90
+ else {
91
+ header = Buffer.alloc(10);
92
+ header[0] = 0x81;
93
+ header[1] = 127;
94
+ header.writeBigUInt64BE(BigInt(payload.length), 2);
95
+ }
96
+ this.socket.write(Buffer.concat([header, payload]));
97
+ }
98
+ read(chunk) {
99
+ this.buffer = Buffer.concat([this.buffer, chunk]);
100
+ while (this.buffer.length >= 2) {
101
+ const first = this.buffer[0];
102
+ const second = this.buffer[1];
103
+ const fin = (first & 0x80) !== 0;
104
+ const opcode = first & 0x0f;
105
+ const masked = (second & 0x80) !== 0;
106
+ let length = second & 0x7f;
107
+ let offset = 2;
108
+ if (length === 126) {
109
+ if (this.buffer.length < offset + 2)
110
+ return;
111
+ length = this.buffer.readUInt16BE(offset);
112
+ offset += 2;
113
+ }
114
+ else if (length === 127) {
115
+ if (this.buffer.length < offset + 8)
116
+ return;
117
+ length = Number(this.buffer.readBigUInt64BE(offset));
118
+ offset += 8;
119
+ }
120
+ const maskLength = masked ? 4 : 0;
121
+ const frameEnd = offset + maskLength + length;
122
+ if (this.buffer.length < frameEnd)
123
+ return;
124
+ const mask = masked ? this.buffer.subarray(offset, offset + 4) : null;
125
+ offset += maskLength;
126
+ const payload = Buffer.from(this.buffer.subarray(offset, offset + length));
127
+ this.buffer = this.buffer.subarray(frameEnd);
128
+ if (mask) {
129
+ for (let index = 0; index < payload.length; index += 1) {
130
+ payload[index] ^= mask[index % 4];
131
+ }
132
+ }
133
+ // Control frames (0x8-0xF) are never fragmented and may be interleaved
134
+ // between data fragments.
135
+ if (opcode === 0x8) {
136
+ this.close();
137
+ return;
138
+ }
139
+ if (opcode === 0x9) {
140
+ this.sendPong(payload);
141
+ continue;
142
+ }
143
+ if (opcode === 0xa) {
144
+ continue; // pong; nothing to do
145
+ }
146
+ // Data frames: 0x1 text, 0x2 binary, 0x0 continuation. Reassemble across
147
+ // fragments so large editor responses (export MP4, captured PNG) survive a
148
+ // multi-frame send.
149
+ if (opcode === 0x1 || opcode === 0x2) {
150
+ this.fragments = [payload];
151
+ this.fragmentOpcode = opcode;
152
+ }
153
+ else if (opcode === 0x0) {
154
+ if (this.fragments.length === 0) {
155
+ debugLog("unexpected continuation frame with no message in progress");
156
+ this.close();
157
+ return;
158
+ }
159
+ this.fragments.push(payload);
160
+ }
161
+ else {
162
+ debugLog(`ignoring unsupported ws opcode 0x${opcode.toString(16)}`);
163
+ continue;
164
+ }
165
+ if (!fin)
166
+ continue; // more fragments to come
167
+ const message = Buffer.concat(this.fragments);
168
+ const completedOpcode = this.fragmentOpcode;
169
+ this.fragments = [];
170
+ this.fragmentOpcode = 0;
171
+ if (completedOpcode === 0x1)
172
+ this.handleText(message.toString("utf8"));
173
+ }
174
+ }
175
+ sendPong(payload) {
176
+ if (this.closed)
177
+ return;
178
+ // Control frame payloads are capped at 125 bytes; echo what fits.
179
+ const length = Math.min(payload.length, 125);
180
+ const header = Buffer.from([0x8a, length]);
181
+ this.socket.write(Buffer.concat([header, payload.subarray(0, length)]));
182
+ }
183
+ handleText(text) {
184
+ let message;
185
+ try {
186
+ message = JSON.parse(text);
187
+ }
188
+ catch {
189
+ return;
190
+ }
191
+ if (message &&
192
+ typeof message === "object" &&
193
+ message.type === "hello") {
194
+ editorSession = message.session;
195
+ debugLog(`editor hello ${JSON.stringify(editorSession)}`);
196
+ return;
197
+ }
198
+ const response = message;
199
+ if (typeof response.id !== "string")
200
+ return;
201
+ const pending = pendingEditorRequests.get(response.id);
202
+ if (!pending)
203
+ return;
204
+ clearTimeout(pending.timer);
205
+ pendingEditorRequests.delete(response.id);
206
+ if (response.error) {
207
+ pending.reject(new Error(String(response.error.message ?? "Editor error.")));
208
+ }
209
+ else {
210
+ pending.resolve(response.result);
211
+ }
212
+ }
213
+ }
214
+ export function getBridgeStatus() {
215
+ const { port } = getConfig();
216
+ return {
217
+ ok: true,
218
+ connected: Boolean(activeEditor && !activeEditor.closed),
219
+ port,
220
+ path: WS_PATH,
221
+ session: editorSession,
222
+ };
223
+ }
224
+ async function fetchBridgeStatus() {
225
+ const { bridgeBaseUrl } = getConfig();
226
+ const response = await fetch(`${bridgeBaseUrl}/status`, {
227
+ signal: AbortSignal.timeout(BRIDGE_PROBE_TIMEOUT_MS),
228
+ });
229
+ if (!response.ok)
230
+ throw new Error(`Bridge status failed: ${response.status}`);
231
+ return response.json();
232
+ }
233
+ async function callExternalBridge(method, params) {
234
+ const { bridgeBaseUrl } = getConfig();
235
+ const response = await fetch(`${bridgeBaseUrl}/call`, {
236
+ method: "POST",
237
+ headers: { "content-type": "application/json" },
238
+ body: JSON.stringify({ method, params }),
239
+ signal: AbortSignal.timeout(EDITOR_CALL_TIMEOUT_MS),
240
+ });
241
+ const payload = (await response.json());
242
+ if (!response.ok || payload.error) {
243
+ throw new Error(payload.error ?? `Bridge call failed: ${response.status}`);
244
+ }
245
+ return payload.result;
246
+ }
247
+ export async function callEditor(method, params) {
248
+ await ensureBridge();
249
+ if (!activeEditor || activeEditor.closed) {
250
+ if (!serverPromise) {
251
+ return callExternalBridge(method, params);
252
+ }
253
+ throw new Error("No active ScreenSlick editor session. Open the editor and enable Agent.");
254
+ }
255
+ const id = `agent_${++editorRequestCounter}`;
256
+ activeEditor.sendJson({ id, method, params });
257
+ return new Promise((resolve, reject) => {
258
+ const timer = setTimeout(() => {
259
+ pendingEditorRequests.delete(id);
260
+ reject(new Error(`ScreenSlick editor did not answer "${method}" in time.`));
261
+ }, EDITOR_CALL_TIMEOUT_MS);
262
+ pendingEditorRequests.set(id, { resolve, reject, timer });
263
+ });
264
+ }
265
+ export async function ensureBridge() {
266
+ if (!serverPromise) {
267
+ try {
268
+ return await fetchBridgeStatus();
269
+ }
270
+ catch { }
271
+ }
272
+ if (serverPromise) {
273
+ await serverPromise;
274
+ return getBridgeStatus();
275
+ }
276
+ serverPromise = startBridgeServer();
277
+ try {
278
+ await serverPromise;
279
+ }
280
+ catch (error) {
281
+ // Starting our own bridge failed, most likely because another MCP instance
282
+ // already bound the port (EADDRINUSE). Clear the rejected promise so future
283
+ // calls re-probe, and fall back to whoever owns the bridge right now.
284
+ serverPromise = null;
285
+ debugLog(`bridge startup failed, falling back to existing bridge ${error instanceof Error ? error.message : String(error)}`);
286
+ return await fetchBridgeStatus();
287
+ }
288
+ return getBridgeStatus();
289
+ }
290
+ async function startBridgeServer() {
291
+ const { host, port } = getConfig();
292
+ const server = createServer(async (request, response) => {
293
+ if (!isLocalRequest(request)) {
294
+ sendJsonResponse(response, 403, { error: "Forbidden" });
295
+ return;
296
+ }
297
+ try {
298
+ if (request.method === "GET" && request.url === "/status") {
299
+ sendJsonResponse(response, 200, getBridgeStatus());
300
+ return;
301
+ }
302
+ if (request.method === "POST" && request.url === "/call") {
303
+ const body = await readJsonBody(request);
304
+ const method = String(body.method ?? "");
305
+ const result = await callEditor(method, body.params);
306
+ sendJsonResponse(response, 200, { result });
307
+ return;
308
+ }
309
+ sendJsonResponse(response, 404, { error: "Not found" });
310
+ }
311
+ catch (error) {
312
+ sendJsonResponse(response, 500, {
313
+ error: error instanceof Error ? error.message : "Unknown bridge error.",
314
+ });
315
+ }
316
+ });
317
+ server.on("upgrade", (request, socket, head) => {
318
+ debugLog(`upgrade url=${request.url} remote=${request.socket.remoteAddress}`);
319
+ if (request.url !== WS_PATH ||
320
+ !isLocalRequest(request) ||
321
+ request.headers.upgrade?.toLowerCase() !== "websocket") {
322
+ socket.destroy();
323
+ return;
324
+ }
325
+ const key = request.headers["sec-websocket-key"];
326
+ if (typeof key !== "string") {
327
+ socket.destroy();
328
+ return;
329
+ }
330
+ socket.write([
331
+ "HTTP/1.1 101 Switching Protocols",
332
+ "Upgrade: websocket",
333
+ "Connection: Upgrade",
334
+ `Sec-WebSocket-Accept: ${createAcceptKey(key)}`,
335
+ "\r\n",
336
+ ].join("\r\n"));
337
+ if (head.length > 0)
338
+ socket.unshift(head);
339
+ activeEditor?.close();
340
+ activeEditor = new WebSocketConnection(socket);
341
+ debugLog("editor connected");
342
+ });
343
+ server.on("error", (error) => {
344
+ debugLog(`bridge server error ${error.message}`);
345
+ });
346
+ await new Promise((resolve, reject) => {
347
+ server.once("error", reject);
348
+ server.listen(port, host, () => {
349
+ server.off("error", reject);
350
+ debugLog(`bridge listening ${host}:${port}${WS_PATH}`);
351
+ resolve();
352
+ });
353
+ });
354
+ return server;
355
+ }
356
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const DEFAULT_HOST = "127.0.0.1";
2
+ export declare const DEFAULT_PORT = 32117;
3
+ export declare const WS_PATH = "/screenslick-agent";
4
+ export declare function getConfig(): {
5
+ host: string;
6
+ port: number;
7
+ logPath: string;
8
+ bridgeBaseUrl: string;
9
+ websocketUrl: string;
10
+ };
package/dist/config.js ADDED
@@ -0,0 +1,26 @@
1
+ import { dirname, join } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
4
+ export const DEFAULT_HOST = "127.0.0.1";
5
+ export const DEFAULT_PORT = 32117;
6
+ export const WS_PATH = "/screenslick-agent";
7
+ export function getConfig() {
8
+ const port = Number(process.env.SCREEN_SLICK_AGENT_PORT ?? DEFAULT_PORT);
9
+ const host = process.env.SCREEN_SLICK_AGENT_HOST ?? DEFAULT_HOST;
10
+ const logPath = process.env.SCREEN_SLICK_AGENT_LOG ??
11
+ join(packageRoot, ".tmp", "screenslick-agent-mcp.log");
12
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) {
13
+ throw new Error(`Invalid SCREEN_SLICK_AGENT_PORT "${String(process.env.SCREEN_SLICK_AGENT_PORT)}".`);
14
+ }
15
+ if (host !== DEFAULT_HOST) {
16
+ throw new Error("SCREEN_SLICK_AGENT_HOST must be 127.0.0.1. The ScreenSlick bridge is intentionally localhost-only.");
17
+ }
18
+ return {
19
+ host,
20
+ port,
21
+ logPath,
22
+ bridgeBaseUrl: `http://${host}:${port}`,
23
+ websocketUrl: `ws://${host}:${port}${WS_PATH}`,
24
+ };
25
+ }
26
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AACxC,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC;AAClC,MAAM,CAAC,MAAM,OAAO,GAAG,oBAAoB,CAAC;AAE5C,MAAM,UAAU,SAAS;IACvB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,YAAY,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,YAAY,CAAC;IACjE,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,CAAC,sBAAsB;QAClC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,2BAA2B,CAAC,CAAC;IAEzD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CACb,oCAAoC,MAAM,CACxC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CACpC,IAAI,CACN,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,oGAAoG,CACrG,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI;QACJ,IAAI;QACJ,OAAO;QACP,aAAa,EAAE,UAAU,IAAI,IAAI,IAAI,EAAE;QACvC,YAAY,EAAE,QAAQ,IAAI,IAAI,IAAI,GAAG,OAAO,EAAE;KAC/C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { callEditor, ensureBridge, getBridgeStatus } from "./bridge.js";
5
+ import { debugLog } from "./log.js";
6
+ import { editorMethods, passthroughToolSchemas, toolDescriptions, } from "./toolSchemas.js";
7
+ function textContent(value) {
8
+ return {
9
+ content: [
10
+ {
11
+ type: "text",
12
+ text: typeof value === "string" ? value : JSON.stringify(value, null, 2),
13
+ },
14
+ ],
15
+ };
16
+ }
17
+ function selectVoiceInfo(capabilities) {
18
+ if (capabilities &&
19
+ typeof capabilities === "object" &&
20
+ "commands" in capabilities) {
21
+ const commands = capabilities.commands;
22
+ if (commands && typeof commands === "object" && "voiceover" in commands) {
23
+ const voiceover = commands.voiceover;
24
+ if (voiceover &&
25
+ typeof voiceover === "object" &&
26
+ "voiceSelection" in voiceover) {
27
+ return voiceover.voiceSelection;
28
+ }
29
+ }
30
+ }
31
+ return capabilities;
32
+ }
33
+ async function callScreenSlickTool(name, args) {
34
+ if (name === "screenslick_bridge_status") {
35
+ await ensureBridge();
36
+ return textContent(getBridgeStatus());
37
+ }
38
+ const editorMethod = editorMethods[name];
39
+ if (!editorMethod) {
40
+ throw new Error(`Unknown ScreenSlick tool "${name}".`);
41
+ }
42
+ const result = await callEditor(editorMethod, args);
43
+ if (name === "screenslick_list_voices") {
44
+ return textContent(selectVoiceInfo(result));
45
+ }
46
+ return textContent(result);
47
+ }
48
+ async function main() {
49
+ const server = new McpServer({
50
+ name: "screenslick",
51
+ version: "0.1.0",
52
+ });
53
+ for (const [name, inputSchema] of Object.entries(passthroughToolSchemas)) {
54
+ server.registerTool(name, {
55
+ description: toolDescriptions[name],
56
+ inputSchema,
57
+ }, async (args) => callScreenSlickTool(name, args));
58
+ }
59
+ void ensureBridge().catch((error) => {
60
+ debugLog(`background bridge startup failed ${error instanceof Error ? error.message : String(error)}`);
61
+ });
62
+ const transport = new StdioServerTransport();
63
+ await server.connect(transport);
64
+ }
65
+ process.on("SIGINT", () => {
66
+ debugLog("mcp received SIGINT");
67
+ process.exit(0);
68
+ });
69
+ process.on("SIGTERM", () => {
70
+ debugLog("mcp received SIGTERM");
71
+ process.exit(0);
72
+ });
73
+ main().catch((error) => {
74
+ debugLog(`fatal startup error ${error instanceof Error ? error.message : String(error)}`);
75
+ console.error(error instanceof Error ? error.message : String(error));
76
+ process.exit(1);
77
+ });
78
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/log.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function debugLog(message: string): void;
package/dist/log.js ADDED
@@ -0,0 +1,14 @@
1
+ import { appendFileSync, mkdirSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { getConfig } from "./config.js";
4
+ export function debugLog(message) {
5
+ try {
6
+ const { logPath } = getConfig();
7
+ mkdirSync(dirname(logPath), { recursive: true });
8
+ appendFileSync(logPath, `[${new Date().toISOString()}] ${message}\n`);
9
+ }
10
+ catch {
11
+ // Logging should never break MCP tool calls.
12
+ }
13
+ }
14
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;QAChC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,cAAc,CAAC,OAAO,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,OAAO,IAAI,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;IAC/C,CAAC;AACH,CAAC"}
@@ -0,0 +1,255 @@
1
+ import { z } from "zod";
2
+ export declare const passthroughToolSchemas: {
3
+ screenslick_bridge_status: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
4
+ screenslick_get_project: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
5
+ screenslick_get_capabilities: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
6
+ screenslick_list_voices: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
7
+ screenslick_list_music: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
8
+ screenslick_list_sound_effects: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
9
+ screenslick_list_effects: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
10
+ screenslick_remove_silences: z.ZodObject<{
11
+ minDuration: z.ZodOptional<z.ZodNumber>;
12
+ dryRun: z.ZodOptional<z.ZodBoolean>;
13
+ mode: z.ZodOptional<z.ZodEnum<["aggressive", "default", "conservative", "long-pauses"]>>;
14
+ }, "strict", z.ZodTypeAny, {
15
+ minDuration?: number | undefined;
16
+ dryRun?: boolean | undefined;
17
+ mode?: "default" | "aggressive" | "conservative" | "long-pauses" | undefined;
18
+ }, {
19
+ minDuration?: number | undefined;
20
+ dryRun?: boolean | undefined;
21
+ mode?: "default" | "aggressive" | "conservative" | "long-pauses" | undefined;
22
+ }>;
23
+ screenslick_generate_transcript: z.ZodObject<{
24
+ language: z.ZodOptional<z.ZodString>;
25
+ modelSize: z.ZodOptional<z.ZodEnum<["tiny", "base", "small"]>>;
26
+ provider: z.ZodOptional<z.ZodEnum<["local", "premium"]>>;
27
+ enableSubtitles: z.ZodOptional<z.ZodBoolean>;
28
+ }, "strict", z.ZodTypeAny, {
29
+ provider?: "local" | "premium" | undefined;
30
+ language?: string | undefined;
31
+ modelSize?: "tiny" | "base" | "small" | undefined;
32
+ enableSubtitles?: boolean | undefined;
33
+ }, {
34
+ provider?: "local" | "premium" | undefined;
35
+ language?: string | undefined;
36
+ modelSize?: "tiny" | "base" | "small" | undefined;
37
+ enableSubtitles?: boolean | undefined;
38
+ }>;
39
+ screenslick_generate_script: z.ZodObject<{
40
+ mode: z.ZodOptional<z.ZodEnum<["script", "improve"]>>;
41
+ brief: z.ZodOptional<z.ZodObject<{
42
+ videoType: z.ZodOptional<z.ZodEnum<["demo", "tutorial", "walkthrough", "release", "sales"]>>;
43
+ goal: z.ZodOptional<z.ZodString>;
44
+ audience: z.ZodOptional<z.ZodString>;
45
+ tone: z.ZodOptional<z.ZodString>;
46
+ notes: z.ZodOptional<z.ZodString>;
47
+ }, "strict", z.ZodTypeAny, {
48
+ videoType?: "tutorial" | "demo" | "walkthrough" | "release" | "sales" | undefined;
49
+ goal?: string | undefined;
50
+ audience?: string | undefined;
51
+ tone?: string | undefined;
52
+ notes?: string | undefined;
53
+ }, {
54
+ videoType?: "tutorial" | "demo" | "walkthrough" | "release" | "sales" | undefined;
55
+ goal?: string | undefined;
56
+ audience?: string | undefined;
57
+ tone?: string | undefined;
58
+ notes?: string | undefined;
59
+ }>>;
60
+ }, "strict", z.ZodTypeAny, {
61
+ mode?: "script" | "improve" | undefined;
62
+ brief?: {
63
+ videoType?: "tutorial" | "demo" | "walkthrough" | "release" | "sales" | undefined;
64
+ goal?: string | undefined;
65
+ audience?: string | undefined;
66
+ tone?: string | undefined;
67
+ notes?: string | undefined;
68
+ } | undefined;
69
+ }, {
70
+ mode?: "script" | "improve" | undefined;
71
+ brief?: {
72
+ videoType?: "tutorial" | "demo" | "walkthrough" | "release" | "sales" | undefined;
73
+ goal?: string | undefined;
74
+ audience?: string | undefined;
75
+ tone?: string | undefined;
76
+ notes?: string | undefined;
77
+ } | undefined;
78
+ }>;
79
+ screenslick_generate_voiceover: z.ZodObject<{
80
+ source: z.ZodOptional<z.ZodEnum<["transcript", "script"]>>;
81
+ script: z.ZodOptional<z.ZodString>;
82
+ clips: z.ZodOptional<z.ZodArray<z.ZodObject<{
83
+ text: z.ZodString;
84
+ startMs: z.ZodOptional<z.ZodNumber>;
85
+ endMs: z.ZodOptional<z.ZodNumber>;
86
+ targetDurationMs: z.ZodOptional<z.ZodNumber>;
87
+ voice: z.ZodOptional<z.ZodString>;
88
+ speed: z.ZodOptional<z.ZodNumber>;
89
+ provider: z.ZodOptional<z.ZodEnum<["local", "gemini"]>>;
90
+ style: z.ZodOptional<z.ZodEnum<["natural", "tutorial", "cheerful", "calm", "energetic", "dramatic"]>>;
91
+ direction: z.ZodOptional<z.ZodString>;
92
+ }, "strict", z.ZodTypeAny, {
93
+ text: string;
94
+ startMs?: number | undefined;
95
+ endMs?: number | undefined;
96
+ targetDurationMs?: number | undefined;
97
+ voice?: string | undefined;
98
+ speed?: number | undefined;
99
+ provider?: "local" | "gemini" | undefined;
100
+ style?: "natural" | "tutorial" | "cheerful" | "calm" | "energetic" | "dramatic" | undefined;
101
+ direction?: string | undefined;
102
+ }, {
103
+ text: string;
104
+ startMs?: number | undefined;
105
+ endMs?: number | undefined;
106
+ targetDurationMs?: number | undefined;
107
+ voice?: string | undefined;
108
+ speed?: number | undefined;
109
+ provider?: "local" | "gemini" | undefined;
110
+ style?: "natural" | "tutorial" | "cheerful" | "calm" | "energetic" | "dramatic" | undefined;
111
+ direction?: string | undefined;
112
+ }>, "many">>;
113
+ enable: z.ZodOptional<z.ZodBoolean>;
114
+ }, "strict", z.ZodTypeAny, {
115
+ script?: string | undefined;
116
+ source?: "script" | "transcript" | undefined;
117
+ clips?: {
118
+ text: string;
119
+ startMs?: number | undefined;
120
+ endMs?: number | undefined;
121
+ targetDurationMs?: number | undefined;
122
+ voice?: string | undefined;
123
+ speed?: number | undefined;
124
+ provider?: "local" | "gemini" | undefined;
125
+ style?: "natural" | "tutorial" | "cheerful" | "calm" | "energetic" | "dramatic" | undefined;
126
+ direction?: string | undefined;
127
+ }[] | undefined;
128
+ enable?: boolean | undefined;
129
+ }, {
130
+ script?: string | undefined;
131
+ source?: "script" | "transcript" | undefined;
132
+ clips?: {
133
+ text: string;
134
+ startMs?: number | undefined;
135
+ endMs?: number | undefined;
136
+ targetDurationMs?: number | undefined;
137
+ voice?: string | undefined;
138
+ speed?: number | undefined;
139
+ provider?: "local" | "gemini" | undefined;
140
+ style?: "natural" | "tutorial" | "cheerful" | "calm" | "energetic" | "dramatic" | undefined;
141
+ direction?: string | undefined;
142
+ }[] | undefined;
143
+ enable?: boolean | undefined;
144
+ }>;
145
+ screenslick_add_transcript_voiceover_to_timeline: z.ZodObject<{
146
+ source: z.ZodOptional<z.ZodEnum<["transcript", "script"]>>;
147
+ script: z.ZodOptional<z.ZodString>;
148
+ clips: z.ZodOptional<z.ZodArray<z.ZodObject<{
149
+ text: z.ZodString;
150
+ startMs: z.ZodOptional<z.ZodNumber>;
151
+ endMs: z.ZodOptional<z.ZodNumber>;
152
+ targetDurationMs: z.ZodOptional<z.ZodNumber>;
153
+ voice: z.ZodOptional<z.ZodString>;
154
+ speed: z.ZodOptional<z.ZodNumber>;
155
+ provider: z.ZodOptional<z.ZodEnum<["local", "gemini"]>>;
156
+ style: z.ZodOptional<z.ZodEnum<["natural", "tutorial", "cheerful", "calm", "energetic", "dramatic"]>>;
157
+ direction: z.ZodOptional<z.ZodString>;
158
+ }, "strict", z.ZodTypeAny, {
159
+ text: string;
160
+ startMs?: number | undefined;
161
+ endMs?: number | undefined;
162
+ targetDurationMs?: number | undefined;
163
+ voice?: string | undefined;
164
+ speed?: number | undefined;
165
+ provider?: "local" | "gemini" | undefined;
166
+ style?: "natural" | "tutorial" | "cheerful" | "calm" | "energetic" | "dramatic" | undefined;
167
+ direction?: string | undefined;
168
+ }, {
169
+ text: string;
170
+ startMs?: number | undefined;
171
+ endMs?: number | undefined;
172
+ targetDurationMs?: number | undefined;
173
+ voice?: string | undefined;
174
+ speed?: number | undefined;
175
+ provider?: "local" | "gemini" | undefined;
176
+ style?: "natural" | "tutorial" | "cheerful" | "calm" | "energetic" | "dramatic" | undefined;
177
+ direction?: string | undefined;
178
+ }>, "many">>;
179
+ }, "strict", z.ZodTypeAny, {
180
+ script?: string | undefined;
181
+ source?: "script" | "transcript" | undefined;
182
+ clips?: {
183
+ text: string;
184
+ startMs?: number | undefined;
185
+ endMs?: number | undefined;
186
+ targetDurationMs?: number | undefined;
187
+ voice?: string | undefined;
188
+ speed?: number | undefined;
189
+ provider?: "local" | "gemini" | undefined;
190
+ style?: "natural" | "tutorial" | "cheerful" | "calm" | "energetic" | "dramatic" | undefined;
191
+ direction?: string | undefined;
192
+ }[] | undefined;
193
+ }, {
194
+ script?: string | undefined;
195
+ source?: "script" | "transcript" | undefined;
196
+ clips?: {
197
+ text: string;
198
+ startMs?: number | undefined;
199
+ endMs?: number | undefined;
200
+ targetDurationMs?: number | undefined;
201
+ voice?: string | undefined;
202
+ speed?: number | undefined;
203
+ provider?: "local" | "gemini" | undefined;
204
+ style?: "natural" | "tutorial" | "cheerful" | "calm" | "energetic" | "dramatic" | undefined;
205
+ direction?: string | undefined;
206
+ }[] | undefined;
207
+ }>;
208
+ screenslick_preview_voiceover: z.ZodObject<{
209
+ action: z.ZodOptional<z.ZodEnum<["start", "stop"]>>;
210
+ }, "strict", z.ZodTypeAny, {
211
+ action?: "start" | "stop" | undefined;
212
+ }, {
213
+ action?: "start" | "stop" | undefined;
214
+ }>;
215
+ screenslick_toggle_voiceover: z.ZodObject<{
216
+ enabled: z.ZodOptional<z.ZodBoolean>;
217
+ }, "strict", z.ZodTypeAny, {
218
+ enabled?: boolean | undefined;
219
+ }, {
220
+ enabled?: boolean | undefined;
221
+ }>;
222
+ screenslick_apply_commands: z.ZodObject<{
223
+ commands: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">;
224
+ dryRun: z.ZodOptional<z.ZodBoolean>;
225
+ description: z.ZodOptional<z.ZodString>;
226
+ }, "strict", z.ZodTypeAny, {
227
+ commands: Record<string, unknown>[];
228
+ dryRun?: boolean | undefined;
229
+ description?: string | undefined;
230
+ }, {
231
+ commands: Record<string, unknown>[];
232
+ dryRun?: boolean | undefined;
233
+ description?: string | undefined;
234
+ }>;
235
+ screenslick_capture_frame: z.ZodObject<{
236
+ time: z.ZodOptional<z.ZodNumber>;
237
+ }, "strict", z.ZodTypeAny, {
238
+ time?: number | undefined;
239
+ }, {
240
+ time?: number | undefined;
241
+ }>;
242
+ screenslick_export_video: z.ZodObject<{
243
+ settings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
244
+ watermark: z.ZodOptional<z.ZodBoolean>;
245
+ }, "strict", z.ZodTypeAny, {
246
+ settings?: Record<string, unknown> | undefined;
247
+ watermark?: boolean | undefined;
248
+ }, {
249
+ settings?: Record<string, unknown> | undefined;
250
+ watermark?: boolean | undefined;
251
+ }>;
252
+ };
253
+ export type ToolName = keyof typeof passthroughToolSchemas;
254
+ export declare const toolDescriptions: Record<ToolName, string>;
255
+ export declare const editorMethods: Partial<Record<ToolName, string>>;
@@ -0,0 +1,143 @@
1
+ import { z } from "zod";
2
+ const emptySchema = z.object({}).strict();
3
+ const jsonObjectSchema = z.record(z.unknown());
4
+ const optionalJsonObjectSchema = jsonObjectSchema.optional();
5
+ const scriptClipSchema = z
6
+ .object({
7
+ text: z.string(),
8
+ startMs: z.number().optional(),
9
+ endMs: z.number().optional(),
10
+ targetDurationMs: z.number().optional(),
11
+ voice: z.string().optional(),
12
+ speed: z.number().optional(),
13
+ provider: z.enum(["local", "gemini"]).optional(),
14
+ style: z
15
+ .enum(["natural", "tutorial", "cheerful", "calm", "energetic", "dramatic"])
16
+ .optional(),
17
+ direction: z.string().optional(),
18
+ })
19
+ .strict();
20
+ export const passthroughToolSchemas = {
21
+ screenslick_bridge_status: emptySchema,
22
+ screenslick_get_project: emptySchema,
23
+ screenslick_get_capabilities: emptySchema,
24
+ screenslick_list_voices: emptySchema,
25
+ screenslick_list_music: emptySchema,
26
+ screenslick_list_sound_effects: emptySchema,
27
+ screenslick_list_effects: emptySchema,
28
+ screenslick_remove_silences: z
29
+ .object({
30
+ minDuration: z.number().optional(),
31
+ dryRun: z.boolean().optional(),
32
+ mode: z
33
+ .enum(["aggressive", "default", "conservative", "long-pauses"])
34
+ .optional(),
35
+ })
36
+ .strict(),
37
+ screenslick_generate_transcript: z
38
+ .object({
39
+ language: z.string().optional(),
40
+ modelSize: z.enum(["tiny", "base", "small"]).optional(),
41
+ provider: z.enum(["local", "premium"]).optional(),
42
+ enableSubtitles: z.boolean().optional(),
43
+ })
44
+ .strict(),
45
+ screenslick_generate_script: z
46
+ .object({
47
+ mode: z.enum(["script", "improve"]).optional(),
48
+ brief: z
49
+ .object({
50
+ videoType: z
51
+ .enum(["demo", "tutorial", "walkthrough", "release", "sales"])
52
+ .optional(),
53
+ goal: z.string().optional(),
54
+ audience: z.string().optional(),
55
+ tone: z.string().optional(),
56
+ notes: z.string().optional(),
57
+ })
58
+ .strict()
59
+ .optional(),
60
+ })
61
+ .strict(),
62
+ screenslick_generate_voiceover: z
63
+ .object({
64
+ source: z.enum(["transcript", "script"]).optional(),
65
+ script: z.string().optional(),
66
+ clips: z.array(scriptClipSchema).optional(),
67
+ enable: z.boolean().optional(),
68
+ })
69
+ .strict(),
70
+ screenslick_add_transcript_voiceover_to_timeline: z
71
+ .object({
72
+ source: z.enum(["transcript", "script"]).optional(),
73
+ script: z.string().optional(),
74
+ clips: z.array(scriptClipSchema).optional(),
75
+ })
76
+ .strict(),
77
+ screenslick_preview_voiceover: z
78
+ .object({
79
+ action: z.enum(["start", "stop"]).optional(),
80
+ })
81
+ .strict(),
82
+ screenslick_toggle_voiceover: z
83
+ .object({
84
+ enabled: z.boolean().optional(),
85
+ })
86
+ .strict(),
87
+ screenslick_apply_commands: z
88
+ .object({
89
+ commands: z.array(jsonObjectSchema),
90
+ dryRun: z.boolean().optional(),
91
+ description: z.string().optional(),
92
+ })
93
+ .strict(),
94
+ screenslick_capture_frame: z
95
+ .object({
96
+ time: z.number().optional(),
97
+ })
98
+ .strict(),
99
+ screenslick_export_video: z
100
+ .object({
101
+ settings: optionalJsonObjectSchema,
102
+ watermark: z.boolean().optional(),
103
+ })
104
+ .strict(),
105
+ };
106
+ export const toolDescriptions = {
107
+ screenslick_bridge_status: "Check whether a ScreenSlick editor is connected to the local bridge.",
108
+ screenslick_get_project: "Inspect the current ScreenSlick editor project.",
109
+ screenslick_get_capabilities: "List ScreenSlick agent-editable commands, effect fields, animations, sound bindings, backgrounds, layouts, and workflow guidance.",
110
+ screenslick_list_voices: "List ScreenSlick local and premium voiceover voices. Premium Gemini voices consume credits and require user confirmation.",
111
+ screenslick_list_music: "List built-in ScreenSlick music tracks.",
112
+ screenslick_list_sound_effects: "List built-in ScreenSlick sound effects.",
113
+ screenslick_list_effects: "List agent-editable visual effect options.",
114
+ screenslick_remove_silences: "Run the editor's silence removal feature on the current timeline.",
115
+ screenslick_generate_transcript: "Run the editor's transcription/subtitle generation flow on the current video or timeline.",
116
+ screenslick_generate_script: "Ask ScreenSlick's script assistant to write or improve a timed narration plan.",
117
+ screenslick_generate_voiceover: "Generate a full voiceover track using ScreenSlick's native voiceover flow.",
118
+ screenslick_add_transcript_voiceover_to_timeline: "Add transcript or agent-provided script voiceover clips to the timeline.",
119
+ screenslick_preview_voiceover: "Preview or stop the current generated ScreenSlick voiceover.",
120
+ screenslick_toggle_voiceover: "Enable or disable the current generated ScreenSlick voiceover track.",
121
+ screenslick_apply_commands: "Apply a batch of validated creative edit commands to the editor timeline. Call screenslick_get_capabilities first to learn the valid command shapes and effect fields.",
122
+ screenslick_capture_frame: "Capture a PNG preview frame from the current editor.",
123
+ screenslick_export_video: "Export the current editor project as an MP4 data URL.",
124
+ };
125
+ export const editorMethods = {
126
+ screenslick_get_project: "get_project",
127
+ screenslick_get_capabilities: "get_capabilities",
128
+ screenslick_list_voices: "get_capabilities",
129
+ screenslick_list_music: "list_music",
130
+ screenslick_list_sound_effects: "list_sound_effects",
131
+ screenslick_list_effects: "list_effects",
132
+ screenslick_remove_silences: "remove_silences",
133
+ screenslick_generate_transcript: "generate_transcript",
134
+ screenslick_generate_script: "generate_script",
135
+ screenslick_generate_voiceover: "generate_voiceover",
136
+ screenslick_add_transcript_voiceover_to_timeline: "add_transcript_voiceover_to_timeline",
137
+ screenslick_preview_voiceover: "preview_voiceover",
138
+ screenslick_toggle_voiceover: "toggle_voiceover",
139
+ screenslick_apply_commands: "apply_commands",
140
+ screenslick_capture_frame: "capture_frame",
141
+ screenslick_export_video: "export_video",
142
+ };
143
+ //# sourceMappingURL=toolSchemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolSchemas.js","sourceRoot":"","sources":["../src/toolSchemas.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "screenslick-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Local MCP server for controlling the ScreenSlick browser editor.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "bin": {
16
+ "screenslick-mcp": "dist/index.js"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "sideEffects": false,
22
+ "files": [
23
+ "dist",
24
+ "README.md",
25
+ "SECURITY.md",
26
+ "LICENSE"
27
+ ],
28
+ "scripts": {
29
+ "build": "tsc",
30
+ "dev": "tsx src/index.ts",
31
+ "start": "node dist/index.js",
32
+ "typecheck": "tsc --noEmit"
33
+ },
34
+ "keywords": [
35
+ "mcp",
36
+ "model-context-protocol",
37
+ "screenslick",
38
+ "video",
39
+ "screen-recording"
40
+ ],
41
+ "engines": {
42
+ "node": ">=20.10"
43
+ },
44
+ "dependencies": {
45
+ "@modelcontextprotocol/sdk": "^1.29.0",
46
+ "zod": "^3.25.76"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^24.0.3",
50
+ "tsx": "^4.20.3",
51
+ "typescript": "^5.8.3"
52
+ }
53
+ }