@writepanda/mcp 1.62.0 → 1.69.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 +94 -42
- package/package.json +1 -1
package/bin/server.mjs
CHANGED
|
@@ -561,6 +561,37 @@ const TOOLS = [
|
|
|
561
561
|
},
|
|
562
562
|
command: "project.new",
|
|
563
563
|
},
|
|
564
|
+
{
|
|
565
|
+
name: "project_fork_from_shot",
|
|
566
|
+
description:
|
|
567
|
+
"Fork an exported video's AI-generated shot into a new 9:16 project. Carries forward the source project's timing surgery (trim regions, transcript edits, speed regions, per-clip transcribed/audioCleaned status) but STRIPS every overlay row — zooms, FX, motion graphics, captions, transitions, lower thirds, annotations, clip-transforms, background music — because those were sized for 16:9 and don't fit a vertical short. The new project is cropped to the shot's [startMs, endMs] range, switched to 9:16, and ready to receive Shorts-native graphics/captions on top. Pass exportId + shotId from export.list (the shot lives under `entry.generatedShots[]`); the verb looks up the source project path, runs the fork, writes the new file, and returns its id + path. If the source project has been edited since export (revision drift) the verb returns `revision_mismatch` with the live revision; confirm with the user and retry with `force: true`. Returns { id, path, name, aspectRatio, sourceProjectPath, sourceProjectRevision, liveRevision, project }.",
|
|
568
|
+
inputSchema: {
|
|
569
|
+
type: "object",
|
|
570
|
+
properties: {
|
|
571
|
+
exportId: {
|
|
572
|
+
type: "string",
|
|
573
|
+
description: "Export library entry id (from export.list).",
|
|
574
|
+
},
|
|
575
|
+
shotId: {
|
|
576
|
+
type: "string",
|
|
577
|
+
description:
|
|
578
|
+
"Shot id (from the export entry's `generatedShots` array; produced by generate-shorts).",
|
|
579
|
+
},
|
|
580
|
+
aspectRatio: {
|
|
581
|
+
type: "string",
|
|
582
|
+
description:
|
|
583
|
+
"Target aspect. Defaults to '9:16' (the right answer for almost every shot generator output).",
|
|
584
|
+
},
|
|
585
|
+
force: {
|
|
586
|
+
type: "boolean",
|
|
587
|
+
description:
|
|
588
|
+
"Set true to fork even when the source project has drifted since export. Without it, drift returns revision_mismatch and the caller must confirm with the user first.",
|
|
589
|
+
},
|
|
590
|
+
},
|
|
591
|
+
required: ["exportId", "shotId"],
|
|
592
|
+
},
|
|
593
|
+
command: "project.fork-from-shot",
|
|
594
|
+
},
|
|
564
595
|
{
|
|
565
596
|
name: "project_open",
|
|
566
597
|
description:
|
|
@@ -575,7 +606,7 @@ const TOOLS = [
|
|
|
575
606
|
command: "project.open",
|
|
576
607
|
},
|
|
577
608
|
|
|
578
|
-
// ── compose: clips, motion graphics, FX
|
|
609
|
+
// ── compose: clips, motion graphics, FX ────────────────────────
|
|
579
610
|
{
|
|
580
611
|
name: "project_add_clip",
|
|
581
612
|
description:
|
|
@@ -786,54 +817,71 @@ const TOOLS = [
|
|
|
786
817
|
src: { type: "string", description: "Direct path/URL (alternative to fxId)" },
|
|
787
818
|
atMs: { type: "number" },
|
|
788
819
|
durationMs: { type: "number", description: "Default 2500ms for bundled FX" },
|
|
820
|
+
speed: {
|
|
821
|
+
type: "number",
|
|
822
|
+
description:
|
|
823
|
+
"Playback-speed multiplier for the looping FX (0.25-4, default 1). 2 = twice as fast, 0.5 = half. Speeds up / slows down a film burn, light leak, etc. without re-rendering.",
|
|
824
|
+
},
|
|
789
825
|
expectedRevision: { type: "number" },
|
|
790
826
|
},
|
|
791
827
|
required: ["atMs"],
|
|
792
828
|
},
|
|
793
829
|
command: "project.add-fx",
|
|
794
830
|
},
|
|
831
|
+
{
|
|
832
|
+
name: "project_add_transition",
|
|
833
|
+
description:
|
|
834
|
+
"Place a transition at a cut between two clips. Drops a bundled transition overlay (a full-frame transparent WebM that goes opaque at its midpoint) CENTERED on atMs, so the opaque peak masks the cut and reads as a scene change. No render step. Pass atMs = the cut time (a clip boundary from project_read). Ids (asset_list_transitions): fade-black, fade-white, flash, light-sweep, film-burn, glitch.",
|
|
835
|
+
inputSchema: {
|
|
836
|
+
type: "object",
|
|
837
|
+
properties: {
|
|
838
|
+
id: { type: "string" },
|
|
839
|
+
path: { type: "string" },
|
|
840
|
+
transitionId: { type: "string", description: "Bundled id, e.g. fade-black. From asset_list_transitions." },
|
|
841
|
+
file: { type: "string", description: "Custom transition video (path / file:// URL). Use instead of transitionId." },
|
|
842
|
+
atMs: { type: "number", description: "Edited-timeline CUT time to center the transition on." },
|
|
843
|
+
durationMs: { type: "number", description: "Total length. Default 1000 (native length of the bundled set)." },
|
|
844
|
+
expectedRevision: { type: "number" },
|
|
845
|
+
},
|
|
846
|
+
required: ["atMs"],
|
|
847
|
+
},
|
|
848
|
+
command: "project.add-transition",
|
|
849
|
+
},
|
|
795
850
|
{
|
|
796
851
|
name: "project_add_lower_third",
|
|
797
|
-
description:
|
|
852
|
+
description:
|
|
853
|
+
"One-call lower third: renders an lt-* nameplate motion template (hyperframes) with your name/title and places it on the timeline as a transparent overlay at atMs. ASYNC — returns { jobId, outputPath }; call job_wait — it resolves once the region is PLACED (result: { path, revision, outputPath, durationMs }), no separate project_add_motion_graphic call needed. Designs (see motion_list, category lower-third): lt-vox-marker (default, highlighter swipe), lt-broadcast-bar (news chyron), lt-glass-card (frosted), lt-kinetic-stack (bold word-by-word), lt-minimal-line (editorial), lt-corner-plate (documentary bracket + kicker slot), lt-accent-slab (knockout name), lt-avatar-pill (creator pill), lt-typewriter-tag (mono typing), lt-gradient-sweep (gradient glow).",
|
|
798
854
|
inputSchema: {
|
|
799
855
|
type: "object",
|
|
800
856
|
properties: {
|
|
801
857
|
id: { type: "string" },
|
|
802
858
|
path: { type: "string" },
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
durationMs: { type: "number", description: "Default 5000ms" },
|
|
807
|
-
designType: {
|
|
859
|
+
name: { type: "string", description: "Primary text (person/brand name)" },
|
|
860
|
+
title: { type: "string", description: "Secondary line (role / handle / tagline)" },
|
|
861
|
+
templateId: {
|
|
808
862
|
type: "string",
|
|
809
|
-
description:
|
|
810
|
-
"slash-reveal | center-stack | split-horizontal | name-bar | border-frame | minimal-underline | box-reveal | corner-brackets. Default: slash-reveal.",
|
|
863
|
+
description: "lt-* design id. Default lt-vox-marker.",
|
|
811
864
|
},
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
backgroundColor: {
|
|
865
|
+
atMs: { type: "number", description: "Edited timeline time" },
|
|
866
|
+
aspectRatio: {
|
|
815
867
|
type: "string",
|
|
816
|
-
description: "
|
|
868
|
+
description: "16:9 | 9:16 | 1:1. Default 16:9 — match the project's aspect.",
|
|
817
869
|
},
|
|
818
|
-
|
|
819
|
-
type: "
|
|
820
|
-
description:
|
|
870
|
+
slots: {
|
|
871
|
+
type: "object",
|
|
872
|
+
description:
|
|
873
|
+
"Optional extra slot overrides (colors like accentColor/inkColor, or kicker for lt-corner-plate). Keys from motion_list. name/title args win over same-key entries.",
|
|
821
874
|
},
|
|
822
|
-
fontSize: { type: "number", description: "Primary text font size in px. Default 28" },
|
|
823
|
-
fontFamily: { type: "string", description: "CSS font family name. Default Inter" },
|
|
824
875
|
soundUrl: {
|
|
825
876
|
type: "string",
|
|
826
877
|
description:
|
|
827
|
-
'SFX
|
|
828
|
-
},
|
|
829
|
-
soundVolume: {
|
|
830
|
-
type: "number",
|
|
831
|
-
description: "Sound volume 0–1. Default 0.8.",
|
|
878
|
+
'SFX on enter. Bundled id (bundled:sound/<id>). Default bundled:sound/mouse-click. Pass "none" for silent.',
|
|
832
879
|
},
|
|
880
|
+
soundVolume: { type: "number", description: "Sound volume 0–1. Default 1." },
|
|
833
881
|
anchorSourceMs: {
|
|
834
882
|
type: "number",
|
|
835
883
|
description:
|
|
836
|
-
"Anchor
|
|
884
|
+
"Anchor to a SOURCE-time moment. Pass when atMs comes from a transcript word's startMs so the region survives later trims.",
|
|
837
885
|
},
|
|
838
886
|
anchorSourceEndMs: {
|
|
839
887
|
type: "number",
|
|
@@ -841,7 +889,7 @@ const TOOLS = [
|
|
|
841
889
|
},
|
|
842
890
|
expectedRevision: { type: "number" },
|
|
843
891
|
},
|
|
844
|
-
required: ["
|
|
892
|
+
required: ["name", "atMs"],
|
|
845
893
|
},
|
|
846
894
|
command: "project.add-lower-third",
|
|
847
895
|
},
|
|
@@ -893,7 +941,7 @@ const TOOLS = [
|
|
|
893
941
|
{
|
|
894
942
|
name: "project_set_region_sound",
|
|
895
943
|
description:
|
|
896
|
-
'Set or clear the sound effect on an existing region (zoom / motionGraphic /
|
|
944
|
+
'Set or clear the sound effect on an existing region (zoom / motionGraphic / fx). Use to swap the default zoom swoosh, add a ding to a motion graphic, or mute an effect sound. Pass soundUrl="none" to clear.',
|
|
897
945
|
inputSchema: {
|
|
898
946
|
type: "object",
|
|
899
947
|
properties: {
|
|
@@ -902,7 +950,7 @@ const TOOLS = [
|
|
|
902
950
|
regionId: { type: "string", description: "Target region id" },
|
|
903
951
|
regionType: {
|
|
904
952
|
type: "string",
|
|
905
|
-
enum: ["zoom", "motionGraphic", "
|
|
953
|
+
enum: ["zoom", "motionGraphic", "fx"],
|
|
906
954
|
description: "Region kind that owns the id",
|
|
907
955
|
},
|
|
908
956
|
soundUrl: {
|
|
@@ -1117,7 +1165,7 @@ const TOOLS = [
|
|
|
1117
1165
|
{
|
|
1118
1166
|
name: "project_move_clip",
|
|
1119
1167
|
description:
|
|
1120
|
-
"Reorder a clip on the main track. `clipId` identifies the clip; `toIndex` is its new 0-based position after the move. Project-level regions (zooms, trims, speeds, annotations, FX,
|
|
1168
|
+
"Reorder a clip on the main track. `clipId` identifies the clip; `toIndex` is its new 0-based position after the move. Project-level regions (zooms, trims, speeds, annotations, FX, media overlays, clip transforms) automatically migrate to follow their original clips so the user-perceived edits stay attached to the same content — a zoom that was 'into the explanation in clip 2' is still pointing at the same explanation after clip 2 moves to position 0. Per-clip transcripts ride on the clips themselves and don't need separate migration.",
|
|
1121
1169
|
inputSchema: {
|
|
1122
1170
|
type: "object",
|
|
1123
1171
|
properties: {
|
|
@@ -1140,7 +1188,7 @@ const TOOLS = [
|
|
|
1140
1188
|
{
|
|
1141
1189
|
name: "project_remove_region",
|
|
1142
1190
|
description:
|
|
1143
|
-
"Delete an existing region (zoom, trim, speed, annotation, fx,
|
|
1191
|
+
"Delete an existing region (zoom, trim, speed, annotation, fx, 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.",
|
|
1144
1192
|
inputSchema: {
|
|
1145
1193
|
type: "object",
|
|
1146
1194
|
properties: {
|
|
@@ -1149,7 +1197,7 @@ const TOOLS = [
|
|
|
1149
1197
|
regionType: {
|
|
1150
1198
|
type: "string",
|
|
1151
1199
|
description:
|
|
1152
|
-
"zoom | trim | speed | annotation | fx |
|
|
1200
|
+
"zoom | trim | speed | annotation | fx | overlay | clip-transform | audio-overlay",
|
|
1153
1201
|
},
|
|
1154
1202
|
regionId: { type: "string", description: "id of the region to delete" },
|
|
1155
1203
|
expectedRevision: { type: "number" },
|
|
@@ -1180,7 +1228,7 @@ const TOOLS = [
|
|
|
1180
1228
|
{
|
|
1181
1229
|
name: "project_update_region",
|
|
1182
1230
|
description:
|
|
1183
|
-
"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),
|
|
1231
|
+
"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), fx (atMs, durationMs, opacity, blendMode, speed), 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.",
|
|
1184
1232
|
inputSchema: {
|
|
1185
1233
|
type: "object",
|
|
1186
1234
|
properties: {
|
|
@@ -1189,13 +1237,13 @@ const TOOLS = [
|
|
|
1189
1237
|
regionType: {
|
|
1190
1238
|
type: "string",
|
|
1191
1239
|
description:
|
|
1192
|
-
"zoom | trim | speed | annotation | fx |
|
|
1240
|
+
"zoom | trim | speed | annotation | fx | overlay | clip-transform | audio-overlay",
|
|
1193
1241
|
},
|
|
1194
1242
|
regionId: { type: "string", description: "id of the region to update" },
|
|
1195
1243
|
patch: {
|
|
1196
1244
|
type: "object",
|
|
1197
1245
|
description:
|
|
1198
|
-
"Fields to update (partial). E.g. { depth: 4 } to change zoom depth,
|
|
1246
|
+
"Fields to update (partial). E.g. { depth: 4 } to change zoom depth, or { startMs: 2000, endMs: 15000, sourceStartMs: 4000 } to shift + trim an audio overlay (play seconds 4–17 of the source from the 2s mark on the timeline).",
|
|
1199
1247
|
},
|
|
1200
1248
|
expectedRevision: { type: "number" },
|
|
1201
1249
|
},
|
|
@@ -1713,7 +1761,7 @@ const TOOLS = [
|
|
|
1713
1761
|
{
|
|
1714
1762
|
name: "caption_set_template",
|
|
1715
1763
|
description:
|
|
1716
|
-
"Pick a caption template: classic, modern, minimal, bold, spotlight, boxed, neon, colored,
|
|
1764
|
+
"Pick a caption template: classic, modern, minimal, bold, spotlight, boxed, neon, colored, or editorial. `editorial` is a magazine-emphasis style: the word being spoken right now renders large (and takes an accent color) while the rest of the line shrinks, so one big word sweeps across the line in time with the speech.",
|
|
1717
1765
|
inputSchema: {
|
|
1718
1766
|
type: "object",
|
|
1719
1767
|
properties: {
|
|
@@ -1730,7 +1778,6 @@ const TOOLS = [
|
|
|
1730
1778
|
"boxed",
|
|
1731
1779
|
"neon",
|
|
1732
1780
|
"colored",
|
|
1733
|
-
"texture",
|
|
1734
1781
|
"editorial",
|
|
1735
1782
|
],
|
|
1736
1783
|
},
|
|
@@ -1744,7 +1791,7 @@ const TOOLS = [
|
|
|
1744
1791
|
{
|
|
1745
1792
|
name: "caption_set_style",
|
|
1746
1793
|
description:
|
|
1747
|
-
"Override specific style properties of the caption overlay without changing the template. All fields are optional — pass only what you want to change. positionY controls vertical placement (0=top, 100=bottom, default 85). fontSize
|
|
1794
|
+
"Override specific style properties of the caption overlay without changing the template. All fields are optional — pass only what you want to change. positionY controls vertical placement (0=top, 100=bottom, default 85). fontSize is in REM (e.g. '2.6rem'), matching the editor's Font size slider; it is clamped to 1.0–5.0rem (a px value is converted to rem), so you can't exceed the editor's max.",
|
|
1748
1795
|
inputSchema: {
|
|
1749
1796
|
type: "object",
|
|
1750
1797
|
properties: {
|
|
@@ -1767,11 +1814,9 @@ const TOOLS = [
|
|
|
1767
1814
|
},
|
|
1768
1815
|
strokeColor: { type: "string", description: "Text stroke/outline color" },
|
|
1769
1816
|
strokeWidth: { type: "number", description: "Text stroke width in px" },
|
|
1770
|
-
fontSize: {
|
|
1771
|
-
texture: {
|
|
1817
|
+
fontSize: {
|
|
1772
1818
|
type: "string",
|
|
1773
|
-
|
|
1774
|
-
description: "Texture for the 'texture' caption template. Ignored by other templates.",
|
|
1819
|
+
description: "Font size in REM, e.g. '2.6rem'. Clamped to 1.0–5.0rem (the editor's slider range).",
|
|
1775
1820
|
},
|
|
1776
1821
|
expectedRevision: { type: "number" },
|
|
1777
1822
|
},
|
|
@@ -2060,6 +2105,13 @@ const TOOLS = [
|
|
|
2060
2105
|
inputSchema: { type: "object", properties: {} },
|
|
2061
2106
|
command: "asset.list-fx",
|
|
2062
2107
|
},
|
|
2108
|
+
{
|
|
2109
|
+
name: "asset_list_transitions",
|
|
2110
|
+
description:
|
|
2111
|
+
"List every bundled transition (id, title, category, durationSeconds). Use the id with project_add_transition, centered on a cut.",
|
|
2112
|
+
inputSchema: { type: "object", properties: {} },
|
|
2113
|
+
command: "asset.list-transitions",
|
|
2114
|
+
},
|
|
2063
2115
|
{
|
|
2064
2116
|
name: "asset_list_music",
|
|
2065
2117
|
description:
|
|
@@ -2121,7 +2173,7 @@ const TOOLS = [
|
|
|
2121
2173
|
{
|
|
2122
2174
|
name: "export_start",
|
|
2123
2175
|
description:
|
|
2124
|
-
"Render the project to MP4 via the same Tier-3 PixiJS pipeline the editor's Export Video button uses (v1.24+ — convergence release). When an editor window is already open on the target project, the agent reuses it. Otherwise the agent spawns a hidden editor window for the duration of the render and closes it after. ASYNC — returns { jobId, outputPath }; call job_wait. Honours every region/style/caption/FX/
|
|
2176
|
+
"Render the project to MP4 via the same Tier-3 PixiJS pipeline the editor's Export Video button uses (v1.24+ — convergence release). When an editor window is already open on the target project, the agent reuses it. Otherwise the agent spawns a hidden editor window for the duration of the render and closes it after. ASYNC — returns { jobId, outputPath }; call job_wait. Honours every region/style/caption/FX/motion-graphic in the project. Video overlays (motion graphics added via project_add_motion_graphic) — opaque MP4 and transparent WebM/VP9+alpha — composite inline in the export pipeline; no extra call needed.",
|
|
2125
2177
|
inputSchema: {
|
|
2126
2178
|
type: "object",
|
|
2127
2179
|
properties: {
|
|
@@ -2348,7 +2400,7 @@ const TOOLS = [
|
|
|
2348
2400
|
const server = new Server(
|
|
2349
2401
|
{
|
|
2350
2402
|
name: "pandastudio",
|
|
2351
|
-
version: "1.
|
|
2403
|
+
version: "1.69.0",
|
|
2352
2404
|
},
|
|
2353
2405
|
{
|
|
2354
2406
|
capabilities: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@writepanda/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.69.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",
|