@writepanda/mcp 1.194.0 → 1.200.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 +171 -36
- package/package.json +1 -1
package/bin/server.mjs
CHANGED
|
@@ -620,10 +620,43 @@ const TOOLS = [
|
|
|
620
620
|
{
|
|
621
621
|
name: "system_status",
|
|
622
622
|
description:
|
|
623
|
-
"App version and license; automationGated true = trial expired, every other tool fails. Call first.",
|
|
623
|
+
"App version and license; automationGated true = trial expired, every other tool fails; license.socialPublishing.allowed false = the plan has no Instagram/TikTok/social publishing (Creator, Team, Pro only). Call first.",
|
|
624
624
|
inputSchema: { type: "object", properties: {} },
|
|
625
625
|
command: "system.status",
|
|
626
626
|
},
|
|
627
|
+
{
|
|
628
|
+
name: "system_report_issue",
|
|
629
|
+
description:
|
|
630
|
+
"Report a PandaStudio problem to the team (emailed; repeats group into one issue). Call it yourself, without asking, on a capability gap, an unexpected command failure, or output that doesn't match the project; then say in chat that you reported it. Not for user mistakes, missing keys, network or taste. Technical facts only: never put transcript/captions in title or details (userContent + userConsented only after the user agrees). sent=false with a reason: don't retry.",
|
|
631
|
+
inputSchema: {
|
|
632
|
+
type: "object",
|
|
633
|
+
properties: {
|
|
634
|
+
title: { type: "string", description: "One line: what's broken." },
|
|
635
|
+
details: {
|
|
636
|
+
type: "string",
|
|
637
|
+
description: "What happened and your diagnosis (no user content).",
|
|
638
|
+
},
|
|
639
|
+
kind: {
|
|
640
|
+
type: "string",
|
|
641
|
+
enum: ["capability-gap", "command-failed", "wrong-output", "crash", "confusing", "other"],
|
|
642
|
+
},
|
|
643
|
+
key: {
|
|
644
|
+
type: "string",
|
|
645
|
+
description: "Kebab-case problem name, e.g. custom-font-not-in-export.",
|
|
646
|
+
},
|
|
647
|
+
userGoal: { type: "string" },
|
|
648
|
+
command: { type: "string", description: "e.g. caption.set-style" },
|
|
649
|
+
workaround: { type: "string" },
|
|
650
|
+
agent: { type: "string", description: "Your runtime / model." },
|
|
651
|
+
id: { type: "string", description: "Project id (default: open project)." },
|
|
652
|
+
path: { type: "string" },
|
|
653
|
+
userContent: { type: "string" },
|
|
654
|
+
userConsented: { type: "boolean" },
|
|
655
|
+
},
|
|
656
|
+
required: ["title", "details"],
|
|
657
|
+
},
|
|
658
|
+
command: "system.report-issue",
|
|
659
|
+
},
|
|
627
660
|
{
|
|
628
661
|
name: "skill_read",
|
|
629
662
|
description:
|
|
@@ -1052,51 +1085,88 @@ const TOOLS = [
|
|
|
1052
1085
|
},
|
|
1053
1086
|
command: "export.publish-youtube",
|
|
1054
1087
|
},
|
|
1088
|
+
// ── Social publishing (2.0.3): Instagram, TikTok, Facebook, LinkedIn, X ──
|
|
1089
|
+
// Through PandaQueue; every verb acts on the ACTIVE workspace's own
|
|
1090
|
+
// accounts. The older instagram.* verbs remain callable via pandastudio_call.
|
|
1055
1091
|
{
|
|
1056
|
-
name: "
|
|
1092
|
+
name: "social_channels",
|
|
1057
1093
|
description:
|
|
1058
|
-
"
|
|
1094
|
+
"Social accounts connected in the active workspace (Instagram, TikTok, Facebook, LinkedIn, X) with ids, limits and per-post settings, plus each network's count.",
|
|
1059
1095
|
inputSchema: { type: "object", properties: {} },
|
|
1060
|
-
command: "
|
|
1096
|
+
command: "social.channels",
|
|
1061
1097
|
},
|
|
1062
1098
|
{
|
|
1063
|
-
name: "
|
|
1064
|
-
description:
|
|
1099
|
+
name: "social_connect",
|
|
1100
|
+
description:
|
|
1101
|
+
"Connect a network to the active workspace: opens its sign-in in the user's browser, returns { sessionId } at once; poll social_connect_status. Instagram: Business/Creator only.",
|
|
1065
1102
|
inputSchema: {
|
|
1066
1103
|
type: "object",
|
|
1067
1104
|
properties: {
|
|
1068
|
-
|
|
1105
|
+
network: { type: "string", enum: ["instagram", "tiktok", "facebook", "linkedin", "x"] },
|
|
1069
1106
|
},
|
|
1107
|
+
required: ["network"],
|
|
1070
1108
|
},
|
|
1071
|
-
command: "
|
|
1109
|
+
command: "social.connect",
|
|
1072
1110
|
},
|
|
1073
1111
|
{
|
|
1074
|
-
name: "
|
|
1075
|
-
description: "
|
|
1076
|
-
inputSchema: {
|
|
1077
|
-
|
|
1112
|
+
name: "social_connect_status",
|
|
1113
|
+
description: "{ state: pending | connected | failed, channels } for a social_connect session.",
|
|
1114
|
+
inputSchema: {
|
|
1115
|
+
type: "object",
|
|
1116
|
+
properties: { sessionId: { type: "string" } },
|
|
1117
|
+
required: ["sessionId"],
|
|
1118
|
+
},
|
|
1119
|
+
command: "social.connect-status",
|
|
1078
1120
|
},
|
|
1079
1121
|
{
|
|
1080
|
-
name: "
|
|
1122
|
+
name: "social_disconnect",
|
|
1081
1123
|
description:
|
|
1082
|
-
"Disconnect
|
|
1083
|
-
inputSchema: {
|
|
1084
|
-
|
|
1124
|
+
"Disconnect one social account (id from social_channels). Destructive: user confirms (see instructions).",
|
|
1125
|
+
inputSchema: {
|
|
1126
|
+
type: "object",
|
|
1127
|
+
properties: { channelId: { type: "string" } },
|
|
1128
|
+
required: ["channelId"],
|
|
1129
|
+
},
|
|
1130
|
+
command: "social.disconnect",
|
|
1085
1131
|
},
|
|
1086
1132
|
{
|
|
1087
|
-
name: "
|
|
1133
|
+
name: "export_publish_social",
|
|
1088
1134
|
description:
|
|
1089
|
-
"
|
|
1135
|
+
"Post an export entry to connected social accounts, now or scheduled. Public: confirm accounts + caption first. Returns { jobId }; job_wait gives { state, channels[{ permalink, error }], summary }.",
|
|
1090
1136
|
inputSchema: {
|
|
1091
1137
|
type: "object",
|
|
1092
1138
|
properties: {
|
|
1093
1139
|
id: { type: "string", description: "Export entry id." },
|
|
1094
|
-
|
|
1095
|
-
|
|
1140
|
+
channelIds: {
|
|
1141
|
+
type: "array",
|
|
1142
|
+
items: { type: "string" },
|
|
1143
|
+
description: "Account ids from social_channels.",
|
|
1144
|
+
},
|
|
1145
|
+
networks: {
|
|
1146
|
+
type: "array",
|
|
1147
|
+
items: { type: "string" },
|
|
1148
|
+
description: "Every connected account of these networks.",
|
|
1149
|
+
},
|
|
1150
|
+
caption: { type: "string" },
|
|
1151
|
+
captions: { type: "object", description: "{ channelId: caption } overrides." },
|
|
1152
|
+
settings: { type: "object", description: "{ channelId: { ...network settings } }." },
|
|
1153
|
+
when: { type: "string", enum: ["now", "schedule"] },
|
|
1154
|
+
scheduledAt: { type: "string", description: "ISO 8601 with offset; for schedule." },
|
|
1096
1155
|
},
|
|
1097
1156
|
required: ["id"],
|
|
1098
1157
|
},
|
|
1099
|
-
command: "export.publish-
|
|
1158
|
+
command: "export.publish-social",
|
|
1159
|
+
},
|
|
1160
|
+
{
|
|
1161
|
+
name: "social_post_status",
|
|
1162
|
+
description:
|
|
1163
|
+
"Status and links of a post from export_publish_social (pass exportId to update the export's record).",
|
|
1164
|
+
inputSchema: {
|
|
1165
|
+
type: "object",
|
|
1166
|
+
properties: { postId: { type: "string" }, exportId: { type: "string" } },
|
|
1167
|
+
required: ["postId"],
|
|
1168
|
+
},
|
|
1169
|
+
command: "social.post-status",
|
|
1100
1170
|
},
|
|
1101
1171
|
{
|
|
1102
1172
|
name: "export_list_youtube",
|
|
@@ -2043,19 +2113,55 @@ const TOOLS = [
|
|
|
2043
2113
|
command: "project.remove-bleep",
|
|
2044
2114
|
},
|
|
2045
2115
|
{
|
|
2046
|
-
name: "
|
|
2116
|
+
name: "project_follow_speaker",
|
|
2117
|
+
description:
|
|
2118
|
+
"Podcast recordings (each person on their own camera): cut the frame to whoever is talking from the transcript's speaker tags. podcast-solo per turn, podcast-pair (both) in quick back-and-forth, no cut for short interjections. Anchored, re-runnable; run after the cuts. One wide shot of several people: project_auto_reframe instead.",
|
|
2119
|
+
inputSchema: {
|
|
2120
|
+
type: "object",
|
|
2121
|
+
properties: {
|
|
2122
|
+
id: { type: "string" },
|
|
2123
|
+
path: { type: "string" },
|
|
2124
|
+
minTurnMs: { type: "number", description: "Shorter turns don't cut away (default 1200)." },
|
|
2125
|
+
pair: {
|
|
2126
|
+
type: "boolean",
|
|
2127
|
+
description: "Both people during quick exchanges (default true).",
|
|
2128
|
+
},
|
|
2129
|
+
exchangeTurnMs: {
|
|
2130
|
+
type: "number",
|
|
2131
|
+
description: "Turn length that counts as quick (default 2600).",
|
|
2132
|
+
},
|
|
2133
|
+
dryRun: { type: "boolean" },
|
|
2134
|
+
expectedRevision: { type: "number" },
|
|
2135
|
+
},
|
|
2136
|
+
},
|
|
2137
|
+
command: "project.follow-speaker",
|
|
2138
|
+
},
|
|
2139
|
+
{
|
|
2140
|
+
name: "project_check_broll",
|
|
2047
2141
|
description:
|
|
2048
|
-
"B-roll, the LAST step of an edit
|
|
2142
|
+
"B-roll, the LAST step of an edit. YOU pick the moments from what's said (transcript_get; any language, any topic; in a Short ~1 per 6-8 s with the first right after the opening line, in long-form ~1 per 10-15 s) and what each picture shows; this checks them: span, clashes with the steps list / end card / other pictures, spacing, a nearby suggestion when blocked, insetSide (card away from the face). No moments: free stretches. Returns imageConnector. Never makes images: show the user your moments and ASK: their own images, generate on their connector (uses credits), or none. No one to ask: skip it and say so.",
|
|
2049
2143
|
inputSchema: {
|
|
2050
2144
|
type: "object",
|
|
2051
2145
|
properties: {
|
|
2052
2146
|
id: { type: "string" },
|
|
2053
2147
|
path: { type: "string" },
|
|
2054
|
-
|
|
2148
|
+
moments: {
|
|
2149
|
+
type: "array",
|
|
2150
|
+
items: {
|
|
2151
|
+
type: "object",
|
|
2152
|
+
properties: {
|
|
2153
|
+
wordId: { type: "string" },
|
|
2154
|
+
atMs: { type: "number" },
|
|
2155
|
+
endWordId: { type: "string" },
|
|
2156
|
+
durationMs: { type: "number" },
|
|
2157
|
+
picture: { type: "string", description: "What the picture shows." },
|
|
2158
|
+
},
|
|
2159
|
+
},
|
|
2160
|
+
},
|
|
2055
2161
|
minGapMs: { type: "number" },
|
|
2056
2162
|
},
|
|
2057
2163
|
},
|
|
2058
|
-
command: "project.
|
|
2164
|
+
command: "project.check-broll",
|
|
2059
2165
|
},
|
|
2060
2166
|
{
|
|
2061
2167
|
name: "project_add_broll",
|
|
@@ -3695,7 +3801,11 @@ const TOOLS = [
|
|
|
3695
3801
|
path: { type: "string" },
|
|
3696
3802
|
wordsPerLine: { type: "number" },
|
|
3697
3803
|
positionY: { type: "number", description: "% from the top, default 85." },
|
|
3698
|
-
fontFamily: {
|
|
3804
|
+
fontFamily: {
|
|
3805
|
+
type: "string",
|
|
3806
|
+
description:
|
|
3807
|
+
"A family from asset_list_fonts (bundled, custom or system). Unknown names render in Inter and come back as a warning.",
|
|
3808
|
+
},
|
|
3699
3809
|
color: { type: "string" },
|
|
3700
3810
|
backgroundColor: { type: "string" },
|
|
3701
3811
|
highlightColor: { type: "string", description: "Spoken word." },
|
|
@@ -3776,7 +3886,7 @@ const TOOLS = [
|
|
|
3776
3886
|
{
|
|
3777
3887
|
name: "media_generate_image",
|
|
3778
3888
|
description:
|
|
3779
|
-
"Generate one image on the user's own image connector (auto: Replicate, else Higgsfield; their credits). Only after the user agreed to generating (ask first; B-roll:
|
|
3889
|
+
"Generate one image on the user's own image connector (auto: Replicate, else Higgsfield; their credits). Only after the user agreed to generating (ask first; B-roll: pick moments, project_check_broll, then ask). Returns { imagePath, provider, model, transparent }. transparent=true: trimmed PNG sticker. No connector: code NO_IMAGE_CONNECTOR, so ask the user for their own images. Each call is a paid generation.",
|
|
3780
3890
|
inputSchema: {
|
|
3781
3891
|
type: "object",
|
|
3782
3892
|
properties: {
|
|
@@ -4390,6 +4500,21 @@ const TOOLS = [
|
|
|
4390
4500
|
},
|
|
4391
4501
|
command: "recipe.list",
|
|
4392
4502
|
},
|
|
4503
|
+
{
|
|
4504
|
+
name: "recipe_pick",
|
|
4505
|
+
description:
|
|
4506
|
+
"No style named ('edit my video', 'make this a Short')? The recipes that fit this project's format and footage, each with pickWhen, plus defaultId. Choose by what's said, then recipe_apply_style + recipe_render.",
|
|
4507
|
+
inputSchema: {
|
|
4508
|
+
type: "object",
|
|
4509
|
+
properties: {
|
|
4510
|
+
id: { type: "string", description: "Project id (default: the open project)." },
|
|
4511
|
+
path: { type: "string" },
|
|
4512
|
+
format: { type: "string", enum: ["short", "long"] },
|
|
4513
|
+
footage: { type: "string", enum: ["camera", "screen", "podcast", "none"] },
|
|
4514
|
+
},
|
|
4515
|
+
},
|
|
4516
|
+
command: "recipe.pick",
|
|
4517
|
+
},
|
|
4393
4518
|
{
|
|
4394
4519
|
name: "recipe_get",
|
|
4395
4520
|
description: "Read one recipe in full.",
|
|
@@ -4769,6 +4894,18 @@ const TOOLS = [
|
|
|
4769
4894
|
inputSchema: { type: "object", properties: {} },
|
|
4770
4895
|
command: "asset.list-luts",
|
|
4771
4896
|
},
|
|
4897
|
+
{
|
|
4898
|
+
name: "asset_list_fonts",
|
|
4899
|
+
description:
|
|
4900
|
+
"Font families text can use: bundled, scriptFallbacks (Noto, used per character for Indic/Arabic/Hebrew/Thai text), custom (the user's imported fonts; prefer one covering the video's language), system with includeSystem. Pass one to caption_set_style fontFamily.",
|
|
4901
|
+
inputSchema: {
|
|
4902
|
+
type: "object",
|
|
4903
|
+
properties: {
|
|
4904
|
+
includeSystem: { type: "boolean", description: "Also list installed families (long)." },
|
|
4905
|
+
},
|
|
4906
|
+
},
|
|
4907
|
+
command: "asset.list-fonts",
|
|
4908
|
+
},
|
|
4772
4909
|
|
|
4773
4910
|
// ── project-aware LLM ──────────────────────────────────────────
|
|
4774
4911
|
{
|
|
@@ -5172,24 +5309,22 @@ Start with system_status. Unknown arguments are rejected. Verbs without a tool o
|
|
|
5172
5309
|
|
|
5173
5310
|
Before an editing pass, read the skill's "Which tool for which moment" section (skill_read section="Which tool for which moment").
|
|
5174
5311
|
|
|
5175
|
-
"Edit my video" with no specifics = this pipeline, in order. Confirm scope once ("full polish, or just part of it?"), then run it all:
|
|
5312
|
+
"Edit my video" / "make this a Short" with no specifics = this pipeline, in order. Confirm scope once ("full polish, or just part of it?"), then run it all:
|
|
5176
5313
|
1. transcript_transcribe clips not yet transcribed (project_read clipStates).
|
|
5177
5314
|
2. transcript_remove_fillers.
|
|
5178
5315
|
3. Fix misheard names / brands with transcript_find_replace (transcript_insert_words for dropped words).
|
|
5179
5316
|
4. transcript_find_issues, then transcript_delete_words on each duplicate take / false start (keep the LAST take; keep severity "low" ones).
|
|
5180
5317
|
5. transcript_remove_silences.
|
|
5181
5318
|
6. audio_clean clips not yet cleaned.
|
|
5182
|
-
7.
|
|
5183
|
-
8. B-roll, last:
|
|
5319
|
+
7. The style, after steps 2-5 (they shift the timeline). The user's named style, recipe, creator or a saved memory wins. Otherwise call recipe_pick: it returns the recipes that fit this project's format and footage, each with pickWhen, plus defaultId. Read the transcript, choose the ONE candidate whose pickWhen matches what is said (defaultId when none clearly fits), do its "before" step if any, then recipe_apply_style + recipe_render and follow the prompt: the recipe decides captions, graphics, zooms, music and transitions. (An app without recipe_pick, 2.0.5 and older: recipe_list with format short or long, and choose by description and footage.) Tell the user which recipe and why in one line and name one or two alternatives. Only when no candidate exists or the user asked for a plain clean-up: captions (caption_toggle, template glowStack), a few motion graphics, emphasis zooms.
|
|
5320
|
+
8. B-roll, last: pick the moments yourself from what's said (any language), check them with project_check_broll, show the user your moments and ASK: their own images, generated on their image connector (only if one is connected; it uses their credits), or no B-roll. Never generate or invent images without their answer. Place what they give with project_add_broll. Nobody to ask: skip it and say so.
|
|
5184
5321
|
9. llm_generate_title / description / timestamps, then preview_show and ask before export_start. Never export before the user has seen the preview.
|
|
5185
|
-
Report the real count each step returned.
|
|
5322
|
+
Report the real count each step returned. No music, intro/outro cards or FX overlays unless the recipe or the user asks for them.
|
|
5323
|
+
A single named operation ("just add captions", "remove the silences") is exactly that: no recipe.
|
|
5186
5324
|
|
|
5187
|
-
|
|
5188
|
-
- Long-form 16:9 with the speaker on camera: the Ali style recipe, id educator-talking-head-chapters (recipe_apply_style, then recipe_render and follow its prompt). It keeps burned-in captions OFF (keyword pops instead). Not for camera-less screen recordings or Loom-style internal videos.
|
|
5189
|
-
- Shorts / Reels / TikTok (9:16): the Shorts recipe that fits: hard-truth-one-liner-short (one blunt claim), rules-listicle-cutaways-short (numbered tips), rapid-fire-list-short (many one-line items), storytime-turn-short (story with a twist), framework-explainer-short (one concept), split-screen-short-broll (showable things), social-ad-hook-variants (selling an offer), faceless-short (no footage), else warm-educator-short.
|
|
5190
|
-
A Short from a SCREEN RECORDING first gets project_set_vertical_screen_layout, then the recipe. Say which recipe you used and why, and offer others (recipe_list).
|
|
5325
|
+
Destructive actions need the user's own confirmation: project_delete, workspace_delete, recipe_delete, memory_forget, export_delete, export_clear_thumbnail, youtube_disconnect, social_disconnect. Ask plainly in chat first ("Delete project 'Demo'? This can't be undone.") and call only after they agree. PandaStudio then confirms with them itself: in its own chat the call returns confirmation_required and changes nothing while a Delete / Cancel card waits (tell them to press it; don't call again; the outcome arrives as their next message); from other apps a dialog asks, and the call is refused when nobody is at the app. Nothing you send can approve it.
|
|
5191
5326
|
|
|
5192
|
-
|
|
5327
|
+
PandaStudio problems (a capability gap like an imported font the export can't draw, a command failing unexpectedly, a render not matching the project): call system_report_issue yourself, then tell the user you reported it. Not for user mistakes, missing keys or taste.
|
|
5193
5328
|
|
|
5194
5329
|
Destination decides everything: infer it (Shorts/TikTok/vertical/<=90s: shorts; YouTube/tutorial/>8 min: youtube-long; LinkedIn; Loom/internal), else ask once.
|
|
5195
5330
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@writepanda/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.200.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",
|