premiere-pro-mcp 1.12.2 → 1.14.1

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 (77) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +120 -26
  3. package/artifacts/MCPBridgeCEP.zxp +0 -0
  4. package/cep-plugin/CSXS/manifest.xml +3 -3
  5. package/cep-plugin/index.html +1 -1
  6. package/cep-plugin/main.js +16 -1
  7. package/cep-plugin/updater.cjs +1 -1
  8. package/dist/bridge/file-bridge.d.ts +2 -1
  9. package/dist/bridge/file-bridge.js +48 -26
  10. package/dist/http-server.js +19 -2
  11. package/dist/index.js +26 -8
  12. package/dist/intake/project-intake.d.ts +112 -0
  13. package/dist/intake/project-intake.js +555 -0
  14. package/dist/platform-capabilities.d.ts +10 -8
  15. package/dist/platform-capabilities.js +2 -1
  16. package/dist/resources/live-context-resources.d.ts +22 -0
  17. package/dist/resources/live-context-resources.js +494 -0
  18. package/dist/security/capabilities.js +21 -0
  19. package/dist/server.d.ts +2 -0
  20. package/dist/server.js +56 -8
  21. package/dist/telemetry.d.ts +7 -8
  22. package/dist/telemetry.js +11 -4
  23. package/dist/tool-capability-report.js +5 -2
  24. package/dist/tools/audio.d.ts +101 -0
  25. package/dist/tools/audio.js +219 -1
  26. package/dist/tools/competitor-gaps.d.ts +370 -0
  27. package/dist/tools/competitor-gaps.js +829 -0
  28. package/dist/tools/export.d.ts +162 -0
  29. package/dist/tools/export.js +290 -0
  30. package/dist/tools/health.d.ts +10 -7
  31. package/dist/tools/health.js +8 -6
  32. package/dist/tools/inspection.d.ts +55 -0
  33. package/dist/tools/inspection.js +252 -0
  34. package/dist/tools/interchange-analysis.d.ts +248 -0
  35. package/dist/tools/interchange-analysis.js +264 -0
  36. package/dist/tools/media-analysis.d.ts +243 -0
  37. package/dist/tools/media-analysis.js +216 -0
  38. package/dist/tools/playhead.js +13 -6
  39. package/dist/tools/project-intake.d.ts +41 -0
  40. package/dist/tools/project-intake.js +120 -0
  41. package/dist/tools/recovery.d.ts +33 -0
  42. package/dist/tools/recovery.js +58 -1
  43. package/dist/tools/sequence.d.ts +16 -0
  44. package/dist/tools/sequence.js +37 -2
  45. package/dist/tools/spot-workflows.d.ts +379 -0
  46. package/dist/tools/spot-workflows.js +519 -0
  47. package/dist/tools/utility.js +21 -1
  48. package/dist/workflows/catalog.d.ts +7 -2
  49. package/dist/workflows/catalog.js +6 -0
  50. package/dist/workflows/tool-metadata.js +6 -0
  51. package/dist/workflows/tool-packs.d.ts +36 -0
  52. package/dist/workflows/tool-packs.js +150 -0
  53. package/docs/editorial-workflow-host-validation.md +81 -0
  54. package/docs/licensed-host-report.template.json +20 -0
  55. package/docs/licensed-host-sweep.matrix.json +35 -0
  56. package/docs/licensed-host-sweep.md +73 -0
  57. package/docs/licensed-host-sweep.schema.json +70 -0
  58. package/docs/licensed-host-sweep.template.json +47 -0
  59. package/docs/quickstart/README.md +16 -0
  60. package/docs/quickstart/en.md +70 -0
  61. package/docs/quickstart/es.md +77 -0
  62. package/docs/quickstart/ja.md +70 -0
  63. package/docs/quickstart/locales.json +18 -0
  64. package/docs/supported-actions.md +36 -4
  65. package/package.json +18 -4
  66. package/scripts/build-connector-installer.sh +4 -0
  67. package/scripts/check-quickstart-locales.mjs +34 -0
  68. package/scripts/create-licensed-host-sweep.mjs +75 -0
  69. package/scripts/install-cep.ps1 +35 -1
  70. package/scripts/uninstall-cep.ps1 +34 -0
  71. package/scripts/uninstall-cep.sh +64 -0
  72. package/scripts/validate-licensed-host-report.mjs +94 -6
  73. package/scripts/validate-mcp-registry-metadata.mjs +34 -0
  74. package/scripts/validate-project-intake-host-report.mjs +211 -0
  75. package/scripts/verify-npm-package.mjs +119 -0
  76. package/scripts/verify-release-tag.mjs +36 -0
  77. package/uxp-plugin/manifest.json +1 -1
