@writepanda/mcp 1.210.0 → 1.213.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 +183 -16
- package/package.json +1 -1
package/bin/server.mjs
CHANGED
|
@@ -212,6 +212,7 @@ async function callPandastudio(command, args = {}) {
|
|
|
212
212
|
} catch {
|
|
213
213
|
body = { raw: text };
|
|
214
214
|
}
|
|
215
|
+
if (res.status === 409 && body?.details?.code === "revision_conflict") return body;
|
|
215
216
|
if (res.status >= 400) {
|
|
216
217
|
throw new Error(`HTTP ${res.status}: ${body?.error ?? text.slice(0, 200)}`);
|
|
217
218
|
}
|
|
@@ -635,6 +636,84 @@ const MOTION_ELEMENT_PROPS = {
|
|
|
635
636
|
anchor: { type: "string", enum: ["auto", "free"] },
|
|
636
637
|
};
|
|
637
638
|
const TOOLS = [
|
|
639
|
+
{
|
|
640
|
+
name: "folder_list",
|
|
641
|
+
description:
|
|
642
|
+
"Manage flat folders in the active workspace. Delete keeps projects unless deleteProjects is true.",
|
|
643
|
+
inputSchema: {
|
|
644
|
+
type: "object",
|
|
645
|
+
properties: {},
|
|
646
|
+
required: [],
|
|
647
|
+
},
|
|
648
|
+
command: "folder.list",
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
name: "folder_create",
|
|
652
|
+
description:
|
|
653
|
+
"Manage flat folders in the active workspace. Delete keeps projects unless deleteProjects is true.",
|
|
654
|
+
inputSchema: {
|
|
655
|
+
type: "object",
|
|
656
|
+
properties: {
|
|
657
|
+
name: {
|
|
658
|
+
type: "string",
|
|
659
|
+
},
|
|
660
|
+
},
|
|
661
|
+
required: ["name"],
|
|
662
|
+
},
|
|
663
|
+
command: "folder.create",
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
name: "folder_rename",
|
|
667
|
+
description:
|
|
668
|
+
"Manage flat folders in the active workspace. Delete keeps projects unless deleteProjects is true.",
|
|
669
|
+
inputSchema: {
|
|
670
|
+
type: "object",
|
|
671
|
+
properties: {
|
|
672
|
+
id: {
|
|
673
|
+
type: "string",
|
|
674
|
+
},
|
|
675
|
+
name: {
|
|
676
|
+
type: "string",
|
|
677
|
+
},
|
|
678
|
+
},
|
|
679
|
+
required: ["id", "name"],
|
|
680
|
+
},
|
|
681
|
+
command: "folder.rename",
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
name: "folder_delete",
|
|
685
|
+
description:
|
|
686
|
+
"Manage flat folders in the active workspace. Delete keeps projects unless deleteProjects is true.",
|
|
687
|
+
inputSchema: {
|
|
688
|
+
type: "object",
|
|
689
|
+
properties: {
|
|
690
|
+
id: {
|
|
691
|
+
type: "string",
|
|
692
|
+
},
|
|
693
|
+
deleteProjects: {
|
|
694
|
+
type: "boolean",
|
|
695
|
+
default: false,
|
|
696
|
+
},
|
|
697
|
+
},
|
|
698
|
+
required: ["id"],
|
|
699
|
+
},
|
|
700
|
+
command: "folder.delete",
|
|
701
|
+
},
|
|
702
|
+
{
|
|
703
|
+
name: "folder_contents",
|
|
704
|
+
description:
|
|
705
|
+
"Manage flat folders in the active workspace. Delete keeps projects unless deleteProjects is true.",
|
|
706
|
+
inputSchema: {
|
|
707
|
+
type: "object",
|
|
708
|
+
properties: {
|
|
709
|
+
id: {
|
|
710
|
+
type: "string",
|
|
711
|
+
},
|
|
712
|
+
},
|
|
713
|
+
required: ["id"],
|
|
714
|
+
},
|
|
715
|
+
command: "folder.contents",
|
|
716
|
+
},
|
|
638
717
|
// ── system + discovery ──────────────────────────────────────────
|
|
639
718
|
{
|
|
640
719
|
name: "system_status",
|
|
@@ -1272,6 +1351,8 @@ const TOOLS = [
|
|
|
1272
1351
|
inputSchema: {
|
|
1273
1352
|
type: "object",
|
|
1274
1353
|
properties: {
|
|
1354
|
+
folderId: { type: ["string", "null"], description: "Folder UUID" },
|
|
1355
|
+
topLevel: { type: "boolean" },
|
|
1275
1356
|
allWorkspaces: { type: "boolean" },
|
|
1276
1357
|
sortBy: { type: "string", enum: ["modifiedAt", "createdAt", "name"] },
|
|
1277
1358
|
order: { type: "string", enum: ["desc", "asc"] },
|
|
@@ -1287,6 +1368,7 @@ const TOOLS = [
|
|
|
1287
1368
|
inputSchema: {
|
|
1288
1369
|
type: "object",
|
|
1289
1370
|
properties: {
|
|
1371
|
+
folderId: { type: ["string", "null"], description: "Folder UUID" },
|
|
1290
1372
|
id: { type: "string" },
|
|
1291
1373
|
path: { type: "string" },
|
|
1292
1374
|
folder: { type: "string" },
|
|
@@ -1314,6 +1396,7 @@ const TOOLS = [
|
|
|
1314
1396
|
inputSchema: {
|
|
1315
1397
|
type: "object",
|
|
1316
1398
|
properties: {
|
|
1399
|
+
folderId: { type: ["string", "null"], description: "Folder UUID" },
|
|
1317
1400
|
id: { type: "string" },
|
|
1318
1401
|
path: { type: "string" },
|
|
1319
1402
|
},
|
|
@@ -1376,6 +1459,9 @@ const TOOLS = [
|
|
|
1376
1459
|
inputSchema: {
|
|
1377
1460
|
type: "object",
|
|
1378
1461
|
properties: {
|
|
1462
|
+
folderId: { type: ["string", "null"], description: "Folder UUID" },
|
|
1463
|
+
parentProjectId: { type: "string" },
|
|
1464
|
+
originKind: { type: "string", enum: ["agent", "recipe"] },
|
|
1379
1465
|
name: { type: "string" },
|
|
1380
1466
|
withMedia: { type: "array", items: { type: "string" } },
|
|
1381
1467
|
},
|
|
@@ -1390,6 +1476,7 @@ const TOOLS = [
|
|
|
1390
1476
|
inputSchema: {
|
|
1391
1477
|
type: "object",
|
|
1392
1478
|
properties: {
|
|
1479
|
+
folderId: { type: ["string", "null"], description: "Folder UUID" },
|
|
1393
1480
|
exportId: { type: "string" },
|
|
1394
1481
|
shotId: { type: "string" },
|
|
1395
1482
|
aspectRatio: { type: "string", description: "Default 9:16." },
|
|
@@ -1479,7 +1566,8 @@ const TOOLS = [
|
|
|
1479
1566
|
},
|
|
1480
1567
|
{
|
|
1481
1568
|
name: "podcast_open_host",
|
|
1482
|
-
description:
|
|
1569
|
+
description:
|
|
1570
|
+
"Open or focus the live podcast host window. Call podcast_status for the session code and guest link once it loads.",
|
|
1483
1571
|
inputSchema: {
|
|
1484
1572
|
type: "object",
|
|
1485
1573
|
properties: {
|
|
@@ -1490,10 +1578,22 @@ const TOOLS = [
|
|
|
1490
1578
|
command: "podcast.open-host",
|
|
1491
1579
|
},
|
|
1492
1580
|
...[
|
|
1493
|
-
[
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1581
|
+
[
|
|
1582
|
+
"status",
|
|
1583
|
+
"Read the live podcast session code, guest link, participants, recording, and sharing state.",
|
|
1584
|
+
],
|
|
1585
|
+
[
|
|
1586
|
+
"start-recording",
|
|
1587
|
+
"Start recording the host and signal connected guests to record. Returns once recording has really started; fails with the reason otherwise.",
|
|
1588
|
+
],
|
|
1589
|
+
[
|
|
1590
|
+
"stop-recording",
|
|
1591
|
+
"Stop recording and finalize podcast media. Check podcast_status for finalization and guest uploads.",
|
|
1592
|
+
],
|
|
1593
|
+
[
|
|
1594
|
+
"start-screen-share",
|
|
1595
|
+
"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.",
|
|
1596
|
+
],
|
|
1497
1597
|
["stop-screen-share", "Stop and finalize the host's podcast screen share."],
|
|
1498
1598
|
["open-in-editor", "Open the finished podcast in the editor when guest media has arrived."],
|
|
1499
1599
|
].map(([noun, description]) => ({
|
|
@@ -1573,7 +1673,7 @@ const TOOLS = [
|
|
|
1573
1673
|
{
|
|
1574
1674
|
name: "project_update_motion_graphic",
|
|
1575
1675
|
description:
|
|
1576
|
-
"Edit a generated graphic (overlay with generatedFrom) and re-render it in place, keeping timing and position. ASYNC: { jobId }.",
|
|
1676
|
+
"Edit a generated graphic (overlay with generatedFrom) and re-render it in place, keeping timing and position. ASYNC: { jobId }. Concurrent saves are merged and retried (three attempts). Exhausted conflicts report code revision_conflict / status 409 (job.errorDetails for async jobs).",
|
|
1577
1677
|
inputSchema: {
|
|
1578
1678
|
type: "object",
|
|
1579
1679
|
properties: {
|
|
@@ -1597,7 +1697,7 @@ const TOOLS = [
|
|
|
1597
1697
|
{
|
|
1598
1698
|
name: "project_add_emoji",
|
|
1599
1699
|
description:
|
|
1600
|
-
"Place an animated emoji overlay. ASYNC: { jobId }; job_wait gives result.overlayId.",
|
|
1700
|
+
"Place an animated emoji overlay. ASYNC: { jobId }; job_wait gives result.overlayId. Concurrent saves are merged and retried (three attempts). Exhausted conflicts report code revision_conflict / status 409 (job.errorDetails for async jobs).",
|
|
1601
1701
|
inputSchema: {
|
|
1602
1702
|
type: "object",
|
|
1603
1703
|
properties: {
|
|
@@ -1803,7 +1903,7 @@ const TOOLS = [
|
|
|
1803
1903
|
{
|
|
1804
1904
|
name: "project_add_lower_third",
|
|
1805
1905
|
description:
|
|
1806
|
-
"Render a nameplate and place it at atMs in one call, laid out for the project's aspect. ASYNC: { jobId }; job_wait gives result.overlayId once placed.",
|
|
1906
|
+
"Render a nameplate and place it at atMs in one call, laid out for the project's aspect. ASYNC: { jobId }; job_wait gives result.overlayId once placed. Concurrent saves are merged and retried (three attempts). Exhausted conflicts report code revision_conflict / status 409 (job.errorDetails for async jobs).",
|
|
1807
1907
|
inputSchema: {
|
|
1808
1908
|
type: "object",
|
|
1809
1909
|
properties: {
|
|
@@ -1840,7 +1940,7 @@ const TOOLS = [
|
|
|
1840
1940
|
{
|
|
1841
1941
|
name: "project_add_title_behind",
|
|
1842
1942
|
description:
|
|
1843
|
-
"1-3 huge words at head height BEHIND the presenter. ASYNC: job_wait gives regionId, face.",
|
|
1943
|
+
"1-3 huge words at head height BEHIND the presenter. ASYNC: job_wait gives regionId, face. Concurrent saves are merged and retried (three attempts). Exhausted conflicts report code revision_conflict / status 409 (job.errorDetails for async jobs).",
|
|
1844
1944
|
inputSchema: {
|
|
1845
1945
|
type: "object",
|
|
1846
1946
|
properties: {
|
|
@@ -2587,7 +2687,7 @@ const TOOLS = [
|
|
|
2587
2687
|
{
|
|
2588
2688
|
name: "audio_probe",
|
|
2589
2689
|
description:
|
|
2590
|
-
"Per-clip audio stats: hasAudio, mean/max dB, silence spans (source time), plus audio overlays. A few seconds per clip.",
|
|
2690
|
+
"Per-clip audio stats: hasAudio, integratedLufs (null if unavailable/silent), tooQuiet (< -30 LUFS), mean/max dB, silence spans (source time), plus audio overlays. A few seconds per clip.",
|
|
2591
2691
|
inputSchema: {
|
|
2592
2692
|
type: "object",
|
|
2593
2693
|
properties: {
|
|
@@ -2987,7 +3087,7 @@ const TOOLS = [
|
|
|
2987
3087
|
{
|
|
2988
3088
|
name: "project_center_camera_on_face",
|
|
2989
3089
|
description:
|
|
2990
|
-
"Keep the presenter's face centred in the camera card by tracking it (can take a minute). clear: true turns it off.",
|
|
3090
|
+
"Keep the presenter's face centred in the camera card by tracking it (can take a minute). clear: true turns it off. Concurrent saves are merged and retried (three attempts). Exhausted conflicts report code revision_conflict / status 409 (job.errorDetails for async jobs).",
|
|
2991
3091
|
inputSchema: {
|
|
2992
3092
|
type: "object",
|
|
2993
3093
|
properties: {
|
|
@@ -3004,7 +3104,7 @@ const TOOLS = [
|
|
|
3004
3104
|
{
|
|
3005
3105
|
name: "project_batch",
|
|
3006
3106
|
description:
|
|
3007
|
-
"Run up to 200 verb.noun commands on one project in order (id / path filled in; not atomic; stops at the first failure by default). Returns { ran, failed, results[] }.",
|
|
3107
|
+
"Run up to 200 verb.noun commands on one project in order (id / path filled in; not atomic; stops at the first failure by default). Returns { ran, failed, results[] }. Concurrent saves are merged and retried (three attempts). Exhausted conflicts report code revision_conflict / status 409 (job.errorDetails for async jobs).",
|
|
3008
3108
|
inputSchema: {
|
|
3009
3109
|
type: "object",
|
|
3010
3110
|
properties: {
|
|
@@ -3225,7 +3325,7 @@ const TOOLS = [
|
|
|
3225
3325
|
{
|
|
3226
3326
|
name: "project_auto_reframe",
|
|
3227
3327
|
description:
|
|
3228
|
-
"Active-speaker auto-reframe of landscape multi-person footage for vertical / square: frames whoever talks, shot by shot. split=true stacks two people (podcast / interview wide) one above the other on a 9:16 canvas. Slow (minutes). clear reverts.",
|
|
3328
|
+
"Active-speaker auto-reframe of landscape multi-person footage for vertical / square: frames whoever talks, shot by shot. split=true stacks two people (podcast / interview wide) one above the other on a 9:16 canvas. Slow (minutes). clear reverts. Concurrent saves are merged and retried (three attempts). Exhausted conflicts report code revision_conflict / status 409 (job.errorDetails for async jobs).",
|
|
3229
3329
|
inputSchema: {
|
|
3230
3330
|
type: "object",
|
|
3231
3331
|
properties: {
|
|
@@ -3686,16 +3786,52 @@ const TOOLS = [
|
|
|
3686
3786
|
},
|
|
3687
3787
|
|
|
3688
3788
|
// ── transcript-based editing ────────────────────────────────────
|
|
3789
|
+
{
|
|
3790
|
+
name: "transcript_detect_language",
|
|
3791
|
+
description:
|
|
3792
|
+
"Guess a clip's language locally from up to 30 seconds. Returns guess or null when unavailable. Confirm with the user before cloud transcription.",
|
|
3793
|
+
inputSchema: {
|
|
3794
|
+
type: "object",
|
|
3795
|
+
properties: { id: { type: "string" }, path: { type: "string" }, clipId: { type: "string" } },
|
|
3796
|
+
},
|
|
3797
|
+
command: "transcript.detect-language",
|
|
3798
|
+
},
|
|
3799
|
+
|
|
3800
|
+
{
|
|
3801
|
+
name: "system_set_transcription_preferences",
|
|
3802
|
+
description:
|
|
3803
|
+
"Save workspace language and provider atomically. Confirm consent to upload audio for cloud. Cloud cannot use auto.",
|
|
3804
|
+
inputSchema: {
|
|
3805
|
+
type: "object",
|
|
3806
|
+
required: ["language", "provider"],
|
|
3807
|
+
properties: {
|
|
3808
|
+
language: { type: "string" },
|
|
3809
|
+
provider: { type: "string", enum: ["local", "deepgram", "elevenlabs"] },
|
|
3810
|
+
},
|
|
3811
|
+
},
|
|
3812
|
+
command: "system.set-transcription-preferences",
|
|
3813
|
+
},
|
|
3814
|
+
|
|
3689
3815
|
{
|
|
3690
3816
|
name: "transcript_transcribe",
|
|
3691
3817
|
description:
|
|
3692
|
-
"Transcribe clips with word timestamps (default: only clips without words). To REDO a transcript (wrong language, bad run)
|
|
3818
|
+
"Transcribe clips with word timestamps (default: only clips without words). To REDO a transcript (wrong language, bad run) confirm language, pass per-run language and provider overrides, 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. Concurrent saves are merged and retried (three attempts). Exhausted conflicts report code revision_conflict / status 409 (job.errorDetails for async jobs).",
|
|
3693
3819
|
inputSchema: {
|
|
3694
3820
|
type: "object",
|
|
3695
3821
|
properties: {
|
|
3696
3822
|
id: { type: "string" },
|
|
3697
3823
|
path: { type: "string" },
|
|
3698
3824
|
clipId: { type: "string", description: "Only this clip, even if already transcribed." },
|
|
3825
|
+
language: {
|
|
3826
|
+
type: "string",
|
|
3827
|
+
description:
|
|
3828
|
+
"Per-run spoken language name (english, tamil, etc.). Cloud cannot use auto.",
|
|
3829
|
+
},
|
|
3830
|
+
provider: {
|
|
3831
|
+
type: "string",
|
|
3832
|
+
enum: ["local", "deepgram", "elevenlabs"],
|
|
3833
|
+
description: "Per-run provider. Audio is sent to the selected cloud provider.",
|
|
3834
|
+
},
|
|
3699
3835
|
force: { type: "boolean", description: "Re-transcribe clips that already have words." },
|
|
3700
3836
|
},
|
|
3701
3837
|
},
|
|
@@ -3854,7 +3990,7 @@ const TOOLS = [
|
|
|
3854
3990
|
{
|
|
3855
3991
|
name: "audio_clean",
|
|
3856
3992
|
description:
|
|
3857
|
-
"Denoise each clip
|
|
3993
|
+
"Denoise each clip’s audio, optionally reducing room echo. Speech below -30 LUFS is boosted to -16 LUFS / -1.5 dBTP by default; warnings explain boosts. Original kept; audio_reset_clean restores it. ASYNC: { jobId }, job_wait. Concurrent saves are merged and retried (three attempts); exhausted conflicts report code revision_conflict / status 409.",
|
|
3858
3994
|
inputSchema: {
|
|
3859
3995
|
type: "object",
|
|
3860
3996
|
properties: {
|
|
@@ -3862,11 +3998,42 @@ const TOOLS = [
|
|
|
3862
3998
|
path: { type: "string" },
|
|
3863
3999
|
clipId: { type: "string" },
|
|
3864
4000
|
echo: { type: "boolean", description: "Only when the user mentions echo / reverb." },
|
|
4001
|
+
normalize: {
|
|
4002
|
+
type: "boolean",
|
|
4003
|
+
description: "Default true: boost very quiet speech. Set false to opt out.",
|
|
4004
|
+
},
|
|
3865
4005
|
},
|
|
3866
4006
|
},
|
|
3867
4007
|
command: "audio.clean",
|
|
3868
4008
|
},
|
|
3869
4009
|
|
|
4010
|
+
{
|
|
4011
|
+
name: "audio_normalize",
|
|
4012
|
+
description:
|
|
4013
|
+
"Normalize a clip’s active audio without denoising. Default -16 LUFS, -1.5 dBTP ceiling. Silent audio skipped with warnings. Original kept. ASYNC: job_wait.",
|
|
4014
|
+
inputSchema: {
|
|
4015
|
+
type: "object",
|
|
4016
|
+
properties: {
|
|
4017
|
+
id: { type: "string" },
|
|
4018
|
+
path: { type: "string" },
|
|
4019
|
+
clipId: { type: "string" },
|
|
4020
|
+
targetLufs: { type: "number", minimum: -70, maximum: -5, default: -16 },
|
|
4021
|
+
},
|
|
4022
|
+
required: ["clipId"],
|
|
4023
|
+
},
|
|
4024
|
+
command: "audio.normalize",
|
|
4025
|
+
},
|
|
4026
|
+
{
|
|
4027
|
+
name: "audio_reset_clean",
|
|
4028
|
+
description:
|
|
4029
|
+
"Restore original clip audio by clearing cleaned/normalized audio and echo metadata. Optional clipId; otherwise all clips. Keeps generated files. Synchronous.",
|
|
4030
|
+
inputSchema: {
|
|
4031
|
+
type: "object",
|
|
4032
|
+
properties: { id: { type: "string" }, path: { type: "string" }, clipId: { type: "string" } },
|
|
4033
|
+
},
|
|
4034
|
+
command: "audio.reset-clean",
|
|
4035
|
+
},
|
|
4036
|
+
|
|
3870
4037
|
// ── captions ────────────────────────────────────────────────────
|
|
3871
4038
|
{
|
|
3872
4039
|
name: "caption_toggle",
|
|
@@ -4573,7 +4740,7 @@ const TOOLS = [
|
|
|
4573
4740
|
{
|
|
4574
4741
|
name: "media_download_url",
|
|
4575
4742
|
description:
|
|
4576
|
-
"Download a video or its audio from a page link (YouTube, Vimeo...). Only content the user has rights to. ASYNC: job_wait gives { path, title, durationMs }.",
|
|
4743
|
+
"Download a video or its audio from a page link (YouTube, Vimeo...). Only content the user has rights to. ASYNC: job_wait gives { path, title, durationMs }. Project placement retries concurrent-save conflicts (three attempts); exhaustion is job.errorDetails with revision_conflict / status 409.",
|
|
4577
4744
|
inputSchema: {
|
|
4578
4745
|
type: "object",
|
|
4579
4746
|
properties: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@writepanda/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.213.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",
|