@agimon-ai/video-editor-mcp 0.2.0 → 0.2.2

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/dist/cli.cjs CHANGED
@@ -1,179 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_stdio = require('./stdio-C-vwZanD.cjs');
3
- let commander = require("commander");
4
- let node_child_process = require("node:child_process");
5
- let node_path = require("node:path");
6
- node_path = require_stdio.__toESM(node_path);
7
- let chalk = require("chalk");
8
- chalk = require_stdio.__toESM(chalk);
9
- let node_fs = require("node:fs");
10
- node_fs = require_stdio.__toESM(node_fs);
11
-
12
- //#region package.json
13
- var version = "0.1.0";
14
-
15
- //#endregion
16
- //#region src/commands/http-serve.ts
17
- /**
18
- * HTTP Serve Command
19
- *
20
- * Starts Remotion Studio for interactive video editing.
21
- */
22
- const httpServeCommand = new commander.Command("http-serve").description("Start Remotion Studio for video editing").option("-p, --port <port>", "Port to run Remotion Studio on", "3001").action(async (options) => {
23
- try {
24
- const port = parseInt(options.port, 10);
25
- const packageDir = node_path.default.resolve(__dirname, "..");
26
- console.error(chalk.default.green(`✓ Starting Remotion Studio on port ${port}...`));
27
- console.error(chalk.default.gray(` Working directory: ${packageDir}`));
28
- const studio = (0, node_child_process.spawn)(node_path.default.join(packageDir, "node_modules", ".bin", "remotion"), [
29
- "studio",
30
- "--port",
31
- String(port)
32
- ], {
33
- stdio: "inherit",
34
- cwd: packageDir
35
- });
36
- studio.on("error", (error) => {
37
- console.error(chalk.default.red(`Failed to start Remotion Studio: ${error.message}`));
38
- process.exit(1);
39
- });
40
- process.on("SIGINT", () => {
41
- studio.kill("SIGINT");
42
- process.exit(0);
43
- });
44
- process.on("SIGTERM", () => {
45
- studio.kill("SIGTERM");
46
- process.exit(0);
47
- });
48
- } catch (error) {
49
- console.error("Error executing http-serve:", error);
50
- process.exit(1);
51
- }
52
- });
53
-
54
- //#endregion
55
- //#region src/commands/mcp-serve.ts
56
- /**
57
- * MCP Serve Command
58
- *
59
- * DESIGN PATTERNS:
60
- * - Command pattern with Commander for CLI argument parsing
61
- * - Transport abstraction pattern for flexible deployment (stdio, HTTP, SSE)
62
- * - Factory pattern for creating transport handlers
63
- * - Graceful shutdown pattern with signal handling
64
- *
65
- * CODING STANDARDS:
66
- * - Use async/await for asynchronous operations
67
- * - Implement proper error handling with try-catch blocks
68
- * - Handle process signals for graceful shutdown
69
- * - Provide clear CLI options and help messages
70
- *
71
- * AVOID:
72
- * - Hardcoded configuration values (use CLI options or environment variables)
73
- * - Missing error handling for transport startup
74
- * - Not cleaning up resources on shutdown
75
- */
76
- /**
77
- * Start MCP server with given transport handler
78
- */
79
- async function startServer(handler) {
80
- await handler.start();
81
- const shutdown = async (signal) => {
82
- console.error(`\nReceived ${signal}, shutting down gracefully...`);
83
- try {
84
- await handler.stop();
85
- process.exit(0);
86
- } catch (error) {
87
- console.error("Error during shutdown:", error);
88
- process.exit(1);
89
- }
90
- };
91
- process.on("SIGINT", () => shutdown("SIGINT"));
92
- process.on("SIGTERM", () => shutdown("SIGTERM"));
93
- }
94
- /**
95
- * MCP Serve command
96
- */
97
- const mcpServeCommand = new commander.Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", "Transport type: stdio", "stdio").action(async (options) => {
98
- try {
99
- const transportType = options.type.toLowerCase();
100
- if (transportType === "stdio") await startServer(new require_stdio.StdioTransportHandler(require_stdio.createServer(require_stdio.createContainer())));
101
- else {
102
- console.error(`Unknown transport type: ${transportType}. Use: stdio`);
103
- process.exit(1);
104
- }
105
- } catch (error) {
106
- console.error("Failed to start MCP server:", error);
107
- process.exit(1);
108
- }
109
- });
110
-
111
- //#endregion
112
- //#region src/commands/render.ts
113
- /**
114
- * Render Command
115
- *
116
- * Renders a video from JSON props using Remotion.
117
- */
118
- const renderCommand = new commander.Command("render").description("Render a video from JSON props file").requiredOption("-i, --input <path>", "Path to JSON props file").requiredOption("-o, --output <path>", "Output video file path").option("-c, --composition <id>", "Composition ID", "Main").option("--codec <codec>", "Video codec (h264, h265, vp8, vp9)", "h264").action(async (options) => {
119
- try {
120
- process.stderr.write(chalk.default.blue("🎬 Starting video render...\n"));
121
- process.stderr.write(chalk.default.gray(` Input: ${options.input}\n`));
122
- process.stderr.write(chalk.default.gray(` Output: ${options.output}\n`));
123
- process.stderr.write(chalk.default.gray(` Composition: ${options.composition}\n`));
124
- process.stderr.write(chalk.default.gray(` Codec: ${options.codec}\n`));
125
- if (!node_fs.default.existsSync(options.input)) {
126
- process.stderr.write(chalk.default.red(`Error: Input file not found: ${options.input}\n`));
127
- process.exit(1);
128
- }
129
- const propsContent = node_fs.default.readFileSync(options.input, "utf-8");
130
- const inputProps = JSON.parse(propsContent);
131
- const renderService = require_stdio.createContainer().get(require_stdio.TYPES.RenderService);
132
- process.stderr.write(chalk.default.blue("📦 Bundling Remotion project...\n"));
133
- const result = await renderService.render({
134
- compositionId: options.composition,
135
- inputProps,
136
- outputPath: options.output,
137
- codec: options.codec
138
- });
139
- process.stderr.write(chalk.default.green(`✓ Video rendered successfully: ${result.outputPath}\n`));
140
- } catch (error) {
141
- process.stderr.write(chalk.default.red(`Error rendering video: ${error}\n`));
142
- process.exit(1);
143
- }
144
- });
145
-
146
- //#endregion
147
- //#region src/cli.ts
148
- /**
149
- * MCP Server Entry Point
150
- *
151
- * DESIGN PATTERNS:
152
- * - CLI pattern with Commander for argument parsing
153
- * - Command pattern for organizing CLI commands
154
- * - Transport abstraction for multiple communication methods
155
- *
156
- * CODING STANDARDS:
157
- * - Use async/await for asynchronous operations
158
- * - Handle errors gracefully with try-catch
159
- * - Log important events for debugging
160
- * - Register all commands in main entry point
161
- *
162
- * AVOID:
163
- * - Hardcoding command logic in index.ts (use separate command files)
164
- * - Missing error handling for command execution
165
- */
166
- /**
167
- * Main entry point
168
- */
169
- async function main() {
170
- const program = new commander.Command();
171
- program.name("video-editor-mcp").description("MCP server for video editing with Remotion").version(version);
172
- program.addCommand(mcpServeCommand);
173
- program.addCommand(httpServeCommand);
174
- program.addCommand(renderCommand);
175
- await program.parseAsync(process.argv);
176
- }
177
- main();
178
-
179
- //#endregion
2
+ const e=require(`./stdio-DRNt1yxK.cjs`);let t=require(`commander`),n=require(`node:child_process`),r=require(`node:path`);r=e.m(r);let i=require(`chalk`);i=e.m(i);let a=require(`node:fs`);a=e.m(a);var o=`0.2.1`;const s=new t.Command(`http-serve`).description(`Start Remotion Studio for video editing`).option(`-p, --port <port>`,`Port to run Remotion Studio on`,`3001`).action(async e=>{try{let t=parseInt(e.port,10),a=r.default.resolve(__dirname,`..`);console.error(i.default.green(`✓ Starting Remotion Studio on port ${t}...`)),console.error(i.default.gray(` Working directory: ${a}`));let o=(0,n.spawn)(r.default.join(a,`node_modules`,`.bin`,`remotion`),[`studio`,`--port`,String(t)],{stdio:`inherit`,cwd:a});o.on(`error`,e=>{console.error(i.default.red(`Failed to start Remotion Studio: ${e.message}`)),process.exit(1)}),process.on(`SIGINT`,()=>{o.kill(`SIGINT`),process.exit(0)}),process.on(`SIGTERM`,()=>{o.kill(`SIGTERM`),process.exit(0)})}catch(e){console.error(`Error executing http-serve:`,e),process.exit(1)}});async function c(e){await e.start();let t=async t=>{console.error(`\nReceived ${t}, shutting down gracefully...`);try{await e.stop(),process.exit(0)}catch(e){console.error(`Error during shutdown:`,e),process.exit(1)}};process.on(`SIGINT`,()=>t(`SIGINT`)),process.on(`SIGTERM`,()=>t(`SIGTERM`))}const l=new t.Command(`mcp-serve`).description(`Start MCP server with specified transport`).option(`-t, --type <type>`,`Transport type: stdio`,`stdio`).action(async t=>{try{let n=t.type.toLowerCase();n===`stdio`?await c(new e.t(e.n(e.r()))):(console.error(`Unknown transport type: ${n}. Use: stdio`),process.exit(1))}catch(e){console.error(`Failed to start MCP server:`,e),process.exit(1)}}),u=new t.Command(`render`).description(`Render a video from JSON props file`).requiredOption(`-i, --input <path>`,`Path to JSON props file`).requiredOption(`-o, --output <path>`,`Output video file path`).option(`-c, --composition <id>`,`Composition ID`,`Main`).option(`--codec <codec>`,`Video codec (h264, h265, vp8, vp9)`,`h264`).action(async t=>{try{process.stderr.write(i.default.blue(`🎬 Starting video render...
3
+ `)),process.stderr.write(i.default.gray(` Input: ${t.input}\n`)),process.stderr.write(i.default.gray(` Output: ${t.output}\n`)),process.stderr.write(i.default.gray(` Composition: ${t.composition}\n`)),process.stderr.write(i.default.gray(` Codec: ${t.codec}\n`)),a.default.existsSync(t.input)||(process.stderr.write(i.default.red(`Error: Input file not found: ${t.input}\n`)),process.exit(1));let n=a.default.readFileSync(t.input,`utf-8`),r=JSON.parse(n),o=e.r().get(e.d.RenderService);process.stderr.write(i.default.blue(`📦 Bundling Remotion project...
4
+ `));let s=await o.render({compositionId:t.composition,inputProps:r,outputPath:t.output,codec:t.codec});process.stderr.write(i.default.green(`✓ Video rendered successfully: ${s.outputPath}\n`))}catch(e){process.stderr.write(i.default.red(`Error rendering video: ${e}\n`)),process.exit(1)}});async function d(){let e=new t.Command;e.name(`video-editor-mcp`).description(`MCP server for video editing with Remotion`).version(o),e.addCommand(l),e.addCommand(s),e.addCommand(u),await e.parseAsync(process.argv)}d();
5
+ //# sourceMappingURL=cli.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.cjs","names":["Command","path","Command","StdioTransportHandler","createServer","createContainer","Command","fs","createContainer","TYPES","Command","packageJson.version"],"sources":["../package.json","../src/commands/http-serve.ts","../src/commands/mcp-serve.ts","../src/commands/render.ts","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"@agimon-ai/video-editor-mcp\",\n \"description\": \"MCP server for video editing with Remotion\",\n \"version\": \"0.2.1\",\n \"license\": \"AGPL-3.0\",\n \"keywords\": [\n \"mcp\",\n \"model-context-protocol\",\n \"remotion\",\n \"video-editor\",\n \"typescript\"\n ],\n \"bin\": {\n \"video-editor-mcp\": \"./dist/cli.cjs\"\n },\n \"main\": \"./dist/index.cjs\",\n \"types\": \"./dist/index.d.cts\",\n \"module\": \"./dist/index.mjs\",\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"scripts\": {\n \"dev\": \"node --loader ts-node/esm src/cli.ts mcp-serve\",\n \"build\": \"tsdown\",\n \"test\": \"vitest --run\",\n \"lint\": \"eslint src\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"1.19.1\",\n \"@remotion/bundler\": \"^4.0.0\",\n \"@remotion/captions\": \"^4.0.0\",\n \"@remotion/cli\": \"^4.0.0\",\n \"@remotion/fonts\": \"^4.0.0\",\n \"@remotion/gif\": \"^4.0.0\",\n \"@remotion/google-fonts\": \"^4.0.0\",\n \"@remotion/lottie\": \"^4.0.0\",\n \"@remotion/media-utils\": \"^4.0.0\",\n \"@remotion/renderer\": \"^4.0.0\",\n \"@remotion/transitions\": \"^4.0.0\",\n \"chalk\": \"5.4.1\",\n \"commander\": \"14.0.0\",\n \"inversify\": \"7.1.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"reflect-metadata\": \"0.2.2\",\n \"remotion\": \"^4.0.0\",\n \"zod\": \"4.3.6\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.0.0\",\n \"@types/react\": \"^19.0.0\",\n \"tsdown\": \"0.16.1\",\n \"typescript\": \"5.9.3\",\n \"vitest\": \"4.0.18\"\n },\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n },\n \"./cli\": {\n \"import\": \"./dist/cli.mjs\",\n \"require\": \"./dist/cli.cjs\"\n },\n \"./package.json\": \"./package.json\"\n }\n}\n","/**\n * HTTP Serve Command\n *\n * Starts Remotion Studio for interactive video editing.\n */\n\nimport { spawn } from 'node:child_process';\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\n\nexport const httpServeCommand = new Command('http-serve')\n .description('Start Remotion Studio for video editing')\n .option('-p, --port <port>', 'Port to run Remotion Studio on', '3001')\n .action(async (options: { port: string }) => {\n try {\n const port = parseInt(options.port, 10);\n\n // Get the package directory (where remotion entry point is)\n // In compiled output, files are flat in dist/, so go up one level\n const packageDir = path.resolve(import.meta.dirname, '..');\n\n console.error(chalk.green(`✓ Starting Remotion Studio on port ${port}...`));\n console.error(chalk.gray(` Working directory: ${packageDir}`));\n\n // Use the locally installed remotion CLI\n const remotionBin = path.join(packageDir, 'node_modules', '.bin', 'remotion');\n\n const studio = spawn(remotionBin, ['studio', '--port', String(port)], {\n stdio: 'inherit',\n cwd: packageDir,\n });\n\n studio.on('error', (error) => {\n console.error(chalk.red(`Failed to start Remotion Studio: ${error.message}`));\n process.exit(1);\n });\n\n process.on('SIGINT', () => {\n studio.kill('SIGINT');\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n studio.kill('SIGTERM');\n process.exit(0);\n });\n } catch (error) {\n console.error('Error executing http-serve:', error);\n process.exit(1);\n }\n });\n","/**\n * MCP Serve Command\n *\n * DESIGN PATTERNS:\n * - Command pattern with Commander for CLI argument parsing\n * - Transport abstraction pattern for flexible deployment (stdio, HTTP, SSE)\n * - Factory pattern for creating transport handlers\n * - Graceful shutdown pattern with signal handling\n *\n * CODING STANDARDS:\n * - Use async/await for asynchronous operations\n * - Implement proper error handling with try-catch blocks\n * - Handle process signals for graceful shutdown\n * - Provide clear CLI options and help messages\n *\n * AVOID:\n * - Hardcoded configuration values (use CLI options or environment variables)\n * - Missing error handling for transport startup\n * - Not cleaning up resources on shutdown\n */\n\nimport { Command } from 'commander';\nimport { createContainer } from '../container/index.js';\nimport { createServer } from '../server/index.js';\nimport { StdioTransportHandler } from '../transports/stdio.js';\n\n/**\n * Start MCP server with given transport handler\n */\nasync function startServer(handler: any) {\n await handler.start();\n\n // Handle graceful shutdown\n const shutdown = async (signal: string) => {\n console.error(`\\nReceived ${signal}, shutting down gracefully...`);\n try {\n await handler.stop();\n process.exit(0);\n } catch (error) {\n console.error('Error during shutdown:', error);\n process.exit(1);\n }\n };\n\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n}\n\n/**\n * MCP Serve command\n */\nexport const mcpServeCommand = new Command('mcp-serve')\n .description('Start MCP server with specified transport')\n .option('-t, --type <type>', 'Transport type: stdio', 'stdio')\n .action(async (options) => {\n try {\n const transportType = options.type.toLowerCase();\n\n if (transportType === 'stdio') {\n const container = createContainer();\n const server = createServer(container);\n const handler = new StdioTransportHandler(server);\n await startServer(handler);\n } else {\n console.error(`Unknown transport type: ${transportType}. Use: stdio`);\n process.exit(1);\n }\n } catch (error) {\n console.error('Failed to start MCP server:', error);\n process.exit(1);\n }\n });\n","/**\n * Render Command\n *\n * Renders a video from JSON props using Remotion.\n */\n\nimport fs from 'node:fs';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport { createContainer } from '../container/index.js';\nimport { RenderService } from '../services/RenderService.js';\nimport { TYPES } from '../types/index.js';\n\ninterface RenderOptions {\n input: string;\n output: string;\n composition: string;\n codec: 'h264' | 'h265' | 'vp8' | 'vp9';\n}\n\nexport const renderCommand = new Command('render')\n .description('Render a video from JSON props file')\n .requiredOption('-i, --input <path>', 'Path to JSON props file')\n .requiredOption('-o, --output <path>', 'Output video file path')\n .option('-c, --composition <id>', 'Composition ID', 'Main')\n .option('--codec <codec>', 'Video codec (h264, h265, vp8, vp9)', 'h264')\n .action(async (options: RenderOptions) => {\n try {\n process.stderr.write(chalk.blue('🎬 Starting video render...\\n'));\n process.stderr.write(chalk.gray(` Input: ${options.input}\\n`));\n process.stderr.write(chalk.gray(` Output: ${options.output}\\n`));\n process.stderr.write(chalk.gray(` Composition: ${options.composition}\\n`));\n process.stderr.write(chalk.gray(` Codec: ${options.codec}\\n`));\n\n // Read JSON props file\n if (!fs.existsSync(options.input)) {\n process.stderr.write(chalk.red(`Error: Input file not found: ${options.input}\\n`));\n process.exit(1);\n }\n\n const propsContent = fs.readFileSync(options.input, 'utf-8');\n const inputProps = JSON.parse(propsContent) as Record<string, unknown>;\n\n // Create container and get RenderService\n const container = createContainer();\n const renderService = container.get<RenderService>(TYPES.RenderService);\n\n process.stderr.write(chalk.blue('📦 Bundling Remotion project...\\n'));\n\n const result = await renderService.render({\n compositionId: options.composition,\n inputProps,\n outputPath: options.output,\n codec: options.codec,\n });\n\n process.stderr.write(chalk.green(`✓ Video rendered successfully: ${result.outputPath}\\n`));\n } catch (error) {\n process.stderr.write(chalk.red(`Error rendering video: ${error}\\n`));\n process.exit(1);\n }\n });\n","#!/usr/bin/env node\n/**\n * MCP Server Entry Point\n *\n * DESIGN PATTERNS:\n * - CLI pattern with Commander for argument parsing\n * - Command pattern for organizing CLI commands\n * - Transport abstraction for multiple communication methods\n *\n * CODING STANDARDS:\n * - Use async/await for asynchronous operations\n * - Handle errors gracefully with try-catch\n * - Log important events for debugging\n * - Register all commands in main entry point\n *\n * AVOID:\n * - Hardcoding command logic in index.ts (use separate command files)\n * - Missing error handling for command execution\n */\nimport { Command } from 'commander';\nimport packageJson from '../package.json' with { type: 'json' };\nimport { httpServeCommand } from './commands/http-serve.js';\nimport { mcpServeCommand } from './commands/mcp-serve.js';\nimport { renderCommand } from './commands/render.js';\n\n/**\n * Main entry point\n */\nasync function main() {\n const program = new Command();\n\n program\n .name('video-editor-mcp')\n .description('MCP server for video editing with Remotion')\n .version(packageJson.version);\n\n // Add all commands\n program.addCommand(mcpServeCommand);\n program.addCommand(httpServeCommand);\n program.addCommand(renderCommand);\n\n // Parse arguments\n await program.parseAsync(process.argv);\n}\n\nmain();\n"],"mappings":"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"}
package/dist/cli.mjs CHANGED
@@ -1,177 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { d as TYPES, n as createServer, r as createContainer, t as StdioTransportHandler } from "./stdio-C7h0m1FD.mjs";
3
- import { Command } from "commander";
4
- import { spawn } from "node:child_process";
5
- import path from "node:path";
6
- import chalk from "chalk";
7
- import fs from "node:fs";
8
-
9
- //#region package.json
10
- var version = "0.1.0";
11
-
12
- //#endregion
13
- //#region src/commands/http-serve.ts
14
- /**
15
- * HTTP Serve Command
16
- *
17
- * Starts Remotion Studio for interactive video editing.
18
- */
19
- const httpServeCommand = new Command("http-serve").description("Start Remotion Studio for video editing").option("-p, --port <port>", "Port to run Remotion Studio on", "3001").action(async (options) => {
20
- try {
21
- const port = parseInt(options.port, 10);
22
- const packageDir = path.resolve(import.meta.dirname, "..");
23
- console.error(chalk.green(`✓ Starting Remotion Studio on port ${port}...`));
24
- console.error(chalk.gray(` Working directory: ${packageDir}`));
25
- const studio = spawn(path.join(packageDir, "node_modules", ".bin", "remotion"), [
26
- "studio",
27
- "--port",
28
- String(port)
29
- ], {
30
- stdio: "inherit",
31
- cwd: packageDir
32
- });
33
- studio.on("error", (error) => {
34
- console.error(chalk.red(`Failed to start Remotion Studio: ${error.message}`));
35
- process.exit(1);
36
- });
37
- process.on("SIGINT", () => {
38
- studio.kill("SIGINT");
39
- process.exit(0);
40
- });
41
- process.on("SIGTERM", () => {
42
- studio.kill("SIGTERM");
43
- process.exit(0);
44
- });
45
- } catch (error) {
46
- console.error("Error executing http-serve:", error);
47
- process.exit(1);
48
- }
49
- });
50
-
51
- //#endregion
52
- //#region src/commands/mcp-serve.ts
53
- /**
54
- * MCP Serve Command
55
- *
56
- * DESIGN PATTERNS:
57
- * - Command pattern with Commander for CLI argument parsing
58
- * - Transport abstraction pattern for flexible deployment (stdio, HTTP, SSE)
59
- * - Factory pattern for creating transport handlers
60
- * - Graceful shutdown pattern with signal handling
61
- *
62
- * CODING STANDARDS:
63
- * - Use async/await for asynchronous operations
64
- * - Implement proper error handling with try-catch blocks
65
- * - Handle process signals for graceful shutdown
66
- * - Provide clear CLI options and help messages
67
- *
68
- * AVOID:
69
- * - Hardcoded configuration values (use CLI options or environment variables)
70
- * - Missing error handling for transport startup
71
- * - Not cleaning up resources on shutdown
72
- */
73
- /**
74
- * Start MCP server with given transport handler
75
- */
76
- async function startServer(handler) {
77
- await handler.start();
78
- const shutdown = async (signal) => {
79
- console.error(`\nReceived ${signal}, shutting down gracefully...`);
80
- try {
81
- await handler.stop();
82
- process.exit(0);
83
- } catch (error) {
84
- console.error("Error during shutdown:", error);
85
- process.exit(1);
86
- }
87
- };
88
- process.on("SIGINT", () => shutdown("SIGINT"));
89
- process.on("SIGTERM", () => shutdown("SIGTERM"));
90
- }
91
- /**
92
- * MCP Serve command
93
- */
94
- const mcpServeCommand = new Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", "Transport type: stdio", "stdio").action(async (options) => {
95
- try {
96
- const transportType = options.type.toLowerCase();
97
- if (transportType === "stdio") await startServer(new StdioTransportHandler(createServer(createContainer())));
98
- else {
99
- console.error(`Unknown transport type: ${transportType}. Use: stdio`);
100
- process.exit(1);
101
- }
102
- } catch (error) {
103
- console.error("Failed to start MCP server:", error);
104
- process.exit(1);
105
- }
106
- });
107
-
108
- //#endregion
109
- //#region src/commands/render.ts
110
- /**
111
- * Render Command
112
- *
113
- * Renders a video from JSON props using Remotion.
114
- */
115
- const renderCommand = new Command("render").description("Render a video from JSON props file").requiredOption("-i, --input <path>", "Path to JSON props file").requiredOption("-o, --output <path>", "Output video file path").option("-c, --composition <id>", "Composition ID", "Main").option("--codec <codec>", "Video codec (h264, h265, vp8, vp9)", "h264").action(async (options) => {
116
- try {
117
- process.stderr.write(chalk.blue("🎬 Starting video render...\n"));
118
- process.stderr.write(chalk.gray(` Input: ${options.input}\n`));
119
- process.stderr.write(chalk.gray(` Output: ${options.output}\n`));
120
- process.stderr.write(chalk.gray(` Composition: ${options.composition}\n`));
121
- process.stderr.write(chalk.gray(` Codec: ${options.codec}\n`));
122
- if (!fs.existsSync(options.input)) {
123
- process.stderr.write(chalk.red(`Error: Input file not found: ${options.input}\n`));
124
- process.exit(1);
125
- }
126
- const propsContent = fs.readFileSync(options.input, "utf-8");
127
- const inputProps = JSON.parse(propsContent);
128
- const renderService = createContainer().get(TYPES.RenderService);
129
- process.stderr.write(chalk.blue("📦 Bundling Remotion project...\n"));
130
- const result = await renderService.render({
131
- compositionId: options.composition,
132
- inputProps,
133
- outputPath: options.output,
134
- codec: options.codec
135
- });
136
- process.stderr.write(chalk.green(`✓ Video rendered successfully: ${result.outputPath}\n`));
137
- } catch (error) {
138
- process.stderr.write(chalk.red(`Error rendering video: ${error}\n`));
139
- process.exit(1);
140
- }
141
- });
142
-
143
- //#endregion
144
- //#region src/cli.ts
145
- /**
146
- * MCP Server Entry Point
147
- *
148
- * DESIGN PATTERNS:
149
- * - CLI pattern with Commander for argument parsing
150
- * - Command pattern for organizing CLI commands
151
- * - Transport abstraction for multiple communication methods
152
- *
153
- * CODING STANDARDS:
154
- * - Use async/await for asynchronous operations
155
- * - Handle errors gracefully with try-catch
156
- * - Log important events for debugging
157
- * - Register all commands in main entry point
158
- *
159
- * AVOID:
160
- * - Hardcoding command logic in index.ts (use separate command files)
161
- * - Missing error handling for command execution
162
- */
163
- /**
164
- * Main entry point
165
- */
166
- async function main() {
167
- const program = new Command();
168
- program.name("video-editor-mcp").description("MCP server for video editing with Remotion").version(version);
169
- program.addCommand(mcpServeCommand);
170
- program.addCommand(httpServeCommand);
171
- program.addCommand(renderCommand);
172
- await program.parseAsync(process.argv);
173
- }
174
- main();
175
-
176
- //#endregion
177
- export { };
2
+ import{d as e,n as t,r as n,t as r}from"./stdio-C7h0m1FD.mjs";import{Command as i}from"commander";import{spawn as a}from"node:child_process";import o from"node:path";import s from"chalk";import c from"node:fs";var l=`0.2.1`;const u=new i(`http-serve`).description(`Start Remotion Studio for video editing`).option(`-p, --port <port>`,`Port to run Remotion Studio on`,`3001`).action(async e=>{try{let t=parseInt(e.port,10),n=o.resolve(import.meta.dirname,`..`);console.error(s.green(`✓ Starting Remotion Studio on port ${t}...`)),console.error(s.gray(` Working directory: ${n}`));let r=a(o.join(n,`node_modules`,`.bin`,`remotion`),[`studio`,`--port`,String(t)],{stdio:`inherit`,cwd:n});r.on(`error`,e=>{console.error(s.red(`Failed to start Remotion Studio: ${e.message}`)),process.exit(1)}),process.on(`SIGINT`,()=>{r.kill(`SIGINT`),process.exit(0)}),process.on(`SIGTERM`,()=>{r.kill(`SIGTERM`),process.exit(0)})}catch(e){console.error(`Error executing http-serve:`,e),process.exit(1)}});async function d(e){await e.start();let t=async t=>{console.error(`\nReceived ${t}, shutting down gracefully...`);try{await e.stop(),process.exit(0)}catch(e){console.error(`Error during shutdown:`,e),process.exit(1)}};process.on(`SIGINT`,()=>t(`SIGINT`)),process.on(`SIGTERM`,()=>t(`SIGTERM`))}const f=new i(`mcp-serve`).description(`Start MCP server with specified transport`).option(`-t, --type <type>`,`Transport type: stdio`,`stdio`).action(async e=>{try{let i=e.type.toLowerCase();i===`stdio`?await d(new r(t(n()))):(console.error(`Unknown transport type: ${i}. Use: stdio`),process.exit(1))}catch(e){console.error(`Failed to start MCP server:`,e),process.exit(1)}}),p=new i(`render`).description(`Render a video from JSON props file`).requiredOption(`-i, --input <path>`,`Path to JSON props file`).requiredOption(`-o, --output <path>`,`Output video file path`).option(`-c, --composition <id>`,`Composition ID`,`Main`).option(`--codec <codec>`,`Video codec (h264, h265, vp8, vp9)`,`h264`).action(async t=>{try{process.stderr.write(s.blue(`🎬 Starting video render...
3
+ `)),process.stderr.write(s.gray(` Input: ${t.input}\n`)),process.stderr.write(s.gray(` Output: ${t.output}\n`)),process.stderr.write(s.gray(` Composition: ${t.composition}\n`)),process.stderr.write(s.gray(` Codec: ${t.codec}\n`)),c.existsSync(t.input)||(process.stderr.write(s.red(`Error: Input file not found: ${t.input}\n`)),process.exit(1));let r=c.readFileSync(t.input,`utf-8`),i=JSON.parse(r),a=n().get(e.RenderService);process.stderr.write(s.blue(`📦 Bundling Remotion project...
4
+ `));let o=await a.render({compositionId:t.composition,inputProps:i,outputPath:t.output,codec:t.codec});process.stderr.write(s.green(`✓ Video rendered successfully: ${o.outputPath}\n`))}catch(e){process.stderr.write(s.red(`Error rendering video: ${e}\n`)),process.exit(1)}});async function m(){let e=new i;e.name(`video-editor-mcp`).description(`MCP server for video editing with Remotion`).version(l),e.addCommand(f),e.addCommand(u),e.addCommand(p),await e.parseAsync(process.argv)}m();export{};
5
+ //# sourceMappingURL=cli.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.mjs","names":["packageJson.version"],"sources":["../package.json","../src/commands/http-serve.ts","../src/commands/mcp-serve.ts","../src/commands/render.ts","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"@agimon-ai/video-editor-mcp\",\n \"description\": \"MCP server for video editing with Remotion\",\n \"version\": \"0.2.1\",\n \"license\": \"AGPL-3.0\",\n \"keywords\": [\n \"mcp\",\n \"model-context-protocol\",\n \"remotion\",\n \"video-editor\",\n \"typescript\"\n ],\n \"bin\": {\n \"video-editor-mcp\": \"./dist/cli.cjs\"\n },\n \"main\": \"./dist/index.cjs\",\n \"types\": \"./dist/index.d.cts\",\n \"module\": \"./dist/index.mjs\",\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"scripts\": {\n \"dev\": \"node --loader ts-node/esm src/cli.ts mcp-serve\",\n \"build\": \"tsdown\",\n \"test\": \"vitest --run\",\n \"lint\": \"eslint src\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"1.19.1\",\n \"@remotion/bundler\": \"^4.0.0\",\n \"@remotion/captions\": \"^4.0.0\",\n \"@remotion/cli\": \"^4.0.0\",\n \"@remotion/fonts\": \"^4.0.0\",\n \"@remotion/gif\": \"^4.0.0\",\n \"@remotion/google-fonts\": \"^4.0.0\",\n \"@remotion/lottie\": \"^4.0.0\",\n \"@remotion/media-utils\": \"^4.0.0\",\n \"@remotion/renderer\": \"^4.0.0\",\n \"@remotion/transitions\": \"^4.0.0\",\n \"chalk\": \"5.4.1\",\n \"commander\": \"14.0.0\",\n \"inversify\": \"7.1.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"reflect-metadata\": \"0.2.2\",\n \"remotion\": \"^4.0.0\",\n \"zod\": \"4.3.6\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.0.0\",\n \"@types/react\": \"^19.0.0\",\n \"tsdown\": \"0.16.1\",\n \"typescript\": \"5.9.3\",\n \"vitest\": \"4.0.18\"\n },\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n },\n \"./cli\": {\n \"import\": \"./dist/cli.mjs\",\n \"require\": \"./dist/cli.cjs\"\n },\n \"./package.json\": \"./package.json\"\n }\n}\n","/**\n * HTTP Serve Command\n *\n * Starts Remotion Studio for interactive video editing.\n */\n\nimport { spawn } from 'node:child_process';\nimport path from 'node:path';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\n\nexport const httpServeCommand = new Command('http-serve')\n .description('Start Remotion Studio for video editing')\n .option('-p, --port <port>', 'Port to run Remotion Studio on', '3001')\n .action(async (options: { port: string }) => {\n try {\n const port = parseInt(options.port, 10);\n\n // Get the package directory (where remotion entry point is)\n // In compiled output, files are flat in dist/, so go up one level\n const packageDir = path.resolve(import.meta.dirname, '..');\n\n console.error(chalk.green(`✓ Starting Remotion Studio on port ${port}...`));\n console.error(chalk.gray(` Working directory: ${packageDir}`));\n\n // Use the locally installed remotion CLI\n const remotionBin = path.join(packageDir, 'node_modules', '.bin', 'remotion');\n\n const studio = spawn(remotionBin, ['studio', '--port', String(port)], {\n stdio: 'inherit',\n cwd: packageDir,\n });\n\n studio.on('error', (error) => {\n console.error(chalk.red(`Failed to start Remotion Studio: ${error.message}`));\n process.exit(1);\n });\n\n process.on('SIGINT', () => {\n studio.kill('SIGINT');\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n studio.kill('SIGTERM');\n process.exit(0);\n });\n } catch (error) {\n console.error('Error executing http-serve:', error);\n process.exit(1);\n }\n });\n","/**\n * MCP Serve Command\n *\n * DESIGN PATTERNS:\n * - Command pattern with Commander for CLI argument parsing\n * - Transport abstraction pattern for flexible deployment (stdio, HTTP, SSE)\n * - Factory pattern for creating transport handlers\n * - Graceful shutdown pattern with signal handling\n *\n * CODING STANDARDS:\n * - Use async/await for asynchronous operations\n * - Implement proper error handling with try-catch blocks\n * - Handle process signals for graceful shutdown\n * - Provide clear CLI options and help messages\n *\n * AVOID:\n * - Hardcoded configuration values (use CLI options or environment variables)\n * - Missing error handling for transport startup\n * - Not cleaning up resources on shutdown\n */\n\nimport { Command } from 'commander';\nimport { createContainer } from '../container/index.js';\nimport { createServer } from '../server/index.js';\nimport { StdioTransportHandler } from '../transports/stdio.js';\n\n/**\n * Start MCP server with given transport handler\n */\nasync function startServer(handler: any) {\n await handler.start();\n\n // Handle graceful shutdown\n const shutdown = async (signal: string) => {\n console.error(`\\nReceived ${signal}, shutting down gracefully...`);\n try {\n await handler.stop();\n process.exit(0);\n } catch (error) {\n console.error('Error during shutdown:', error);\n process.exit(1);\n }\n };\n\n process.on('SIGINT', () => shutdown('SIGINT'));\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n}\n\n/**\n * MCP Serve command\n */\nexport const mcpServeCommand = new Command('mcp-serve')\n .description('Start MCP server with specified transport')\n .option('-t, --type <type>', 'Transport type: stdio', 'stdio')\n .action(async (options) => {\n try {\n const transportType = options.type.toLowerCase();\n\n if (transportType === 'stdio') {\n const container = createContainer();\n const server = createServer(container);\n const handler = new StdioTransportHandler(server);\n await startServer(handler);\n } else {\n console.error(`Unknown transport type: ${transportType}. Use: stdio`);\n process.exit(1);\n }\n } catch (error) {\n console.error('Failed to start MCP server:', error);\n process.exit(1);\n }\n });\n","/**\n * Render Command\n *\n * Renders a video from JSON props using Remotion.\n */\n\nimport fs from 'node:fs';\nimport chalk from 'chalk';\nimport { Command } from 'commander';\nimport { createContainer } from '../container/index.js';\nimport { RenderService } from '../services/RenderService.js';\nimport { TYPES } from '../types/index.js';\n\ninterface RenderOptions {\n input: string;\n output: string;\n composition: string;\n codec: 'h264' | 'h265' | 'vp8' | 'vp9';\n}\n\nexport const renderCommand = new Command('render')\n .description('Render a video from JSON props file')\n .requiredOption('-i, --input <path>', 'Path to JSON props file')\n .requiredOption('-o, --output <path>', 'Output video file path')\n .option('-c, --composition <id>', 'Composition ID', 'Main')\n .option('--codec <codec>', 'Video codec (h264, h265, vp8, vp9)', 'h264')\n .action(async (options: RenderOptions) => {\n try {\n process.stderr.write(chalk.blue('🎬 Starting video render...\\n'));\n process.stderr.write(chalk.gray(` Input: ${options.input}\\n`));\n process.stderr.write(chalk.gray(` Output: ${options.output}\\n`));\n process.stderr.write(chalk.gray(` Composition: ${options.composition}\\n`));\n process.stderr.write(chalk.gray(` Codec: ${options.codec}\\n`));\n\n // Read JSON props file\n if (!fs.existsSync(options.input)) {\n process.stderr.write(chalk.red(`Error: Input file not found: ${options.input}\\n`));\n process.exit(1);\n }\n\n const propsContent = fs.readFileSync(options.input, 'utf-8');\n const inputProps = JSON.parse(propsContent) as Record<string, unknown>;\n\n // Create container and get RenderService\n const container = createContainer();\n const renderService = container.get<RenderService>(TYPES.RenderService);\n\n process.stderr.write(chalk.blue('📦 Bundling Remotion project...\\n'));\n\n const result = await renderService.render({\n compositionId: options.composition,\n inputProps,\n outputPath: options.output,\n codec: options.codec,\n });\n\n process.stderr.write(chalk.green(`✓ Video rendered successfully: ${result.outputPath}\\n`));\n } catch (error) {\n process.stderr.write(chalk.red(`Error rendering video: ${error}\\n`));\n process.exit(1);\n }\n });\n","#!/usr/bin/env node\n/**\n * MCP Server Entry Point\n *\n * DESIGN PATTERNS:\n * - CLI pattern with Commander for argument parsing\n * - Command pattern for organizing CLI commands\n * - Transport abstraction for multiple communication methods\n *\n * CODING STANDARDS:\n * - Use async/await for asynchronous operations\n * - Handle errors gracefully with try-catch\n * - Log important events for debugging\n * - Register all commands in main entry point\n *\n * AVOID:\n * - Hardcoding command logic in index.ts (use separate command files)\n * - Missing error handling for command execution\n */\nimport { Command } from 'commander';\nimport packageJson from '../package.json' with { type: 'json' };\nimport { httpServeCommand } from './commands/http-serve.js';\nimport { mcpServeCommand } from './commands/mcp-serve.js';\nimport { renderCommand } from './commands/render.js';\n\n/**\n * Main entry point\n */\nasync function main() {\n const program = new Command();\n\n program\n .name('video-editor-mcp')\n .description('MCP server for video editing with Remotion')\n .version(packageJson.version);\n\n // Add all commands\n program.addCommand(mcpServeCommand);\n program.addCommand(httpServeCommand);\n program.addCommand(renderCommand);\n\n // Parse arguments\n await program.parseAsync(process.argv);\n}\n\nmain();\n"],"mappings":"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"}