@writepanda/mcp 1.81.0 → 1.87.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 +185 -10
- package/package.json +1 -1
package/bin/server.mjs
CHANGED
|
@@ -321,6 +321,50 @@ const TOOLS = [
|
|
|
321
321
|
},
|
|
322
322
|
command: "workspace.set-brand",
|
|
323
323
|
},
|
|
324
|
+
{
|
|
325
|
+
name: "workspace_get_project_defaults",
|
|
326
|
+
description:
|
|
327
|
+
"Return the active workspace's project-look defaults (wallpaper/background, captionSettings, editorDefaults) that new projects and fresh recordings start from. Returns { defaults: null } when none are set.",
|
|
328
|
+
inputSchema: { type: "object", properties: {} },
|
|
329
|
+
command: "workspace.get-project-defaults",
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: "workspace_set_project_defaults",
|
|
333
|
+
description:
|
|
334
|
+
"Set the active workspace's project-look defaults so every NEW project + recording starts from them (so the user does not re-set the same look each time). Pass any subset under `defaults`. Unknown/badly-typed fields are dropped. Pass defaults=null (or omit) to clear. Use when the user says e.g. 'use this look for all my projects' or 'always start with this background/captions'.",
|
|
335
|
+
inputSchema: {
|
|
336
|
+
type: "object",
|
|
337
|
+
properties: {
|
|
338
|
+
defaults: {
|
|
339
|
+
type: ["object", "null"],
|
|
340
|
+
properties: {
|
|
341
|
+
wallpaper: { type: "string" },
|
|
342
|
+
captionSettings: {
|
|
343
|
+
type: "object",
|
|
344
|
+
properties: {
|
|
345
|
+
enabled: { type: "boolean" },
|
|
346
|
+
templateId: { type: "string" },
|
|
347
|
+
wordsPerLine: { type: "integer" },
|
|
348
|
+
positionY: { type: "number" },
|
|
349
|
+
styleOverrides: { type: "object" },
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
editorDefaults: {
|
|
353
|
+
type: "object",
|
|
354
|
+
properties: {
|
|
355
|
+
padding: { type: "number" },
|
|
356
|
+
shadowIntensity: { type: "number" },
|
|
357
|
+
borderRadius: { type: "number" },
|
|
358
|
+
showBlur: { type: "boolean" },
|
|
359
|
+
motionBlurAmount: { type: "number" },
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
command: "workspace.set-project-defaults",
|
|
367
|
+
},
|
|
324
368
|
|
|
325
369
|
// ── YouTube publishing (v1.19) ──────────────────────────────────
|
|
326
370
|
// Connect Google accounts per workspace, publish exports, edit
|
|
@@ -977,6 +1021,120 @@ const TOOLS = [
|
|
|
977
1021
|
},
|
|
978
1022
|
command: "project.add-zoom",
|
|
979
1023
|
},
|
|
1024
|
+
{
|
|
1025
|
+
name: "project_add_spotlight",
|
|
1026
|
+
description:
|
|
1027
|
+
"Add a focus region over the video. kind 'spotlight' DIMS everything OUTSIDE a rounded rectangle to draw the eye to one spot (Focusee-style); kind 'blur' BLURS everything INSIDE the rectangle to hide an email, username, or other sensitive detail. The rect is 0..1 fractions of the video and tracks content through zooms. Defaults give a centred half-size box; pass x/y/width/height to place it.",
|
|
1028
|
+
inputSchema: {
|
|
1029
|
+
type: "object",
|
|
1030
|
+
properties: {
|
|
1031
|
+
id: { type: "string" },
|
|
1032
|
+
path: { type: "string" },
|
|
1033
|
+
atMs: { type: "number" },
|
|
1034
|
+
durationMs: { type: "number" },
|
|
1035
|
+
kind: {
|
|
1036
|
+
type: "string",
|
|
1037
|
+
enum: ["spotlight", "blur"],
|
|
1038
|
+
description: '"spotlight" (default — dims outside) or "blur" (blurs inside).',
|
|
1039
|
+
},
|
|
1040
|
+
x: { type: "number", description: "Rect left edge, 0..1 of video width. Default 0.25." },
|
|
1041
|
+
y: { type: "number", description: "Rect top edge, 0..1 of video height. Default 0.25." },
|
|
1042
|
+
width: { type: "number", description: "Rect width, 0..1. Default 0.5." },
|
|
1043
|
+
height: { type: "number", description: "Rect height, 0..1. Default 0.5." },
|
|
1044
|
+
roundness: { type: "number", description: "Corner radius px, 0..120. Default 16." },
|
|
1045
|
+
maskOpacity: {
|
|
1046
|
+
type: "number",
|
|
1047
|
+
description: "SPOTLIGHT only: surround darkness 0..1. Default 0.6.",
|
|
1048
|
+
},
|
|
1049
|
+
blurAmount: {
|
|
1050
|
+
type: "number",
|
|
1051
|
+
description: "BLUR only: blur strength px, 0..120. Default 12.",
|
|
1052
|
+
},
|
|
1053
|
+
feathering: { type: "number", description: "Soft edge px, 0..120. Default 12." },
|
|
1054
|
+
expectedRevision: { type: "number" },
|
|
1055
|
+
},
|
|
1056
|
+
required: ["atMs", "durationMs"],
|
|
1057
|
+
},
|
|
1058
|
+
command: "project.add-spotlight",
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
name: "project_update_spotlight",
|
|
1062
|
+
description:
|
|
1063
|
+
"Patch an existing focus region in-place: move/resize the rect, retime it, restyle it (roundness/feathering/darkness/blur), or switch spotlight<->blur. Only the fields you pass change. Find ids via project_read under editor.spotlightRegions[].id.",
|
|
1064
|
+
inputSchema: {
|
|
1065
|
+
type: "object",
|
|
1066
|
+
properties: {
|
|
1067
|
+
id: { type: "string" },
|
|
1068
|
+
path: { type: "string" },
|
|
1069
|
+
regionId: {
|
|
1070
|
+
type: "string",
|
|
1071
|
+
description: "The id of the focus region (editor.spotlightRegions[].id).",
|
|
1072
|
+
},
|
|
1073
|
+
startMs: { type: "number", description: "New edited-time start (ms)." },
|
|
1074
|
+
endMs: { type: "number", description: "New edited-time end (ms)." },
|
|
1075
|
+
kind: {
|
|
1076
|
+
type: "string",
|
|
1077
|
+
enum: ["spotlight", "blur"],
|
|
1078
|
+
description: 'Switch kind: "spotlight" (dims outside) or "blur" (blurs inside).',
|
|
1079
|
+
},
|
|
1080
|
+
x: { type: "number", description: "Rect left edge, 0..1 of video width." },
|
|
1081
|
+
y: { type: "number", description: "Rect top edge, 0..1 of video height." },
|
|
1082
|
+
width: { type: "number", description: "Rect width, 0..1." },
|
|
1083
|
+
height: { type: "number", description: "Rect height, 0..1." },
|
|
1084
|
+
roundness: { type: "number", description: "Corner radius px, 0..120." },
|
|
1085
|
+
maskOpacity: {
|
|
1086
|
+
type: "number",
|
|
1087
|
+
description: "SPOTLIGHT only: surround darkness 0..1.",
|
|
1088
|
+
},
|
|
1089
|
+
blurAmount: {
|
|
1090
|
+
type: "number",
|
|
1091
|
+
description: "BLUR only: blur strength px, 0..120.",
|
|
1092
|
+
},
|
|
1093
|
+
feathering: { type: "number", description: "Soft edge px, 0..120." },
|
|
1094
|
+
expectedRevision: { type: "number" },
|
|
1095
|
+
},
|
|
1096
|
+
required: ["regionId"],
|
|
1097
|
+
},
|
|
1098
|
+
command: "project.update-spotlight",
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
name: "project_remove_spotlight",
|
|
1102
|
+
description:
|
|
1103
|
+
"Remove a focus region (spotlight or blur) by id. Find ids via project_read under editor.spotlightRegions[].id.",
|
|
1104
|
+
inputSchema: {
|
|
1105
|
+
type: "object",
|
|
1106
|
+
properties: {
|
|
1107
|
+
id: { type: "string" },
|
|
1108
|
+
path: { type: "string" },
|
|
1109
|
+
regionId: {
|
|
1110
|
+
type: "string",
|
|
1111
|
+
description: "The id of the focus region to remove (editor.spotlightRegions[].id).",
|
|
1112
|
+
},
|
|
1113
|
+
expectedRevision: { type: "number" },
|
|
1114
|
+
},
|
|
1115
|
+
required: ["regionId"],
|
|
1116
|
+
},
|
|
1117
|
+
command: "project.remove-spotlight",
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
name: "project_render_frame",
|
|
1121
|
+
description:
|
|
1122
|
+
"Render the composited preview frame at a given edited-time to a PNG and return its path so a VISION agent can `read` the image. Use this to SEE what's on screen — e.g. to locate an email/username/face to cover before calling project_add_spotlight (kind=blur). Returns { path, width, height, timeMs, maskRect }. `maskRect` is the video content rect as 0..1 fractions of the image — the SAME coordinate space spotlight/blur x/y/width/height use. To cover something you see at image-fractions (ix,iy,iw,ih): x=(ix-maskRect.x)/maskRect.width, y=(iy-maskRect.y)/maskRect.height, width=iw/maskRect.width, height=ih/maskRect.height. Caveats: existing focus regions are NOT drawn (so you see content clearly), and the frame reflects any active zoom at that time — place focus regions referencing an un-zoomed moment, then re-render to verify.",
|
|
1123
|
+
inputSchema: {
|
|
1124
|
+
type: "object",
|
|
1125
|
+
properties: {
|
|
1126
|
+
id: { type: "string" },
|
|
1127
|
+
path: { type: "string" },
|
|
1128
|
+
atMs: { type: "number", description: "Edited-timeline time to render (ms)." },
|
|
1129
|
+
outPath: {
|
|
1130
|
+
type: "string",
|
|
1131
|
+
description: "Optional PNG output path. Defaults to a temp file you can read.",
|
|
1132
|
+
},
|
|
1133
|
+
},
|
|
1134
|
+
required: ["atMs"],
|
|
1135
|
+
},
|
|
1136
|
+
command: "project.render-frame",
|
|
1137
|
+
},
|
|
980
1138
|
{
|
|
981
1139
|
name: "project_set_region_sound",
|
|
982
1140
|
description:
|
|
@@ -1418,20 +1576,12 @@ const TOOLS = [
|
|
|
1418
1576
|
},
|
|
1419
1577
|
format: {
|
|
1420
1578
|
type: "string",
|
|
1421
|
-
description: "mp4 | webm
|
|
1579
|
+
description: "mp4 | webm. Default mp4. (PandaStudio is video-only.)",
|
|
1422
1580
|
},
|
|
1423
1581
|
resolution: {
|
|
1424
1582
|
type: "string",
|
|
1425
1583
|
description: "Output resolution: 4k | 1080p | 720p | 480p | source. Default source.",
|
|
1426
1584
|
},
|
|
1427
|
-
gifFrameRate: {
|
|
1428
|
-
type: "number",
|
|
1429
|
-
description: "GIF frame rate (fps). Only used when format is gif. Default 15.",
|
|
1430
|
-
},
|
|
1431
|
-
gifSize: {
|
|
1432
|
-
type: "string",
|
|
1433
|
-
description: "GIF size preset: small | medium | large. Only used when format is gif.",
|
|
1434
|
-
},
|
|
1435
1585
|
expectedRevision: { type: "number" },
|
|
1436
1586
|
},
|
|
1437
1587
|
},
|
|
@@ -2038,12 +2188,37 @@ const TOOLS = [
|
|
|
2038
2188
|
},
|
|
2039
2189
|
command: "media.generate-narration",
|
|
2040
2190
|
},
|
|
2191
|
+
{
|
|
2192
|
+
name: "media_generate_music",
|
|
2193
|
+
description:
|
|
2194
|
+
"Generate an original instrumental background-music track via Replicate (Google Lyria-2). Project-agnostic; writes audio to <userData>/generated-music/ and returns { audioPath, durationMs, model, predictionId }. Canonical workflow: media_generate_music → project_add_audio (place at startMs, pass the returned durationMs so the overlay is sized). The bundled library (asset_list_music) is the faster default for common moods — reach for generation when the user wants something specific/custom the library doesn't cover. Describe the music in `prompt` (genre, mood, instruments, tempo, use-case). Lyria-2 is instrumental only (~30s clips, 48kHz stereo) — loop for longer videos. Requires the user's Replicate API key (Settings → Integrations).",
|
|
2195
|
+
inputSchema: {
|
|
2196
|
+
type: "object",
|
|
2197
|
+
properties: {
|
|
2198
|
+
prompt: {
|
|
2199
|
+
type: "string",
|
|
2200
|
+
description:
|
|
2201
|
+
"What the music should sound like — genre, mood, instruments, tempo, use-case. e.g. 'upbeat lo-fi hip hop with mellow piano, relaxed, for a coding montage'.",
|
|
2202
|
+
},
|
|
2203
|
+
negativePrompt: {
|
|
2204
|
+
type: "string",
|
|
2205
|
+
description: "Optional — qualities to steer AWAY from, e.g. 'vocals, drums, harsh'.",
|
|
2206
|
+
},
|
|
2207
|
+
seed: {
|
|
2208
|
+
type: "number",
|
|
2209
|
+
description: "Optional integer seed for reproducible output.",
|
|
2210
|
+
},
|
|
2211
|
+
},
|
|
2212
|
+
required: ["prompt"],
|
|
2213
|
+
},
|
|
2214
|
+
command: "media.generate-music",
|
|
2215
|
+
},
|
|
2041
2216
|
// `motion_generate` removed in v1.31.0 — see comment above the
|
|
2042
2217
|
// motion-graphics section.
|
|
2043
2218
|
{
|
|
2044
2219
|
name: "motion_list",
|
|
2045
2220
|
description:
|
|
2046
|
-
"List
|
|
2221
|
+
"List motion-graphic building blocks. Returns two arrays. `templates`: the slot-parameterized bundled templates — each has id, name, description, style, tags, aspectRatios, durationMs, `overlay`, and `slots` (key, type: string|color|list, label, default); render with motion_generate. `registryBlocks`: standalone Hyperframes compositions (animated captions, shader transitions, data-viz, social cards, code themes, VFX) — each has name, kind, title, description, tags, durationMs, dimensions, and `htmlPath`; these have NO slots, so render the htmlPath directly with motion_render_html and edit the HTML if you need different text. Prefer a `template` when one fits (it's parameterized); reach into `registryBlocks` for captions/transitions/data-viz the templates don't cover.",
|
|
2047
2222
|
inputSchema: { type: "object", properties: {} },
|
|
2048
2223
|
command: "motion.list",
|
|
2049
2224
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@writepanda/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.87.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",
|