@writepanda/mcp 1.87.0 → 1.92.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 +182 -9
- package/package.json +1 -1
package/bin/server.mjs
CHANGED
|
@@ -165,7 +165,7 @@ const TOOLS = [
|
|
|
165
165
|
{
|
|
166
166
|
name: "system_get_transcription_language",
|
|
167
167
|
description:
|
|
168
|
-
"Read the active transcription engine selection for the current workspace. Returns { language } where language is one of: 'auto' (Parakeet TDT v3, default — auto-detects English + 25 European languages including Russian/Ukrainian), 'chinese' / 'japanese' / 'korean' / 'hindi' / 'arabic' / 'thai'
|
|
168
|
+
"Read the active transcription engine selection for the current workspace. Returns { language } where language is one of: 'auto' (Parakeet TDT v3, default — auto-detects English + 25 European languages including Russian/Ukrainian), or a Whisper Large-v3-turbo language: 'chinese' / 'japanese' / 'korean' / 'hindi' / 'arabic' / 'thai' / 'tamil' / 'telugu' / 'kannada' / 'malayalam' / 'bengali' / 'marathi' / 'gujarati' / 'punjabi'. Use this when surfacing the active engine to the user or before recommending a switch.",
|
|
169
169
|
inputSchema: { type: "object", properties: {} },
|
|
170
170
|
command: "system.getTranscriptionLanguage",
|
|
171
171
|
},
|
|
@@ -178,7 +178,23 @@ const TOOLS = [
|
|
|
178
178
|
properties: {
|
|
179
179
|
language: {
|
|
180
180
|
type: "string",
|
|
181
|
-
enum: [
|
|
181
|
+
enum: [
|
|
182
|
+
"auto",
|
|
183
|
+
"chinese",
|
|
184
|
+
"japanese",
|
|
185
|
+
"korean",
|
|
186
|
+
"hindi",
|
|
187
|
+
"arabic",
|
|
188
|
+
"thai",
|
|
189
|
+
"tamil",
|
|
190
|
+
"telugu",
|
|
191
|
+
"kannada",
|
|
192
|
+
"malayalam",
|
|
193
|
+
"bengali",
|
|
194
|
+
"marathi",
|
|
195
|
+
"gujarati",
|
|
196
|
+
"punjabi",
|
|
197
|
+
],
|
|
182
198
|
description: "Target language. 'auto' = Parakeet (default); the others route to Whisper.",
|
|
183
199
|
},
|
|
184
200
|
},
|
|
@@ -444,6 +460,54 @@ const TOOLS = [
|
|
|
444
460
|
},
|
|
445
461
|
command: "export.publish-youtube",
|
|
446
462
|
},
|
|
463
|
+
{
|
|
464
|
+
name: "instagram_connect",
|
|
465
|
+
description:
|
|
466
|
+
"Start connecting an Instagram account. Opens the user's browser to the Instagram consent page and returns `{ connectionId, redirectUrl }`. INTERACTIVE: the user must finish consent in the browser, then poll `instagram_status` until active before publishing. Only Business/Creator accounts can publish (a Meta restriction). Requires an activated PandaStudio license.",
|
|
467
|
+
inputSchema: { type: "object", properties: {} },
|
|
468
|
+
command: "instagram.connect",
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
name: "instagram_status",
|
|
472
|
+
description:
|
|
473
|
+
"Check whether the Instagram connection is active yet. Returns `{ status, active }`. Poll after `instagram_connect` until `active` is true.",
|
|
474
|
+
inputSchema: {
|
|
475
|
+
type: "object",
|
|
476
|
+
properties: {
|
|
477
|
+
connectionId: { type: "string", description: "From instagram_connect (optional)." },
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
command: "instagram.status",
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
name: "instagram_account",
|
|
484
|
+
description:
|
|
485
|
+
"Read the connected Instagram account: `username`, `account_type`, and `publishable` (true only for Business/Creator accounts). Call before `export_publish_instagram` to warn the user if their account type can't publish.",
|
|
486
|
+
inputSchema: { type: "object", properties: {} },
|
|
487
|
+
command: "instagram.account",
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
name: "instagram_disconnect",
|
|
491
|
+
description:
|
|
492
|
+
"Disconnect the user's Instagram account. Already-published Reels stay on Instagram.",
|
|
493
|
+
inputSchema: { type: "object", properties: {} },
|
|
494
|
+
command: "instagram.disconnect",
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
name: "export_publish_instagram",
|
|
498
|
+
description:
|
|
499
|
+
"Publish an export-library entry to Instagram as a Reel. The video uploads directly to Composio storage (never through our server) and publishes via the broker. Returns `{ mediaId, permalink }`. LONG-RUNNING: Instagram processes the Reel for ~30-120 s before it goes live. Requires a connected Business/Creator account (check `instagram_account` first). Instagram only accepts short-form video — export a 9:16 clip up to ~90 s.",
|
|
500
|
+
inputSchema: {
|
|
501
|
+
type: "object",
|
|
502
|
+
properties: {
|
|
503
|
+
id: { type: "string", description: "Export entry id." },
|
|
504
|
+
caption: { type: "string", description: "Reel caption, max 2200 chars; hashtags go here." },
|
|
505
|
+
shareToFeed: { type: "boolean", description: "Also show in the feed grid. Default true." },
|
|
506
|
+
},
|
|
507
|
+
required: ["id"],
|
|
508
|
+
},
|
|
509
|
+
command: "export.publish-instagram",
|
|
510
|
+
},
|
|
447
511
|
{
|
|
448
512
|
name: "export_list_youtube",
|
|
449
513
|
description:
|
|
@@ -668,13 +732,18 @@ const TOOLS = [
|
|
|
668
732
|
{
|
|
669
733
|
name: "project_add_clip",
|
|
670
734
|
description:
|
|
671
|
-
"Append (or insert) a video clip into the project's main track. Probes duration via FFmpeg.",
|
|
735
|
+
"Append (or insert) a video clip into the project's main track. Probes duration via FFmpeg. Pass `webcam` (a second, separately-recorded source) to make the clip a two-speaker podcast composite (media=host, webcam=guest, kind=podcast) — for 3+ speakers or audio auto-sync use project_add_podcast_clip instead.",
|
|
672
736
|
inputSchema: {
|
|
673
737
|
type: "object",
|
|
674
738
|
properties: {
|
|
675
739
|
id: { type: "string" },
|
|
676
740
|
path: { type: "string" },
|
|
677
|
-
media: { type: "string", description: "Absolute path to video file" },
|
|
741
|
+
media: { type: "string", description: "Absolute path to video file (the host source)" },
|
|
742
|
+
webcam: {
|
|
743
|
+
type: "string",
|
|
744
|
+
description:
|
|
745
|
+
"Optional absolute path to a SECOND, separately-recorded source (the guest). When set, the clip becomes a two-speaker podcast composite. Use project_add_podcast_clip for 3+ participants or audio auto-sync.",
|
|
746
|
+
},
|
|
678
747
|
atIndex: {
|
|
679
748
|
type: "number",
|
|
680
749
|
description: "Insert before this zero-based clip index. Omit to append at the end.",
|
|
@@ -685,6 +754,83 @@ const TOOLS = [
|
|
|
685
754
|
},
|
|
686
755
|
command: "project.add-clip",
|
|
687
756
|
},
|
|
757
|
+
{
|
|
758
|
+
name: "project_add_podcast_clip",
|
|
759
|
+
description:
|
|
760
|
+
"Assemble 2-4 separately-recorded sources (e.g. host + guest exported from Zoom/Riverside) into ONE podcast composite clip — the import equivalent of an in-app/remote podcast recording. media=host (the authoritative clock); guests=ordered guest paths (1-3). Speakers are assigned host/guest/guest-2/guest-3 and stored as participants[]. By default auto-syncs each guest to the host via audio cross-correlation (set autoSync=false to skip); fine-tune later with project_set_participant_offset. After this, run transcript_transcribe (it transcribes each speaker separately and merges into one speaker-attributed transcript), then edit by transcript exactly like a recorded podcast. Preview + export render every participant via the existing N-party podcast layout.",
|
|
761
|
+
inputSchema: {
|
|
762
|
+
type: "object",
|
|
763
|
+
properties: {
|
|
764
|
+
id: { type: "string" },
|
|
765
|
+
path: { type: "string" },
|
|
766
|
+
media: { type: "string", description: "Absolute path to the HOST video (reference clock)" },
|
|
767
|
+
guests: {
|
|
768
|
+
type: "array",
|
|
769
|
+
items: { type: "string" },
|
|
770
|
+
description:
|
|
771
|
+
"Absolute paths to the 1-3 guest videos in participant order (guest, guest-2, guest-3).",
|
|
772
|
+
},
|
|
773
|
+
labels: {
|
|
774
|
+
type: "array",
|
|
775
|
+
items: { type: "string" },
|
|
776
|
+
description:
|
|
777
|
+
"Optional display names parallel to [host, ...guests] (index 0 = host). Falls back to the speaker id.",
|
|
778
|
+
},
|
|
779
|
+
autoSync: {
|
|
780
|
+
type: "boolean",
|
|
781
|
+
description:
|
|
782
|
+
"Audio-align each guest to the host before assembling (default true). Set false to assemble with zero offsets.",
|
|
783
|
+
},
|
|
784
|
+
atIndex: {
|
|
785
|
+
type: "number",
|
|
786
|
+
description: "0-based insert position in the clips array. Omit to append.",
|
|
787
|
+
},
|
|
788
|
+
expectedRevision: { type: "number" },
|
|
789
|
+
},
|
|
790
|
+
required: ["media", "guests"],
|
|
791
|
+
},
|
|
792
|
+
command: "project.add-podcast-clip",
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
name: "project_set_participant_offset",
|
|
796
|
+
description:
|
|
797
|
+
"Fine-tune ONE participant's A/V sync on a multi-party podcast composite. speaker = guest | guest-2 | guest-3 (the host is the reference clock and can't be offset). offsetMs shifts that participant's video AND audio vs the host: positive delays, negative advances, 0 clears (±10000). The N-party analogue of project_set_webcam_offset (which only reaches guest-1). Honored in preview + export.",
|
|
798
|
+
inputSchema: {
|
|
799
|
+
type: "object",
|
|
800
|
+
properties: {
|
|
801
|
+
id: { type: "string" },
|
|
802
|
+
path: { type: "string" },
|
|
803
|
+
clipId: { type: "string", description: "Clip id of the podcast composite" },
|
|
804
|
+
speaker: {
|
|
805
|
+
type: "string",
|
|
806
|
+
description: "Which participant to nudge: guest | guest-2 | guest-3",
|
|
807
|
+
},
|
|
808
|
+
offsetMs: {
|
|
809
|
+
type: "number",
|
|
810
|
+
description: "Time nudge in ms (±10000). Positive delays this guest; 0 clears.",
|
|
811
|
+
},
|
|
812
|
+
expectedRevision: { type: "number" },
|
|
813
|
+
},
|
|
814
|
+
required: ["clipId", "speaker", "offsetMs"],
|
|
815
|
+
},
|
|
816
|
+
command: "project.set-participant-offset",
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
name: "project_auto_sync_podcast",
|
|
820
|
+
description:
|
|
821
|
+
"Re-run audio auto-sync on an existing podcast composite clip: cross-correlates each guest's audio against the host and stores the resulting offset on each participant. Use after project_add_podcast_clip with autoSync=false, or to re-align if a manual nudge drifted. Returns the per-guest offsets + confidence; fine-tune afterward with project_set_participant_offset.",
|
|
822
|
+
inputSchema: {
|
|
823
|
+
type: "object",
|
|
824
|
+
properties: {
|
|
825
|
+
id: { type: "string" },
|
|
826
|
+
path: { type: "string" },
|
|
827
|
+
clipId: { type: "string", description: "Clip id of the podcast composite" },
|
|
828
|
+
expectedRevision: { type: "number" },
|
|
829
|
+
},
|
|
830
|
+
required: ["clipId"],
|
|
831
|
+
},
|
|
832
|
+
command: "project.auto-sync-podcast",
|
|
833
|
+
},
|
|
688
834
|
{
|
|
689
835
|
name: "project_add_motion_graphic",
|
|
690
836
|
description:
|
|
@@ -1301,19 +1447,22 @@ const TOOLS = [
|
|
|
1301
1447
|
{
|
|
1302
1448
|
name: "project_save",
|
|
1303
1449
|
description:
|
|
1304
|
-
"
|
|
1450
|
+
"Persist a project. Two modes: (1) pass a full `project` JSON to OVERWRITE the file (use after building/mutating a project object client-side) — always pass `expectedRevision` so a concurrent edit returns { ok:false, details:{ code:'revision_conflict' } }; (2) OMIT `project` to simply confirm the current on-disk state. The add_*/set_* verbs already autosave, so a bodyless save is a no-op confirmation that returns the current revision — NOT an error. You usually don't need an explicit save at all.",
|
|
1305
1451
|
inputSchema: {
|
|
1306
1452
|
type: "object",
|
|
1307
1453
|
properties: {
|
|
1308
1454
|
id: { type: "string" },
|
|
1309
1455
|
path: { type: "string" },
|
|
1310
|
-
project: {
|
|
1456
|
+
project: {
|
|
1457
|
+
type: "object",
|
|
1458
|
+
description:
|
|
1459
|
+
"Full project JSON to persist (overwrite mode). Omit to just confirm current on-disk state — edits via add_*/set_* verbs already autosave.",
|
|
1460
|
+
},
|
|
1311
1461
|
expectedRevision: {
|
|
1312
1462
|
type: "number",
|
|
1313
|
-
description: "Revision from your last project_read. Strongly recommended.",
|
|
1463
|
+
description: "Revision from your last project_read. Strongly recommended in overwrite mode.",
|
|
1314
1464
|
},
|
|
1315
1465
|
},
|
|
1316
|
-
required: ["project"],
|
|
1317
1466
|
},
|
|
1318
1467
|
command: "project.save",
|
|
1319
1468
|
},
|
|
@@ -1686,6 +1835,16 @@ const TOOLS = [
|
|
|
1686
1835
|
description: "Fallback duration when neither endMs nor maxDurationMs is given.",
|
|
1687
1836
|
},
|
|
1688
1837
|
volume: { type: "number", description: "Volume multiplier 0–2. Default 0.8." },
|
|
1838
|
+
fadeIn: {
|
|
1839
|
+
type: "number",
|
|
1840
|
+
description:
|
|
1841
|
+
"Fade-in ramp at the overlay's audible start, in ms (e.g. 1000 = 1s). Applied by the export mixer. Omit for a hard start.",
|
|
1842
|
+
},
|
|
1843
|
+
fadeOut: {
|
|
1844
|
+
type: "number",
|
|
1845
|
+
description:
|
|
1846
|
+
"Fade-out ramp ending at the overlay's audible end, in ms. Applied for bounded overlays (endMs/maxDurationMs set); ignored on uncapped full-length overlays. Useful for seam-crossfading a looped music bed. Omit for a hard stop.",
|
|
1847
|
+
},
|
|
1689
1848
|
maxDurationMs: {
|
|
1690
1849
|
type: "number",
|
|
1691
1850
|
description:
|
|
@@ -2497,6 +2656,20 @@ const TOOLS = [
|
|
|
2497
2656
|
},
|
|
2498
2657
|
command: "llm.generate-description",
|
|
2499
2658
|
},
|
|
2659
|
+
{
|
|
2660
|
+
name: "llm_generate_caption",
|
|
2661
|
+
description:
|
|
2662
|
+
"Generate an Instagram Reel caption (1-3 punchy sentences + a few hashtags) from the merged transcript, on the local model. Feed the result into export_publish_instagram's caption.",
|
|
2663
|
+
inputSchema: {
|
|
2664
|
+
type: "object",
|
|
2665
|
+
properties: {
|
|
2666
|
+
id: { type: "string" },
|
|
2667
|
+
path: { type: "string" },
|
|
2668
|
+
maxChars: { type: "number", description: "Default 2200" },
|
|
2669
|
+
},
|
|
2670
|
+
},
|
|
2671
|
+
command: "llm.generate-caption",
|
|
2672
|
+
},
|
|
2500
2673
|
{
|
|
2501
2674
|
name: "llm_generate_timestamps",
|
|
2502
2675
|
description: "Generate YouTube-style chapter timestamps from the merged transcript.",
|
|
@@ -2760,7 +2933,7 @@ const TOOLS = [
|
|
|
2760
2933
|
const server = new Server(
|
|
2761
2934
|
{
|
|
2762
2935
|
name: "pandastudio",
|
|
2763
|
-
version: "1.
|
|
2936
|
+
version: "1.71.0",
|
|
2764
2937
|
},
|
|
2765
2938
|
{
|
|
2766
2939
|
capabilities: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@writepanda/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.92.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",
|