@writepanda/mcp 1.15.0 → 1.18.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.
Files changed (2) hide show
  1. package/bin/server.mjs +81 -15
  2. package/package.json +1 -1
package/bin/server.mjs CHANGED
@@ -171,6 +171,13 @@ const TOOLS = [
171
171
  inputSchema: { type: "object", properties: {} },
172
172
  command: "project.list",
173
173
  },
174
+ {
175
+ name: "project_current",
176
+ description:
177
+ "Return the project currently loaded in the editor window: { project: {id, path, name, revision, clipCount} | null }. Use this when the user says 'edit what I'm working on' / 'the project that's open' — no need to ask them for an id. Returns { project: null } when no editor window is open.",
178
+ inputSchema: { type: "object", properties: {} },
179
+ command: "project.current",
180
+ },
174
181
  {
175
182
  name: "project_show",
176
183
  description:
@@ -242,8 +249,7 @@ const TOOLS = [
242
249
  media: { type: "string", description: "Absolute path to video file" },
243
250
  atIndex: {
244
251
  type: "number",
245
- description:
246
- "Insert before this zero-based clip index. Omit to append at the end.",
252
+ description: "Insert before this zero-based clip index. Omit to append at the end.",
247
253
  },
248
254
  expectedRevision: { type: "number" },
249
255
  },
@@ -254,7 +260,7 @@ const TOOLS = [
254
260
  {
255
261
  name: "project_add_motion_graphic",
256
262
  description:
257
- "Drop a motion-graphic MP4 (typically the output of motion_generate) onto the timeline.",
263
+ "Drop a motion-graphic MP4 (typically the output of motion_generate) onto the timeline. Optional SFX plays when it appears.",
258
264
  inputSchema: {
259
265
  type: "object",
260
266
  properties: {
@@ -263,6 +269,15 @@ const TOOLS = [
263
269
  file: { type: "string", description: "Absolute path to MP4" },
264
270
  durationMs: { type: "number" },
265
271
  atMs: { type: "number", description: "Default: end of timeline" },
272
+ soundUrl: {
273
+ type: "string",
274
+ description:
275
+ "Optional SFX played when the motion graphic appears. Bundled id (bundled:sound/<id>) like bundled:sound/message-pop, bundled:sound/swoosh-fast, etc. — use asset_list_sounds to discover. No default.",
276
+ },
277
+ soundVolume: {
278
+ type: "number",
279
+ description: "Sound volume 0–1. Default 1 when soundUrl is set.",
280
+ },
266
281
  expectedRevision: { type: "number" },
267
282
  },
268
283
  required: ["file", "durationMs"],
@@ -305,7 +320,7 @@ const TOOLS = [
305
320
  designType: {
306
321
  type: "string",
307
322
  description:
308
- "name-bar | slash-reveal | center-stack | minimal-underline | box-reveal | corner-brackets | border-frame | split-horizontal",
323
+ "slash-reveal | center-stack | split-horizontal | name-bar | border-frame | minimal-underline | box-reveal | corner-brackets. Default: slash-reveal.",
309
324
  },
310
325
  accentColor: { type: "string", description: "Hex accent/background color" },
311
326
  textColor: { type: "string", description: "Hex text color. Default #ffffff" },
@@ -319,6 +334,15 @@ const TOOLS = [
319
334
  },
320
335
  fontSize: { type: "number", description: "Primary text font size in px. Default 28" },
321
336
  fontFamily: { type: "string", description: "CSS font family name. Default Inter" },
337
+ soundUrl: {
338
+ type: "string",
339
+ description:
340
+ 'SFX played when the lower third enters. Bundled id (bundled:sound/<id>). Default bundled:sound/mouse-click. Pass "none" for silent.',
341
+ },
342
+ soundVolume: {
343
+ type: "number",
344
+ description: "Sound volume 0–1. Default 0.8.",
345
+ },
322
346
  expectedRevision: { type: "number" },
323
347
  },
324
348
  required: ["content", "atMs"],
@@ -330,7 +354,7 @@ const TOOLS = [
330
354
  {
331
355
  name: "project_add_zoom",
332
356
  description:
333
- "Add a zoom region — highlight a UI moment. Typical pattern: find 'click X' in transcript, drop zoom there.",
357
+ "Add a zoom region — highlight a UI moment. Typical pattern: find 'click X' in transcript, drop zoom there. Ships with a short swoosh SFX by default; pass soundUrl=\"none\" for silent.",
334
358
  inputSchema: {
335
359
  type: "object",
336
360
  properties: {
@@ -341,12 +365,51 @@ const TOOLS = [
341
365
  depth: { type: "number", description: "1 (mild) - 6 (extreme). Default 3" },
342
366
  focusX: { type: "number", description: "Normalised 0-1 horizontal center. Default 0.5" },
343
367
  focusY: { type: "number", description: "Normalised 0-1 vertical center. Default 0.5" },
368
+ soundUrl: {
369
+ type: "string",
370
+ description:
371
+ 'SFX played at the zoom\'s leading edge. Bundled id (bundled:sound/<id>). Default bundled:sound/swoosh-fast. Pass "none" for silent.',
372
+ },
373
+ soundVolume: {
374
+ type: "number",
375
+ description: "Sound volume 0–1. Default 1.",
376
+ },
344
377
  expectedRevision: { type: "number" },
345
378
  },
346
379
  required: ["atMs", "durationMs"],
347
380
  },
348
381
  command: "project.add-zoom",
349
382
  },
383
+ {
384
+ name: "project_set_region_sound",
385
+ description:
386
+ 'Set or clear the sound effect on an existing region (zoom / motionGraphic / lowerThird / fx). Use to swap the default zoom swoosh, add a ding to a motion graphic, or mute a lower-third click. Pass soundUrl="none" to clear.',
387
+ inputSchema: {
388
+ type: "object",
389
+ properties: {
390
+ id: { type: "string" },
391
+ path: { type: "string" },
392
+ regionId: { type: "string", description: "Target region id" },
393
+ regionType: {
394
+ type: "string",
395
+ enum: ["zoom", "motionGraphic", "lowerThird", "fx"],
396
+ description: "Region kind that owns the id",
397
+ },
398
+ soundUrl: {
399
+ type: "string",
400
+ description:
401
+ 'Bundled id (bundled:sound/<id>), absolute path, or file:// URL. Pass "none" to clear.',
402
+ },
403
+ soundVolume: {
404
+ type: "number",
405
+ description: 'Sound volume 0–1. Ignored when soundUrl is "none". Default 1.',
406
+ },
407
+ expectedRevision: { type: "number" },
408
+ },
409
+ required: ["regionId", "regionType", "soundUrl"],
410
+ },
411
+ command: "project.set-region-sound",
412
+ },
350
413
  {
351
414
  name: "project_add_trim",
352
415
  description: "Mark a span the exporter SKIPS. Use directly for manual cuts.",
@@ -605,8 +668,7 @@ const TOOLS = [
605
668
  },
606
669
  resolution: {
607
670
  type: "string",
608
- description:
609
- "Output resolution: 4k | 1080p | 720p | 480p | source. Default source.",
671
+ description: "Output resolution: 4k | 1080p | 720p | 480p | source. Default source.",
610
672
  },
611
673
  gifFrameRate: {
612
674
  type: "number",
@@ -614,8 +676,7 @@ const TOOLS = [
614
676
  },
615
677
  gifSize: {
616
678
  type: "string",
617
- description:
618
- "GIF size preset: small | medium | large. Only used when format is gif.",
679
+ description: "GIF size preset: small | medium | large. Only used when format is gif.",
619
680
  },
620
681
  expectedRevision: { type: "number" },
621
682
  },
@@ -957,7 +1018,7 @@ const TOOLS = [
957
1018
  {
958
1019
  name: "motion_list",
959
1020
  description:
960
- "List every motion-graphic template (id, name, slots, defaults, aspectRatios). 19 templates ship today.",
1021
+ "List every motion-graphic template (id, name, slots, defaults, aspectRatios). 20 templates ship today, including youtube-lower-third for YouTube-style name plates.",
961
1022
  inputSchema: { type: "object", properties: {} },
962
1023
  command: "motion.list",
963
1024
  },
@@ -971,7 +1032,7 @@ const TOOLS = [
971
1032
  {
972
1033
  name: "motion_generate",
973
1034
  description:
974
- "Render a motion graphic asynchronously. Returns { jobId, outputPath }; call job_wait. Output is an MP4 you can pass to project_add_motion_graphic.",
1035
+ "Render a motion graphic asynchronously. Returns { jobId, outputPath }; call job_wait. Output is an MP4 you can pass to project_add_motion_graphic. Use templateId=youtube-lower-third (slots: channelName, handle, accentColor) for YouTube-style name plates with avatar + Subscribe button.",
975
1036
  inputSchema: {
976
1037
  type: "object",
977
1038
  properties: {
@@ -987,7 +1048,7 @@ const TOOLS = [
987
1048
  {
988
1049
  name: "motion_render_html",
989
1050
  description:
990
- "Render arbitrary HTML/CSS/JS to an MP4. Use this when the bundled motion-graphic templates don't fit the brief. Pass either inline `html` or a `htmlPath`. Animations should auto-start on DOMContentLoaded. IMPORTANT: renders are sequential — call job_wait to completion before starting another render, or you'll get a RENDER_BUSY error. Async — returns { jobId, outputPath }; poll job_wait for the final MP4.",
1051
+ "Render arbitrary HTML/CSS/JS to video. Use this when the bundled motion-graphic templates don't fit the brief — you write the HTML, the Chromium → capturePage → FFmpeg pipeline does the rest. Pass either inline `html` or a `htmlPath`. Animations should auto-start on DOMContentLoaded. Set `transparent: true` to get a WebM with alpha channel for overlays (lower thirds, watermarks, name plates) that composite over existing video. IMPORTANT: renders are sequential — call job_wait to completion before starting another render, or you'll get a RENDER_BUSY error. Async — returns { jobId, outputPath }; poll job_wait for the final file.",
991
1052
  inputSchema: {
992
1053
  type: "object",
993
1054
  properties: {
@@ -1011,7 +1072,7 @@ const TOOLS = [
1011
1072
  audioPath: {
1012
1073
  type: "string",
1013
1074
  description:
1014
- "Absolute path to an audio file (mp3, wav, aac, m4a) to mux into the MP4. Without this the output is silent.",
1075
+ "Absolute path to an audio file (mp3, wav, aac, m4a) to mux into the MP4. Without this the output is silent. Ignored when transparent: true.",
1015
1076
  },
1016
1077
  audioVolume: {
1017
1078
  type: "number",
@@ -1021,7 +1082,12 @@ const TOOLS = [
1021
1082
  type: "array",
1022
1083
  items: { type: "string" },
1023
1084
  description:
1024
- "Absolute paths to local files to stage alongside inline HTML. Reference them by basename: pass [\"/path/logo.png\"] and use <img src=\"logo.png\"> in the HTML. Avoids base64-encoding large images.",
1085
+ 'Absolute paths to local files to stage alongside inline HTML. Reference them by basename: pass ["/path/logo.png"] and use <img src="logo.png"> in the HTML. Avoids base64-encoding large images.',
1086
+ },
1087
+ transparent: {
1088
+ type: "boolean",
1089
+ description:
1090
+ "Render with a transparent background (VP9/yuva420p WebM instead of H.264 MP4). Use for overlays — lower thirds, watermarks, bug logos, name plates — anything that composites on top of existing video without a white/black fill. The returned outputPath will have a .webm extension. Note: audioPath is ignored in transparent mode.",
1025
1091
  },
1026
1092
  },
1027
1093
  },
@@ -1159,7 +1225,7 @@ const TOOLS = [
1159
1225
  {
1160
1226
  name: "export_start",
1161
1227
  description:
1162
- "Render the project to MP4 via the same Skia native render-helper the editor's Export button uses. ASYNC — returns { jobId, outputPath }; call job_wait. Honours every region/style/caption/FX/lower-third/motion-graphic.",
1228
+ "Render the project to MP4 via the same Skia native render-helper the editor's Export button uses. ASYNC — returns { jobId, outputPath }; call job_wait. Honours every region/style/caption/FX/lower-third/motion-graphic. Video overlays (motion graphics added via project_add_motion_graphic) are automatically composited in a post-process FFmpeg pass — both opaque MP4 and transparent WebM/VP9+alpha overlays are supported; no extra call needed.",
1163
1229
  inputSchema: {
1164
1230
  type: "object",
1165
1231
  properties: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@writepanda/mcp",
3
- "version": "1.15.0",
3
+ "version": "1.18.0",
4
4
  "description": "Model Context Protocol server for PandaStudio. Exposes the desktop video editor's automation surface to Cursor, Continue, Cline, Claude Desktop, and any MCP-compliant client.",
5
5
  "keywords": [
6
6
  "pandastudio",