@writepanda/mcp 1.210.0 → 1.211.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 +61 -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
|
}
|
|
@@ -1479,7 +1480,8 @@ const TOOLS = [
|
|
|
1479
1480
|
},
|
|
1480
1481
|
{
|
|
1481
1482
|
name: "podcast_open_host",
|
|
1482
|
-
description:
|
|
1483
|
+
description:
|
|
1484
|
+
"Open or focus the live podcast host window. Call podcast_status for the session code and guest link once it loads.",
|
|
1483
1485
|
inputSchema: {
|
|
1484
1486
|
type: "object",
|
|
1485
1487
|
properties: {
|
|
@@ -1490,10 +1492,22 @@ const TOOLS = [
|
|
|
1490
1492
|
command: "podcast.open-host",
|
|
1491
1493
|
},
|
|
1492
1494
|
...[
|
|
1493
|
-
[
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1495
|
+
[
|
|
1496
|
+
"status",
|
|
1497
|
+
"Read the live podcast session code, guest link, participants, recording, and sharing state.",
|
|
1498
|
+
],
|
|
1499
|
+
[
|
|
1500
|
+
"start-recording",
|
|
1501
|
+
"Start recording the host and signal connected guests to record. Returns once recording has really started; fails with the reason otherwise.",
|
|
1502
|
+
],
|
|
1503
|
+
[
|
|
1504
|
+
"stop-recording",
|
|
1505
|
+
"Stop recording and finalize podcast media. Check podcast_status for finalization and guest uploads.",
|
|
1506
|
+
],
|
|
1507
|
+
[
|
|
1508
|
+
"start-screen-share",
|
|
1509
|
+
"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.",
|
|
1510
|
+
],
|
|
1497
1511
|
["stop-screen-share", "Stop and finalize the host's podcast screen share."],
|
|
1498
1512
|
["open-in-editor", "Open the finished podcast in the editor when guest media has arrived."],
|
|
1499
1513
|
].map(([noun, description]) => ({
|
|
@@ -1573,7 +1587,7 @@ const TOOLS = [
|
|
|
1573
1587
|
{
|
|
1574
1588
|
name: "project_update_motion_graphic",
|
|
1575
1589
|
description:
|
|
1576
|
-
"Edit a generated graphic (overlay with generatedFrom) and re-render it in place, keeping timing and position. ASYNC: { jobId }.",
|
|
1590
|
+
"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
1591
|
inputSchema: {
|
|
1578
1592
|
type: "object",
|
|
1579
1593
|
properties: {
|
|
@@ -1597,7 +1611,7 @@ const TOOLS = [
|
|
|
1597
1611
|
{
|
|
1598
1612
|
name: "project_add_emoji",
|
|
1599
1613
|
description:
|
|
1600
|
-
"Place an animated emoji overlay. ASYNC: { jobId }; job_wait gives result.overlayId.",
|
|
1614
|
+
"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
1615
|
inputSchema: {
|
|
1602
1616
|
type: "object",
|
|
1603
1617
|
properties: {
|
|
@@ -1803,7 +1817,7 @@ const TOOLS = [
|
|
|
1803
1817
|
{
|
|
1804
1818
|
name: "project_add_lower_third",
|
|
1805
1819
|
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.",
|
|
1820
|
+
"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
1821
|
inputSchema: {
|
|
1808
1822
|
type: "object",
|
|
1809
1823
|
properties: {
|
|
@@ -1840,7 +1854,7 @@ const TOOLS = [
|
|
|
1840
1854
|
{
|
|
1841
1855
|
name: "project_add_title_behind",
|
|
1842
1856
|
description:
|
|
1843
|
-
"1-3 huge words at head height BEHIND the presenter. ASYNC: job_wait gives regionId, face.",
|
|
1857
|
+
"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
1858
|
inputSchema: {
|
|
1845
1859
|
type: "object",
|
|
1846
1860
|
properties: {
|
|
@@ -2587,7 +2601,7 @@ const TOOLS = [
|
|
|
2587
2601
|
{
|
|
2588
2602
|
name: "audio_probe",
|
|
2589
2603
|
description:
|
|
2590
|
-
"Per-clip audio stats: hasAudio, mean/max dB, silence spans (source time), plus audio overlays. A few seconds per clip.",
|
|
2604
|
+
"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
2605
|
inputSchema: {
|
|
2592
2606
|
type: "object",
|
|
2593
2607
|
properties: {
|
|
@@ -2987,7 +3001,7 @@ const TOOLS = [
|
|
|
2987
3001
|
{
|
|
2988
3002
|
name: "project_center_camera_on_face",
|
|
2989
3003
|
description:
|
|
2990
|
-
"Keep the presenter's face centred in the camera card by tracking it (can take a minute). clear: true turns it off.",
|
|
3004
|
+
"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
3005
|
inputSchema: {
|
|
2992
3006
|
type: "object",
|
|
2993
3007
|
properties: {
|
|
@@ -3004,7 +3018,7 @@ const TOOLS = [
|
|
|
3004
3018
|
{
|
|
3005
3019
|
name: "project_batch",
|
|
3006
3020
|
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[] }.",
|
|
3021
|
+
"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
3022
|
inputSchema: {
|
|
3009
3023
|
type: "object",
|
|
3010
3024
|
properties: {
|
|
@@ -3225,7 +3239,7 @@ const TOOLS = [
|
|
|
3225
3239
|
{
|
|
3226
3240
|
name: "project_auto_reframe",
|
|
3227
3241
|
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.",
|
|
3242
|
+
"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
3243
|
inputSchema: {
|
|
3230
3244
|
type: "object",
|
|
3231
3245
|
properties: {
|
|
@@ -3689,7 +3703,7 @@ const TOOLS = [
|
|
|
3689
3703
|
{
|
|
3690
3704
|
name: "transcript_transcribe",
|
|
3691
3705
|
description:
|
|
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.",
|
|
3706
|
+
"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. Concurrent saves are merged and retried (three attempts). Exhausted conflicts report code revision_conflict / status 409 (job.errorDetails for async jobs).",
|
|
3693
3707
|
inputSchema: {
|
|
3694
3708
|
type: "object",
|
|
3695
3709
|
properties: {
|
|
@@ -3854,7 +3868,7 @@ const TOOLS = [
|
|
|
3854
3868
|
{
|
|
3855
3869
|
name: "audio_clean",
|
|
3856
3870
|
description:
|
|
3857
|
-
"Denoise each clip
|
|
3871
|
+
"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
3872
|
inputSchema: {
|
|
3859
3873
|
type: "object",
|
|
3860
3874
|
properties: {
|
|
@@ -3862,11 +3876,42 @@ const TOOLS = [
|
|
|
3862
3876
|
path: { type: "string" },
|
|
3863
3877
|
clipId: { type: "string" },
|
|
3864
3878
|
echo: { type: "boolean", description: "Only when the user mentions echo / reverb." },
|
|
3879
|
+
normalize: {
|
|
3880
|
+
type: "boolean",
|
|
3881
|
+
description: "Default true: boost very quiet speech. Set false to opt out.",
|
|
3882
|
+
},
|
|
3865
3883
|
},
|
|
3866
3884
|
},
|
|
3867
3885
|
command: "audio.clean",
|
|
3868
3886
|
},
|
|
3869
3887
|
|
|
3888
|
+
{
|
|
3889
|
+
name: "audio_normalize",
|
|
3890
|
+
description:
|
|
3891
|
+
"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.",
|
|
3892
|
+
inputSchema: {
|
|
3893
|
+
type: "object",
|
|
3894
|
+
properties: {
|
|
3895
|
+
id: { type: "string" },
|
|
3896
|
+
path: { type: "string" },
|
|
3897
|
+
clipId: { type: "string" },
|
|
3898
|
+
targetLufs: { type: "number", minimum: -70, maximum: -5, default: -16 },
|
|
3899
|
+
},
|
|
3900
|
+
required: ["clipId"],
|
|
3901
|
+
},
|
|
3902
|
+
command: "audio.normalize",
|
|
3903
|
+
},
|
|
3904
|
+
{
|
|
3905
|
+
name: "audio_reset_clean",
|
|
3906
|
+
description:
|
|
3907
|
+
"Restore original clip audio by clearing cleaned/normalized audio and echo metadata. Optional clipId; otherwise all clips. Keeps generated files. Synchronous.",
|
|
3908
|
+
inputSchema: {
|
|
3909
|
+
type: "object",
|
|
3910
|
+
properties: { id: { type: "string" }, path: { type: "string" }, clipId: { type: "string" } },
|
|
3911
|
+
},
|
|
3912
|
+
command: "audio.reset-clean",
|
|
3913
|
+
},
|
|
3914
|
+
|
|
3870
3915
|
// ── captions ────────────────────────────────────────────────────
|
|
3871
3916
|
{
|
|
3872
3917
|
name: "caption_toggle",
|
|
@@ -4573,7 +4618,7 @@ const TOOLS = [
|
|
|
4573
4618
|
{
|
|
4574
4619
|
name: "media_download_url",
|
|
4575
4620
|
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 }.",
|
|
4621
|
+
"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
4622
|
inputSchema: {
|
|
4578
4623
|
type: "object",
|
|
4579
4624
|
properties: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@writepanda/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.211.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",
|