Files
jhonny-editor/bm/premiere-pro-mcp-main/scripts/generate-supported-actions.mjs
T
João Henrique b541f502ba feat: initial commit - Jhonny Editor
- Adicionado estrutura completa do projeto
- Configurado MCP server para Premiere Pro
- Adicionado documentação e skills
- Configurado Gitignore para o projeto
2026-09-08 09:59:31 -04:00

177 lines
7.2 KiB
JavaScript
Executable File

import { readFile, writeFile } from "node:fs/promises";
import { resolve } from "node:path";
import { pathToFileURL } from "node:url";
import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
import { createServer } from "../dist/server.js";
const DEFAULT_CAPABILITIES = "inspect,edit,export,filesystem";
const FULL_CAPABILITIES = `${DEFAULT_CAPABILITIES},unsafe-script`;
const OUTPUT_PATH = resolve("docs/supported-actions.md");
const disabledTelemetry = {
enabled: false,
capture() {},
async shutdown() {},
};
const mockUxpBridge = {
async request() {
return {};
},
getState() {
return { status: "connected", connected: true };
},
};
async function collectRegisteredTools(capabilities, includeUxp) {
const previousCapabilities = process.env.PREMIERE_MCP_CAPABILITIES;
process.env.PREMIERE_MCP_CAPABILITIES = capabilities;
const server = createServer({}, {
telemetry: disabledTelemetry,
...(includeUxp ? { uxpBridge: mockUxpBridge } : {}),
});
const client = new Client({ name: "supported-actions-generator", version: "1.0.0" });
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
try {
await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]);
const tools = [];
let cursor;
do {
const response = await client.listTools(cursor ? { cursor } : undefined);
tools.push(...response.tools);
cursor = response.nextCursor;
} while (cursor);
return tools.sort((left, right) => left.name.localeCompare(right.name));
} finally {
await client.close();
await server.close();
if (previousCapabilities === undefined) delete process.env.PREMIERE_MCP_CAPABILITIES;
else process.env.PREMIERE_MCP_CAPABILITIES = previousCapabilities;
}
}
function escapeCell(value) {
return String(value ?? "")
.replace(/\s+/g, " ")
.trim()
.replaceAll("|", "\\|");
}
function code(value) {
return `\`${String(value).replaceAll("`", "\\`")}\``;
}
function renderModes(tool) {
const properties = tool.inputSchema?.properties ?? {};
const actionValues = properties.action?.enum;
if (Array.isArray(actionValues) && actionValues.length > 0) {
return actionValues.map(code).join(", ");
}
const modeGroups = Object.entries(properties)
.filter(([, property]) => Array.isArray(property?.enum) && property.enum.length > 0)
.map(([name, property]) => `${code(name)}: ${property.enum.map(code).join(", ")}`);
return modeGroups.length > 0 ? modeGroups.join("; ") : "Single operation";
}
function renderToolRows(tools, availability) {
return tools.map((tool) => (
`| ${code(tool.name)} | ${availability} | ${renderModes(tool)} | ${escapeCell(tool.description)} |`
)).join("\n");
}
export async function generateSupportedActionsMarkdown() {
const defaultCore = await collectRegisteredTools(DEFAULT_CAPABILITIES, false);
const fullCore = await collectRegisteredTools(FULL_CAPABILITIES, false);
const connectedDefault = await collectRegisteredTools(DEFAULT_CAPABILITIES, true);
const defaultNames = new Set(defaultCore.map((tool) => tool.name));
const fullNames = new Set(fullCore.map((tool) => tool.name));
const restrictedCore = fullCore.filter((tool) => !defaultNames.has(tool.name));
const uxpTools = connectedDefault.filter((tool) => !defaultNames.has(tool.name));
if (uxpTools.some((tool) => fullNames.has(tool.name))) {
throw new Error("The UXP additions overlap the registered core tool names.");
}
return `# Supported actions catalog
<!-- Generated by \`npm run docs:supported-actions\`. Do not edit the tables manually. -->
This is the complete source-derived public action catalog for the current repository.
The generator reads the same MCP registration surface used by clients, so tool names,
descriptions, action enums, authority visibility, and counts stay aligned with the code.
Release metadata and distributed-artifact claims remain versioned separately; this
source catalog may include unreleased actions.
| Surface | Count | Availability |
| --- | ---: | --- |
| Registered core actions | ${fullCore.length} | CEP/local server catalog; host and authority checks still apply |
| Default-profile core actions | ${defaultCore.length} | Advertised with \`${DEFAULT_CAPABILITIES}\` |
| Restricted core actions | ${restrictedCore.length} | Require explicit \`unsafe-script\` authority |
| Authenticated UXP additions | ${uxpTools.length} | Advertised only while a compatible authenticated UXP panel is connected |
| Default profile with UXP | ${connectedDefault.length} | ${defaultCore.length} core plus ${uxpTools.length} UXP tools |
## How to read support
- \`tools/list\` is authoritative for what the current MCP session may call.
- \`get_capabilities\` reports the full registered catalog, authority decisions, backend
eligibility, and any live-host verification still required.
- A listed tool is not proof that a particular Premiere installation supports every host
API. The authenticated UXP capability handshake and per-call preflight remain authoritative.
- CEP remains the compatibility backend. A failed UXP mutation is never automatically
replayed through CEP or the undocumented QE DOM.
- Automated tests establish schemas, routing, bounds, transactions, and readback contracts;
they do not replace validation in a real Premiere host.
## Core actions
Each core tool is one callable MCP action. “Actions or modes” records a top-level
\`action\` enum when present, otherwise other top-level enum selectors, or “Single
operation” when the tool has no enum-based mode.
| MCP tool | Availability | Actions or modes | Description |
| --- | --- | --- | --- |
${renderToolRows(defaultCore, "Default profile")}
${renderToolRows(restrictedCore, `Requires ${code("unsafe-script")}`)}
## Authenticated UXP actions
These tools are additive. They appear only while the local loopback UXP bridge is
authenticated and the connected host advertises the required command capabilities.
| MCP tool | Availability | Actions or modes | Description |
| --- | --- | --- | --- |
${renderToolRows(uxpTools, "Connected UXP")}
## Maintenance
Run \`npm run docs:supported-actions\` after changing tool registration or action enums.
\`npm run check\` fails when this generated page no longer matches the registered surface.
`;
}
async function main() {
const checkOnly = process.argv.slice(2).includes("--check");
const unknown = process.argv.slice(2).filter((argument) => argument !== "--check");
if (unknown.length > 0) throw new Error(`Unknown argument: ${unknown[0]}`);
const markdown = await generateSupportedActionsMarkdown();
if (checkOnly) {
const current = await readFile(OUTPUT_PATH, "utf8").catch(() => "");
if (current.replaceAll("\r\n", "\n") !== markdown) {
throw new Error("docs/supported-actions.md is stale. Run npm run docs:supported-actions.");
}
process.stdout.write("Supported actions catalog is current.\n");
return;
}
await writeFile(OUTPUT_PATH, markdown, "utf8");
process.stdout.write(`Wrote ${OUTPUT_PATH}\n`);
}
if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
main().catch((error) => {
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
process.exitCode = 1;
});
}