@writepanda/mcp 1.205.0 → 1.210.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 +203 -24
- package/package.json +1 -1
package/bin/server.mjs
CHANGED
|
@@ -577,7 +577,7 @@ const MOTION_ELEMENT_PROPS = {
|
|
|
577
577
|
content: {
|
|
578
578
|
type: ["object", "string", "array"],
|
|
579
579
|
description:
|
|
580
|
-
'keyword/chip/stamp/slam/behind/highlight { text } (or a bare string); count { value, to?, prefix?, suffix?, label?, decimals? } (value "20-30" = range); steps { items[], cues? (ms offsets from start) }; lowerThird { title, subtitle? (<=320 chars, wraps), look?: plate|plain|typewriter }; endCard { lines: [a, b] }; progress { label?, fromMs?, toMs? }; iconPop { emoji } | { icon }; frame { look: viewfinder | selection | corners, label? }; sticker { image: transparent PNG path, label? }; ticker { text (one story per line, <=2000 chars), label?, speed? (40-600 px/s) }; credits { title?, entries: [{ role?, name }] | "Role: Name" strings (<=200) }; crawl { title?, text (<=6000 chars), tilt? (0-80), turn? (-60..60) }. Any script, symbols and emoji draw.',
|
|
580
|
+
'keyword/chip/stamp/slam/behind/highlight { text } (or a bare string); count { value, to?, prefix?, suffix?, label?, decimals? } (value "20-30" = range); steps { items[], cues? (ms offsets from start) }; lowerThird { title, subtitle? (<=320 chars, wraps), look?: plate|plain|typewriter, typeSpeed? (typewriter pace, 5-80 chars/s, default ~22) }; endCard { lines: [a, b] }; progress { label?, fromMs?, toMs? }; iconPop { emoji } | { icon }; frame { look: viewfinder | selection | corners, label? }; sticker { image: transparent PNG path, label? }; ticker { text (one story per line, <=2000 chars), label?, speed? (40-600 px/s) }; credits { title?, entries: [{ role?, name }] | "Role: Name" strings (<=200) }; crawl { title?, text (<=6000 chars), tilt? (0-80), turn? (-60..60) }. Any script, symbols and emoji draw.',
|
|
581
581
|
},
|
|
582
582
|
atMs: { type: "number", description: "Start, edited ms. Or wordId." },
|
|
583
583
|
wordId: {
|
|
@@ -627,7 +627,11 @@ const MOTION_ELEMENT_PROPS = {
|
|
|
627
627
|
enum: ["auto", "none", "pop", "whoosh", "hit", "tick", "bell"],
|
|
628
628
|
description: "Role for project_compose_soundtrack.",
|
|
629
629
|
},
|
|
630
|
-
zIndex: {
|
|
630
|
+
zIndex: {
|
|
631
|
+
type: "number",
|
|
632
|
+
description:
|
|
633
|
+
"Stack order, higher on top (default 0). Front elements share one stack with media overlays and annotations at group base + zIndex (B-roll 0, overlays 1000, annotations 2000, front elements 3000), so by default they draw over both; -2500 drops one under the default overlays.",
|
|
634
|
+
},
|
|
631
635
|
anchor: { type: "string", enum: ["auto", "free"] },
|
|
632
636
|
};
|
|
633
637
|
const TOOLS = [
|
|
@@ -635,7 +639,7 @@ const TOOLS = [
|
|
|
635
639
|
{
|
|
636
640
|
name: "system_status",
|
|
637
641
|
description:
|
|
638
|
-
"App version and license; automationGated true = trial expired, every other tool fails; license.socialPublishing.allowed false = the plan has no Instagram/TikTok/social publishing (Creator, Team, Pro only). Call first.",
|
|
642
|
+
"App version and license; automationGated true = trial expired, or the Solo plan (license.agentEditing.allowed false: no agent editing, relay license.agentEditing.message to the user), and every other tool fails; license.socialPublishing.allowed false = the plan has no Instagram/TikTok/social publishing (Creator, Team, Pro only); license.exportQuality.allowed = the export_start qualities that work (free trial: draft 720p only; standard/high/ultra need a license). Call first.",
|
|
639
643
|
inputSchema: { type: "object", properties: {} },
|
|
640
644
|
command: "system.status",
|
|
641
645
|
},
|
|
@@ -725,7 +729,7 @@ const TOOLS = [
|
|
|
725
729
|
{
|
|
726
730
|
name: "system_get_transcription_language",
|
|
727
731
|
description:
|
|
728
|
-
"Workspace transcription language
|
|
732
|
+
"Workspace transcription language. auto = Parakeet TDT v3, which detects the language itself across 25 languages, English included: Bulgarian, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, German, Greek, Hungarian, Italian, Latvian, Lithuanian, Maltese, Polish, Portuguese, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish, Ukrainian. Anything else names a Whisper language.",
|
|
729
733
|
inputSchema: { type: "object", properties: {} },
|
|
730
734
|
command: "system.get-transcription-language",
|
|
731
735
|
},
|
|
@@ -752,7 +756,7 @@ const TOOLS = [
|
|
|
752
756
|
{
|
|
753
757
|
name: "system_set_transcription_language",
|
|
754
758
|
description:
|
|
755
|
-
"Set the workspace transcription language.
|
|
759
|
+
"Set the workspace transcription language. auto = Parakeet TDT v3, which detects the language itself across 25 languages, English included: Bulgarian, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, German, Greek, Hungarian, Italian, Latvian, Lithuanian, Maltese, Polish, Portuguese, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish, Ukrainian. For any of those (e.g. Romanian) use auto; their names are accepted and saved as auto. The other values use Whisper, a ~1.1 GB download: tell the user first (system.is-whisper-model-downloaded via pandastudio_call).",
|
|
756
760
|
inputSchema: {
|
|
757
761
|
type: "object",
|
|
758
762
|
properties: {
|
|
@@ -762,6 +766,30 @@ const TOOLS = [
|
|
|
762
766
|
"auto",
|
|
763
767
|
"english",
|
|
764
768
|
"en",
|
|
769
|
+
"bulgarian",
|
|
770
|
+
"croatian",
|
|
771
|
+
"czech",
|
|
772
|
+
"danish",
|
|
773
|
+
"dutch",
|
|
774
|
+
"estonian",
|
|
775
|
+
"finnish",
|
|
776
|
+
"french",
|
|
777
|
+
"german",
|
|
778
|
+
"greek",
|
|
779
|
+
"hungarian",
|
|
780
|
+
"italian",
|
|
781
|
+
"latvian",
|
|
782
|
+
"lithuanian",
|
|
783
|
+
"maltese",
|
|
784
|
+
"polish",
|
|
785
|
+
"portuguese",
|
|
786
|
+
"romanian",
|
|
787
|
+
"russian",
|
|
788
|
+
"slovak",
|
|
789
|
+
"slovenian",
|
|
790
|
+
"spanish",
|
|
791
|
+
"swedish",
|
|
792
|
+
"ukrainian",
|
|
765
793
|
"chinese",
|
|
766
794
|
"japanese",
|
|
767
795
|
"korean",
|
|
@@ -1048,8 +1076,14 @@ const TOOLS = [
|
|
|
1048
1076
|
},
|
|
1049
1077
|
{
|
|
1050
1078
|
name: "youtube_connect",
|
|
1051
|
-
description:
|
|
1052
|
-
|
|
1079
|
+
description:
|
|
1080
|
+
"Connect a YouTube account via browser sign-in (only when the user asks). Pass email to reconnect an existing account. permissionIssue set = the user unticked a Google permission: relay its message.",
|
|
1081
|
+
inputSchema: {
|
|
1082
|
+
type: "object",
|
|
1083
|
+
properties: {
|
|
1084
|
+
email: { type: "string", description: "Reconnect: that account's email." },
|
|
1085
|
+
},
|
|
1086
|
+
},
|
|
1053
1087
|
command: "youtube.connect",
|
|
1054
1088
|
},
|
|
1055
1089
|
{
|
|
@@ -1065,13 +1099,15 @@ const TOOLS = [
|
|
|
1065
1099
|
},
|
|
1066
1100
|
{
|
|
1067
1101
|
name: "youtube_list_accounts",
|
|
1068
|
-
description:
|
|
1102
|
+
description:
|
|
1103
|
+
"Connected YouTube accounts and channels (pick before export_publish_youtube). issues[] = accounts missing a Google permission (code youtube_permission_missing): relay message, follow howToFix (the user reconnects in Settings > YouTube, leaving every box ticked; you can't do the sign-in).",
|
|
1069
1104
|
inputSchema: { type: "object", properties: {} },
|
|
1070
1105
|
command: "youtube.list-accounts",
|
|
1071
1106
|
},
|
|
1072
1107
|
{
|
|
1073
1108
|
name: "youtube_list_channels",
|
|
1074
|
-
description:
|
|
1109
|
+
description:
|
|
1110
|
+
"Refresh an account's channel list from YouTube (bypasses cache). Error code youtube_permission_missing = channel permission unticked on Google's screen: relay message, follow howToFix; canStillPublish true = publish without channelId.",
|
|
1075
1111
|
inputSchema: {
|
|
1076
1112
|
type: "object",
|
|
1077
1113
|
properties: { accountId: { type: "string" } },
|
|
@@ -1082,7 +1118,7 @@ const TOOLS = [
|
|
|
1082
1118
|
{
|
|
1083
1119
|
name: "export_publish_youtube",
|
|
1084
1120
|
description:
|
|
1085
|
-
"Publish an export entry to YouTube. Slow. Check the entry's youtubeVideoId before republishing. Returns { videoUrl }.",
|
|
1121
|
+
"Publish an export entry to YouTube. Slow. Check the entry's youtubeVideoId before republishing. channelId optional (uploads go to the account's own channel; omit when channels can't be listed). Error code youtube_permission_missing: relay message, follow howToFix. Returns { videoUrl, channelId }.",
|
|
1086
1122
|
inputSchema: {
|
|
1087
1123
|
type: "object",
|
|
1088
1124
|
properties: {
|
|
@@ -1096,7 +1132,7 @@ const TOOLS = [
|
|
|
1096
1132
|
privacyStatus: { type: "string", enum: ["public", "unlisted", "private"] },
|
|
1097
1133
|
setThumbnail: { type: "boolean" },
|
|
1098
1134
|
},
|
|
1099
|
-
required: ["id", "accountId", "
|
|
1135
|
+
required: ["id", "accountId", "title"],
|
|
1100
1136
|
},
|
|
1101
1137
|
command: "export.publish-youtube",
|
|
1102
1138
|
},
|
|
@@ -1300,7 +1336,8 @@ const TOOLS = [
|
|
|
1300
1336
|
},
|
|
1301
1337
|
{
|
|
1302
1338
|
name: "project_current",
|
|
1303
|
-
description:
|
|
1339
|
+
description:
|
|
1340
|
+
"The project open in the editor, or null, plus the editor's LIVE playhead read at call time: playhead { ms, timeBase: 'edited', durationMs, inCut, playing } (null + playheadNote when unavailable). playhead.ms is EDITED (output) ms, what add-* atMs takes. Call it when the user says 'here' / 'at the playhead' / 'now': the chat context's playhead is from when the message was sent.",
|
|
1304
1341
|
inputSchema: { type: "object", properties: {} },
|
|
1305
1342
|
command: "project.current",
|
|
1306
1343
|
},
|
|
@@ -1379,7 +1416,7 @@ const TOOLS = [
|
|
|
1379
1416
|
{
|
|
1380
1417
|
name: "project_add_clip",
|
|
1381
1418
|
description:
|
|
1382
|
-
"Append or insert a video clip, or a still image shown for durationMs, on the main track (later content moves with it).
|
|
1419
|
+
"Append or insert a video clip, or a still image shown for durationMs, on the main track (later content moves with it). atMs (edited time) inserts at that moment, splitting the clip under it; add replaceToMs to replace [atMs, replaceToMs) with the clip (e.g. a re-recorded take).",
|
|
1383
1420
|
inputSchema: {
|
|
1384
1421
|
type: "object",
|
|
1385
1422
|
properties: {
|
|
@@ -1390,6 +1427,14 @@ const TOOLS = [
|
|
|
1390
1427
|
fill: { type: "boolean", description: "Images: cover the frame (default true)." },
|
|
1391
1428
|
webcam: { type: "string", description: "Guest source: a two-speaker podcast clip." },
|
|
1392
1429
|
atIndex: { type: "number", description: "0-based; omit = append." },
|
|
1430
|
+
atMs: {
|
|
1431
|
+
type: "number",
|
|
1432
|
+
description: "Insert at this edited ms (splits the clip there; not with atIndex).",
|
|
1433
|
+
},
|
|
1434
|
+
replaceToMs: {
|
|
1435
|
+
type: "number",
|
|
1436
|
+
description: "With atMs: cut [atMs, replaceToMs) (a trim) and put the clip there.",
|
|
1437
|
+
},
|
|
1393
1438
|
expectedRevision: { type: "number" },
|
|
1394
1439
|
},
|
|
1395
1440
|
required: ["media"],
|
|
@@ -1432,6 +1477,66 @@ const TOOLS = [
|
|
|
1432
1477
|
},
|
|
1433
1478
|
command: "project.add-podcast-clip",
|
|
1434
1479
|
},
|
|
1480
|
+
{
|
|
1481
|
+
name: "podcast_open_host",
|
|
1482
|
+
description: "Open or focus the live podcast host window. Call podcast_status for the session code and guest link once it loads.",
|
|
1483
|
+
inputSchema: {
|
|
1484
|
+
type: "object",
|
|
1485
|
+
properties: {
|
|
1486
|
+
sessionCode: { type: "string", description: "Resume an existing session." },
|
|
1487
|
+
projectPath: { type: "string", description: "Matching podcast project when resuming." },
|
|
1488
|
+
},
|
|
1489
|
+
},
|
|
1490
|
+
command: "podcast.open-host",
|
|
1491
|
+
},
|
|
1492
|
+
...[
|
|
1493
|
+
["status", "Read the live podcast session code, guest link, participants, recording, and sharing state."],
|
|
1494
|
+
["start-recording", "Start recording the host and signal connected guests to record. Returns once recording has really started; fails with the reason otherwise."],
|
|
1495
|
+
["stop-recording", "Stop recording and finalize podcast media. Check podcast_status for finalization and guest uploads."],
|
|
1496
|
+
["start-screen-share", "Open the desktop picker to share and record the host screen during a podcast. Waits for the host to choose; fails if the picker is cancelled or capture fails."],
|
|
1497
|
+
["stop-screen-share", "Stop and finalize the host's podcast screen share."],
|
|
1498
|
+
["open-in-editor", "Open the finished podcast in the editor when guest media has arrived."],
|
|
1499
|
+
].map(([noun, description]) => ({
|
|
1500
|
+
name: `podcast_${noun.replaceAll("-", "_")}`,
|
|
1501
|
+
description,
|
|
1502
|
+
inputSchema: { type: "object", properties: {} },
|
|
1503
|
+
command: `podcast.${noun}`,
|
|
1504
|
+
})),
|
|
1505
|
+
{
|
|
1506
|
+
name: "project_set_podcast_source_crop",
|
|
1507
|
+
description:
|
|
1508
|
+
"Frame one podcast camera or screen-share source independently. Use source=host|guest|guest-2|guest-3|share:0; normalized x,y,width,height. 0,0,1,1 resets the crop. Preview and export use the same framing.",
|
|
1509
|
+
inputSchema: {
|
|
1510
|
+
type: "object",
|
|
1511
|
+
properties: {
|
|
1512
|
+
id: { type: "string" },
|
|
1513
|
+
path: { type: "string" },
|
|
1514
|
+
clipId: { type: "string" },
|
|
1515
|
+
source: { type: "string", description: "host, guest, guest-2, guest-3, or share:<index>." },
|
|
1516
|
+
x: { type: "number", description: "Left edge, 0-1." },
|
|
1517
|
+
y: { type: "number", description: "Top edge, 0-1." },
|
|
1518
|
+
width: { type: "number", description: "Crop width, >0 to 1." },
|
|
1519
|
+
height: { type: "number", description: "Crop height, >0 to 1." },
|
|
1520
|
+
expectedRevision: { type: "number" },
|
|
1521
|
+
},
|
|
1522
|
+
required: ["clipId", "source", "x", "y", "width", "height"],
|
|
1523
|
+
},
|
|
1524
|
+
command: "project.set-podcast-source-crop",
|
|
1525
|
+
},
|
|
1526
|
+
{
|
|
1527
|
+
name: "project_list_podcast_screen_shares",
|
|
1528
|
+
description:
|
|
1529
|
+
"List the screen-share intervals shown on the podcast editor timeline. Returns speaker, clip-local and merged-source timing, edited timing after trims/speed, and whether each interval is visible. Read-only.",
|
|
1530
|
+
inputSchema: {
|
|
1531
|
+
type: "object",
|
|
1532
|
+
properties: {
|
|
1533
|
+
id: { type: "string" },
|
|
1534
|
+
path: { type: "string" },
|
|
1535
|
+
clipId: { type: "string", description: "Optional podcast clip filter." },
|
|
1536
|
+
},
|
|
1537
|
+
},
|
|
1538
|
+
command: "project.list-podcast-screen-shares",
|
|
1539
|
+
},
|
|
1435
1540
|
{
|
|
1436
1541
|
name: "project_set_participant_offset",
|
|
1437
1542
|
description: "Nudge one guest's A/V sync on a podcast composite (host is the reference).",
|
|
@@ -1560,7 +1665,7 @@ const TOOLS = [
|
|
|
1560
1665
|
{
|
|
1561
1666
|
name: "project_add_designed_segment",
|
|
1562
1667
|
description:
|
|
1563
|
-
"Designed segment: host live on one half, a graphic panel on the other, in one call. The panel is a full-frame transparent render with the camera's half left empty (
|
|
1668
|
+
"Designed segment: host live on one half, a graphic panel on the other, in one call. The panel is a full-frame transparent render with the camera's half left empty (skill_read file='motion-templates' section='designed segments').",
|
|
1564
1669
|
inputSchema: {
|
|
1565
1670
|
type: "object",
|
|
1566
1671
|
properties: {
|
|
@@ -2922,7 +3027,7 @@ const TOOLS = [
|
|
|
2922
3027
|
{
|
|
2923
3028
|
name: "project_update_region",
|
|
2924
3029
|
description:
|
|
2925
|
-
"Patch a region; unspecified fields are kept. Patchable: zoom (depth, focusX, focusY, focusMode static|auto), trim / speed (startMs, endMs, speed, rampIn, rampOut, preservePitch, freezeMs, reverse, reverseAudio), fx (atMs, durationMs, opacity, blendMode, speed), annotation, overlay (x, y, width, height in canvas %, layer, opacity, blendMode, muted, volume, loop, motionBlur), adjustment (startMs, endMs, blendMode), motion (motionBlur), clip-transform (startMs, endMs, preset, transitionMs, easing, bezier), background-effect (as project_add_background_effect), audio-overlay (startMs, endMs, sourceStartMs, volume 0-2, fadeIn, fadeOut).",
|
|
3030
|
+
"Patch a region; unspecified fields are kept. Patchable: zoom (depth, focusX, focusY, focusMode static|auto), trim / speed (startMs, endMs, speed, rampIn, rampOut, preservePitch, freezeMs, reverse, reverseAudio), fx (atMs, durationMs, opacity, blendMode, speed, zIndex), annotation (zIndex), overlay (x, y, width, height in canvas %, layer, opacity, blendMode, muted, volume, loop, motionBlur, zIndex), adjustment (startMs, endMs, blendMode), motion (motionBlur), clip-transform (startMs, endMs, preset, transitionMs, easing, bezier), background-effect (as project_add_background_effect), audio-overlay (startMs, endMs, sourceStartMs, volume 0-2, fadeIn, fadeOut).",
|
|
2926
3031
|
inputSchema: {
|
|
2927
3032
|
type: "object",
|
|
2928
3033
|
properties: {
|
|
@@ -2931,7 +3036,11 @@ const TOOLS = [
|
|
|
2931
3036
|
path: { type: "string" },
|
|
2932
3037
|
regionType: { type: "string", enum: REGION_TYPES },
|
|
2933
3038
|
regionId: { type: "string" },
|
|
2934
|
-
patch: {
|
|
3039
|
+
patch: {
|
|
3040
|
+
type: "object",
|
|
3041
|
+
description:
|
|
3042
|
+
"e.g. { depth: 4 }; null clears a value. zIndex (overlay / annotation / fx): stack order, higher on top; overlays, annotations and front motion elements share one stack at group base + zIndex (B-roll 0, overlays 1000, annotations 2000, motion elements 3000).",
|
|
3043
|
+
},
|
|
2935
3044
|
expectedRevision: { type: "number" },
|
|
2936
3045
|
},
|
|
2937
3046
|
required: ["regionType", "regionId", "patch"],
|
|
@@ -3140,13 +3249,19 @@ const TOOLS = [
|
|
|
3140
3249
|
},
|
|
3141
3250
|
{
|
|
3142
3251
|
name: "project_set_export_settings",
|
|
3143
|
-
description:
|
|
3252
|
+
description:
|
|
3253
|
+
"Project export defaults (Export dialog and export_start). quality good and source need a license: a free trial gets quality_requires_license, use medium.",
|
|
3144
3254
|
inputSchema: {
|
|
3145
3255
|
type: "object",
|
|
3146
3256
|
properties: {
|
|
3147
3257
|
id: { type: "string" },
|
|
3148
3258
|
path: { type: "string" },
|
|
3149
|
-
quality: {
|
|
3259
|
+
quality: {
|
|
3260
|
+
type: "string",
|
|
3261
|
+
enum: ["medium", "good", "source"],
|
|
3262
|
+
description:
|
|
3263
|
+
"medium 720p, good 1080p, source = source resolution (good/source license only).",
|
|
3264
|
+
},
|
|
3150
3265
|
format: { type: "string", enum: ["mp4"] },
|
|
3151
3266
|
normalizeLoudness: {
|
|
3152
3267
|
type: ["boolean", "string"],
|
|
@@ -3574,7 +3689,7 @@ const TOOLS = [
|
|
|
3574
3689
|
{
|
|
3575
3690
|
name: "transcript_transcribe",
|
|
3576
3691
|
description:
|
|
3577
|
-
"Transcribe clips with word timestamps (default: only clips without words). To REDO a transcript (wrong language, bad run) fix the language first, then force: true (all clips) or clipId. Word fixes are re-applied; tell the user about result droppedWordEdits[] (fixes that may need redoing). ASYNC: { jobId }, job_wait.",
|
|
3692
|
+
"Transcribe clips with word timestamps (default: only clips without words). To REDO a transcript (wrong language, bad run) fix the language first, then force: true (all clips) or clipId. Word fixes are re-applied; tell the user about result droppedWordEdits[] (fixes that may need redoing). Each clip is transcribed only over the part it plays (head trim to out-point, e.g. one half of a split; result transcribedRanges[]). ASYNC: { jobId }, job_wait.",
|
|
3578
3693
|
inputSchema: {
|
|
3579
3694
|
type: "object",
|
|
3580
3695
|
properties: {
|
|
@@ -4520,6 +4635,24 @@ const TOOLS = [
|
|
|
4520
4635
|
},
|
|
4521
4636
|
command: "recipe.list",
|
|
4522
4637
|
},
|
|
4638
|
+
{
|
|
4639
|
+
name: "recipe_prepare_reference",
|
|
4640
|
+
description:
|
|
4641
|
+
"Prepare evidence for learning a reference video's editing style, without editing any project. Async job: whole-video contact sheets, dense motion samples, transition candidates and mixed-audio excerpts. Inspect the evidence and save a portable reference-specific recipe; do not assume generic effects or exact source sound files.",
|
|
4642
|
+
inputSchema: {
|
|
4643
|
+
type: "object",
|
|
4644
|
+
properties: {
|
|
4645
|
+
file: {
|
|
4646
|
+
type: "string",
|
|
4647
|
+
description: "Absolute local video path (download links with media_download_url first).",
|
|
4648
|
+
},
|
|
4649
|
+
title: { type: "string" },
|
|
4650
|
+
sourceUrl: { type: "string" },
|
|
4651
|
+
},
|
|
4652
|
+
required: ["file"],
|
|
4653
|
+
},
|
|
4654
|
+
command: "recipe.prepare-reference",
|
|
4655
|
+
},
|
|
4523
4656
|
{
|
|
4524
4657
|
name: "recipe_pick",
|
|
4525
4658
|
description:
|
|
@@ -4732,7 +4865,8 @@ const TOOLS = [
|
|
|
4732
4865
|
},
|
|
4733
4866
|
{
|
|
4734
4867
|
name: "motion_craft",
|
|
4735
|
-
description:
|
|
4868
|
+
description:
|
|
4869
|
+
"Launch / promo film craft library (story arcs, blueprints, GSAP rules, design presets): no id lists topics; id returns the doc. An unknown id fails with the closest ids and every valid id. Not the custom motion-graphic HTML contract: that is skill_read section='custom motion graphics'.",
|
|
4736
4870
|
inputSchema: {
|
|
4737
4871
|
type: "object",
|
|
4738
4872
|
properties: {
|
|
@@ -4782,7 +4916,7 @@ const TOOLS = [
|
|
|
4782
4916
|
{
|
|
4783
4917
|
name: "motion_render_html",
|
|
4784
4918
|
description:
|
|
4785
|
-
"Render custom HTML to video when no template fits. Contract (
|
|
4919
|
+
"Render custom HTML to video when no template fits. Contract (skill_read section='custom motion graphics'; render details in skill_read file='custom-html'): a paused GSAP timeline at window.__timelines[<data-composition-id>] and a root with data-composition-id / width / height / duration. Lint and STATIC_RENDER failures must be fixed, never placed. ASYNC: { jobId }.",
|
|
4786
4920
|
inputSchema: {
|
|
4787
4921
|
type: "object",
|
|
4788
4922
|
properties: {
|
|
@@ -4862,6 +4996,44 @@ const TOOLS = [
|
|
|
4862
4996
|
},
|
|
4863
4997
|
|
|
4864
4998
|
// ── assets ──────────────────────────────────────────────────────
|
|
4999
|
+
{
|
|
5000
|
+
name: "asset_list_sound_patterns",
|
|
5001
|
+
description:
|
|
5002
|
+
"List shared motion sound recipes: counted entrances, scroll ratchets, slides, swipes and presses. Use asset_plan_sound_pattern with actual animation timings.",
|
|
5003
|
+
inputSchema: { type: "object", properties: { query: { type: "string" } } },
|
|
5004
|
+
command: "asset.list-sound-patterns",
|
|
5005
|
+
},
|
|
5006
|
+
{
|
|
5007
|
+
name: "asset_plan_sound_pattern",
|
|
5008
|
+
description:
|
|
5009
|
+
"Plan motion-synced sounds without writing a project. Returns cues for project_add_sound_cues; use a unique group per animation. One cue per actual event, variant rotation, quiet starting gain, tails bounded by settle. Preview below narration.",
|
|
5010
|
+
inputSchema: {
|
|
5011
|
+
type: "object",
|
|
5012
|
+
properties: {
|
|
5013
|
+
pattern: { type: "string", description: "Id from asset_list_sound_patterns." },
|
|
5014
|
+
atMs: { type: "integer", minimum: 0, description: "Edited-timeline motion start." },
|
|
5015
|
+
endMs: { type: "integer", description: "Edited-timeline motion end/settle." },
|
|
5016
|
+
eventOffsetsMs: {
|
|
5017
|
+
type: "array",
|
|
5018
|
+
items: { type: "integer", minimum: 0 },
|
|
5019
|
+
minItems: 1,
|
|
5020
|
+
maxItems: 500,
|
|
5021
|
+
description:
|
|
5022
|
+
"Actual entrance/crossing/gesture offsets relative to atMs; strictly increasing. Follow easing, not an assumed uniform stagger.",
|
|
5023
|
+
},
|
|
5024
|
+
volume: { type: "number", minimum: 0, maximum: 2 },
|
|
5025
|
+
sounds: {
|
|
5026
|
+
type: "array",
|
|
5027
|
+
items: { type: "string" },
|
|
5028
|
+
minItems: 1,
|
|
5029
|
+
maxItems: 500,
|
|
5030
|
+
description: "Optional alternate ids/paths, rotated.",
|
|
5031
|
+
},
|
|
5032
|
+
},
|
|
5033
|
+
required: ["pattern", "atMs", "endMs", "eventOffsetsMs"],
|
|
5034
|
+
},
|
|
5035
|
+
command: "asset.plan-sound-pattern",
|
|
5036
|
+
},
|
|
4865
5037
|
{
|
|
4866
5038
|
name: "asset_list_emoji",
|
|
4867
5039
|
description: "List animated emoji for project_add_emoji.",
|
|
@@ -4985,14 +5157,19 @@ const TOOLS = [
|
|
|
4985
5157
|
{
|
|
4986
5158
|
name: "export_start",
|
|
4987
5159
|
description:
|
|
4988
|
-
"Render the project to MP4. ASYNC: { jobId, outputPath }; job_wait. Tell the user any warning and the result's loudness before / after.",
|
|
5160
|
+
"Render the project to MP4. ASYNC: { jobId, outputPath, quality }; job_wait. Tell the user any warning and the result's loudness before / after. Free trial: draft (720p) only (system_status license.exportQuality); standard/high/ultra fail with quality_requires_license.",
|
|
4989
5161
|
inputSchema: {
|
|
4990
5162
|
type: "object",
|
|
4991
5163
|
properties: {
|
|
4992
5164
|
id: { type: "string" },
|
|
4993
5165
|
path: { type: "string" },
|
|
4994
5166
|
outputPath: { type: "string" },
|
|
4995
|
-
quality: {
|
|
5167
|
+
quality: {
|
|
5168
|
+
type: "string",
|
|
5169
|
+
enum: ["draft", "standard", "high", "ultra"],
|
|
5170
|
+
description:
|
|
5171
|
+
"draft 720p, standard 1080p, high/ultra source resolution (standard and up: license only). Omit = high, or draft on a trial.",
|
|
5172
|
+
},
|
|
4996
5173
|
normalizeLoudness: {
|
|
4997
5174
|
type: ["boolean", "string"],
|
|
4998
5175
|
description: "streaming / podcast / off; omit = project setting.",
|
|
@@ -5107,7 +5284,7 @@ const TOOLS = [
|
|
|
5107
5284
|
{
|
|
5108
5285
|
name: "clips_export",
|
|
5109
5286
|
description:
|
|
5110
|
-
"Export a clip set's finished clips to MP4 (all, or clipIds) into Movies/PandaStudio Clips/<video
|
|
5287
|
+
"Export a clip set's finished clips to MP4 (all, or clipIds) into Movies/PandaStudio Clips/<video>/, at standard quality (1080p; 720p on a free trial). Async: returns { jobId, outputDir }; job_wait for { exported[] }.",
|
|
5111
5288
|
inputSchema: {
|
|
5112
5289
|
type: "object",
|
|
5113
5290
|
properties: {
|
|
@@ -5425,6 +5602,8 @@ const INSTRUCTIONS = `PandaStudio is a desktop video editor; these tools drive t
|
|
|
5425
5602
|
|
|
5426
5603
|
Start with system_status. Unknown arguments are rejected. Verbs without a tool of their own (system_list_commands) go through pandastudio_call.
|
|
5427
5604
|
|
|
5605
|
+
Read-only tools (project_read, transcript_get / _search / _find_issues, audio_probe, project_render_frame / _render_sheet, timeline_*, ...) use the project open in the editor when you pass no id or path; edits always need the id.
|
|
5606
|
+
|
|
5428
5607
|
Before an editing pass, read the skill's "Which tool for which moment" section (skill_read section="Which tool for which moment").
|
|
5429
5608
|
|
|
5430
5609
|
"Edit my video" / "make this a Short" with no specifics = this pipeline, in order. Confirm scope once ("full polish, or just part of it?"), then run it all:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@writepanda/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.210.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",
|