@writepanda/mcp 1.51.0 → 1.56.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/bin/server.mjs +42 -17
- package/package.json +1 -1
package/bin/server.mjs
CHANGED
|
@@ -599,7 +599,7 @@ const TOOLS = [
|
|
|
599
599
|
{
|
|
600
600
|
name: "project_add_motion_graphic",
|
|
601
601
|
description:
|
|
602
|
-
"Drop a motion-graphic MP4/WebM onto the timeline. PREFERRED: pass `fromJob` (the jobId from motion_render_html / motion_generate / motion_concat) — the server resolves the outputPath internally, so you never handle the path string at all. Fallback: pass `file` (an absolute path) only for external/uploaded files.
|
|
602
|
+
"Drop a motion-graphic MP4/WebM onto the timeline. PREFERRED: pass `fromJob` (the jobId from motion_render_html / motion_generate / motion_concat) — the server resolves the outputPath internally, so you never handle the path string at all. Fallback: pass `file` (an absolute path) only for external/uploaded files. **Defaults to a `bundled:sound/mouse-click` SFX as the graphic appears** — pass `soundUrl: null` to make it silent, or any other `bundled:sound/<id>` to swap the sound.",
|
|
603
603
|
inputSchema: {
|
|
604
604
|
type: "object",
|
|
605
605
|
properties: {
|
|
@@ -618,13 +618,13 @@ const TOOLS = [
|
|
|
618
618
|
durationMs: { type: "number" },
|
|
619
619
|
atMs: { type: "number", description: "Default: end of timeline" },
|
|
620
620
|
soundUrl: {
|
|
621
|
-
type: "string",
|
|
621
|
+
type: ["string", "null"],
|
|
622
622
|
description:
|
|
623
|
-
"
|
|
623
|
+
"SFX played when the motion graphic appears. Defaults to bundled:sound/mouse-click. Pass any other bundled id (bundled:sound/<id> — bundled:sound/swoosh-fast, bundled:sound/message-pop, etc.; use asset_list_sounds to discover) to swap the sound, or pass null explicitly to make the graphic silent.",
|
|
624
624
|
},
|
|
625
625
|
soundVolume: {
|
|
626
626
|
type: "number",
|
|
627
|
-
description: "Sound volume 0–1. Default 1 when soundUrl is
|
|
627
|
+
description: "Sound volume 0–1. Default 1. Ignored when soundUrl is null.",
|
|
628
628
|
},
|
|
629
629
|
anchorSourceMs: {
|
|
630
630
|
type: "number",
|
|
@@ -690,13 +690,13 @@ const TOOLS = [
|
|
|
690
690
|
description: "Slide-in/out window at each edge in ms. Default 320.",
|
|
691
691
|
},
|
|
692
692
|
soundUrl: {
|
|
693
|
-
type: "string",
|
|
693
|
+
type: ["string", "null"],
|
|
694
694
|
description:
|
|
695
|
-
"
|
|
695
|
+
"SFX when the segment appears. Defaults to bundled:sound/mouse-click (inherited from project.add-motion-graphic). Pass any other bundled:sound/<id> to swap, or pass null explicitly to make the segment silent.",
|
|
696
696
|
},
|
|
697
697
|
soundVolume: {
|
|
698
698
|
type: "number",
|
|
699
|
-
description: "Sound volume 0–1. Default 1 when soundUrl is
|
|
699
|
+
description: "Sound volume 0–1. Default 1. Ignored when soundUrl is null.",
|
|
700
700
|
},
|
|
701
701
|
anchorSourceMs: {
|
|
702
702
|
type: "number",
|
|
@@ -1125,7 +1125,7 @@ const TOOLS = [
|
|
|
1125
1125
|
{
|
|
1126
1126
|
name: "project_remove_region",
|
|
1127
1127
|
description:
|
|
1128
|
-
"Delete an existing region (zoom, trim, speed, annotation, fx, lower-third, overlay, audio-overlay) by its id. Use project_read to find region ids — visual regions live under editor.*Regions; audio overlays live under audioOverlays[]. Returns the updated project.",
|
|
1128
|
+
"Delete an existing region (zoom, trim, speed, annotation, fx, lower-third, overlay, clip-transform, audio-overlay) by its id. Use project_read to find region ids — visual regions live under editor.*Regions; audio overlays live under audioOverlays[]. If the region belongs to a link group (designed-segment pair: a clip-transform parking the camera into one half + the panel motion-graphic on the other half), deleting either half also removes its peer so the pair stays coherent. Returns the updated project.",
|
|
1129
1129
|
inputSchema: {
|
|
1130
1130
|
type: "object",
|
|
1131
1131
|
properties: {
|
|
@@ -1134,7 +1134,7 @@ const TOOLS = [
|
|
|
1134
1134
|
regionType: {
|
|
1135
1135
|
type: "string",
|
|
1136
1136
|
description:
|
|
1137
|
-
"zoom | trim | speed | annotation | fx | lower-third | overlay | audio-overlay",
|
|
1137
|
+
"zoom | trim | speed | annotation | fx | lower-third | overlay | clip-transform | audio-overlay",
|
|
1138
1138
|
},
|
|
1139
1139
|
regionId: { type: "string", description: "id of the region to delete" },
|
|
1140
1140
|
expectedRevision: { type: "number" },
|
|
@@ -1165,7 +1165,7 @@ const TOOLS = [
|
|
|
1165
1165
|
{
|
|
1166
1166
|
name: "project_update_region",
|
|
1167
1167
|
description:
|
|
1168
|
-
"Patch fields on an existing region without replacing it. Accepts any subset of the region's own properties — only the supplied fields are changed, everything else is preserved. Works on zoom (depth, focusX, focusY), trim (startMs, endMs), speed (startMs, endMs, speed), lower-third (content, subtitle, atMs, durationMs, designType, accentColor, textColor, backgroundColor, backgroundRadius, fontSize, fontFamily), fx (atMs, durationMs), annotation, overlay, and audio-overlay (startMs, endMs, sourceStartMs, volume — lets you drag-trim an audio overlay without removing it).",
|
|
1168
|
+
"Patch fields on an existing region without replacing it. Accepts any subset of the region's own properties — only the supplied fields are changed, everything else is preserved. Works on zoom (depth, focusX, focusY), trim (startMs, endMs), speed (startMs, endMs, speed), lower-third (content, subtitle, atMs, durationMs, designType, accentColor, textColor, backgroundColor, backgroundRadius, fontSize, fontFamily), fx (atMs, durationMs), annotation, overlay, clip-transform (startMs, endMs, preset, transitionMs), and audio-overlay (startMs, endMs, sourceStartMs, volume — lets you drag-trim an audio overlay without removing it). Time shifts on a link-grouped region (e.g. one half of a designed segment) propagate to every peer in the group so the pair stays coherent.",
|
|
1169
1169
|
inputSchema: {
|
|
1170
1170
|
type: "object",
|
|
1171
1171
|
properties: {
|
|
@@ -1174,7 +1174,7 @@ const TOOLS = [
|
|
|
1174
1174
|
regionType: {
|
|
1175
1175
|
type: "string",
|
|
1176
1176
|
description:
|
|
1177
|
-
"zoom | trim | speed | annotation | fx | lower-third | overlay | audio-overlay",
|
|
1177
|
+
"zoom | trim | speed | annotation | fx | lower-third | overlay | clip-transform | audio-overlay",
|
|
1178
1178
|
},
|
|
1179
1179
|
regionId: { type: "string", description: "id of the region to update" },
|
|
1180
1180
|
patch: {
|
|
@@ -1193,7 +1193,7 @@ const TOOLS = [
|
|
|
1193
1193
|
{
|
|
1194
1194
|
name: "project_set_webcam_layout",
|
|
1195
1195
|
description:
|
|
1196
|
-
"Set the webcam layout preset and optional position/scale for the current project. Use 'none' to hide the webcam overlay entirely.",
|
|
1196
|
+
"Set the webcam layout preset and optional position/scale for the current project. Use 'none' to hide the webcam overlay entirely. Use 'podcast' for a two-speaker composite (host + guest as co-equal tiles).",
|
|
1197
1197
|
inputSchema: {
|
|
1198
1198
|
type: "object",
|
|
1199
1199
|
properties: {
|
|
@@ -1202,7 +1202,7 @@ const TOOLS = [
|
|
|
1202
1202
|
preset: {
|
|
1203
1203
|
type: "string",
|
|
1204
1204
|
description:
|
|
1205
|
-
"picture-in-picture | vertical-stack | side-by-side | none. 'none' hides the webcam.",
|
|
1205
|
+
"picture-in-picture | vertical-stack | side-by-side | podcast | none. 'podcast' shows two co-equal speaker tiles; 'none' hides the webcam.",
|
|
1206
1206
|
},
|
|
1207
1207
|
cx: {
|
|
1208
1208
|
type: "number",
|
|
@@ -1443,20 +1443,40 @@ const TOOLS = [
|
|
|
1443
1443
|
{
|
|
1444
1444
|
name: "project_set_clip_kind",
|
|
1445
1445
|
description:
|
|
1446
|
-
"Stamp a clip's capture origin authoritatively: kind = camera | screen | upload. project.read returns each clip's kind (your visual-strategy signal: camera → designed segments + emphasis zooms; screen → cursor zooms). On pre-v1.28 projects kind wasn't recorded, so project.read INFERS it (flagged kindInferred:true) — and inference can be wrong. Use this to correct/lock it. `camera` = talking-head; `screen` = screen recording (maybe with webcam PiP); `upload` = imported file.",
|
|
1446
|
+
"Stamp a clip's capture origin authoritatively: kind = camera | screen | upload | podcast. project.read returns each clip's kind (your visual-strategy signal: camera → designed segments + emphasis zooms; screen → cursor zooms). On pre-v1.28 projects kind wasn't recorded, so project.read INFERS it (flagged kindInferred:true) — and inference can be wrong. Use this to correct/lock it. `camera` = talking-head; `screen` = screen recording (maybe with webcam PiP); `upload` = imported file; `podcast` = two-speaker composite (host=mediaPath, guest=webcamPath).",
|
|
1447
1447
|
inputSchema: {
|
|
1448
1448
|
type: "object",
|
|
1449
1449
|
properties: {
|
|
1450
1450
|
id: { type: "string" },
|
|
1451
1451
|
path: { type: "string" },
|
|
1452
1452
|
clipId: { type: "string", description: "Clip id from project_read mainTrack.clips[n].id" },
|
|
1453
|
-
kind: { type: "string", enum: ["camera", "screen", "upload"] },
|
|
1453
|
+
kind: { type: "string", enum: ["camera", "screen", "upload", "podcast"] },
|
|
1454
1454
|
expectedRevision: { type: "number" },
|
|
1455
1455
|
},
|
|
1456
1456
|
required: ["clipId", "kind"],
|
|
1457
1457
|
},
|
|
1458
1458
|
command: "project.set-clip-kind",
|
|
1459
1459
|
},
|
|
1460
|
+
{
|
|
1461
|
+
name: "project_set_webcam_offset",
|
|
1462
|
+
description:
|
|
1463
|
+
"Fine-tune a podcast composite's guest/host sync. offsetMs shifts the guest (webcamPath) relative to the host: positive delays the guest, negative advances it, 0 clears it (±10000). Honored in preview + export — the guest VIDEO and AUDIO shift together. Use when the two speakers look or sound slightly out of sync.",
|
|
1464
|
+
inputSchema: {
|
|
1465
|
+
type: "object",
|
|
1466
|
+
properties: {
|
|
1467
|
+
id: { type: "string" },
|
|
1468
|
+
path: { type: "string" },
|
|
1469
|
+
clipId: { type: "string", description: "Clip id of the podcast composite" },
|
|
1470
|
+
offsetMs: {
|
|
1471
|
+
type: "number",
|
|
1472
|
+
description: "Guest time nudge in ms (±10000). Positive delays guest; 0 clears.",
|
|
1473
|
+
},
|
|
1474
|
+
expectedRevision: { type: "number" },
|
|
1475
|
+
},
|
|
1476
|
+
required: ["clipId", "offsetMs"],
|
|
1477
|
+
},
|
|
1478
|
+
command: "project.set-webcam-offset",
|
|
1479
|
+
},
|
|
1460
1480
|
|
|
1461
1481
|
// ── transcript-based editing ────────────────────────────────────
|
|
1462
1482
|
{
|
|
@@ -1509,12 +1529,17 @@ const TOOLS = [
|
|
|
1509
1529
|
{
|
|
1510
1530
|
name: "transcript_remove_fillers",
|
|
1511
1531
|
description:
|
|
1512
|
-
"Auto-detect filler words (
|
|
1532
|
+
"Auto-detect filler words and bulk-trim them. By DEFAULT removes only vocalised pauses (um, uh, uhm, umm, hmm, hm) — sounds with no lexical meaning, so removing every occurrence never breaks a sentence. Pass aggressive=true to ALSO catch lexical-word fillers (like, you know, i mean, sort of, kind of); these can false-positive on legitimate uses ('I like this template' loses 'like'), so the agent should only opt in when the user explicitly asks for a thorough cleanup. Also strips immediately-repeated words ('the the') unless includeRepeats=false.",
|
|
1513
1533
|
inputSchema: {
|
|
1514
1534
|
type: "object",
|
|
1515
1535
|
properties: {
|
|
1516
1536
|
id: { type: "string" },
|
|
1517
1537
|
path: { type: "string" },
|
|
1538
|
+
aggressive: {
|
|
1539
|
+
type: "boolean",
|
|
1540
|
+
description:
|
|
1541
|
+
"Include lexical-word fillers (like, you know, i mean, sort of, kind of) in addition to vocalised pauses. False positives possible on legitimate uses. Default false.",
|
|
1542
|
+
},
|
|
1518
1543
|
includeRepeats: { type: "boolean", description: "Default true" },
|
|
1519
1544
|
expectedRevision: { type: "number" },
|
|
1520
1545
|
},
|
|
@@ -2225,7 +2250,7 @@ const TOOLS = [
|
|
|
2225
2250
|
const server = new Server(
|
|
2226
2251
|
{
|
|
2227
2252
|
name: "pandastudio",
|
|
2228
|
-
version: "1.
|
|
2253
|
+
version: "1.56.0",
|
|
2229
2254
|
},
|
|
2230
2255
|
{
|
|
2231
2256
|
capabilities: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@writepanda/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.56.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",
|