@synthetic-ai/premiere-mcp 2.1.0 → 2.3.0-dev.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/CHANGELOG.md +135 -123
- package/LICENSE +21 -21
- package/README.md +242 -242
- package/cep-plugin/.debug +8 -8
- package/cep-plugin/CSInterface.js +92 -92
- package/cep-plugin/host.jsx +7 -7
- package/cep-plugin/index.html +472 -472
- package/cep-plugin/main.js +6 -0
- package/cep-plugin/premiere.jsx +24947 -24947
- package/dist/bridge/script-builder.js +378 -378
- package/dist/index.js +103 -4
- package/dist/license.js +38 -0
- package/dist/server.js +60 -60
- package/dist/tools/advanced.js +357 -357
- package/dist/tools/audio-advanced.js +1049 -1049
- package/dist/tools/audio.js +42 -42
- package/dist/tools/captions.js +27 -27
- package/dist/tools/clipboard.js +214 -214
- package/dist/tools/color-advanced.js +253 -253
- package/dist/tools/discovery.js +291 -291
- package/dist/tools/effects.js +285 -285
- package/dist/tools/export-presets.js +206 -206
- package/dist/tools/export.js +255 -255
- package/dist/tools/health.js +10 -10
- package/dist/tools/inspection.js +885 -885
- package/dist/tools/keyframes.js +369 -369
- package/dist/tools/markers.js +89 -89
- package/dist/tools/media.js +178 -178
- package/dist/tools/metadata.js +94 -94
- package/dist/tools/multicam.js +50 -50
- package/dist/tools/playback.js +15 -15
- package/dist/tools/playhead.js +95 -95
- package/dist/tools/project-manager.js +21 -21
- package/dist/tools/project.js +149 -149
- package/dist/tools/scripting.js +319 -319
- package/dist/tools/selection.js +202 -202
- package/dist/tools/sequence-advanced.js +379 -379
- package/dist/tools/sequence-settings.js +564 -564
- package/dist/tools/sequence.js +167 -167
- package/dist/tools/source-monitor.js +68 -68
- package/dist/tools/text.js +58 -58
- package/dist/tools/timeline.js +312 -312
- package/dist/tools/track-management.js +446 -446
- package/dist/tools/track-targeting.js +635 -635
- package/dist/tools/tracks.js +87 -87
- package/dist/tools/transitions-motion.js +174 -174
- package/dist/tools/transitions.js +111 -111
- package/dist/tools/utility.js +606 -606
- package/dist/tools/workspace.js +29 -29
- package/package.json +66 -66
- package/scripts/build-chat-dmg.sh +210 -210
- package/scripts/build-chat-zip.sh +291 -291
- package/scripts/install-cep-windows.ps1 +99 -99
- package/scripts/install-cep.sh +66 -66
- package/scripts/install-chat-plugin.bat +67 -67
- package/scripts/install-chat-plugin.sh +85 -85
- package/scripts/install-windows.bat +95 -95
- package/scripts/package.mjs +254 -254
package/dist/index.js
CHANGED
|
@@ -2,12 +2,102 @@
|
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
import { createServer } from "./server.js";
|
|
4
4
|
import { cleanupTempDir, getTempDir } from "./bridge/file-bridge.js";
|
|
5
|
+
import { checkLicense } from "./license.js";
|
|
5
6
|
import { execSync } from "child_process";
|
|
6
7
|
import { fileURLToPath } from "url";
|
|
7
8
|
import path from "path";
|
|
9
|
+
import { existsSync, mkdirSync, writeFileSync, unlinkSync } from "fs";
|
|
8
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
11
|
const __dirname = path.dirname(__filename);
|
|
10
12
|
const projectRoot = path.resolve(__dirname, "..");
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// --doctor — standalone diagnostics, no MCP client or Premiere Pro required
|
|
15
|
+
// to run it. Prints a PASS/WARN/FAIL summary and exits 1 if anything failed,
|
|
16
|
+
// so it's also usable in a script (`premiere-mcp --doctor || echo "broken"`).
|
|
17
|
+
// Defined before the flag-handling block below since it's called from there.
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const GREEN = "\x1b[32m";
|
|
20
|
+
const RED = "\x1b[31m";
|
|
21
|
+
const YELLOW = "\x1b[33m";
|
|
22
|
+
const DIM = "\x1b[2m";
|
|
23
|
+
const RESET = "\x1b[0m";
|
|
24
|
+
function printCheck(result, label, detail) {
|
|
25
|
+
const icon = result === "pass" ? `${GREEN}✓${RESET}` : result === "warn" ? `${YELLOW}!${RESET}` : `${RED}✗${RESET}`;
|
|
26
|
+
console.log(` ${icon} ${label}${detail ? `\n ${DIM}${detail}${RESET}` : ""}`);
|
|
27
|
+
}
|
|
28
|
+
function premiereInstallCandidates() {
|
|
29
|
+
const years = ["2026", "2025", "2024", "2023", "2022"];
|
|
30
|
+
if (process.platform === "darwin") {
|
|
31
|
+
return years.map((y) => `/Applications/Adobe Premiere Pro ${y}/Adobe Premiere Pro ${y}.app`);
|
|
32
|
+
}
|
|
33
|
+
return years.map((y) => `C:\\Program Files\\Adobe\\Adobe Premiere Pro ${y}\\Adobe Premiere Pro.exe`);
|
|
34
|
+
}
|
|
35
|
+
// Returns whether any check failed — the caller sets process.exitCode rather
|
|
36
|
+
// than us calling process.exit() here. On Windows, forcing process.exit()
|
|
37
|
+
// immediately after an in-flight fetch/AbortController teardown (the live
|
|
38
|
+
// license check below) can crash with a libuv assertion
|
|
39
|
+
// ("UV_HANDLE_CLOSING", src/win/async.c) before the process actually exits.
|
|
40
|
+
// Setting exitCode and letting the event loop drain naturally avoids it.
|
|
41
|
+
async function runDoctor() {
|
|
42
|
+
console.log(`\n${DIM}premiere-mcp doctor — checking your setup${RESET}\n`);
|
|
43
|
+
let hasFail = false;
|
|
44
|
+
// 1. Node version
|
|
45
|
+
const nodeMajor = parseInt(process.version.slice(1).split(".")[0], 10);
|
|
46
|
+
if (nodeMajor >= 18) {
|
|
47
|
+
printCheck("pass", `Node.js ${process.version}`);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
hasFail = true;
|
|
51
|
+
printCheck("fail", `Node.js ${process.version}`, "Requires Node 18 or newer — update from nodejs.org");
|
|
52
|
+
}
|
|
53
|
+
// 2. OS (informational — both are supported, this just confirms detection)
|
|
54
|
+
const osLabel = process.platform === "darwin" ? "macOS" : process.platform === "win32" ? "Windows" : process.platform;
|
|
55
|
+
printCheck(process.platform === "darwin" || process.platform === "win32" ? "pass" : "warn", `OS: ${osLabel}`);
|
|
56
|
+
// 3. Premiere Pro install detected on disk
|
|
57
|
+
const found = premiereInstallCandidates().find((p) => existsSync(p));
|
|
58
|
+
if (found) {
|
|
59
|
+
printCheck("pass", "Premiere Pro detected", found);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
printCheck("warn", "Premiere Pro not found in the usual install location", "Not fatal — the MCP server only needs Premiere Pro running when a tool actually calls it.");
|
|
63
|
+
}
|
|
64
|
+
// 4. License key present
|
|
65
|
+
const licenseKey = process.env.PREMIERE_PRO_MCP_LICENSE;
|
|
66
|
+
if (!licenseKey) {
|
|
67
|
+
hasFail = true;
|
|
68
|
+
printCheck("fail", "PREMIERE_PRO_MCP_LICENSE not set", "Add it to your MCP client config (claude_desktop_config.json or equivalent).");
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
printCheck("pass", `License key present (${licenseKey.slice(0, 8)}...)`);
|
|
72
|
+
// 5. Live validation against synthetic.com.ar (also exercises network reachability)
|
|
73
|
+
const result = await checkLicense();
|
|
74
|
+
if (result.valid) {
|
|
75
|
+
printCheck("pass", "License validates", result.expiresAt ? `Expires: ${result.expiresAt}` : "No expiration");
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
hasFail = true;
|
|
79
|
+
printCheck("fail", "License validation failed", result.message ?? "Unknown reason");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// 6. Bridge temp directory writable
|
|
83
|
+
const tempDir = getTempDir();
|
|
84
|
+
try {
|
|
85
|
+
if (!existsSync(tempDir))
|
|
86
|
+
mkdirSync(tempDir, { recursive: true, mode: 0o700 });
|
|
87
|
+
const probe = path.join(tempDir, `.doctor-probe-${Date.now()}`);
|
|
88
|
+
writeFileSync(probe, "ok");
|
|
89
|
+
unlinkSync(probe);
|
|
90
|
+
printCheck("pass", "Bridge temp directory writable", tempDir);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
hasFail = true;
|
|
94
|
+
printCheck("fail", "Bridge temp directory not writable", `${tempDir} — ${err instanceof Error ? err.message : String(err)}`);
|
|
95
|
+
}
|
|
96
|
+
console.log(hasFail
|
|
97
|
+
? `\n${RED}Some checks failed.${RESET} Fix the items above, or share this output with support at https://synthetic.com.ar/dashboard/support\n`
|
|
98
|
+
: `\n${GREEN}Everything looks good.${RESET}\n`);
|
|
99
|
+
return hasFail;
|
|
100
|
+
}
|
|
11
101
|
// Handle CLI flags
|
|
12
102
|
const args = process.argv.slice(2);
|
|
13
103
|
if (args.includes("--help") || args.includes("-h")) {
|
|
@@ -16,6 +106,7 @@ premiere-pro-mcp — MCP server for Adobe Premiere Pro (437 tools)
|
|
|
16
106
|
|
|
17
107
|
Usage:
|
|
18
108
|
premiere-pro-mcp Start the MCP server (stdio transport)
|
|
109
|
+
premiere-pro-mcp --doctor Check your setup (Node, license, Premiere Pro, temp dir)
|
|
19
110
|
premiere-pro-mcp --install-cep Install the CEP plugin into Premiere Pro
|
|
20
111
|
premiere-pro-mcp --help Show this help message
|
|
21
112
|
premiere-pro-mcp --version Show version
|
|
@@ -33,6 +124,12 @@ if (args.includes("--version") || args.includes("-v")) {
|
|
|
33
124
|
console.log(pkg.default.version);
|
|
34
125
|
process.exit(0);
|
|
35
126
|
}
|
|
127
|
+
let ranAsFlag = false;
|
|
128
|
+
if (args.includes("--doctor")) {
|
|
129
|
+
const hasFail = await runDoctor();
|
|
130
|
+
process.exitCode = hasFail ? 1 : 0;
|
|
131
|
+
ranAsFlag = true;
|
|
132
|
+
}
|
|
36
133
|
if (args.includes("--install-cep")) {
|
|
37
134
|
const scriptPath = path.join(projectRoot, "scripts", "install-cep.sh");
|
|
38
135
|
console.log("Installing CEP plugin...\n");
|
|
@@ -63,8 +160,10 @@ async function main() {
|
|
|
63
160
|
await server.connect(transport);
|
|
64
161
|
console.error(`[premiere-pro-mcp] Server connected and ready`);
|
|
65
162
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
163
|
+
if (!ranAsFlag) {
|
|
164
|
+
main().catch((err) => {
|
|
165
|
+
console.error("[premiere-pro-mcp] Fatal error:", err);
|
|
166
|
+
process.exit(1);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
70
169
|
//# sourceMappingURL=index.js.map
|
package/dist/license.js
CHANGED
|
@@ -3,9 +3,45 @@
|
|
|
3
3
|
* Same pattern as ae-mcp/src/server.mjs and photoshop-mcp/server.mjs:
|
|
4
4
|
* validate once, cache for an hour, let diagnostic tools through for free.
|
|
5
5
|
*/
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import crypto from "node:crypto";
|
|
6
10
|
const LICENSE_KEY = process.env.PREMIERE_PRO_MCP_LICENSE;
|
|
7
11
|
const LICENSE_VALIDATION_URL = "https://synthetic.com.ar/api/v1/license/validate";
|
|
8
12
|
const LICENSE_CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
|
|
13
|
+
// Device identity (for the 2-device license cap) — shared across all
|
|
14
|
+
// Synthetic MCP packages on purpose: one physical machine should count as
|
|
15
|
+
// ONE device against the cap, not one per product installed on it. See
|
|
16
|
+
// photoshop-mcp/server.mjs's getMachineId() for the identical logic.
|
|
17
|
+
function getMachineId() {
|
|
18
|
+
try {
|
|
19
|
+
const dir = path.join(os.homedir(), ".synthetic");
|
|
20
|
+
const file = path.join(dir, "device-id");
|
|
21
|
+
if (fs.existsSync(file)) {
|
|
22
|
+
const id = fs.readFileSync(file, "utf8").trim();
|
|
23
|
+
if (id)
|
|
24
|
+
return id;
|
|
25
|
+
}
|
|
26
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
27
|
+
const id = crypto.randomUUID();
|
|
28
|
+
fs.writeFileSync(file, id, "utf8");
|
|
29
|
+
return id;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return "volatile-" + crypto.randomUUID();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function getDeviceLabel() {
|
|
36
|
+
try {
|
|
37
|
+
return `${os.hostname()} (${process.platform})`;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const MACHINE_ID = getMachineId();
|
|
44
|
+
const DEVICE_LABEL = getDeviceLabel();
|
|
9
45
|
let cache = null;
|
|
10
46
|
async function postJson(url, body) {
|
|
11
47
|
try {
|
|
@@ -41,6 +77,8 @@ export async function checkLicense() {
|
|
|
41
77
|
const result = await postJson(LICENSE_VALIDATION_URL, {
|
|
42
78
|
key: LICENSE_KEY,
|
|
43
79
|
product: "premiere-mcp",
|
|
80
|
+
machineId: MACHINE_ID,
|
|
81
|
+
deviceLabel: DEVICE_LABEL,
|
|
44
82
|
});
|
|
45
83
|
if (result) {
|
|
46
84
|
cache = { ...result, checkedAt: Date.now() };
|
package/dist/server.js
CHANGED
|
@@ -38,66 +38,66 @@ import { getSequenceSettingsTools } from "./tools/sequence-settings.js";
|
|
|
38
38
|
import { EXTENDSCRIPT_REFERENCE } from "./resources/extendscript-reference.js";
|
|
39
39
|
import { checkLicense, licenseErrorResponse, FREE_TOOLS } from "./license.js";
|
|
40
40
|
import { z } from "zod";
|
|
41
|
-
const PREMIERE_INSTRUCTIONS = `You are controlling Adobe Premiere Pro through MCP tools. Follow these best practices:
|
|
42
|
-
|
|
43
|
-
WORKFLOW ORDER:
|
|
44
|
-
1. Always call get_project_info first to understand the current state.
|
|
45
|
-
2. Import media before adding to timeline.
|
|
46
|
-
3. Create/select a sequence before timeline operations.
|
|
47
|
-
4. Add clips first, then effects, then transitions.
|
|
48
|
-
5. Save the project after making significant changes.
|
|
49
|
-
|
|
50
|
-
TIMELINE RULES:
|
|
51
|
-
- Clips are identified by node_id. Use get_active_sequence or list_sequence_tracks to discover node IDs.
|
|
52
|
-
- Video clips on higher track indices appear on top of lower ones (compositing order).
|
|
53
|
-
- Images default to ~5 seconds duration when added to timeline.
|
|
54
|
-
- The first clip added to a new sequence determines its resolution and frame rate.
|
|
55
|
-
- Time values are in seconds (the tools handle tick conversion internally).
|
|
56
|
-
|
|
57
|
-
EFFECTS & TRANSITIONS:
|
|
58
|
-
- Apply effects by name using apply_effect (e.g., "Gaussian Blur", "Lumetri Color").
|
|
59
|
-
- Use list_available_effects to find exact effect names.
|
|
60
|
-
- Transitions require clips to be adjacent (no gap between them).
|
|
61
|
-
- Keep transitions short (0.5-2 seconds typically).
|
|
62
|
-
- Use color_correct for Lumetri Color adjustments rather than manual property setting.
|
|
63
|
-
|
|
64
|
-
KEYFRAMES:
|
|
65
|
-
- Use get_effect_properties to discover property names before setting values.
|
|
66
|
-
- Enable keyframes with add_keyframe; the property auto-enables time-varying.
|
|
67
|
-
- Interpolation types: "linear" (smooth), "hold" (instant jump), "bezier" (custom easing).
|
|
68
|
-
|
|
69
|
-
QE DOM TOOLS:
|
|
70
|
-
- Tools marked "Uses QE DOM" use an undocumented API. They are powerful but may behave unexpectedly.
|
|
71
|
-
- ripple_delete, roll_edit, slide_edit, slip_edit are QE-based advanced trim tools.
|
|
72
|
-
- set_clip_speed_qe is more reliable than the ExtendScript speed method.
|
|
73
|
-
|
|
74
|
-
CLIPS & SELECTION:
|
|
75
|
-
- Use set_clip_selection to select clips before operations that work on selection (link, unlink, scene_edit_detection).
|
|
76
|
-
- Use overwrite_clip for 3-point editing (overwrites existing content).
|
|
77
|
-
- Use add_to_timeline for insert editing (ripples content forward).
|
|
78
|
-
|
|
79
|
-
BINS & ORGANIZATION:
|
|
80
|
-
- Bins are folders in the project panel. Use create_bin, delete_bin, rename_bin.
|
|
81
|
-
- Use move_item_to_bin to organize imported media.
|
|
82
|
-
- create_smart_bin creates auto-populating search bins.
|
|
83
|
-
|
|
84
|
-
EXPORT:
|
|
85
|
-
- Use export_sequence for AME-based encoding with presets.
|
|
86
|
-
- Use export_frame to capture a single frame as an image.
|
|
87
|
-
- Use start_batch_encode to begin rendering all queued items.
|
|
88
|
-
|
|
89
|
-
ERROR HANDLING:
|
|
90
|
-
- If a tool returns "No active sequence", call set_active_sequence first.
|
|
91
|
-
- If a tool returns "Clip not found", the node_id may have changed after timeline edits. Re-query the sequence.
|
|
92
|
-
- If "QE clip not found", the clip index may differ between DOM and QE. Try re-querying.
|
|
93
|
-
|
|
94
|
-
CUSTOM SCRIPTING:
|
|
95
|
-
- Use execute_extendscript to write and run any ExtendScript code for tasks not covered by existing tools.
|
|
96
|
-
- Use evaluate_expression for quick one-line queries.
|
|
97
|
-
- Use inspect_dom_object to explore unfamiliar objects.
|
|
98
|
-
- Use get_premiere_state as your first call to understand the full current context.
|
|
99
|
-
- Use get_sequence_structure for detailed timeline layout before edits.
|
|
100
|
-
- Read the "extendscript-reference" resource for the complete API cheat sheet.
|
|
41
|
+
const PREMIERE_INSTRUCTIONS = `You are controlling Adobe Premiere Pro through MCP tools. Follow these best practices:
|
|
42
|
+
|
|
43
|
+
WORKFLOW ORDER:
|
|
44
|
+
1. Always call get_project_info first to understand the current state.
|
|
45
|
+
2. Import media before adding to timeline.
|
|
46
|
+
3. Create/select a sequence before timeline operations.
|
|
47
|
+
4. Add clips first, then effects, then transitions.
|
|
48
|
+
5. Save the project after making significant changes.
|
|
49
|
+
|
|
50
|
+
TIMELINE RULES:
|
|
51
|
+
- Clips are identified by node_id. Use get_active_sequence or list_sequence_tracks to discover node IDs.
|
|
52
|
+
- Video clips on higher track indices appear on top of lower ones (compositing order).
|
|
53
|
+
- Images default to ~5 seconds duration when added to timeline.
|
|
54
|
+
- The first clip added to a new sequence determines its resolution and frame rate.
|
|
55
|
+
- Time values are in seconds (the tools handle tick conversion internally).
|
|
56
|
+
|
|
57
|
+
EFFECTS & TRANSITIONS:
|
|
58
|
+
- Apply effects by name using apply_effect (e.g., "Gaussian Blur", "Lumetri Color").
|
|
59
|
+
- Use list_available_effects to find exact effect names.
|
|
60
|
+
- Transitions require clips to be adjacent (no gap between them).
|
|
61
|
+
- Keep transitions short (0.5-2 seconds typically).
|
|
62
|
+
- Use color_correct for Lumetri Color adjustments rather than manual property setting.
|
|
63
|
+
|
|
64
|
+
KEYFRAMES:
|
|
65
|
+
- Use get_effect_properties to discover property names before setting values.
|
|
66
|
+
- Enable keyframes with add_keyframe; the property auto-enables time-varying.
|
|
67
|
+
- Interpolation types: "linear" (smooth), "hold" (instant jump), "bezier" (custom easing).
|
|
68
|
+
|
|
69
|
+
QE DOM TOOLS:
|
|
70
|
+
- Tools marked "Uses QE DOM" use an undocumented API. They are powerful but may behave unexpectedly.
|
|
71
|
+
- ripple_delete, roll_edit, slide_edit, slip_edit are QE-based advanced trim tools.
|
|
72
|
+
- set_clip_speed_qe is more reliable than the ExtendScript speed method.
|
|
73
|
+
|
|
74
|
+
CLIPS & SELECTION:
|
|
75
|
+
- Use set_clip_selection to select clips before operations that work on selection (link, unlink, scene_edit_detection).
|
|
76
|
+
- Use overwrite_clip for 3-point editing (overwrites existing content).
|
|
77
|
+
- Use add_to_timeline for insert editing (ripples content forward).
|
|
78
|
+
|
|
79
|
+
BINS & ORGANIZATION:
|
|
80
|
+
- Bins are folders in the project panel. Use create_bin, delete_bin, rename_bin.
|
|
81
|
+
- Use move_item_to_bin to organize imported media.
|
|
82
|
+
- create_smart_bin creates auto-populating search bins.
|
|
83
|
+
|
|
84
|
+
EXPORT:
|
|
85
|
+
- Use export_sequence for AME-based encoding with presets.
|
|
86
|
+
- Use export_frame to capture a single frame as an image.
|
|
87
|
+
- Use start_batch_encode to begin rendering all queued items.
|
|
88
|
+
|
|
89
|
+
ERROR HANDLING:
|
|
90
|
+
- If a tool returns "No active sequence", call set_active_sequence first.
|
|
91
|
+
- If a tool returns "Clip not found", the node_id may have changed after timeline edits. Re-query the sequence.
|
|
92
|
+
- If "QE clip not found", the clip index may differ between DOM and QE. Try re-querying.
|
|
93
|
+
|
|
94
|
+
CUSTOM SCRIPTING:
|
|
95
|
+
- Use execute_extendscript to write and run any ExtendScript code for tasks not covered by existing tools.
|
|
96
|
+
- Use evaluate_expression for quick one-line queries.
|
|
97
|
+
- Use inspect_dom_object to explore unfamiliar objects.
|
|
98
|
+
- Use get_premiere_state as your first call to understand the full current context.
|
|
99
|
+
- Use get_sequence_structure for detailed timeline layout before edits.
|
|
100
|
+
- Read the "extendscript-reference" resource for the complete API cheat sheet.
|
|
101
101
|
`;
|
|
102
102
|
/**
|
|
103
103
|
* Convert a JSON Schema-style parameters object to a Zod shape for MCP SDK registration.
|