@writepanda/mcp 1.38.0 → 1.44.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 +117 -3
  2. package/package.json +1 -1
package/bin/server.mjs CHANGED
@@ -431,6 +431,21 @@ const TOOLS = [
431
431
  },
432
432
  command: "project.setFolder",
433
433
  },
434
+ {
435
+ name: "project_rename",
436
+ description:
437
+ "Rename a project (the display name shown in the editor title bar and the Home grid). Identify the project by `id` (preferred) or `path`. Pass the new `name` (trimmed; must be non-empty). The on-disk filename is NOT changed (files are keyed by project id), so this is safe to call while the project is open. Returns { id, path, name }. Use when the user asks to rename, retitle, or relabel a project.",
438
+ inputSchema: {
439
+ type: "object",
440
+ properties: {
441
+ id: { type: "string", description: "Project UUID (preferred)." },
442
+ path: { type: "string", description: "Absolute project file path." },
443
+ name: { type: "string", description: "New display name. Trimmed; must be non-empty." },
444
+ },
445
+ required: ["name"],
446
+ },
447
+ command: "project.rename",
448
+ },
434
449
  {
435
450
  name: "project_locate",
436
451
  description:
@@ -1082,6 +1097,25 @@ const TOOLS = [
1082
1097
  },
1083
1098
  command: "project.remove-region",
1084
1099
  },
1100
+ {
1101
+ name: "project_clear_edits",
1102
+ description:
1103
+ "Reset the project to a clean editing slate in ONE atomic call. Removes every time-based region (trim, speed, zoom, motion graphic, lower third, FX, annotation, clip-transform), removes all audio overlays, and turns captions off (keeping the user's chosen caption template + style overrides so re-enabling later restores their look). Clips, transcripts, cleaned audio, and the project aspect ratio are NOT touched. Use this when the user says 'start over', 'clear all edits', or 'reset the timeline' — instead of looping project_remove_region (which N-tuples revisions and failure points). Pass full=true to also clear per-clip LUTs + crops + webcam layout + wallpaper for a true blank canvas. Returns a `cleared` summary listing how many of each kind were removed.",
1104
+ inputSchema: {
1105
+ type: "object",
1106
+ properties: {
1107
+ id: { type: "string" },
1108
+ path: { type: "string" },
1109
+ full: {
1110
+ type: "boolean",
1111
+ description:
1112
+ "Also reset project-level visual config (per-clip LUT presets, LUT intensity, screen crop, webcam crop, webcam layout, wallpaper). Default false — only time-based edits + captions.enabled are cleared. Aspect ratio is NEVER reset.",
1113
+ },
1114
+ expectedRevision: { type: "number" },
1115
+ },
1116
+ },
1117
+ command: "project.clear-edits",
1118
+ },
1085
1119
  {
1086
1120
  name: "project_update_region",
1087
1121
  description:
@@ -1360,6 +1394,23 @@ const TOOLS = [
1360
1394
  },
1361
1395
  command: "project.set-clip-lut",
1362
1396
  },
1397
+ {
1398
+ name: "project_set_clip_kind",
1399
+ description:
1400
+ "Stamp a clip's capture origin authoritatively: kind = camera | screen | upload. project.read returns each clip's kind (your visual-strategy signal: camera → designed segments + emphasis zooms; screen → cursor zooms). On pre-v1.28 projects kind wasn't recorded, so project.read INFERS it (flagged kindInferred:true) — and inference can be wrong. Use this to correct/lock it. `camera` = talking-head; `screen` = screen recording (maybe with webcam PiP); `upload` = imported file.",
1401
+ inputSchema: {
1402
+ type: "object",
1403
+ properties: {
1404
+ id: { type: "string" },
1405
+ path: { type: "string" },
1406
+ clipId: { type: "string", description: "Clip id from project_read mainTrack.clips[n].id" },
1407
+ kind: { type: "string", enum: ["camera", "screen", "upload"] },
1408
+ expectedRevision: { type: "number" },
1409
+ },
1410
+ required: ["clipId", "kind"],
1411
+ },
1412
+ command: "project.set-clip-kind",
1413
+ },
1363
1414
 
1364
1415
  // ── transcript-based editing ────────────────────────────────────
1365
1416
  {
@@ -1439,6 +1490,25 @@ const TOOLS = [
1439
1490
  },
1440
1491
  command: "transcript.search",
1441
1492
  },
