@studiomeyer/mcp-video 1.0.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.
Files changed (184) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  3. package/.github/workflows/ci.yml +34 -0
  4. package/CHANGELOG.md +24 -0
  5. package/CONTRIBUTING.md +75 -0
  6. package/LICENSE +21 -0
  7. package/README.md +198 -0
  8. package/USAGE.md +144 -0
  9. package/dist/handlers/capcut.d.ts +6 -0
  10. package/dist/handlers/capcut.js +229 -0
  11. package/dist/handlers/capcut.js.map +1 -0
  12. package/dist/handlers/editing.d.ts +6 -0
  13. package/dist/handlers/editing.js +242 -0
  14. package/dist/handlers/editing.js.map +1 -0
  15. package/dist/handlers/index.d.ts +2 -0
  16. package/dist/handlers/index.js +33 -0
  17. package/dist/handlers/index.js.map +1 -0
  18. package/dist/handlers/post-production.d.ts +5 -0
  19. package/dist/handlers/post-production.js +109 -0
  20. package/dist/handlers/post-production.js.map +1 -0
  21. package/dist/handlers/smart-screenshot.d.ts +5 -0
  22. package/dist/handlers/smart-screenshot.js +83 -0
  23. package/dist/handlers/smart-screenshot.js.map +1 -0
  24. package/dist/handlers/tts.d.ts +5 -0
  25. package/dist/handlers/tts.js +83 -0
  26. package/dist/handlers/tts.js.map +1 -0
  27. package/dist/handlers/video.d.ts +5 -0
  28. package/dist/handlers/video.js +127 -0
  29. package/dist/handlers/video.js.map +1 -0
  30. package/dist/lib/dual-transport.d.ts +42 -0
  31. package/dist/lib/dual-transport.js +208 -0
  32. package/dist/lib/dual-transport.js.map +1 -0
  33. package/dist/lib/logger.d.ts +12 -0
  34. package/dist/lib/logger.js +42 -0
  35. package/dist/lib/logger.js.map +1 -0
  36. package/dist/lib/types.d.ts +16 -0
  37. package/dist/lib/types.js +15 -0
  38. package/dist/lib/types.js.map +1 -0
  39. package/dist/schemas/capcut.d.ts +608 -0
  40. package/dist/schemas/capcut.js +411 -0
  41. package/dist/schemas/capcut.js.map +1 -0
  42. package/dist/schemas/editing.d.ts +822 -0
  43. package/dist/schemas/editing.js +466 -0
  44. package/dist/schemas/editing.js.map +1 -0
  45. package/dist/schemas/index.d.ts +2366 -0
  46. package/dist/schemas/index.js +15 -0
  47. package/dist/schemas/index.js.map +1 -0
  48. package/dist/schemas/post-production.d.ts +379 -0
  49. package/dist/schemas/post-production.js +268 -0
  50. package/dist/schemas/post-production.js.map +1 -0
  51. package/dist/schemas/smart-screenshot.d.ts +127 -0
  52. package/dist/schemas/smart-screenshot.js +122 -0
  53. package/dist/schemas/smart-screenshot.js.map +1 -0
  54. package/dist/schemas/tts.d.ts +220 -0
  55. package/dist/schemas/tts.js +194 -0
  56. package/dist/schemas/tts.js.map +1 -0
  57. package/dist/schemas/video.d.ts +236 -0
  58. package/dist/schemas/video.js +210 -0
  59. package/dist/schemas/video.js.map +1 -0
  60. package/dist/server.d.ts +11 -0
  61. package/dist/server.js +239 -0
  62. package/dist/server.js.map +1 -0
  63. package/dist/server.test.d.ts +1 -0
  64. package/dist/server.test.js +87 -0
  65. package/dist/server.test.js.map +1 -0
  66. package/dist/tools/engine/audio-mixer.d.ts +40 -0
  67. package/dist/tools/engine/audio-mixer.js +169 -0
  68. package/dist/tools/engine/audio-mixer.js.map +1 -0
  69. package/dist/tools/engine/audio.d.ts +22 -0
  70. package/dist/tools/engine/audio.js +73 -0
  71. package/dist/tools/engine/audio.js.map +1 -0
  72. package/dist/tools/engine/beat-sync.d.ts +31 -0
  73. package/dist/tools/engine/beat-sync.js +270 -0
  74. package/dist/tools/engine/beat-sync.js.map +1 -0
  75. package/dist/tools/engine/capture.d.ts +12 -0
  76. package/dist/tools/engine/capture.js +290 -0
  77. package/dist/tools/engine/capture.js.map +1 -0
  78. package/dist/tools/engine/chroma-key.d.ts +27 -0
  79. package/dist/tools/engine/chroma-key.js +154 -0
  80. package/dist/tools/engine/chroma-key.js.map +1 -0
  81. package/dist/tools/engine/concat.d.ts +49 -0
  82. package/dist/tools/engine/concat.js +149 -0
  83. package/dist/tools/engine/concat.js.map +1 -0
  84. package/dist/tools/engine/cursor.d.ts +26 -0
  85. package/dist/tools/engine/cursor.js +185 -0
  86. package/dist/tools/engine/cursor.js.map +1 -0
  87. package/dist/tools/engine/easing.d.ts +15 -0
  88. package/dist/tools/engine/easing.js +100 -0
  89. package/dist/tools/engine/easing.js.map +1 -0
  90. package/dist/tools/engine/editing.d.ts +158 -0
  91. package/dist/tools/engine/editing.js +541 -0
  92. package/dist/tools/engine/editing.js.map +1 -0
  93. package/dist/tools/engine/encoder.d.ts +31 -0
  94. package/dist/tools/engine/encoder.js +154 -0
  95. package/dist/tools/engine/encoder.js.map +1 -0
  96. package/dist/tools/engine/index.d.ts +30 -0
  97. package/dist/tools/engine/index.js +23 -0
  98. package/dist/tools/engine/index.js.map +1 -0
  99. package/dist/tools/engine/lut-presets.d.ts +25 -0
  100. package/dist/tools/engine/lut-presets.js +141 -0
  101. package/dist/tools/engine/lut-presets.js.map +1 -0
  102. package/dist/tools/engine/narrated-video.d.ts +63 -0
  103. package/dist/tools/engine/narrated-video.js +163 -0
  104. package/dist/tools/engine/narrated-video.js.map +1 -0
  105. package/dist/tools/engine/scenes.d.ts +17 -0
  106. package/dist/tools/engine/scenes.js +223 -0
  107. package/dist/tools/engine/scenes.js.map +1 -0
  108. package/dist/tools/engine/smart-screenshot.d.ts +80 -0
  109. package/dist/tools/engine/smart-screenshot.js +744 -0
  110. package/dist/tools/engine/smart-screenshot.js.map +1 -0
  111. package/dist/tools/engine/social-format.d.ts +66 -0
  112. package/dist/tools/engine/social-format.js +107 -0
  113. package/dist/tools/engine/social-format.js.map +1 -0
  114. package/dist/tools/engine/template-renderer.d.ts +45 -0
  115. package/dist/tools/engine/template-renderer.js +233 -0
  116. package/dist/tools/engine/template-renderer.js.map +1 -0
  117. package/dist/tools/engine/templates.d.ts +87 -0
  118. package/dist/tools/engine/templates.js +272 -0
  119. package/dist/tools/engine/templates.js.map +1 -0
  120. package/dist/tools/engine/text-animations.d.ts +33 -0
  121. package/dist/tools/engine/text-animations.js +192 -0
  122. package/dist/tools/engine/text-animations.js.map +1 -0
  123. package/dist/tools/engine/text-overlay.d.ts +27 -0
  124. package/dist/tools/engine/text-overlay.js +84 -0
  125. package/dist/tools/engine/text-overlay.js.map +1 -0
  126. package/dist/tools/engine/tts.d.ts +54 -0
  127. package/dist/tools/engine/tts.js +186 -0
  128. package/dist/tools/engine/tts.js.map +1 -0
  129. package/dist/tools/engine/types.d.ts +166 -0
  130. package/dist/tools/engine/types.js +13 -0
  131. package/dist/tools/engine/types.js.map +1 -0
  132. package/dist/tools/engine/voice-effects.d.ts +18 -0
  133. package/dist/tools/engine/voice-effects.js +215 -0
  134. package/dist/tools/engine/voice-effects.js.map +1 -0
  135. package/dist/tools/index.d.ts +32 -0
  136. package/dist/tools/index.js +23 -0
  137. package/dist/tools/index.js.map +1 -0
  138. package/package.json +56 -0
  139. package/scripts/check-deps.js +39 -0
  140. package/src/handlers/capcut.ts +245 -0
  141. package/src/handlers/editing.ts +260 -0
  142. package/src/handlers/index.ts +34 -0
  143. package/src/handlers/post-production.ts +136 -0
  144. package/src/handlers/smart-screenshot.ts +86 -0
  145. package/src/handlers/tts.ts +103 -0
  146. package/src/handlers/video.ts +137 -0
  147. package/src/lib/dual-transport.ts +272 -0
  148. package/src/lib/logger.ts +59 -0
  149. package/src/lib/types.ts +25 -0
  150. package/src/schemas/capcut.ts +418 -0
  151. package/src/schemas/editing.ts +476 -0
  152. package/src/schemas/index.ts +15 -0
  153. package/src/schemas/post-production.ts +273 -0
  154. package/src/schemas/smart-screenshot.ts +122 -0
  155. package/src/schemas/tts.ts +197 -0
  156. package/src/schemas/video.ts +211 -0
  157. package/src/server.test.ts +99 -0
  158. package/src/server.ts +289 -0
  159. package/src/tools/engine/audio-mixer.ts +244 -0
  160. package/src/tools/engine/audio.ts +115 -0
  161. package/src/tools/engine/beat-sync.ts +356 -0
  162. package/src/tools/engine/capture.ts +360 -0
  163. package/src/tools/engine/chroma-key.ts +202 -0
  164. package/src/tools/engine/concat.ts +242 -0
  165. package/src/tools/engine/cursor.ts +222 -0
  166. package/src/tools/engine/easing.ts +120 -0
  167. package/src/tools/engine/editing.ts +809 -0
  168. package/src/tools/engine/encoder.ts +208 -0
  169. package/src/tools/engine/index.ts +33 -0
  170. package/src/tools/engine/lut-presets.ts +235 -0
  171. package/src/tools/engine/narrated-video.ts +267 -0
  172. package/src/tools/engine/scenes.ts +309 -0
  173. package/src/tools/engine/smart-screenshot.ts +923 -0
  174. package/src/tools/engine/social-format.ts +146 -0
  175. package/src/tools/engine/template-renderer.ts +294 -0
  176. package/src/tools/engine/templates.ts +370 -0
  177. package/src/tools/engine/text-animations.ts +282 -0
  178. package/src/tools/engine/text-overlay.ts +143 -0
  179. package/src/tools/engine/tts.ts +284 -0
  180. package/src/tools/engine/types.ts +191 -0
  181. package/src/tools/engine/voice-effects.ts +258 -0
  182. package/src/tools/index.ts +67 -0
  183. package/tsconfig.json +19 -0
  184. package/vitest.config.ts +7 -0