package/CHANGELOG.md CHANGED
@@ -6,6 +6,49 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.14.1] - 2026-08-27
10
+
11
+ ### Fixed
12
+
13
+ - Made npm package verification isolate its temporary tarball and select the
14
+ package matching `package.json`, avoiding a current npm CLI packaging
15
+ regression before publication.
16
+
17
+ ## [1.14.0] - 2026-08-27
18
+
19
+ ### Added
20
+
21
+ - Added focused `essential`, `inspection`, `delivery`, and `captions` tool packs
22
+ so compatible MCP clients can begin with a smaller task-specific catalog.
23
+ - Added `inspect_sequence_review_report`, a read-only, handoff-oriented sequence
24
+ report, and explicit MCP output schemas for every registered tool.
25
+
26
+ ### Safety
27
+
28
+ - Tool packs change discoverability, not authority. Review reports redact media
29
+ paths by default and include marker comments only with explicit opt-in.
30
+ - Package and response-contract checks remain distinct from licensed Premiere
31
+ host verification.
32
+
33
+ ## [1.13.0] - 2026-08-22
34
+
35
+ ### Added
36
+
37
+ - Added `preview_project_intake`, a bounded, inspect-only project intake tool
38
+ that evaluates Premiere project organization against a facility-supplied
39
+ template and returns redacted findings plus proposed actions without changing
40
+ the project.
41
+ - Added a deterministic intake rules engine, a guided workflow entry, a public
42
+ facts page, and design-partner/security pilot contracts for human-supervised
43
+ assistant-editor adoption.
44
+
45
+ ### Safety
46
+
47
+ - File paths remain redacted unless explicitly requested, recursive capture and
48
+ outputs are bounded, and the intake workflow does not mutate or persist
49
+ project data. Automated tests passed, while licensed-host execution remains a
50
+ separate gate because Premiere 2026 hung before the CEP panel could open.
51
+
9
52
  ## [1.12.2] - 2026-08-22
10
53
 
11
54
  ### Fixed
package/README.md CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  # MCP for Adobe Premiere Pro
4
4
 
