@writepanda/mcp 1.116.0 → 1.119.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 +165 -1
  2. package/package.json +2 -2
package/bin/server.mjs CHANGED
@@ -668,6 +668,20 @@ const TOOLS = [
668
668
  },
669
669
  command: "project.rename",
670
670
  },
671
+ {
672
+ name: "project_duplicate",
673
+ description:
674
+ "Duplicate a project — exact copy with all edits (trims, zooms, overlays, captions, transcript, everything), new id + '(copy)' name. Identify the source by `id` (preferred) or `path`. The source is untouched (non-destructive); media files are shared, not copied. Returns { id, path, name } of the new project. Use when the user asks to duplicate, copy, or clone a project.",
675
+ inputSchema: {
676
+ type: "object",
677
+ properties: {
678
+ id: { type: "string", description: "Source project UUID (preferred)." },
679
+ path: { type: "string", description: "Absolute source project file path." },
680
+ },
681
+ required: ["id"],
682
+ },
683
+ command: "project.duplicate",
684
+ },
671
685
  {
672
686
  name: "project_locate",
673
687
  description:
@@ -2703,7 +2717,7 @@ const TOOLS = [
2703
2717
  {
2704
2718
  name: "media_generate_image",
2705
2719
  description:
2706
- 'Generate a single image via Replicate gpt-image-2 — for B-roll, concept stills, reference frames. Project-agnostic; writes to <userData>/generated-images/ and returns { imagePath, prompt, aspectRatio, predictionId }. The canonical B-roll workflow is: media_generate_image → motion_render_html (Ken-Burns + vignette wrap to a WebM) → project_add_motion_graphic — see SKILL.md "B-roll generation". Aspect ratios are gpt-image-2 native (1:1 / 3:2 / 2:3). For 16:9 video B-roll, generate 3:2 and crop in the wrap; for 9:16, generate 2:3. Requires the user\'s Replicate API key (Settings → Integrations).',
2720
+ 'Generate a single image via Replicate gpt-image-2 — for B-roll, concept stills, reference frames. Project-agnostic; writes to <userData>/generated-images/ and returns { imagePath, prompt, aspectRatio, predictionId }. For a FACELESS / image-driven video, pair with media_image_to_video (one-call Ken-Burns clip → project_add_clip). For B-roll layered over footage, the motion_render_html wrap (Ken-Burns + vignette → project_add_motion_graphic) still applies — see SKILL.md "Faceless videos" / "B-roll generation". Aspect ratios are gpt-image-2 native (1:1 / 3:2 / 2:3). For 16:9 generate 3:2; for 9:16 generate 2:3. Requires the user\'s Replicate API key (Settings → Integrations).',
2707
2721
  inputSchema: {
2708
2722
  type: "object",
2709
2723
  properties: {
@@ -2734,6 +2748,50 @@ const TOOLS = [
2734
2748
  },
2735
2749
  command: "media.generate-image",
2736
2750
  },
2751
+ {
2752
+ name: "media_image_to_video",
2753
+ description:
2754
+ "Turn a STILL image into a Ken-Burns video clip (slow pan/zoom) via FFmpeg — the native, one-call way to build faceless / image-driven videos. Takes an imagePath + durationMs, writes an H.264 MP4 to <userData>/ken-burns/, and returns { videoPath, durationMs, width, height }. Feed videoPath straight into project_add_clip. Fast, deterministic alternative to the motion_render_html Ken-Burns wrap (no headless browser). Canonical faceless-short loop: media_generate_image (2:3 for 9:16) → media_image_to_video (per beat, alternate zoom in/out) → project_add_clip, then media_generate_narration → project_add_audio at each clip's cumulative start.",
2755
+ inputSchema: {
2756
+ type: "object",
2757
+ properties: {
2758
+ imagePath: {
2759
+ type: "string",
2760
+ description: "Absolute path (or file:// URL) to the source still image.",
2761
+ },
2762
+ durationMs: {
2763
+ type: "number",
2764
+ description:
2765
+ "Clip length in ms. Match to the beat's narration length + a small tail (300-500ms) so the visual holds until the VO finishes.",
2766
+ },
2767
+ aspectRatio: {
2768
+ type: "string",
2769
+ description:
2770
+ "Output frame: '16:9' (default) | '9:16' (shorts) | '1:1' | '4:5' | '2:3' | '3:2'. The still is scaled to COVER these dims then panned.",
2771
+ },
2772
+ zoom: {
2773
+ type: "string",
2774
+ description:
2775
+ "Motion: 'in' (default, push in) | 'out' (pull out) | 'none' (static). Alternate in/out across beats for a lively cut.",
2776
+ },
2777
+ zoomAmount: {
2778
+ type: "number",
2779
+ description:
2780
+ "Peak zoom delta 0.05-0.4 (default 0.12 → ends at 1.12×). Keep ≤0.2 for a subtle documentary feel.",
2781
+ },
2782
+ fps: {
2783
+ type: "number",
2784
+ description: "Output frame rate (default 30).",
2785
+ },
2786
+ outputName: {
2787
+ type: "string",
2788
+ description: "Optional file-stem hint. Slugified; timestamp appended automatically.",
2789
+ },
2790
+ },
2791
+ required: ["imagePath", "durationMs"],
2792
+ },
2793
+ command: "media.image-to-video",
2794
+ },
2737
2795
  {
2738
2796
  name: "media_generate_narration",
2739
2797
  description:
@@ -2800,6 +2858,112 @@ const TOOLS = [
2800
2858
  },
2801
2859
  command: "media.generate-music",
2802
2860
  },
2861
+ {
2862
+ name: "media_list_avatars",
2863
+ description:
2864
+ "List the HeyGen avatars on the user's account (studio avatars + talking photos) for talking-head video generation. Returns { avatars: [{ avatarId, name, kind, gender, previewImageUrl }], count }. Use an avatarId with media_generate_avatar_video (pass avatarKind='talking_photo' for a photo avatar). Requires the user's HeyGen API key (Settings → Integrations); the HeyGen API is a paid capability, not on every plan.",
2865
+ inputSchema: { type: "object", properties: {} },
2866
+ command: "media.list-avatars",
2867
+ },
2868
+ {
2869
+ name: "media_list_avatar_voices",
2870
+ description:
2871
+ "List the HeyGen voices on the user's account for talking-head video generation. Returns { voices: [{ voiceId, name, language, gender, previewAudioUrl }], count }. Use a voiceId with media_generate_avatar_video. Requires the user's HeyGen API key (Settings → Integrations).",
2872
+ inputSchema: { type: "object", properties: {} },
2873
+ command: "media.list-avatar-voices",
2874
+ },
2875
+ {
2876
+ name: "media_generate_avatar_video",
2877
+ description:
2878
+ "Generate a HeyGen talking-head video from the user's own avatar + a script. ASYNC: returns { jobId }; poll job_wait for { videoPath, durationSec, width, height }, then add it to the timeline with project_add_clip. Discover avatarId with media_list_avatars and voiceId with media_list_avatar_voices. Requires the user's HeyGen API key + credits (Settings → Integrations); renders server-side over minutes (poll with a generous timeout). Billed against the user's own HeyGen credits, not by PandaStudio.",
2879
+ inputSchema: {
2880
+ type: "object",
2881
+ properties: {
2882
+ avatarId: {
2883
+ type: "string",
2884
+ description: "HeyGen avatar id (from media_list_avatars).",
2885
+ },
2886
+ voiceId: {
2887
+ type: "string",
2888
+ description: "HeyGen voice id (from media_list_avatar_voices).",
2889
+ },
2890
+ script: {
2891
+ type: "string",
2892
+ description: "The text the avatar speaks. Plain text; HeyGen handles TTS.",
2893
+ },
2894
+ avatarKind: {
2895
+ type: "string",
2896
+ enum: ["avatar", "talking_photo"],
2897
+ description: "'avatar' (studio avatar, default) | 'talking_photo' (photo avatar).",
2898
+ },
2899
+ aspectRatio: {
2900
+ type: "string",
2901
+ enum: ["16:9", "9:16", "1:1"],
2902
+ description: "'16:9' (default, YouTube) | '9:16' (Shorts/Reels) | '1:1'.",
2903
+ },
2904
+ resolution: {
2905
+ type: "string",
2906
+ enum: ["720p", "1080p"],
2907
+ description: "'720p' (default, cheaper on credits) | '1080p'.",
2908
+ },
2909
+ speed: {
2910
+ type: "number",
2911
+ description: "Voice speed multiplier 0.5–1.5 (default 1).",
2912
+ },
2913
+ backgroundColor: {
2914
+ type: "string",
2915
+ description: "Optional solid background hex, e.g. '#000000'.",
2916
+ },
2917
+ outputName: {
2918
+ type: "string",
2919
+ description: "Optional file-stem hint; timestamp is appended. Defaults to the script head.",
2920
+ },
2921
+ },
2922
+ required: ["avatarId", "voiceId", "script"],
2923
+ },
2924
+ command: "media.generate-avatar-video",
2925
+ },
2926
+ {
2927
+ name: "memory_save",
2928
+ description:
2929
+ "Remember a durable fact or preference about this user/workspace, carried across ALL future chats (injected into every session). Use for STANDING context — brand, default caption/zoom styles, channel name + tone, recurring instructions ('always 9:16 for this client'). Do NOT use for one-off requests about the current edit. Idempotent on identical text. Returns { id, text }.",
2930
+ inputSchema: {
2931
+ type: "object",
2932
+ properties: {
2933
+ note: {
2934
+ type: "string",
2935
+ description:
2936
+ "One concise fact/preference, e.g. 'Channel is WritePanda; energetic tone, fast cuts' or 'Default caption template: editorial'.",
2937
+ },
2938
+ },
2939
+ required: ["note"],
2940
+ },
2941
+ command: "memory.save",
2942
+ },
2943
+ {
2944
+ name: "memory_forget",
2945
+ description:
2946
+ "Remove durable memory entries by id (from memory_list) or by a case-insensitive text substring. Use when a saved preference is outdated or wrong. Returns { removed, remaining }.",
2947
+ inputSchema: {
2948
+ type: "object",
2949
+ properties: {
2950
+ query: {
2951
+ type: "string",
2952
+ description:
2953
+ "An entry id (e.g. 'a1b2c3') for an exact remove, or a text fragment to remove every matching note.",
2954
+ },
2955
+ },
2956
+ required: ["query"],
2957
+ },
2958
+ command: "memory.forget",
2959
+ },
2960
+ {
2961
+ name: "memory_list",
2962
+ description:
2963
+ "List the durable memory for this workspace — the same notes injected into every chat. Returns { entries: [{ id, text }], count }. Rarely needed (memory is already in context); use to get ids for memory_forget or to audit what's stored.",
2964
+ inputSchema: { type: "object", properties: {} },
2965
+ command: "memory.list",
2966
+ },
2803
2967
  // `motion_generate` removed in v1.31.0 — see comment above the
2804
2968
  // motion-graphics section.
2805
2969
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@writepanda/mcp",
3
- "version": "1.116.0",
3
+ "version": "1.119.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",
@@ -36,7 +36,7 @@
36
36
  "LICENSE"
37
37
  ],
38
38
  "dependencies": {
39
- "@modelcontextprotocol/sdk": "^1.0.4"
39
+ "@modelcontextprotocol/sdk": "~1.29.0"
40
40
  },
41
41
  "publishConfig": {
42
42
  "access": "public"