@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.
Files changed (2) hide show
  1. package/bin/server.mjs +185 -10
  2. 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 | gif. Default mp4.",
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 the bundled motion-graphic templates an agent can drop onto the timeline. Returns each template's id, name, description, style, tags, aspectRatios, durationMs, `overlay` (true → renders with alpha; sits over the video), and `slots` — the editable fields (key, type: string|color|list, label, default). Call this to discover what's available and exactly which text/colors you can set, then render one with motion_generate. The SKILL.md 'Motion graphics' catalog documents when to use each.",
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.81.0",
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",