@kolbo/mcp 1.75.7 → 1.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +65 -65
- package/src/apps/widgets/upload.js +28 -0
- package/src/tools/generate.js +20 -13
package/package.json
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@kolbo/mcp",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Kolbo AI MCP Server - Generate images, videos, music, speech, and sound effects from Claude Code",
|
|
5
|
-
"main": "src/index.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"kolbo-mcp": "./bin/kolbo-mcp.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"start": "node src/index.js",
|
|
11
|
-
"smoke": "node scripts/smoke.js",
|
|
12
|
-
"check-skill-bundle": "node scripts/check-skill-bundle.js",
|
|
13
|
-
"check-parity": "node scripts/check-parity.js",
|
|
14
|
-
"prepublishOnly": "node scripts/smoke.js && node scripts/check-skill-bundle.js && node scripts/check-parity.js && node scripts/check-widget-fields.js && node scripts/check-widget-render.js && node scripts/check-model-catalog.js && node scripts/check-skill-tools.js && node scripts/check-submission-contract.js && node scripts/check-install.js",
|
|
15
|
-
"check-model-catalog": "node scripts/check-model-catalog.js",
|
|
16
|
-
"check-widget-fields": "node scripts/check-widget-fields.js",
|
|
17
|
-
"check-widget-render": "node scripts/check-widget-render.js",
|
|
18
|
-
"check-skill-tools": "node scripts/check-skill-tools.js",
|
|
19
|
-
"check-submission-contract": "node scripts/check-submission-contract.js",
|
|
20
|
-
"generate-chatgpt-submission": "node scripts/generate-chatgpt-submission.js",
|
|
21
|
-
"check-install": "node scripts/check-install.js"
|
|
22
|
-
},
|
|
23
|
-
"keywords": [
|
|
24
|
-
"kolbo",
|
|
25
|
-
"mcp",
|
|
26
|
-
"ai",
|
|
27
|
-
"image-generation",
|
|
28
|
-
"video-generation",
|
|
29
|
-
"music-generation",
|
|
30
|
-
"text-to-speech",
|
|
31
|
-
"claude-code",
|
|
32
|
-
"claude-desktop",
|
|
33
|
-
"model-context-protocol"
|
|
34
|
-
],
|
|
35
|
-
"license": "MIT",
|
|
36
|
-
"repository": {
|
|
37
|
-
"type": "git",
|
|
38
|
-
"url": "https://github.com/Zoharvan12/kolbo-mcp"
|
|
39
|
-
},
|
|
40
|
-
"homepage": "https://docs.kolbo.ai/developer-api/claude-code-skill",
|
|
41
|
-
"author": "Kolbo AI <support@kolbo.ai>",
|
|
42
|
-
"publishConfig": {
|
|
43
|
-
"access": "public"
|
|
44
|
-
},
|
|
45
|
-
"files": [
|
|
46
|
-
"src/",
|
|
47
|
-
"bin/",
|
|
48
|
-
"skill/",
|
|
49
|
-
"README.md"
|
|
50
|
-
],
|
|
51
|
-
"dependencies": {
|
|
52
|
-
"@modelcontextprotocol/ext-apps": "^1.7.4",
|
|
53
|
-
"@modelcontextprotocol/sdk": "1.29.0",
|
|
54
|
-
"form-data": "^4.0.6",
|
|
55
|
-
"zod": "^3.25.0"
|
|
56
|
-
},
|
|
57
|
-
"overrides": {
|
|
58
|
-
"hono": "^4.12.12",
|
|
59
|
-
"@hono/node-server": "^1.19.13",
|
|
60
|
-
"path-to-regexp": "^8.4.2"
|
|
61
|
-
},
|
|
62
|
-
"engines": {
|
|
63
|
-
"node": ">=18.0.0"
|
|
64
|
-
}
|
|
65
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@kolbo/mcp",
|
|
3
|
+
"version": "1.76.0",
|
|
4
|
+
"description": "Kolbo AI MCP Server - Generate images, videos, music, speech, and sound effects from Claude Code",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"kolbo-mcp": "./bin/kolbo-mcp.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node src/index.js",
|
|
11
|
+
"smoke": "node scripts/smoke.js",
|
|
12
|
+
"check-skill-bundle": "node scripts/check-skill-bundle.js",
|
|
13
|
+
"check-parity": "node scripts/check-parity.js",
|
|
14
|
+
"prepublishOnly": "node scripts/smoke.js && node scripts/check-skill-bundle.js && node scripts/check-parity.js && node scripts/check-widget-fields.js && node scripts/check-widget-render.js && node scripts/check-model-catalog.js && node scripts/check-skill-tools.js && node scripts/check-submission-contract.js && node scripts/check-install.js",
|
|
15
|
+
"check-model-catalog": "node scripts/check-model-catalog.js",
|
|
16
|
+
"check-widget-fields": "node scripts/check-widget-fields.js",
|
|
17
|
+
"check-widget-render": "node scripts/check-widget-render.js",
|
|
18
|
+
"check-skill-tools": "node scripts/check-skill-tools.js",
|
|
19
|
+
"check-submission-contract": "node scripts/check-submission-contract.js",
|
|
20
|
+
"generate-chatgpt-submission": "node scripts/generate-chatgpt-submission.js",
|
|
21
|
+
"check-install": "node scripts/check-install.js"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"kolbo",
|
|
25
|
+
"mcp",
|
|
26
|
+
"ai",
|
|
27
|
+
"image-generation",
|
|
28
|
+
"video-generation",
|
|
29
|
+
"music-generation",
|
|
30
|
+
"text-to-speech",
|
|
31
|
+
"claude-code",
|
|
32
|
+
"claude-desktop",
|
|
33
|
+
"model-context-protocol"
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/Zoharvan12/kolbo-mcp"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://docs.kolbo.ai/developer-api/claude-code-skill",
|
|
41
|
+
"author": "Kolbo AI <support@kolbo.ai>",
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"src/",
|
|
47
|
+
"bin/",
|
|
48
|
+
"skill/",
|
|
49
|
+
"README.md"
|
|
50
|
+
],
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@modelcontextprotocol/ext-apps": "^1.7.4",
|
|
53
|
+
"@modelcontextprotocol/sdk": "1.29.0",
|
|
54
|
+
"form-data": "^4.0.6",
|
|
55
|
+
"zod": "^3.25.0"
|
|
56
|
+
},
|
|
57
|
+
"overrides": {
|
|
58
|
+
"hono": "^4.12.12",
|
|
59
|
+
"@hono/node-server": "^1.19.13",
|
|
60
|
+
"path-to-regexp": "^8.4.2"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=18.0.0"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -295,10 +295,37 @@ function upload(it) {
|
|
|
295
295
|
var xhr = new XMLHttpRequest();
|
|
296
296
|
xhr.open('POST', state.upload_url, true);
|
|
297
297
|
xhr.setRequestHeader('Authorization', 'Bearer ' + state.token);
|
|
298
|
+
// A stalled upload used to sit at N% forever: there was no timeout and no
|
|
299
|
+
// ontimeout/onabort handler, only onload/onerror. A file above the CDN body
|
|
300
|
+
// cap in front of the API dies exactly this way — the edge sees Content-Length,
|
|
301
|
+
// kills the connection a few percent in, and the browser never reports it, so
|
|
302
|
+
// the row froze at 1% with no error and no retry. Watch PROGRESS rather than
|
|
303
|
+
// total elapsed time, so a genuinely slow large upload is never punished.
|
|
304
|
+
var STALL_MS = 90000;
|
|
305
|
+
var lastTick = Date.now();
|
|
306
|
+
var stalled = false;
|
|
307
|
+
var watchdog = setInterval(function () {
|
|
308
|
+
if (Date.now() - lastTick < STALL_MS) return;
|
|
309
|
+
stalled = true;
|
|
310
|
+
clearInterval(watchdog);
|
|
311
|
+
try { xhr.abort(); } catch (e) {}
|
|
312
|
+
}, 5000);
|
|
313
|
+
function settle() { clearInterval(watchdog); }
|
|
298
314
|
xhr.upload.onprogress = function (e) {
|
|
315
|
+
lastTick = Date.now();
|
|
299
316
|
if (e.lengthComputable) { it.pct = Math.round((e.loaded / e.total) * 100); renderRow(it); }
|
|
300
317
|
};
|
|
318
|
+
xhr.onabort = function () {
|
|
319
|
+
settle();
|
|
320
|
+
if (!stalled) return;
|
|
321
|
+
active--;
|
|
322
|
+
it.status = 'error';
|
|
323
|
+
it.err = 'Upload stalled — the file may be too large for this connection';
|
|
324
|
+
render();
|
|
325
|
+
pump();
|
|
326
|
+
};
|
|
301
327
|
xhr.onload = function () {
|
|
328
|
+
settle();
|
|
302
329
|
active--;
|
|
303
330
|
var res = null;
|
|
304
331
|
try { res = JSON.parse(xhr.responseText); } catch (e) {}
|
|
@@ -317,6 +344,7 @@ function upload(it) {
|
|
|
317
344
|
pump();
|
|
318
345
|
};
|
|
319
346
|
xhr.onerror = function () {
|
|
347
|
+
settle();
|
|
320
348
|
active--;
|
|
321
349
|
it.status = 'error';
|
|
322
350
|
it.err = 'Network error — try the full-screen uploader';
|
package/src/tools/generate.js
CHANGED
|
@@ -508,13 +508,13 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
508
508
|
);
|
|
509
509
|
|
|
510
510
|
// ─── generate_video ────────────────────────────────────────
|
|
511
|
-
//
|
|
512
|
-
//
|
|
513
|
-
//
|
|
514
|
-
//
|
|
511
|
+
// Text-to-video is now a MODE inside videoGeneration/controller.js (sdk/controller.js
|
|
512
|
+
// posts mode:'text_to_video'), and that controller DOES read visualDnaIds — so Visual
|
|
513
|
+
// DNA works here. The old "text-to-video never reads visualDnaIds" note described the
|
|
514
|
+
// retired textToVideoGeneration path and was stale.
|
|
515
515
|
server.tool(
|
|
516
516
|
'generate_video',
|
|
517
|
-
'Generate a video from a text prompt using Kolbo AI. For SEVERAL different videos, pass all their prompts in `prompts` in ONE call (one combined widget) — never a series of separate calls. For animating an existing still image into motion, use generate_video_from_image instead. For a coordinated multi-scene video campaign, use generate_creative_director with workflow_type="video". Supports reference images (for style/composition guidance)
|
|
517
|
+
'Generate a video from a text prompt using Kolbo AI. For SEVERAL different videos, pass all their prompts in `prompts` in ONE call (one combined widget) — never a series of separate calls. For animating an existing still image into motion, use generate_video_from_image instead. For a coordinated multi-scene video campaign, use generate_creative_director with workflow_type="video". Supports reference images (for style/composition guidance) and Visual DNA for character consistency. Returns the final video URL when complete.',
|
|
518
518
|
{
|
|
519
519
|
prompt: z.string().optional().describe('Text description of the video to generate. Required unless `prompts` is provided.'),
|
|
520
520
|
prompts: promptsField('videos'),
|
|
@@ -525,16 +525,17 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
525
525
|
reference_images: z.array(z.string()).optional().describe('Array of image URLs used as visual references (style / composition / subject). **Cap: pass at most `max_reference_images` URLs from list_models for the chosen model — exceeding it is a deterministic 400.**'),
|
|
526
526
|
resolution: z.string().optional().describe('Video resolution tier (vertical pixels): "720p" / "1080p" / "1440p" / "2160p". Some models use labels like "512P"/"1024P"/"768P"/"1080P". Model-dependent — call list_models and read supported_resolutions. Read resolution_multipliers to predict cost.'),
|
|
527
527
|
preset_id: z.string().optional().describe('Preset ID from list_presets type="video" to apply a saved motion/style preset to this generation.'),
|
|
528
|
+
visual_dna_ids: z.array(z.string()).optional().describe('Array of Visual DNA profile IDs to apply for character/style consistency. Every DNA passed here MUST also be tagged in the prompt as @ExactDNAName. **Cap: pass at most `max_visual_dna` IDs from list_models for the chosen model; if `supports_visual_dna: false`, DNA is silently ignored.**'),
|
|
528
529
|
sound_enabled: z.boolean().optional().describe('Enable (`true`) or disable (`false`) AI-generated synced audio on the output video. Honored by `sound_generation_type: "native"` models (Veo 3.1, Kling V3/2.6, PixVerse V6). Seedance 2.x reports type "none" (no toggle) but `sound_baked_in: true` — those still emit real audio; do not tell the user the model is silent. Omit to use `sound_enabled_by_default`. Pass `false` only when the user asks for silent AND the model is native (not baked-in). Enabling sound may apply `sound_credit_multiplier` to cost.'),
|
|
529
530
|
skip_color_palette: z.boolean().optional().describe('Opt this single call OUT of the account\'s active Color DNA palette (see list_color_palettes / activate_color_palette). By default, if the user has an active palette it strict-grades every generation automatically — pass true only when the user explicitly wants this one video ungraded.'),
|
|
530
531
|
project_id: projectIdField,
|
|
531
532
|
session_id: sessionIdField
|
|
532
533
|
},
|
|
533
|
-
async ({ prompt, prompts, model, aspect_ratio, duration, enhance_prompt = false, reference_images, resolution, preset_id, sound_enabled, skip_color_palette, project_id, session_id }) => {
|
|
534
|
+
async ({ prompt, prompts, model, aspect_ratio, duration, enhance_prompt = false, reference_images, resolution, preset_id, visual_dna_ids, sound_enabled, skip_color_palette, project_id, session_id }) => {
|
|
534
535
|
if (!prompt && !(prompts && prompts.length)) throw new Error('Provide prompt or prompts');
|
|
535
536
|
model = await canonicalModelId(client, model, 'text_to_video'); // lenient id resolution ("z-image" → "z-image/turbo")
|
|
536
537
|
const shared = {
|
|
537
|
-
model, aspect_ratio, duration, enhance_prompt, reference_images, resolution, preset_id, sound_enabled, skip_color_palette, project_id, session_id
|
|
538
|
+
model, aspect_ratio, duration, enhance_prompt, reference_images, resolution, preset_id, visual_dna_ids, sound_enabled, skip_color_palette, project_id, session_id
|
|
538
539
|
};
|
|
539
540
|
|
|
540
541
|
// Batch mode: N different prompts, one widget owning all generation ids.
|
|
@@ -1147,6 +1148,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1147
1148
|
enhance_prompt: z.boolean().optional().describe('Enhance the prompt. Default: false — only pass true if the user explicitly asks to enhance/improve the prompt.'),
|
|
1148
1149
|
visual_dna_ids: z.array(z.string()).optional().describe('Array of Visual DNA profile IDs to apply for character/style consistency across outputs. **Cap: pass at most `max_visual_dna` IDs from list_models for the chosen model.**'),
|
|
1149
1150
|
resolution: z.string().optional().describe('Video resolution tier (vertical pixels): "720p" / "1080p" / "1440p" / "2160p". Model-dependent — call list_models and read supported_resolutions.'),
|
|
1151
|
+
sound_enabled: z.boolean().optional().describe('Enable (`true`) or disable (`false`) AI-generated synced audio on the output video. Honored by `sound_generation_type: "native"` models (Kling O3/V3, Veo 3.1, PixVerse V6). Omit to use `sound_enabled_by_default`. Enabling sound may apply `sound_credit_multiplier` to cost.'),
|
|
1150
1152
|
keyframes: z.array(z.object({
|
|
1151
1153
|
image_url: z.string().describe('Public URL of the keyframe image'),
|
|
1152
1154
|
timestamp_seconds: z.number().describe('Moment on the OUTPUT timeline (seconds, 0 = first frame) where this image is pinned')
|
|
@@ -1157,7 +1159,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1157
1159
|
project_id: projectIdField,
|
|
1158
1160
|
session_id: sessionIdField
|
|
1159
1161
|
},
|
|
1160
|
-
async ({ prompt, model, reference_images, reference_videos, reference_audio_urls, audio_url, files, duration, aspect_ratio, motion, preset_id, enhance_prompt = false, visual_dna_ids, resolution, keyframes, multi_shots, multi_shot_count, session_name, project_id, session_id }) => {
|
|
1162
|
+
async ({ prompt, model, reference_images, reference_videos, reference_audio_urls, audio_url, files, duration, aspect_ratio, motion, preset_id, enhance_prompt = false, visual_dna_ids, resolution, sound_enabled, keyframes, multi_shots, multi_shot_count, session_name, project_id, session_id }) => {
|
|
1161
1163
|
model = await canonicalModelId(client, model, 'elements'); // lenient id resolution ("z-image" → "z-image/turbo")
|
|
1162
1164
|
if (!prompt) throw new Error('prompt is required');
|
|
1163
1165
|
|
|
@@ -1179,6 +1181,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1179
1181
|
if (reference_audio_urls) form.append('reference_audio_urls', JSON.stringify(reference_audio_urls));
|
|
1180
1182
|
if (audio_url) form.append('audio_url', audio_url);
|
|
1181
1183
|
if (resolution) form.append('resolution', resolution);
|
|
1184
|
+
if (sound_enabled !== undefined) form.append('sound_enabled', String(sound_enabled));
|
|
1182
1185
|
if (keyframes) form.append('keyframes', JSON.stringify(keyframes));
|
|
1183
1186
|
if (multi_shots !== undefined) form.append('multi_shots', String(multi_shots));
|
|
1184
1187
|
if (multi_shot_count !== undefined) form.append('multi_shot_count', String(multi_shot_count));
|
|
@@ -1192,7 +1195,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1192
1195
|
} else {
|
|
1193
1196
|
// URL-only mode: plain JSON.
|
|
1194
1197
|
startResponse = await client.post('/v1/generate/elements', {
|
|
1195
|
-
prompt, model, reference_images, reference_videos, reference_audio_urls, audio_url, duration, aspect_ratio, motion, preset_id, enhance_prompt, visual_dna_ids, resolution, keyframes, multi_shots, multi_shot_count, session_name, project_id, session_id
|
|
1198
|
+
prompt, model, reference_images, reference_videos, reference_audio_urls, audio_url, duration, aspect_ratio, motion, preset_id, enhance_prompt, visual_dna_ids, resolution, sound_enabled, keyframes, multi_shots, multi_shot_count, session_name, project_id, session_id
|
|
1196
1199
|
});
|
|
1197
1200
|
}
|
|
1198
1201
|
|
|
@@ -1269,10 +1272,11 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1269
1272
|
enhance_prompt: z.boolean().optional().describe('Enhance the prompt. Default: false — only pass true if the user explicitly asks to enhance/improve the prompt.'),
|
|
1270
1273
|
visual_dna_ids: z.array(z.string()).optional().describe('Array of Visual DNA profile IDs to apply. **Cap: pass at most `max_visual_dna` IDs from list_models for the chosen model; if `supports_visual_dna: false`, DNA is silently ignored.**'),
|
|
1271
1274
|
resolution: z.string().optional().describe('Video resolution tier (vertical pixels): "720p" / "1080p" / "1440p" / "2160p". Model-dependent — call list_models and read supported_resolutions.'),
|
|
1275
|
+
sound_enabled: z.boolean().optional().describe('Enable (`true`) or disable (`false`) AI-generated synced audio on the output video. Honored by `sound_generation_type: "native"` models (Kling O3/V3, Veo 3.1, PixVerse V6). Omit to use `sound_enabled_by_default`. Enabling sound may apply `sound_credit_multiplier` to cost.'),
|
|
1272
1276
|
project_id: projectIdField,
|
|
1273
1277
|
session_id: sessionIdField
|
|
1274
1278
|
},
|
|
1275
|
-
async ({ first_frame_url, last_frame_url, first_frame, last_frame, prompt, model, duration, aspect_ratio, enhance_prompt = false, visual_dna_ids, resolution, project_id, session_id }) => {
|
|
1279
|
+
async ({ first_frame_url, last_frame_url, first_frame, last_frame, prompt, model, duration, aspect_ratio, enhance_prompt = false, visual_dna_ids, resolution, sound_enabled, project_id, session_id }) => {
|
|
1276
1280
|
model = await canonicalModelId(client, model, 'firstlastgenerations'); // lenient id resolution ("z-image" → "z-image/turbo")
|
|
1277
1281
|
const urlMode = first_frame_url && last_frame_url;
|
|
1278
1282
|
const fileMode = first_frame && last_frame;
|
|
@@ -1299,12 +1303,13 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1299
1303
|
if (enhance_prompt !== undefined) form.append('enhance_prompt', String(enhance_prompt));
|
|
1300
1304
|
if (visual_dna_ids) form.append('visual_dna_ids', JSON.stringify(visual_dna_ids));
|
|
1301
1305
|
if (resolution) form.append('resolution', resolution);
|
|
1306
|
+
if (sound_enabled !== undefined) form.append('sound_enabled', String(sound_enabled));
|
|
1302
1307
|
if (project_id) form.append('project_id', project_id);
|
|
1303
1308
|
if (session_id) form.append('session_id', session_id);
|
|
1304
1309
|
startResponse = await client.postMultipart('/v1/generate/first-last-frame', form);
|
|
1305
1310
|
} else {
|
|
1306
1311
|
startResponse = await client.post('/v1/generate/first-last-frame', {
|
|
1307
|
-
first_frame_url, last_frame_url, prompt, model, duration, aspect_ratio, enhance_prompt, visual_dna_ids, resolution, project_id, session_id
|
|
1312
|
+
first_frame_url, last_frame_url, prompt, model, duration, aspect_ratio, enhance_prompt, visual_dna_ids, resolution, sound_enabled, project_id, session_id
|
|
1308
1313
|
});
|
|
1309
1314
|
}
|
|
1310
1315
|
|
|
@@ -1477,6 +1482,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1477
1482
|
reference_images: z.array(z.string()).optional().describe('Array of reference image URLs for models that support additional image inputs. **Cap: pass at most `max_images` URLs from list_models — if `max_images === 0` the model does not accept image refs.** Examples: character reference images for Kling O1/O3, style reference for Aleph/gen4_aleph, character image for WAN VACE video-edit.'),
|
|
1478
1483
|
reference_videos: z.array(z.string()).optional().describe('Array of additional reference video URLs for models that support multiple video inputs. **Cap: pass at most `max_videos` URLs from list_models — if `max_videos <= 1` only the source_video is accepted.** Example: WAN 2.6 reference-to-video accepts 1–3 reference videos.'),
|
|
1479
1484
|
elements: z.array(z.string()).optional().describe('Array of element image URLs. **Cap: pass at most `max_elements` URLs from list_models — if `max_elements === 0` the model does not accept elements.** Elements are style or character reference assets alongside the main video.'),
|
|
1485
|
+
sound_enabled: z.boolean().optional().describe('Enable (`true`) or disable (`false`) AI-generated synced audio on the output video. Honored by `sound_generation_type: "native"` models (Kling O3/V3, Veo 3.1, PixVerse V6). Omit to use `sound_enabled_by_default`. Enabling sound may apply `sound_credit_multiplier` to cost.'),
|
|
1480
1486
|
// VEED Subtitles (model: veed/subtitles) — burns styled subtitles into the video
|
|
1481
1487
|
preset: z.string().optional().describe('VEED Subtitles only: caption style preset (e.g. "glass", "whisper", "fusion", "simple", "vegas"). Call list_models type="video_to_video" for the veed/subtitles model. Ignored by other models.'),
|
|
1482
1488
|
source_language: z.string().optional().describe('VEED Subtitles only: BCP-47 code of the spoken language to improve transcription accuracy (e.g. "en-US", "es-ES", "he-IL"). Omit to auto-detect.'),
|
|
@@ -1498,7 +1504,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1498
1504
|
project_id: projectIdField,
|
|
1499
1505
|
session_id: sessionIdField
|
|
1500
1506
|
},
|
|
1501
|
-
async ({ source_video, prompt, model, aspect_ratio, duration, enhance_prompt = false, visual_dna_ids, resolution, reference_images, reference_videos, elements, preset, source_language, translation_language, srt_content, srt_file_url, vocabulary, customization, project_id, session_id }) => {
|
|
1507
|
+
async ({ source_video, prompt, model, aspect_ratio, duration, enhance_prompt = false, visual_dna_ids, resolution, sound_enabled, reference_images, reference_videos, elements, preset, source_language, translation_language, srt_content, srt_file_url, vocabulary, customization, project_id, session_id }) => {
|
|
1502
1508
|
model = await canonicalModelId(client, model, 'video_to_video'); // lenient id resolution ("z-image" → "z-image/turbo")
|
|
1503
1509
|
if (!source_video) throw new Error('source_video is required');
|
|
1504
1510
|
|
|
@@ -1506,7 +1512,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1506
1512
|
let startResponse;
|
|
1507
1513
|
if (isUrl) {
|
|
1508
1514
|
startResponse = await client.post('/v1/generate/video-from-video', {
|
|
1509
|
-
video_url: source_video, prompt, model, aspect_ratio, duration, enhance_prompt, visual_dna_ids, resolution,
|
|
1515
|
+
video_url: source_video, prompt, model, aspect_ratio, duration, enhance_prompt, visual_dna_ids, resolution, sound_enabled,
|
|
1510
1516
|
reference_images, reference_videos, elements, preset, source_language, translation_language,
|
|
1511
1517
|
srt_content, srt_file_url, vocabulary, customization, project_id, session_id
|
|
1512
1518
|
});
|
|
@@ -1528,6 +1534,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1528
1534
|
if (enhance_prompt !== undefined) form.append('enhance_prompt', String(enhance_prompt));
|
|
1529
1535
|
if (visual_dna_ids) form.append('visual_dna_ids', JSON.stringify(visual_dna_ids));
|
|
1530
1536
|
if (resolution) form.append('resolution', resolution);
|
|
1537
|
+
if (sound_enabled !== undefined) form.append('sound_enabled', String(sound_enabled));
|
|
1531
1538
|
if (reference_images) form.append('reference_images', JSON.stringify(reference_images));
|
|
1532
1539
|
if (reference_videos) form.append('reference_videos', JSON.stringify(reference_videos));
|
|
1533
1540
|
if (elements) form.append('elements', JSON.stringify(elements));
|