1493
+ {
1494
+ name: "transcript_find_issues",
1495
+ description:
1496
+ "Scan the transcript for editorial problems the speaker created and recovered from: **duplicate-take** (a line re-recorded later — keep the cleaner second take, cut the first), **false-start** (an abandoned fragment before a restart), and **adjacent-repeat** (a stutter like 'the the'). Returns candidate `issues`, each with `type`, `severity`, the `wordIds` of the DISCARDED attempt (pass straight to transcript.delete-words), the edited-time span, the offending `text`, and a `note` explaining what's kept. CONSERVATIVE and read-only — it never edits; review each candidate against context before deleting, since some repeats are intentional. Run this after transcribe + remove-fillers as the content-cleanup pass. Filter with `types` (comma-separated) and cap with `limit`.",
1497
+ inputSchema: {
1498
+ type: "object",
1499
+ properties: {
1500
+ id: { type: "string" },
1501
+ path: { type: "string" },
1502
+ types: {
1503
+ type: "string",
1504
+ description:
1505
+ "Optional comma-separated filter: any of `duplicate-take`, `false-start`, `adjacent-repeat`. Omit for all.",
1506
+ },
1507
+ limit: { type: "number", description: "Optional max number of issues to return." },
1508
+ },
1509
+ },
1510
+ command: "transcript.find-issues",
1511
+ },
1442
1512
  {
1443
1513
  name: "transcript_find_replace",
1444
1514
  description:
@@ -1467,7 +1537,8 @@ const TOOLS = [
1467
1537
  path: { type: "string" },
1468
1538
  thresholdMs: {
1469
1539
  type: "number",
1470
- description: "Gaps longer than this are trimmed. Default 700ms.",
1540
+ description:
1541
+ "Gaps longer than this are trimmed. Default 500ms — same threshold as the UI Remove Silences button, so the agent removes the same silences a manual click would.",
1471
1542
  },
1472
1543
  expectedRevision: { type: "number" },
1473
1544
  },
@@ -1510,7 +1581,7 @@ const TOOLS = [
1510
1581
  {
1511
1582
  name: "caption_set_template",
1512
1583
  description:
1513
- "Pick a caption template: classic, modern, minimal, bold, spotlight, boxed, neon, colored, or texture. `texture` fills large uppercase words with a flowing texture mask (lava/marble/metal/wood/concrete/rock) — pick the texture via caption_set_style `texture` (defaults to lava).",
1584
+ "Pick a caption template: classic, modern, minimal, bold, spotlight, boxed, neon, colored, texture, or editorial. `texture` fills large uppercase words with a flowing texture mask (lava/marble/metal/wood/concrete/rock) — pick the texture via caption_set_style `texture` (defaults to lava). `editorial` is a magazine-emphasis style: the word being spoken right now renders large (and takes an accent color) while the rest of the line shrinks, so one big word sweeps across the line in time with the speech.",
1514
1585
  inputSchema: {
1515
1586
  type: "object",
1516
1587
  properties: {
@@ -1528,6 +1599,7 @@ const TOOLS = [
1528
1599
  "neon",
1529
1600
  "colored",
1530
1601
  "texture",
1602
+ "editorial",
1531
1603
  ],
1532
1604
  },
1533
1605
  expectedRevision: { type: "number" },
@@ -1623,7 +1695,49 @@ const TOOLS = [
1623
1695
  command: "media.generate-image",
1624
1696
  },
1625
1697
  // `motion_generate` removed in v1.31.0 — see comment above the
1626
- // motion-graphics section. Authoring path is `motion_render_html`.
1698
+ // motion-graphics section.
1699
+ {
1700
+ name: "motion_list",
1701
+ description:
1702
+ "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.",
1703
+ inputSchema: { type: "object", properties: {} },
1704
+ command: "motion.list",
1705
+ },
1706
+ {
1707
+ name: "motion_generate",
1708
+ description:
1709
+ "Render a bundled template by id with your own slot values (text, colors, list items) and a background mode, then add the result to the timeline with project_add_motion_graphic (or project_add_designed_segment for split-panel). Async — returns { jobId, outputPath }; call job_wait, then pass that jobId as `fromJob` to the add tool. Discover templates + slots with motion_list. Prefer this over motion_render_html whenever a bundled template fits the brief — it's faster and already designed.",
1710
+ inputSchema: {
1711
+ type: "object",
1712
+ properties: {
1713
+ templateId: {
1714
+ type: "string",
1715
+ description: "Template id from motion_list (e.g. creator-card, stat-reveal, split-panel).",
1716
+ },
1717
+ slots: {
1718
+ type: "object",
1719
+ description:
1720
+ "Editable values keyed by slot key (see motion_list / the SKILL catalog): text strings, color hex strings, or list arrays. Omitted slots fall back to the template default.",
1721
+ },
1722
+ aspectRatio: {
1723
+ type: "string",
1724
+ enum: ["16:9", "9:16", "1:1"],
1725
+ description: "Defaults to the template's first listed aspect.",
1726
+ },
1727
+ background: {
1728
+ type: "string",
1729
+ enum: ["solid", "transparent", "glass"],
1730
+ description:
1731
+ "'solid' = hard full-frame card. 'transparent' = alpha; camera shows through un-painted pixels. 'glass' = alpha + frosted blur of the camera behind the content (then set backdropBlurStrength on project_add_motion_graphic). Omit to use the template's natural mode — overlay templates (split-panel, lower thirds, grain/3D/shatter/parallax titles) default to transparent, opaque cards to solid. Don't force 'solid' on an overlay template — its see-through half turns black.",
1732
+ },
1733
+ outputName: { type: "string", description: "Optional filename stem (no extension)." },
1734
+ },
1735
+ required: ["templateId", "slots"],
1736
+ },
1737
+ command: "motion.generate",
1738
+ },
1739
+ // Custom HTML authoring path is `motion_render_html` (for briefs no
1740
+ // bundled template fits).
1627
1741
  {
1628
1742
  name: "motion_render_html",
1629
1743
  description:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@writepanda/mcp",
3
- "version": "1.38.0",
3
+ "version": "1.44.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",