@writepanda/mcp 1.76.0 → 1.81.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 +136 -17
- package/package.json +1 -1
package/bin/server.mjs
CHANGED
|
@@ -379,7 +379,10 @@ const TOOLS = [
|
|
|
379
379
|
id: { type: "string", description: "Export entry id." },
|
|
380
380
|
accountId: { type: "string" },
|
|
381
381
|
channelId: { type: "string" },
|
|
382
|
-
title: {
|
|
382
|
+
title: {
|
|
383
|
+
type: "string",
|
|
384
|
+
description: "Max 100 chars; < and > are stripped (YouTube rejects them).",
|
|
385
|
+
},
|
|
383
386
|
description: {
|
|
384
387
|
type: "string",
|
|
385
388
|
description:
|
|
@@ -420,7 +423,10 @@ const TOOLS = [
|
|
|
420
423
|
properties: {
|
|
421
424
|
accountId: { type: "string" },
|
|
422
425
|
videoId: { type: "string" },
|
|
423
|
-
title: {
|
|
426
|
+
title: {
|
|
427
|
+
type: "string",
|
|
428
|
+
description: "Max 100 chars; < and > are stripped (YouTube rejects them).",
|
|
429
|
+
},
|
|
424
430
|
description: {
|
|
425
431
|
type: "string",
|
|
426
432
|
description:
|
|
@@ -845,10 +851,22 @@ const TOOLS = [
|
|
|
845
851
|
properties: {
|
|
846
852
|
id: { type: "string" },
|
|
847
853
|
path: { type: "string" },
|
|
848
|
-
transitionId: {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
854
|
+
transitionId: {
|
|
855
|
+
type: "string",
|
|
856
|
+
description: "Bundled id, e.g. fade-black. From asset_list_transitions.",
|
|
857
|
+
},
|
|
858
|
+
file: {
|
|
859
|
+
type: "string",
|
|
860
|
+
description: "Custom transition video (path / file:// URL). Use instead of transitionId.",
|
|
861
|
+
},
|
|
862
|
+
atMs: {
|
|
863
|
+
type: "number",
|
|
864
|
+
description: "Edited-timeline CUT time to center the transition on.",
|
|
865
|
+
},
|
|
866
|
+
durationMs: {
|
|
867
|
+
type: "number",
|
|
868
|
+
description: "Total length. Default 1000 (native length of the bundled set).",
|
|
869
|
+
},
|
|
852
870
|
expectedRevision: { type: "number" },
|
|
853
871
|
},
|
|
854
872
|
required: ["atMs"],
|
|
@@ -919,8 +937,16 @@ const TOOLS = [
|
|
|
919
937
|
description:
|
|
920
938
|
"1 (mild) - 6 (extreme). Default 2 (1.5×) — soft, modern feel. Use 3-4 for emphasis beats, 5-6 for dramatic punch-ins.",
|
|
921
939
|
},
|
|
922
|
-
focusX: {
|
|
923
|
-
|
|
940
|
+
focusX: {
|
|
941
|
+
type: "number",
|
|
942
|
+
description:
|
|
943
|
+
"Normalised 0-1 horizontal center. Default 0.5. Ignored when followCursor is true.",
|
|
944
|
+
},
|
|
945
|
+
focusY: {
|
|
946
|
+
type: "number",
|
|
947
|
+
description:
|
|
948
|
+
"Normalised 0-1 vertical center. Default 0.5. Ignored when followCursor is true.",
|
|
949
|
+
},
|
|
924
950
|
followCursor: {
|
|
925
951
|
type: "boolean",
|
|
926
952
|
description:
|
|
@@ -1053,7 +1079,7 @@ const TOOLS = [
|
|
|
1053
1079
|
{
|
|
1054
1080
|
name: "project_add_clip_transform_region",
|
|
1055
1081
|
description:
|
|
1056
|
-
"Time-bounded transform on the main video clip between startMs and endMs. TWO families of preset: (1) cam-* render the single clip inside a sub-rect of the canvas, freeing the rest for motion graphics (use ONLY on camera-only / user-uploaded recordings; for screen recordings use cursor-telemetry zooms). (2)
|
|
1082
|
+
"Time-bounded transform on the main video clip between startMs and endMs. TWO families of preset: (1) cam-* render the single clip inside a sub-rect of the canvas, freeing the rest for motion graphics (use ONLY on camera-only / user-uploaded recordings; for screen recordings use cursor-telemetry zooms). (2) podcast layouts swap the WHOLE podcast composite for the window — change which participant(s) are shown over time WITHIN ONE recording. For multi-party (host + up to 3 guests) use the PARTICIPANT-AWARE presets podcast-solo / podcast-pair / podcast-grid / podcast-screen-share with a `participants` list (e.g. show just guest-2, or Kamal+Vimal side by side). Outside the region the clip renders with its natural layout. Renderer interpolates over `transitionMs` (default 320ms) at each boundary so the tiles smoothly resize.",
|
|
1057
1083
|
inputSchema: {
|
|
1058
1084
|
type: "object",
|
|
1059
1085
|
required: ["startMs", "endMs", "preset"],
|
|
@@ -1080,9 +1106,19 @@ const TOOLS = [
|
|
|
1080
1106
|
"layout-podcast",
|
|
1081
1107
|
"layout-host-full",
|
|
1082
1108
|
"layout-guest-full",
|
|
1109
|
+
"podcast-solo",
|
|
1110
|
+
"podcast-pair",
|
|
1111
|
+
"podcast-grid",
|
|
1112
|
+
"podcast-screen-share",
|
|
1083
1113
|
],
|
|
1084
1114
|
description:
|
|
1085
|
-
"cam-* (camera reposition into a sub-rect): cam-bottom-half / cam-top-half (9:16); cam-right-portrait / cam-left-portrait (16:9 ~35% card); cam-right-portrait-sm (small ~25% host card — for a full-frame graphic background); cam-bottom-right-quarter / cam-bottom-left-quarter (corner card); cam-right-55/left-55/right-50/left-50 (designed splits).
|
|
1115
|
+
"cam-* (camera reposition into a sub-rect): cam-bottom-half / cam-top-half (9:16); cam-right-portrait / cam-left-portrait (16:9 ~35% card); cam-right-portrait-sm (small ~25% host card — for a full-frame graphic background); cam-bottom-right-quarter / cam-bottom-left-quarter (corner card); cam-right-55/left-55/right-50/left-50 (designed splits). PODCAST layouts (whole-composite swap over time, PODCAST clips only): the PARTICIPANT-AWARE family is podcast-solo (one person — pass participants=[who]), podcast-pair (two — participants=[left,right]), podcast-grid (everyone, or participants subset), podcast-screen-share (shared screen + participant strip). Legacy 2-person presets layout-side-by-side / layout-podcast / layout-host-full / layout-guest-full still work. IMPORTANT: podcast/layout-* only do anything on a PODCAST clip (kind='podcast'); on other clips use cam-*. Check clip.kind + participants via project_read first.",
|
|
1116
|
+
},
|
|
1117
|
+
participants: {
|
|
1118
|
+
type: "array",
|
|
1119
|
+
items: { type: "string" },
|
|
1120
|
+
description:
|
|
1121
|
+
"Ordered participant speaker ids for the participant-aware podcast-* presets: 'host' | 'guest' | 'guest-2' | 'guest-3'. podcast-solo→[who], podcast-pair→[left,right], podcast-grid/podcast-screen-share→the set to show (omit = everyone). Ignored by cam-* and legacy layout-* presets.",
|
|
1086
1122
|
},
|
|
1087
1123
|
transitionMs: {
|
|
1088
1124
|
type: "number",
|
|
@@ -1126,12 +1162,17 @@ const TOOLS = [
|
|
|
1126
1162
|
{
|
|
1127
1163
|
name: "project_delete",
|
|
1128
1164
|
description:
|
|
1129
|
-
"Permanently delete a project file from disk. There is no trash — this is irreversible. Use project_list to confirm the id before deleting.",
|
|
1165
|
+
"Permanently delete a project file from disk. There is no trash — this is irreversible. By default the original source recording is KEPT (only the project is removed). Pass deleteRecording=true to ALSO permanently delete the project's original recording file(s) from disk. Use project_list to confirm the id before deleting.",
|
|
1130
1166
|
inputSchema: {
|
|
1131
1167
|
type: "object",
|
|
1132
1168
|
properties: {
|
|
1133
1169
|
id: { type: "string" },
|
|
1134
1170
|
path: { type: "string" },
|
|
1171
|
+
deleteRecording: {
|
|
1172
|
+
type: "boolean",
|
|
1173
|
+
description:
|
|
1174
|
+
"Also permanently delete the project's original source recording file(s). Default false. IRREVERSIBLE.",
|
|
1175
|
+
},
|
|
1135
1176
|
},
|
|
1136
1177
|
},
|
|
1137
1178
|
command: "project.delete",
|
|
@@ -1692,6 +1733,26 @@ const TOOLS = [
|
|
|
1692
1733
|
},
|
|
1693
1734
|
command: "transcript.delete-words",
|
|
1694
1735
|
},
|
|
1736
|
+
{
|
|
1737
|
+
name: "transcript_restore_words",
|
|
1738
|
+
description:
|
|
1739
|
+
"Restore previously deleted words — removes the trim region(s) covering them, undoing transcript_delete_words / transcript_remove_fillers / repeat removal. THIS is the editor's 'select struck-through words → Restore' workflow, callable from MCP. Silence-removal trims are left untouched.",
|
|
1740
|
+
inputSchema: {
|
|
1741
|
+
type: "object",
|
|
1742
|
+
properties: {
|
|
1743
|
+
id: { type: "string" },
|
|
1744
|
+
path: { type: "string" },
|
|
1745
|
+
wordIds: {
|
|
1746
|
+
type: "array",
|
|
1747
|
+
items: { type: "string" },
|
|
1748
|
+
description: "Word IDs (from transcript_get) that are currently deleted.",
|
|
1749
|
+
},
|
|
1750
|
+
expectedRevision: { type: "number" },
|
|
1751
|
+
},
|
|
1752
|
+
required: ["wordIds"],
|
|
1753
|
+
},
|
|
1754
|
+
command: "transcript.restore-words",
|
|
1755
|
+
},
|
|
1695
1756
|
{
|
|
1696
1757
|
name: "transcript_remove_fillers",
|
|
1697
1758
|
description:
|
|
@@ -1758,7 +1819,7 @@ const TOOLS = [
|
|
|
1758
1819
|
find: {
|
|
1759
1820
|
type: "string",
|
|
1760
1821
|
description:
|
|
1761
|
-
|
|
1822
|
+
'Phrase to search for. Case-insensitive; digits and punctuation are ignored on both sides, so "than60" and "than" both match the word "than60". A pure-number/punctuation phrase can\'t be targeted (it normalizes to empty) — include a letter word.',
|
|
1762
1823
|
},
|
|
1763
1824
|
replace: { type: "string", description: "Replacement text (replaces the whole phrase)" },
|
|
1764
1825
|
expectedRevision: { type: "number" },
|
|
@@ -1882,7 +1943,8 @@ const TOOLS = [
|
|
|
1882
1943
|
strokeWidth: { type: "number", description: "Text stroke width in px" },
|
|
1883
1944
|
fontSize: {
|
|
1884
1945
|
type: "string",
|
|
1885
|
-
description:
|
|
1946
|
+
description:
|
|
1947
|
+
"Font size in REM, e.g. '2.6rem'. Clamped to 1.0–5.0rem (the editor's slider range).",
|
|
1886
1948
|
},
|
|
1887
1949
|
expectedRevision: { type: "number" },
|
|
1888
1950
|
},
|
|
@@ -1937,6 +1999,45 @@ const TOOLS = [
|
|
|
1937
1999
|
},
|
|
1938
2000
|
command: "media.generate-image",
|
|
1939
2001
|
},
|
|
2002
|
+
{
|
|
2003
|
+
name: "media_generate_narration",
|
|
2004
|
+
description:
|
|
2005
|
+
"Generate a voiceover / narration audio clip via Replicate TTS, for promo videos and explainers. Project-agnostic; writes audio to <userData>/narration/ and returns { audioPath, durationMs, model, voice, predictionId }. Canonical workflow: media_generate_narration → project_add_audio (place at startMs, pass the returned durationMs so the overlay is sized to the speech). Models: 'elevenlabs-v3' (default, most expressive — embed inline delivery tags in the text like [excited] or [whispers]) | 'gemini-flash-tts' (30 voices, strong multilingual; 'style' sets tone) | 'minimax-turbo' (fast; 'style' maps to an emotion, 'speed' 0.5-2). Voices — gemini e.g. Kore/Puck/Charon; minimax e.g. Friendly_Person/Wise_Woman/Casual_Guy; omit voice for the model default. Requires the user's Replicate API key (Settings → Integrations).",
|
|
2006
|
+
inputSchema: {
|
|
2007
|
+
type: "object",
|
|
2008
|
+
properties: {
|
|
2009
|
+
text: {
|
|
2010
|
+
type: "string",
|
|
2011
|
+
description:
|
|
2012
|
+
"The script to speak. For elevenlabs-v3 you can embed delivery tags inline, e.g. 'Welcome [excited] to the future of editing.'",
|
|
2013
|
+
},
|
|
2014
|
+
model: {
|
|
2015
|
+
type: "string",
|
|
2016
|
+
description: "'elevenlabs-v3' (default) | 'gemini-flash-tts' | 'minimax-turbo'.",
|
|
2017
|
+
},
|
|
2018
|
+
voice: {
|
|
2019
|
+
type: "string",
|
|
2020
|
+
description:
|
|
2021
|
+
"Voice id/name for the chosen model (gemini: Kore/Puck/...; minimax: Friendly_Person/...). Omit for the model default.",
|
|
2022
|
+
},
|
|
2023
|
+
language: {
|
|
2024
|
+
type: "string",
|
|
2025
|
+
description: "Optional BCP-47 language hint, e.g. 'en-US', 'es-ES'.",
|
|
2026
|
+
},
|
|
2027
|
+
style: {
|
|
2028
|
+
type: "string",
|
|
2029
|
+
description:
|
|
2030
|
+
"Optional tone/emotion hint (e.g. 'warm and upbeat'). Maps to Gemini's style prompt and MiniMax's emotion enum.",
|
|
2031
|
+
},
|
|
2032
|
+
speed: {
|
|
2033
|
+
type: "number",
|
|
2034
|
+
description: "Optional playback speed for MiniMax (0.5-2, 1 = normal).",
|
|
2035
|
+
},
|
|
2036
|
+
},
|
|
2037
|
+
required: ["text"],
|
|
2038
|
+
},
|
|
2039
|
+
command: "media.generate-narration",
|
|
2040
|
+
},
|
|
1940
2041
|
// `motion_generate` removed in v1.31.0 — see comment above the
|
|
1941
2042
|
// motion-graphics section.
|
|
1942
2043
|
{
|
|
@@ -2263,20 +2364,38 @@ const TOOLS = [
|
|
|
2263
2364
|
{
|
|
2264
2365
|
name: "export_generate_thumbnail",
|
|
2265
2366
|
description:
|
|
2266
|
-
"Generate a YouTube thumbnail for an export-library entry via Replicate's gpt-image-2 model
|
|
2367
|
+
"Generate a YouTube thumbnail for an export-library entry via Replicate's gpt-image-2 model (3:2, photorealistic, high contrast, mobile-readable). Two ways to drive it: (1) pass `subject` (the topic-relevant hero image, 4-10 words) + `hook` (2-4 word overlay) and optionally `reaction`/`layout` — the prompt is assembled deterministically, no transcript needed; or (2) omit them and the local LLM suggests subject/hook/reaction/layout from the transcript. `prompt` overrides everything with a verbatim prompt. `referenceImagePath` is the person's face (passed as input_images). Requires the user's Replicate API key (Settings → Integrations; stored encrypted). Returns { imagePath, prompt, iterations }.",
|
|
2267
2368
|
inputSchema: {
|
|
2268
2369
|
type: "object",
|
|
2269
2370
|
properties: {
|
|
2270
2371
|
id: { type: "string", description: "Export entry id." },
|
|
2271
|
-
|
|
2372
|
+
subject: {
|
|
2373
|
+
type: "string",
|
|
2374
|
+
description:
|
|
2375
|
+
"The topic-relevant hero image, described concretely (4-10 words), e.g. 'a phone showing a first $79 Stripe sale'. When set, no transcript/LLM is needed.",
|
|
2376
|
+
},
|
|
2377
|
+
hook: {
|
|
2378
|
+
type: "string",
|
|
2379
|
+
description: "2-4 word overlay text (auto-uppercased), e.g. 'FIRST SALE'.",
|
|
2380
|
+
},
|
|
2381
|
+
reaction: {
|
|
2382
|
+
type: "string",
|
|
2383
|
+
description:
|
|
2384
|
+
"Facial reaction: excitement (default) | shock | delight | awe | curiosity | pride | determination | relief.",
|
|
2385
|
+
},
|
|
2386
|
+
layout: {
|
|
2272
2387
|
type: "string",
|
|
2273
2388
|
description:
|
|
2274
|
-
"
|
|
2389
|
+
"Composition: reaction-split (default) | subject-hero | before-after | big-face | product-only | versus.",
|
|
2390
|
+
},
|
|
2391
|
+
prompt: {
|
|
2392
|
+
type: "string",
|
|
2393
|
+
description: "Optional verbatim prompt. Overrides subject/hook/reaction/layout entirely.",
|
|
2275
2394
|
},
|
|
2276
2395
|
referenceImagePath: {
|
|
2277
2396
|
type: "string",
|
|
2278
2397
|
description:
|
|
2279
|
-
"Optional reference image (absolute path or https URL) passed as gpt-image-2 `input_images`.",
|
|
2398
|
+
"Optional reference person image (absolute path or https URL) passed as gpt-image-2 `input_images`.",
|
|
2280
2399
|
},
|
|
2281
2400
|
quality: {
|
|
2282
2401
|
type: "string",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@writepanda/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.81.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",
|