@@ -0,0 +1,476 @@
1
+ /**
2
+ * MCP Tool Schemas for Video Editing features
3
+ * Speed, Color Grading, Effects, Crop, Reverse, Extract Audio,
4
+ * Subtitles, Auto Captions, Keyframe Animation, PiP, Audio Ducking
5
+ */
6
+
7
+ export const editingSchemas = [
8
+ // --- 1. Video Speed ---
9
+ {
10
+ name: 'adjust_video_speed',
11
+ description: 'Change video playback speed. Create slow-motion (0.25x-0.9x), timelapse (1.1x-4.0x), or any speed between. Audio pitch is automatically adjusted to match. Output: MP4.',
12
+ annotations: {
13
+ title: 'Adjust Video Speed',
14
+ readOnlyHint: false,
15
+ destructiveHint: false,
16
+ openWorldHint: false,
17
+ idempotentHint: true,
18
+ },
19
+ inputSchema: {
20
+ type: 'object' as const,
21
+ properties: {
22
+ inputPath: {
23
+ type: 'string',
24
+ description: 'Path to the input video',
25
+ },
26
+ outputPath: {
27
+ type: 'string',
28
+ description: 'Output path for the speed-adjusted video',
29
+ },
30
+ speed: {
31
+ type: 'number',
32
+ description: 'Speed factor: 0.25 (4x slow-mo) to 4.0 (4x faster). 1.0 = original speed. Common: 0.5 = half speed, 2.0 = double speed.',
33
+ },
34
+ audioMode: {
35
+ type: 'string',
36
+ enum: ['match', 'mute', 'original'],
37
+ description: 'Audio handling: "match" adjusts pitch to speed (default), "mute" removes audio, "original" keeps audio unchanged (may desync).',
38
+ },
39
+ },
40
+ required: ['inputPath', 'outputPath', 'speed'],
41
+ },
42
+ },
43
+
44
+ // --- 2. Color Grading ---
45
+ {
46
+ name: 'apply_color_grade',
47
+ description: 'Apply professional color grading to a video. Adjust brightness, contrast, saturation, gamma, and color temperature. Can create cinematic looks: warm sunset (temperature: 0.5, saturation: 1.3), cold thriller (temperature: -0.5, contrast: 1.4), desaturated documentary (saturation: 0.6). Output: MP4.',
48
+ annotations: {
49
+ title: 'Apply Color Grade',
50
+ readOnlyHint: false,
51
+ destructiveHint: false,
52
+ openWorldHint: false,
53
+ idempotentHint: true,
54
+ },
55
+ inputSchema: {
56
+ type: 'object' as const,
57
+ properties: {
58
+ inputPath: {
59
+ type: 'string',
60
+ description: 'Path to the input video',
61
+ },
62
+ outputPath: {
63
+ type: 'string',
64
+ description: 'Output path',
65
+ },
66
+ brightness: {
67
+ type: 'number',
68
+ description: 'Brightness: -1.0 (dark) to 1.0 (bright). 0 = no change. Default: 0.',
69
+ },
70
+ contrast: {
71
+ type: 'number',
72
+ description: 'Contrast: 0.0 (flat) to 3.0 (extreme). 1.0 = no change. Default: 1.0.',
73
+ },
74
+ saturation: {
75
+ type: 'number',
76
+ description: 'Saturation: 0.0 (grayscale) to 3.0 (vivid). 1.0 = no change. Default: 1.0.',
77
+ },
78
+ gamma: {
79
+ type: 'number',
80
+ description: 'Gamma: 0.1 to 10.0. < 1 = brighter midtones, > 1 = darker midtones. 1.0 = no change.',
81
+ },
82
+ temperature: {
83
+ type: 'number',
84
+ description: 'Color temperature: -1.0 (cool/blue) to 1.0 (warm/orange). 0 = neutral. Positive = golden hour, negative = moonlight.',
85
+ },
86
+ },
87
+ required: ['inputPath', 'outputPath'],
88
+ },
89
+ },
90
+
91
+ // --- 3. Video Effects ---
92
+ {
93
+ name: 'apply_video_effect',
94
+ description: 'Apply a visual effect to a video. Available: blur (background/dream), sharpen (crisp detail), vignette (dark edges/cinematic), grayscale (B&W), sepia (vintage warm), noise (film grain), glow (soft bloom). Intensity 0-1. Output: MP4.',
95
+ annotations: {
96
+ title: 'Apply Video Effect',
97
+ readOnlyHint: false,
98
+ destructiveHint: false,
99
+ openWorldHint: false,
100
+ idempotentHint: true,
101
+ },
102
+ inputSchema: {
103
+ type: 'object' as const,
104
+ properties: {
105
+ inputPath: {
106
+ type: 'string',
107
+ description: 'Path to the input video',
108
+ },
109
+ outputPath: {
110
+ type: 'string',
111
+ description: 'Output path',
112
+ },
113
+ effect: {
114
+ type: 'string',
115
+ enum: ['blur', 'sharpen', 'vignette', 'grayscale', 'sepia', 'noise', 'glow'],
116
+ description: 'Effect to apply: blur (dreamy), sharpen (crisp), vignette (dark edges), grayscale (B&W), sepia (vintage), noise (film grain), glow (soft bloom).',
117
+ },
118
+ intensity: {
119
+ type: 'number',
120
+ description: 'Effect intensity 0.0 (subtle) to 1.0 (maximum). Default: 0.5.',
121
+ },
122
+ },
123
+ required: ['inputPath', 'outputPath', 'effect'],
124
+ },
125
+ },
126
+
127
+ // --- 4. Crop Video ---
128
+ {
129
+ name: 'crop_video',
130
+ description: 'Crop a video to a specific region. Specify width, height, and optional x/y offset. Use "center" for x/y to center the crop. Useful for removing borders, focusing on a UI element, or changing aspect ratio. Output: MP4.',
131
+ annotations: {
132
+ title: 'Crop Video',
133
+ readOnlyHint: false,
134
+ destructiveHint: false,
135
+ openWorldHint: false,
136
+ idempotentHint: true,
137
+ },
138
+ inputSchema: {
139
+ type: 'object' as const,
140
+ properties: {
141
+ inputPath: {
142
+ type: 'string',
143
+ description: 'Path to the input video',
144
+ },
145
+ outputPath: {
146
+ type: 'string',
147
+ description: 'Output path',
148
+ },
149
+ width: {
150
+ type: 'number',
151
+ description: 'Width of crop region in pixels',
152
+ },
153
+ height: {
154
+ type: 'number',
155
+ description: 'Height of crop region in pixels',
156
+ },
157
+ x: {
158
+ type: ['number', 'string'],
159
+ description: 'X offset in pixels, or "center" (default: center)',
160
+ },
161
+ y: {
162
+ type: ['number', 'string'],
163
+ description: 'Y offset in pixels, or "center" (default: center)',
164
+ },
165
+ },
166
+ required: ['inputPath', 'outputPath', 'width', 'height'],
167
+ },
168
+ },
169
+
170
+ // --- 5. Reverse Clip ---
171
+ {
172
+ name: 'reverse_clip',
173
+ description: 'Reverse a video clip (play backwards). Optionally also reverse audio. Great for creative reveals, boomerang effects, or dramatic endings. Output: MP4.',
174
+ annotations: {
175
+ title: 'Reverse Video Clip',
176
+ readOnlyHint: false,
177
+ destructiveHint: false,
178
+ openWorldHint: false,
179
+ idempotentHint: true,
180
+ },
181
+ inputSchema: {
182
+ type: 'object' as const,
183
+ properties: {
184
+ inputPath: {
185
+ type: 'string',
186
+ description: 'Path to the input video',
187
+ },
188
+ outputPath: {
189
+ type: 'string',
190
+ description: 'Output path',
191
+ },
192
+ reverseAudio: {
193
+ type: 'boolean',
194
+ description: 'Also reverse audio track (default: true)',
195
+ },
196
+ },
197
+ required: ['inputPath', 'outputPath'],
198
+ },
199
+ },
200
+
201
+ // --- 6. Extract Audio ---
202
+ {
203
+ name: 'extract_audio',
204
+ description: 'Extract the audio track from a video. Supports MP3, AAC, WAV, FLAC output. No video re-encoding needed — fast operation. Output: audio file.',
205
+ annotations: {
206
+ title: 'Extract Audio from Video',
207
+ readOnlyHint: false,
208
+ destructiveHint: false,
209
+ openWorldHint: false,
210
+ idempotentHint: true,
211
+ },
212
+ inputSchema: {
213
+ type: 'object' as const,
214
+ properties: {
215
+ inputPath: {
216
+ type: 'string',
217
+ description: 'Path to the input video',
218
+ },
219
+ outputPath: {
220
+ type: 'string',
221
+ description: 'Output audio file path (e.g., ./output/audio.mp3)',
222
+ },
223
+ format: {
224
+ type: 'string',
225
+ enum: ['mp3', 'aac', 'wav', 'flac'],
226
+ description: 'Audio format (default: mp3). mp3/aac for small files, wav/flac for lossless.',
227
+ },
228
+ bitrate: {
229
+ type: 'string',
230
+ description: 'Bitrate for lossy formats (default: 192k). Higher = better quality.',
231
+ },
232
+ },
233
+ required: ['inputPath', 'outputPath'],
234
+ },
235
+ },
236
+
237
+ // --- 7. Burn Subtitles ---
238
+ {
239
+ name: 'burn_subtitles',
240
+ description: 'Burn (hardcode) subtitles from an SRT or ASS file directly into a video. Subtitles become part of the video pixels — visible on any player without subtitle support. Customize font size, color, outline, and position. Output: MP4.',
241
+ annotations: {
242
+ title: 'Burn Subtitles into Video',
243
+ readOnlyHint: false,
244
+ destructiveHint: false,
245
+ openWorldHint: false,
246
+ idempotentHint: true,
247
+ },
248
+ inputSchema: {
249
+ type: 'object' as const,
250
+ properties: {
251
+ inputPath: {
252
+ type: 'string',
253
+ description: 'Path to the input video',
254
+ },
255
+ outputPath: {
256
+ type: 'string',
257
+ description: 'Output path',
258
+ },
259
+ subtitlePath: {
260
+ type: 'string',
261
+ description: 'Path to SRT or ASS subtitle file',
262
+ },
263
+ fontSize: {
264
+ type: 'number',
265
+ description: 'Font size (default: 24)',
266
+ },
267
+ fontColor: {
268
+ type: 'string',
269
+ description: 'Font color in ASS hex format (default: &Hffffff = white)',
270
+ },
271
+ outlineColor: {
272
+ type: 'string',
273
+ description: 'Outline color (default: &H000000 = black)',
274
+ },
275
+ outlineWidth: {
276
+ type: 'number',
277
+ description: 'Outline width in pixels (default: 2)',
278
+ },
279
+ position: {
280
+ type: 'string',
281
+ enum: ['bottom', 'top', 'center'],
282
+ description: 'Caption position (default: bottom)',
283
+ },
284
+ },
285
+ required: ['inputPath', 'outputPath', 'subtitlePath'],
286
+ },
287
+ },
288
+
289
+ // --- 8. Auto Caption ---
290
+ {
291
+ name: 'auto_caption',
292
+ description: 'Automatically generate captions from speech using OpenAI Whisper, then burn them into the video. Supports 50+ languages with auto-detection. Three steps: extract audio → transcribe → burn subtitles. Also produces an SRT file. Requires OPENAI_API_KEY. Output: MP4 with captions + SRT file.',
293
+ annotations: {
294
+ title: 'Auto-Caption Video (Whisper AI)',
295
+ readOnlyHint: false,
296
+ destructiveHint: false,
297
+ openWorldHint: true,
298
+ idempotentHint: true,
299
+ },
300
+ inputSchema: {
301
+ type: 'object' as const,
302
+ properties: {
303
+ inputPath: {
304
+ type: 'string',
305
+ description: 'Path to the input video with speech',
306
+ },
307
+ outputPath: {
308
+ type: 'string',
309
+ description: 'Output path for captioned video',
310
+ },
311
+ language: {
312
+ type: 'string',
313
+ description: 'Language code (e.g., "en", "de", "es", "fr", "ja"). Default: auto-detect.',
314
+ },
315
+ fontSize: {
316
+ type: 'number',
317
+ description: 'Caption font size (default: 28). Larger for stories/reels.',
318
+ },
319
+ position: {
320
+ type: 'string',
321
+ enum: ['bottom', 'top', 'center'],
322
+ description: 'Caption position (default: bottom)',
323
+ },
324
+ keepSrt: {
325
+ type: 'boolean',
326
+ description: 'Keep the generated SRT file alongside the video (default: true)',
327
+ },
328
+ },
329
+ required: ['inputPath', 'outputPath'],
330
+ },
331
+ },
332
+
333
+ // --- 9. Keyframe Animation ---
334
+ {
335
+ name: 'add_keyframe_animation',
336
+ description: 'Apply cinematic keyframe animation to a video: zoom, pan, and combinations. Define keyframes at specific times and the video smoothly interpolates between them. Perfect for Ken Burns effect on photos, dramatic zooms into UI elements, or slow pans across landscapes. Output: MP4.',
337
+ annotations: {
338
+ title: 'Add Keyframe Animation (Zoom/Pan)',
339
+ readOnlyHint: false,
340
+ destructiveHint: false,
341
+ openWorldHint: false,
342
+ idempotentHint: true,
343
+ },
344
+ inputSchema: {
345
+ type: 'object' as const,
346
+ properties: {
347
+ inputPath: {
348
+ type: 'string',
349
+ description: 'Path to the input video or image',
350
+ },
351
+ outputPath: {
352
+ type: 'string',
353
+ description: 'Output path',
354
+ },
355
+ keyframes: {
356
+ type: 'array',
357
+ items: {
358
+ type: 'object',
359
+ properties: {
360
+ time: { type: 'number', description: 'Time in seconds for this keyframe' },
361
+ scale: { type: 'number', description: 'Zoom: 1.0 = original, 2.0 = 2x zoom in. Default: 1.0' },
362
+ panX: { type: 'number', description: 'Horizontal pan in pixels (0 = center). Positive = right.' },
363
+ panY: { type: 'number', description: 'Vertical pan in pixels (0 = center). Positive = down.' },
364
+ },
365
+ required: ['time'],
366
+ },
367
+ description: 'Array of keyframes. Minimum 2. Video interpolates smoothly between them.',
368
+ },
369
+ outputWidth: {
370
+ type: 'number',
371
+ description: 'Output width (default: source width)',
372
+ },
373
+ outputHeight: {
374
+ type: 'number',
375
+ description: 'Output height (default: source height)',
376
+ },
377
+ },
378
+ required: ['inputPath', 'outputPath', 'keyframes'],
379
+ },
380
+ },
381
+
382
+ // --- 10. Picture-in-Picture ---
383
+ {
384
+ name: 'compose_picture_in_pip',
385
+ description: 'Overlay a smaller video on top of a main video (Picture-in-Picture). Great for tutorials (webcam + screen), reactions (face + content), or commentary. Customize position, size, timing, and border. Output: MP4.',
386
+ annotations: {
387
+ title: 'Picture-in-Picture Composition',
388
+ readOnlyHint: false,
389
+ destructiveHint: false,
390
+ openWorldHint: false,
391
+ idempotentHint: true,
392
+ },
393
+ inputSchema: {
394
+ type: 'object' as const,
395
+ properties: {
396
+ mainVideo: {
397
+ type: 'string',
398
+ description: 'Path to the main (background) video',
399
+ },
400
+ overlayVideo: {
401
+ type: 'string',
402
+ description: 'Path to the overlay (PiP) video — shown smaller on top',
403
+ },
404
+ outputPath: {
405
+ type: 'string',
406
+ description: 'Output path',
407
+ },
408
+ position: {
409
+ type: 'string',
410
+ enum: ['top-left', 'top-right', 'bottom-left', 'bottom-right', 'center'],
411
+ description: 'Position of PiP overlay (default: bottom-right)',
412
+ },
413
+ scale: {
414
+ type: 'number',
415
+ description: 'Size of PiP relative to main video width: 0.1 (tiny) to 0.5 (half). Default: 0.3.',
416
+ },
417
+ startTime: {
418
+ type: 'number',
419
+ description: 'When PiP appears (seconds from start). Default: 0.',
420
+ },
421
+ endTime: {
422
+ type: 'number',
423
+ description: 'When PiP disappears (seconds). Default: end of main video.',
424
+ },
425
+ borderWidth: {
426
+ type: 'number',
427
+ description: 'Border around PiP in pixels (default: 0 = no border)',
428
+ },
429
+ borderColor: {
430
+ type: 'string',
431
+ description: 'Border color (default: white)',
432
+ },
433
+ },
434
+ required: ['mainVideo', 'overlayVideo', 'outputPath'],
435
+ },
436
+ },
437
+
438
+ // --- 11. Audio Ducking ---
439
+ {
440
+ name: 'add_audio_ducking',
441
+ description: 'Apply audio ducking — automatically reduce volume during loud sections (like reducing background music when speech is detected). Uses dynamic range compression. Output: MP4.',
442
+ annotations: {
443
+ title: 'Audio Ducking',
444
+ readOnlyHint: false,
445
+ destructiveHint: false,
446
+ openWorldHint: false,
447
+ idempotentHint: true,
448
+ },
449
+ inputSchema: {
450
+ type: 'object' as const,
451
+ properties: {
452
+ inputPath: {
453
+ type: 'string',
454
+ description: 'Path to the input video',
455
+ },
456
+ outputPath: {
457
+ type: 'string',
458
+ description: 'Output path',
459
+ },
460
+ duckLevel: {
461
+ type: 'number',
462
+ description: 'How much to reduce volume: 0.0 (silent) to 1.0 (no reduction). Default: 0.3 (reduce to 30%).',
463
+ },
464
+ attack: {
465
+ type: 'number',
466
+ description: 'Attack time in seconds — how fast ducking kicks in (default: 0.5)',
467
+ },
468
+ release: {
469
+ type: 'number',
470
+ description: 'Release time in seconds — how fast volume recovers (default: 1.0)',
471
+ },
472
+ },
473
+ required: ['inputPath', 'outputPath'],
474
+ },
475
+ },
476
+ ];
@@ -0,0 +1,15 @@
1
+ import { videoSchemas } from './video.js';
2
+ import { postProductionSchemas } from './post-production.js';
3
+ import { ttsSchemas } from './tts.js';
4
+ import { smartScreenshotSchemas } from './smart-screenshot.js';
5
+ import { editingSchemas } from './editing.js';
6
+ import { capcutSchemas } from './capcut.js';
7
+
8
+ export const TOOLS = [
9
+ ...videoSchemas,
10
+ ...postProductionSchemas,
11
+ ...ttsSchemas,
12
+ ...smartScreenshotSchemas,
13
+ ...editingSchemas,
14
+ ...capcutSchemas,
15
+ ];