5
+ <!-- mcp-name: io.github.leancoderkavy/premiere-pro -->
6
+
5
7
  [![MCP Toplist](https://mcptoplist.com/badge/glama%2Fleancoderkavy%2Fpremiere-pro-mcp.svg)](https://mcptoplist.com/server/glama%2Fleancoderkavy%2Fpremiere-pro-mcp)
6
8
 
7
9
  **Give compatible AI assistants structured control over supported Adobe Premiere Pro workflows.**
8
10
 
9
- 287 core tools across 33 modules, 4 resources, and 10 guided workflows. A connected UXP host adds 50 capability-gated tools.
11
+ 319 core tools across 37 modules, 14 resources, and 11 guided workflows. A connected UXP host adds 50 capability-gated tools.
10
12
 
11
13
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
12
14
  [![Node.js](https://img.shields.io/badge/Node.js-20.19%2B-green.svg)](https://nodejs.org)
@@ -29,35 +31,72 @@ An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that l
29
31
  "Add the B-roll clips to V2, apply a cross dissolve between each, color correct them to match the A-roll, and export a 1080p ProRes."
30
32
  ```
31
33
 
32
- The AI handles the entire workflow through 287 core tools spanning the supported ExtendScript, QE DOM, revisioned project-context retrieval, safe edit-planning, and connection-verification surfaces. A compatible, authenticated UXP panel adds 50 documented, capability-gated tools without replacing the production CEP bridge.
34
+ The AI handles the entire workflow through 319 core tools spanning the supported ExtendScript, QE DOM, local media and interchange analysis, revisioned project-context retrieval, safe edit-planning, project-intake preview, review handoff, and connection-verification surfaces. A compatible, authenticated UXP panel adds 50 documented, capability-gated tools without replacing the production CEP bridge.
33
35
 
34
- ### Latest release: 1.12.2
36
+ ### Latest release: 1.14.1
35
37
 
36
- - **MOGRT text and graphics:** `set_effect_property` now accepts string-backed
37
- parameters with safe serialization and readback status.
38
- - **Effect discovery clarity:** an empty legacy QE effect catalog now returns a
39
- no-mutation capability response and directs connected hosts to the documented
40
- UXP catalog/add workflow.
41
- - **Verification clarity:** property readback remains distinct from playback or
42
- exported-frame verification in a licensed Premiere Pro host.
38
+ - **Focused discovery:** compatible MCP clients can select essential,
39
+ inspection, delivery, or captions tool packs instead of beginning with the
40
+ full catalog.
41
+ - **Review handoff:** `inspect_sequence_review_report` returns a read-only,
42
+ path-redacted sequence report, with marker comments only when requested.
43
+ - **Interoperability:** all registered MCP tools now declare explicit output
44
+ schemas; this release does not substitute automated checks for licensed-host
45
+ verification.
46
+ - **Reliable packaging:** npm package verification now isolates its temporary
47
+ tarball, keeping the validated distribution path compatible with the current
48
+ npm CLI.
43
49
 
44
- See the [v1.12.2 release notes](https://github.com/leancoderkavy/premiere-pro-mcp/releases/tag/v1.12.2)
50
+ See the [v1.14.1 release notes](https://github.com/leancoderkavy/premiere-pro-mcp/releases/tag/v1.14.1)
45
51
  for complete details. Live installation in Premiere Pro still requires host verification.
46
52
 
47
53
  ---
48
54
 
55
+ ## For editors evaluating an AI workflow
56
+
57
+ Before an assistant changes an active project, use the
58
+ [Premiere Pro AI workflow checklist](https://premiere-pro-mcp.com/blog/premiere-pro-ai-workflow-checklist/)
59
+ to define the target and no-change boundaries, verify the local connection, request
60
+ a bounded plan, and inspect the returned result. It is a practical starting point for
61
+ assistant editors and post leads testing a repeatable workflow on a duplicate project
62
+ or small test sequence.
63
+
64
+ For product context, see the [Adobe Premiere AI Assistant and MCP comparison](https://premiere-pro-mcp.com/blog/adobe-premiere-ai-assistant-vs-mcp/)
65
+ and the [Claude Desktop setup guide](https://premiere-pro-mcp.com/blog/claude-desktop-premiere-pro-mcp-setup/).
66
+
67
+ If you are deciding between a single local project, an Adobe Production on shared
68
+ storage, or a remote Team Project, use the [Premiere Pro collaboration workflow
69
+ guide](https://premiere-pro-mcp.com/premiere-pro-collaboration-workflow/) before
70
+ you evaluate an MCP path. It links the relevant Adobe guidance, makes no project
71
+ inspection request, and ends with the same read-only connection check.
72
+
73
+ ---
74
+
49
75
  ## Quick Start
50
76
 
51
77
  ### Easiest supported path: Claude Desktop
52
78
 
53
- 1. Download the current [Claude Desktop bundle (`.mcpb`)](https://github.com/leancoderkavy/premiere-pro-mcp/releases/download/v1.12.2/premiere-pro-mcp-1.12.2.mcpb).
79
+ 1. Download the current [Claude Desktop bundle (`.mcpb`)](https://github.com/leancoderkavy/premiere-pro-mcp/releases/download/v1.14.1/premiere-pro-mcp-1.14.1.mcpb).
54
80
  2. In Claude Desktop, open **Settings > Extensions > Advanced settings > Install Extension**, select the downloaded bundle, and restart Claude Desktop.
55
- 3. Download the separate [signed Premiere connector (`.zxp`)](https://github.com/leancoderkavy/premiere-pro-mcp/releases/download/v1.12.2/MCPBridgeCEP.zxp). Open it with your trusted ZXP installer. If your computer has no ZXP installer, use the npm connector installer in **Advanced setup** below.
81
+ 3. Download the separate [signed Premiere connector (`.zxp`)](https://github.com/leancoderkavy/premiere-pro-mcp/releases/download/v1.14.1/MCPBridgeCEP.zxp). Open it with your trusted ZXP installer. If your computer has no ZXP installer, use the npm connector installer in **Advanced setup** below.
56
82
  4. Restart Premiere, open a project, then open **Window > Extensions > MCP for Adobe Premiere Pro**.
57
83
  5. In Claude, enter: `Safely check my Premiere connection with verify_premiere_connection. Make no changes.`
58
84
 
59
85
  The Claude bundle contains the local MCP server, so this route does not require Node.js. The Premiere connector is a separate required install. The first prompt is read-only and reports whether the server is installed, configured, connected, and live-verified.
60
86
 
87
+ ### First proof, before the first edit
88
+
89
+ ![Illustrated local Premiere MCP workflow](landing/public/premiere-pro-mcp-demo-poster.png)
90
+
91
+ *This is an illustrated workflow, not a Premiere panel screenshot or licensed-host proof.*
92
+
93
+ 1. Open a copied test project and an active sequence in Premiere.
94
+ 2. Open **Window > Extensions > MCP for Adobe Premiere Pro**. “Running” means the local panel bridge is available; it does not show that an edit completed.
95
+ 3. Run `premiere-pro-mcp --doctor` to check only local package/configuration readiness.
96
+ 4. Ask the AI client: `Run verify_premiere_connection. Make no changes.` The returned check is read-only and avoids project names, paths, and media details.
97
+
98
+ If a bridge, project, or active sequence is missing, fix that setup state before allowing a mutation. For a concise, translatable version of this path, see [quick starts in English, Spanish, and Japanese](docs/quickstart/README.md). The translations are machine-assisted drafts and retain command names in English.
99
+
61
100
  ### Other AI assistants
62
101
 
63
102
  Cursor, VS Code/Copilot, Windsurf, and other MCP clients do not currently have a project-provided one-click installer. Use their MCP settings with the advanced npm route below. Keep the assistant, server, connector, and Premiere on the same computer.
@@ -114,6 +153,16 @@ premiere-pro-mcp --doctor
114
153
 
115
154
  Then ask your MCP client to run `verify_premiere_connection`. The check is read-only.
116
155
 
156
+ #### Remove the CEP connector
157
+
158
+ Fully quit Premiere, then remove only this connector:
159
+
160
+ ```bash
161
+ premiere-pro-mcp --uninstall-cep
162
+ ```
163
+
164
+ The uninstaller intentionally leaves Adobe's shared `PlayerDebugMode` setting in place so it does not disrupt other CEP extensions. Remove the MCP server from your AI client's configuration and uninstall the npm package separately if you no longer use it. On macOS, `--uninstall-cep` removes the per-user npm/source install; the signed system-wide `.pkg` route has a separate privileged removal command in [distribution readiness](docs/distribution-readiness.md#connector-removal).
165
+
117
166
  </details>
118
167
 
119
168
  ---
@@ -276,11 +325,11 @@ From a clone of this repository:
276
325
  ```bash
277
326
  codex plugin marketplace add .
278
327
  codex plugin add premiere-pro@premiere-pro-mcp
279
- npx -y premiere-pro-mcp@1.12.2 --install-cep
328
+ npx -y premiere-pro-mcp@1.14.1 --install-cep
280
329
  ```
281
330
 
282
331
  Restart Premiere Pro and start a new Codex session after installation. The plugin
283
- launches `premiere-pro-mcp@1.12.2` through `npx`; the separate CEP installation is
332
+ launches `premiere-pro-mcp@1.14.1` through `npx`; the separate CEP installation is
284
333
  required because the MCP server communicates with the running Premiere host through
285
334
  the local bridge.
286
335
 
@@ -300,7 +349,7 @@ For Claude Code, add this repository as a marketplace and install the plugin:
300
349
  Then install the Premiere bridge and start a new Claude Code session:
301
350
 
302
351
  ```bash
303
- npx -y premiere-pro-mcp@1.12.2 --install-cep
352
+ npx -y premiere-pro-mcp@1.14.1 --install-cep
304
353
  ```
305
354
 
306
355
  The Claude Code package lives in
@@ -339,13 +388,36 @@ installed separately.
339
388
  QE-backed tools are reported as `experimental` because QE is undocumented and can vary between Premiere builds. Authority availability is reported separately from implementation support, so disabling `edit`, for example, does not incorrectly label editing tools as unsupported. Static metadata never claims that a Premiere operation succeeded; use `ping` and inspect each tool result for runtime evidence.
340
389
 
341
390
  MCP `tools/list` is filtered to the active authority profile. The default
342
- `inspect,edit,export,filesystem` profile advertises 285 of the 287 registered
391
+ `inspect,edit,export,filesystem` profile advertises 317 of the 319 registered
343
392
  tools and omits `execute_extendscript` and `evaluate_expression`, which require
344
393
  explicit `unsafe-script` authority. `ping` and `get_capabilities` remain visible
345
394
  under every profile so a restricted or misconfigured server can still explain
346
395
  its state. The call-time capability guard remains authoritative even if listing
347
396
  metadata is wrong.
348
397
 
398
+ ### Workflow-scoped discovery packs and structured outputs
399
+
400
+ By default, the full permitted catalog remains available. Set
401
+ `PREMIERE_MCP_TOOL_PACKS` to `essential`, `inspection`, `delivery`, `captions`,
402
+ or a comma-separated combination such as `inspection,captions` to reduce the
403
+ tool discovery and registered session surface for a focused client. `full` is the explicit
404
+ full-catalog mode and cannot be combined with another pack. `ping` and
405
+ `get_capabilities` remain listed for diagnosis, and every registered call still
406
+ passes through the same capability guard; a pack never grants authority.
407
+
408
+ Every listed tool now declares the same machine-readable result envelope through
409
+ MCP `outputSchema`: `ok`, `tool`, plus `data` on success or `error` on failure.
410
+ The tool-specific `data` shape remains versioned by the individual tool result,
411
+ so clients can reliably distinguish transport success from a Premiere or local
412
+ operation failure without parsing the text block.
413
+
414
+ `inspect_sequence_review_report` creates one read-only handoff report from
415
+ Premiere timeline readback: sequence structure, primary-track gaps, disabled
416
+ clips, muted tracks, marker timing, and offline-source evidence. It never
417
+ returns media paths; marker comments are omitted unless explicitly requested.
418
+ The report is not proof of rendered pixels, audio quality, caption accuracy,
419
+ rights, or editorial approval.
420
+
349
421
  The MCP handshake reads `serverInfo.version` from the installed `package.json`,
350
422
  so clients receive the package version that is actually running rather than a
351
423
  separately maintained literal.
@@ -494,7 +566,7 @@ The file-based IPC bridge is simple, reliable, and works across macOS and Window
494
566
 
495
567
  ---
496
568
 
497
- ## Tools (287 core total; 285 under the default profile; 335 with a connected UXP bridge)
569
+ ## Tools (319 core total; 317 under the default profile; 367 with a connected UXP bridge)
498
570
 
499
571
  The [complete supported-actions catalog](docs/supported-actions.md) lists every
500
572
  registered core tool, the two tools restricted behind explicit `unsafe-script`
@@ -694,15 +766,29 @@ Track targeting, batch operations, markers, audio levels, motion/transform, meta
694
766
 
695
767
  ## MCP Resources
696
768
 
697
- The server exposes four LLM context resources and ten workflow prompts:
769
+ The server exposes fourteen LLM context resources and eleven workflow prompts:
698
770
 
699
771
  | Resource URI | Description |
700
772
  | :----------- | :---------- |
701
773
  | `config://premiere-instructions` | Best practices: workflow order, timeline rules, effect tips, error handling |
702
774
  | `config://extendscript-reference` | Complete ExtendScript API reference for writing custom scripts |
703
775
  | `config://premiere-workflows` | Machine-readable catalog for rough cuts, dialogue cleanup, captions, and delivery |
704
-
705
- These are automatically available to MCP clients that support resources, giving the AI deep context about how to drive Premiere Pro effectively.
776
+ | `config://premiere-project-context` | Revisioned local project-context indexing and retrieval workflow |
777
+ | `premiere://project/info` | Fresh, path-redacted current-project and active-sequence summary |
778
+ | `premiere://project/sequences` | Bounded sequence inventory with stable Premiere IDs |
779
+ | `premiere://project/media` | Bounded, path-redacted project-media inventory |
780
+ | `premiere://project/bins` | Bounded, path-redacted project-bin inventory |
781
+ | `premiere://timeline/active` | Bounded active-timeline tracks, clips, and markers snapshot |
782
+ | `premiere://effects/available` | Bounded video/audio effect catalog for planning |
783
+ | `premiere://effects/applied` | Bounded active-timeline component inventory |
784
+ | `premiere://transitions/available` | Bounded video/audio transition catalog for planning |
785
+ | `premiere://export/presets` | Bounded export-preset names and formats, without native paths |
786
+ | `premiere://project/metadata` | Read-only project and active-timeline summary, without paths or timestamps |
787
+
788
+ The ten `premiere://` snapshots are read-only CEP bridge requests. They include a
789
+ revision token for stale-state detection and omit native media, project-tree, preset,
790
+ and output paths. A successful snapshot proves bridge readback only—not licensed-host
791
+ feature coverage, playback, rendering, or editorial correctness.
706
792
 
707
793
  ---
708
794
 
@@ -787,10 +873,18 @@ Then connect with:
787
873
  | `POSTHOG_DISTINCT_ID` | Optional stable anonymous server identifier | Fly machine ID or random boot ID |
788
874
 
789
875
  When PostHog is enabled, the server records `mcp_connection_attempt`,
790
- `mcp_request`, `mcp_request_rejected`, and `mcp_tool_call`. Events contain operational fields such as
791
- method, tool name, outcome, status code, and duration. Authentication tokens,
792
- IP addresses, MCP arguments, project paths, media names, and tool results are
793
- never sent. Person profiles are disabled for these events.
876
+ `mcp_request`, `mcp_request_rejected`, and `mcp_tool_call`. It also records
877
+ `premiere_mcp_activation_completed` only after the read-only
878
+ `verify_premiere_connection` check confirms the selected bridge, an open
879
+ project, and an active sequence. Events contain bounded operational fields such
880
+ as method, tool name, outcome, status code, duration, and selected bridge.
881
+ Authentication tokens, IP addresses, MCP arguments, project paths, media names,
882
+ and tool results are never sent. Person profiles are disabled for these events.
883
+
884
+ This signal is an aggregate emission, not proof that an analytics provider
885
+ received it, a count of unique people or editors, or evidence that an editing
886
+ workflow succeeded. It does not carry a person or editor identifier, so it
887
+ cannot safely infer "first value."
794
888
 
795
889
  ---
796
890
 
@@ -801,7 +895,7 @@ premiere-pro-mcp/
801
895
  ├── src/
802
896
  │ ├── index.ts # Entry point — stdio transport setup
803
897
  │ ├── http-server.ts # Entry point — HTTP/SSE transport (Fly.io / remote)
804
- │ ├── server.ts # MCP server — registers 287 tools, filtered by authority profile
898
+ │ ├── server.ts # MCP server — registers 319 tools, filtered by authority profile
805
899
  │ ├── bridge/
806
900
  │ │ ├── file-bridge.ts # File-based IPC (write .jsx, poll .json)
807
901
  │ │ └── script-builder.ts # ExtendScript generator with ES3 helpers
Binary file
@@ -1,8 +1,8 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <ExtensionManifest Version="7.0" ExtensionBundleId="com.mcp.premiere.bridge" ExtensionBundleVersion="1.12.2" ExtensionBundleName="MCP for Adobe Premiere Pro">
2
+ <ExtensionManifest Version="7.0" ExtensionBundleId="com.mcp.premiere.bridge" ExtensionBundleVersion="1.14.1" ExtensionBundleName="MCP for Adobe Premiere Pro">
3
3
  <ExtensionList>
4
- <Extension Id="com.mcp.premiere.bridge.panel" Version="1.12.2"/>
5
- <Extension Id="com.mcp.premiere.bridge.headless" Version="1.12.2"/>
4
+ <Extension Id="com.mcp.premiere.bridge.panel" Version="1.14.1"/>
5
+ <Extension Id="com.mcp.premiere.bridge.headless" Version="1.14.1"/>
6
6
  </ExtensionList>
7
7
  <ExecutionEnvironment>
8
8
  <HostList>
@@ -81,7 +81,7 @@
81
81
  <section class="update-section" aria-live="polite">
82
82
  <div class="update-copy">
83
83
  <span class="section-label">Connector updates</span>
84
- <strong id="updateTitle">Version 1.12.2</strong>
84
+ <strong id="updateTitle">Version 1.14.1</strong>
85
85
  <span id="updateDetail">Checking for updates…</span>
86
86
  </div>
87
87
  <button id="btnUpdate" class="button button-update" onclick="handleUpdateClick()" type="button" disabled>
@@ -136,6 +136,21 @@ function writeFile(filePath, content) {
136
136
  }
137
137
  }
138
138
 
139
+ // Publish responses atomically so the MCP process never sees a partially-written
140
+ // JSON file. The staging suffix is not a response filename the server will read.
141
+ function writeResponseFile(filePath, content) {
142
+ var stagedPath = filePath + ".staged";
143
+ try {
144
+ fs.writeFileSync(stagedPath, content, "utf-8");
145
+ fs.renameSync(stagedPath, filePath);
146
+ return true;
147
+ } catch (e) {
148
+ deleteFile(stagedPath);
149
+ log("Error publishing " + filePath + ": " + e.message, "err");
150
+ return false;
151
+ }
152
+ }
153
+
139
154
  function deleteFile(filePath) {
140
155
  try {
141
156
  if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
@@ -234,7 +249,7 @@ function processOneCommand(cmdFileName) {
234
249
  }
235
250
  }
236
251
 
237
- writeFile(resFilePath, response);
252
+ writeResponseFile(resFilePath, response);
238
253
  });
239
254
  }
240
255
 
@@ -7,7 +7,7 @@
7
7
  })(this, function () {
8
8
  "use strict";
9
9
 
10
- var CURRENT_VERSION = "1.12.2";
10
+ var CURRENT_VERSION = "1.14.1";
11
11
  var LATEST_RELEASE_API =
12
12
  "https://api.github.com/repos/leancoderkavy/premiere-pro-mcp/releases/latest";
13
13
  var RELEASES_URL =
@@ -12,7 +12,8 @@ export declare function getTempDir(options?: BridgeOptions): string;
12
12
  * Send a command (ExtendScript) to the CEP plugin and wait for a response.
13
13
  *
14
14
  * Protocol:
15
- * 1. Write script to <tempDir>/cmd_<id>.jsx
15
+ * 1. Write the script to a staging file, then atomically publish it as
16
+ * <tempDir>/cmd_<id>.jsx. The CEP panel only sees complete commands.
16
17
  * 2. CEP plugin picks it up, executes, writes result to <tempDir>/res_<id>.json
17
18
  * 3. We poll for the response file and parse it.
18
19
  */
@@ -1,11 +1,11 @@
1
- import { mkdirSync, writeFileSync, readFileSync, unlinkSync, existsSync, readdirSync, statSync, chmodSync, watch } from "node:fs";
1
+ import { mkdirSync, writeFileSync, readFileSync, unlinkSync, existsSync, readdirSync, renameSync, statSync, chmodSync, watch } from "node:fs";
2
2
  import { basename, dirname, join } from "node:path";
3
3
  import { tmpdir } from "node:os";
4
+ import { randomUUID } from "node:crypto";
4
5
  import { getHelpersSource, helpersFileName, buildBootstrap } from "./script-builder.js";
5
6
  const DEFAULT_TEMP_DIR = join(tmpdir(), "premiere-mcp-bridge");
6
7
  const POLL_FALLBACK_MS = 250;
7
8
  const DEFAULT_TIMEOUT_MS = 30000;
8
- let commandCounter = 0;
9
9
  /**
10
10
  * Create the bridge temp dir private to this user, and — critically — refuse to trust
11
11
  * one we didn't create.
@@ -59,7 +59,8 @@ function ensureHelpers(tempDir) {
59
59
  * Send a command (ExtendScript) to the CEP plugin and wait for a response.
60
60
  *
61
61
  * Protocol:
62
- * 1. Write script to <tempDir>/cmd_<id>.jsx
62
+ * 1. Write the script to a staging file, then atomically publish it as
63
+ * <tempDir>/cmd_<id>.jsx. The CEP panel only sees complete commands.
63
64
  * 2. CEP plugin picks it up, executes, writes result to <tempDir>/res_<id>.json
64
65
  * 3. We poll for the response file and parse it.
65
66
  */
@@ -67,22 +68,27 @@ export async function sendCommand(script, options) {
67
68
  const tempDir = getTempDir(options);
68
69
  const timeoutMs = options?.timeoutMs || DEFAULT_TIMEOUT_MS;
69
70
  ensureDir(tempDir);
70
- const id = `${Date.now()}_${++commandCounter}`;
71
+ const id = randomUUID();
71
72
  const cmdFile = join(tempDir, `cmd_${id}.jsx`);
73
+ const stagedCmdFile = `${cmdFile}.staged`;
72
74
  const resFile = join(tempDir, `res_${id}.json`);
73
75
  const busyFile = join(tempDir, `busy_${id}.json`);
74
76
  // Validate script
75
77
  validateScript(script);
76
- // Write command file (bootstrap loads the helpers into the engine if needed)
77
- writeFileSync(cmdFile, `${ensureHelpers(tempDir)}
78
+ try {
79
+ // Write a complete command before its .jsx name makes it visible to CEP.
80
+ // renameSync is atomic when both paths are in the bridge directory.
81
+ writeFileSync(stagedCmdFile, `${ensureHelpers(tempDir)}
78
82
  ${script}`, "utf-8");
79
- // Poll for response
80
- const result = await pollForResponse(resFile, busyFile, timeoutMs);
81
- // Cleanup
82
- safeUnlink(cmdFile);
83
- safeUnlink(resFile);
84
- safeUnlink(busyFile);
85
- return result;
83
+ renameSync(stagedCmdFile, cmdFile);
84
+ return await pollForResponse(resFile, busyFile, timeoutMs);
85
+ }
86
+ finally {
87
+ safeUnlink(stagedCmdFile);
88
+ safeUnlink(cmdFile);
89
+ safeUnlink(resFile);
90
+ safeUnlink(busyFile);
91
+ }
86
92
  }
87
93
  function validateScript(script, allowUnsafe = false) {
88
94
  const MAX_SCRIPT_SIZE = 500 * 1024; // 500KB
@@ -112,18 +118,24 @@ export async function sendRawCommand(script, options) {
112
118
  const tempDir = getTempDir(options);
113
119
  const timeoutMs = options?.timeoutMs || DEFAULT_TIMEOUT_MS;
114
120
  ensureDir(tempDir);
115
- const id = `${Date.now()}_${++commandCounter}`;
121
+ const id = randomUUID();
116
122
  const cmdFile = join(tempDir, `cmd_${id}.jsx`);
123
+ const stagedCmdFile = `${cmdFile}.staged`;
117
124
  const resFile = join(tempDir, `res_${id}.json`);
118
125
  const busyFile = join(tempDir, `busy_${id}.json`);
119
126
  validateScript(script, true);
120
- writeFileSync(cmdFile, `${ensureHelpers(tempDir)}
127
+ try {
128
+ writeFileSync(stagedCmdFile, `${ensureHelpers(tempDir)}
121
129
  ${script}`, "utf-8");
122
- const result = await pollForResponse(resFile, busyFile, timeoutMs);
123
- safeUnlink(cmdFile);
124
- safeUnlink(resFile);
125
- safeUnlink(busyFile);
126
- return result;
130
+ renameSync(stagedCmdFile, cmdFile);
131
+ return await pollForResponse(resFile, busyFile, timeoutMs);
132
+ }
133
+ finally {
134
+ safeUnlink(stagedCmdFile);
135
+ safeUnlink(cmdFile);
136
+ safeUnlink(resFile);
137
+ safeUnlink(busyFile);
138
+ }
127
139
  }
128
140
  async function pollForResponse(resFile, busyFile, timeoutMs) {
129
141
  const start = Date.now();
@@ -134,6 +146,7 @@ async function pollForResponse(resFile, busyFile, timeoutMs) {
134
146
  // misreporting "is the plugin running?".
135
147
  const hardCapMs = Math.max(timeoutMs * 4, 120_000);
136
148
  let sawBusy = false;
149
+ let lastResponseParseError;
137
150
  const busyIsFresh = () => {
138
151
  try {
139
152
  if (!existsSync(busyFile))
@@ -172,15 +185,20 @@ async function pollForResponse(resFile, busyFile, timeoutMs) {
172
185
  try {
173
186
  const raw = readFileSync(resFile, "utf-8");
174
187
  const result = JSON.parse(raw);
175
- finish(result);
188
+ if (typeof result !== "object" || result === null || typeof result.success !== "boolean") {
189
+ lastResponseParseError = "Failed to parse response: missing boolean success field";
190
+ }
191
+ else {
192
+ finish(result);
193
+ return;
194
+ }
176
195
  }
177
196
  catch (e) {
178
- finish({
179
- success: false,
180
- error: `Failed to parse response: ${e instanceof Error ? e.message : String(e)}`,
181
- });
197
+ // A CEP response can be observed while an older connector is still writing it.
198
+ // Keep polling the same response file; never resend the host operation.
199
+ lastResponseParseError =
200
+ `Failed to parse response: ${e instanceof Error ? e.message : String(e)}`;
182
201
  }
183
- return;
184
202
  }
185
203
  const elapsed = Date.now() - start;
186
204
  if (elapsed >= timeoutMs) {
@@ -189,6 +207,10 @@ async function pollForResponse(resFile, busyFile, timeoutMs) {
189
207
  scheduleFallback();
190
208
  return;
191
209
  }
210
+ if (lastResponseParseError) {
211
+ finish({ success: false, error: lastResponseParseError });
212
+ return;
213
+ }
192
214
  finish({
193
215
  success: false,
194
216
  error: sawBusy
@@ -89,8 +89,25 @@ function serveLanding(req, res, scriptNonce) {
89
89
  relativePath.startsWith(`..${path.sep}`) ||
90
90
  path.isAbsolute(relativePath))
91
91
  return false;
92
- if (!fs.existsSync(filePath))
93
- return false;
92
+ if (!fs.existsSync(filePath)) {
93
+ // Next static exports store dynamic-route Flight payloads in nested folders
94
+ // (for example, __next.blog/$d$slug/__PAGE__.txt), while the client asks
95
+ // for a flattened filename (__next.blog.$d$slug.__PAGE__.txt). Map only
96
+ // that generated shape after every original URL segment has passed the
97
+ // containment check above. Without this, guide-to-guide navigation falls
98
+ // back to a full-document load and emits avoidable 404s.
99
+ const requestedFlightFile = safeSegments.at(-1);
100
+ const flightParts = requestedFlightFile?.split(".") ?? [];
101
+ const isNestedFlightPayload = flightParts.length >= 4 &&
102
+ flightParts[0] === "__next" &&
103
+ flightParts.at(-1) === "txt";
104
+ if (!isNestedFlightPayload)
105
+ return false;
106
+ const remappedFlightPath = path.join(LANDING_DIR, ...safeSegments.slice(0, -1), `${flightParts[0]}.${flightParts[1]}`, ...flightParts.slice(2, -2), `${flightParts.at(-2)}.txt`);
107
+ if (!fs.existsSync(remappedFlightPath))
108
+ return false;
109
+ filePath = remappedFlightPath;
110
+ }
94
111
  let fileStats;
95
112
  try {
96
113
  fileStats = fs.statSync(filePath);
package/dist/index.js CHANGED
@@ -21,11 +21,12 @@ function debugLog(message) {
21
21
  const args = process.argv.slice(2);
22
22
  if (args.includes("--help") || args.includes("-h")) {
23
23
  console.log(`
24
- premiere-pro-mcp — MCP server for Adobe Premiere Pro (285 default-profile tools)
24
+ premiere-pro-mcp — MCP server for Adobe Premiere Pro (317 default-profile tools)
25
25
 
26
26
  Usage:
27
27
  premiere-pro-mcp Start the MCP server (stdio transport)
28
28
  premiere-pro-mcp --install-cep Install the CEP plugin into Premiere Pro
29
+ premiere-pro-mcp --uninstall-cep Remove this CEP plugin from Premiere Pro
29
30
  premiere-pro-mcp --diagnose-cep Check the CEP install, debug keys, and Premiere signature logs
30
31
  premiere-pro-mcp --doctor Check local install/configuration without reading a project
31
32
  premiere-pro-mcp --doctor --json Print the same local check as machine-readable JSON
@@ -37,6 +38,7 @@ Environment variables:
37
38
  PREMIERE_TEMP_DIR Shared temp directory (default: OS temp + /premiere-mcp-bridge)
38
39
  PREMIERE_TIMEOUT_MS Command timeout in ms (default: 30000)
39
40
  PREMIERE_MCP_CAPABILITIES Comma-separated authority profile
41
+ PREMIERE_MCP_TOOL_PACKS Comma-separated discovery packs: full, essential, inspection, delivery, captions
40
42
  PREMIERE_MCP_DEBUG Set to 1/true to enable verbose stderr diagnostics
41
43
  PREMIERE_UXP_TOKEN Enable the authenticated local UXP bridge (minimum 16 characters)
42
44
  PREMIERE_UXP_PORT UXP loopback WebSocket port (default: 7777)
@@ -66,9 +68,18 @@ if (args.includes("--doctor") || args.includes("--support-bundle")) {
66
68
  }
67
69
  process.exit(0);
68
70
  }
69
- if (args.includes("--install-cep") || args.includes("--diagnose-cep")) {
70
- const diagnose = args.includes("--diagnose-cep");
71
- console.log(diagnose ? "Diagnosing CEP plugin...\n" : "Installing CEP plugin...\n");
71
+ const cepActions = ["--install-cep", "--uninstall-cep", "--diagnose-cep"].filter((flag) => args.includes(flag));
72
+ if (cepActions.length > 1) {
73
+ console.error("Use only one CEP action at a time: --install-cep, --uninstall-cep, or --diagnose-cep.");
74
+ process.exit(1);
75
+ }
76
+ if (cepActions.length === 1) {
77
+ const action = cepActions[0];
78
+ const diagnose = action === "--diagnose-cep";
79
+ const uninstall = action === "--uninstall-cep";
80
+ console.log(uninstall
81
+ ? "Removing CEP plugin...\n"
82
+ : diagnose ? "Diagnosing CEP plugin...\n" : "Installing CEP plugin...\n");
72
83
  const isWindows = process.platform === "win32";
73
84
  const isMacOS = process.platform === "darwin";
74
85
  if (!isWindows && !isMacOS) {
@@ -81,20 +92,27 @@ if (args.includes("--install-cep") || args.includes("--diagnose-cep")) {
81
92
  const powershellArgs = ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", scriptPath];
82
93
  if (diagnose)
83
94
  powershellArgs.push("-Diagnose");
95
+ if (uninstall) {
96
+ powershellArgs[4] = path.join(projectRoot, "scripts", "uninstall-cep.ps1");
97
+ }
84
98
  execFileSync("powershell.exe", powershellArgs, { stdio: "inherit", cwd: projectRoot });
85
99
  }
86
100
  else {
87
- execFileSync("bash", [scriptPath, diagnose ? "--diagnose" : "--copy"], {
101
+ const macosScriptPath = uninstall
102
+ ? path.join(projectRoot, "scripts", "uninstall-cep.sh")
103
+ : scriptPath;
104
+ execFileSync("bash", [macosScriptPath, uninstall ? "--user" : diagnose ? "--diagnose" : "--copy"], {
88
105
  stdio: "inherit",
89
106
  cwd: projectRoot,
90
107
  });
91
108
  }
92
109
  }
93
110
  catch {
94
- console.error(`CEP ${diagnose ? "diagnostics" : "installation"} failed. Try running manually:`);
111
+ const operation = uninstall ? "uninstallation" : diagnose ? "diagnostics" : "installation";
112
+ console.error(`CEP ${operation} failed. Try running manually:`);
95
113
  console.error(isWindows
96
- ? ` powershell -ExecutionPolicy Bypass -File "${scriptPath}"${diagnose ? " -Diagnose" : ""}`
97
- : ` bash "${scriptPath}" ${diagnose ? "--diagnose" : "--copy"}`);
114
+ ? ` powershell -ExecutionPolicy Bypass -File "${uninstall ? path.join(projectRoot, "scripts", "uninstall-cep.ps1") : scriptPath}"${diagnose ? " -Diagnose" : ""}`
115
+ : ` bash "${uninstall ? path.join(projectRoot, "scripts", "uninstall-cep.sh") : scriptPath}" ${uninstall ? "--user" : diagnose ? "--diagnose" : "--copy"}`);
98
116
  process.exit(1);
99
117
  }
100
118
  process.exit(0);