@kolbo/mcp 1.106.5 → 1.107.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/apps/index.js +1 -0
- package/src/index.js +2 -0
- package/src/toolAnnotations.js +3 -2
- package/src/tools/generate.js +9 -5
- package/src/tools/morphious_styles.js +59 -0
package/package.json
CHANGED
package/src/apps/index.js
CHANGED
|
@@ -779,6 +779,7 @@ const TOOL_WIDGETS = {
|
|
|
779
779
|
list_voices: UI.mediaGrid,
|
|
780
780
|
list_visual_dnas: UI.mediaGrid,
|
|
781
781
|
list_moodboards: UI.mediaGrid,
|
|
782
|
+
list_morphious_styles: UI.mediaGrid,
|
|
782
783
|
// NOTE: list_color_palettes' handler has always called uiResult(UI.mediaGrid, ...)
|
|
783
784
|
// (see color_palettes.js) but was missing here — hosts that prepare the widget
|
|
784
785
|
// iframe from the tool DECLARATION (claude.ai reads tools/list, not the result)
|
package/src/index.js
CHANGED
|
@@ -70,6 +70,7 @@ const { registerFontTools } = require('./tools/fonts');
|
|
|
70
70
|
const { registerEditorTools } = require('./tools/editor');
|
|
71
71
|
const { registerFlowTools } = require('./tools/flow');
|
|
72
72
|
const { registerTrendTools } = require('./tools/trends');
|
|
73
|
+
const { registerMorphiousStyleTools } = require('./tools/morphious_styles');
|
|
73
74
|
const { registerMediaTools } = require('./tools/media');
|
|
74
75
|
const { registerPresetTools } = require('./tools/presets');
|
|
75
76
|
const { registerArtifactTools } = require('./tools/artifacts');
|
|
@@ -196,6 +197,7 @@ function createServer(opts = {}) {
|
|
|
196
197
|
registerEditorTools(server, client);
|
|
197
198
|
registerFlowTools(server, client);
|
|
198
199
|
registerTrendTools(server, client);
|
|
200
|
+
registerMorphiousStyleTools(server, client);
|
|
199
201
|
registerAnalyzeTools(server, client, toolOptions);
|
|
200
202
|
registerMediaTools(server, client, toolOptions);
|
|
201
203
|
registerPresetTools(server, client, toolOptions);
|
package/src/toolAnnotations.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
const READ_ONLY = [
|
|
12
12
|
'get_flow_schema', 'list_flow_sessions', 'get_flow_session', 'validate_flow_session',
|
|
13
13
|
'estimate_flow_run', 'get_flow_run', 'list_flow_runs',
|
|
14
|
+
'list_morphious_styles',
|
|
14
15
|
'list_trends', 'get_trend', 'estimate_trend_run', 'get_trend_run', 'list_trend_runs',
|
|
15
16
|
'get_download_status',
|
|
16
17
|
'get_video_editor_schema', 'list_video_editor_sessions', 'get_video_editor_session',
|
|
@@ -59,7 +60,7 @@ const PRIVATE_WRITE = [
|
|
|
59
60
|
'import_elevenlabs_voice',
|
|
60
61
|
'create_visual_dna', 'create_visual_dna_folder', 'update_visual_dna_folder',
|
|
61
62
|
'move_visual_dna_to_folder',
|
|
62
|
-
'create_moodboard',
|
|
63
|
+
'create_moodboard', 'create_morphious_style',
|
|
63
64
|
'create_color_palette', 'activate_color_palette', 'deactivate_color_palette',
|
|
64
65
|
'move_session', 'bulk_move_sessions', 'move_generations_to_session',
|
|
65
66
|
'split_session', 'undo_session_organization',
|
|
@@ -102,7 +103,7 @@ const DESTRUCTIVE_WRITE = [
|
|
|
102
103
|
|
|
103
104
|
// Deletes and whole-value replacement updates are conservatively destructive.
|
|
104
105
|
'delete_voice', 'update_visual_dna', 'delete_visual_dna', 'delete_visual_dna_folder',
|
|
105
|
-
'update_moodboard', 'delete_moodboard',
|
|
106
|
+
'update_moodboard', 'delete_moodboard', 'delete_morphious_style',
|
|
106
107
|
'update_color_palette', 'delete_color_palette',
|
|
107
108
|
'delete_media_folder', 'delete_media', 'permanently_delete_media',
|
|
108
109
|
'bulk_delete_media', 'bulk_permanently_delete_media',
|
package/src/tools/generate.js
CHANGED
|
@@ -240,7 +240,8 @@ const MORPHIOUS_GUIDE = ' MORPHIOUS / GENJUTSU (exactly ONE source video, omit d
|
|
|
240
240
|
+ 'kolbo-morphious-motion 1-30 images, 4-30s; kolbo-morphious-swap 0-30 images, 4-30s; both 480p/720p/1080p, output keeps the source shape. '
|
|
241
241
|
+ 'Lite (kolbo-morphious-lite-motion 1-10 images / kolbo-morphious-lite-swap 0-10 images) caps at 15s. '
|
|
242
242
|
+ 'kolbo-morphious-reframe: NO images/DNA, 1-300s, aspect_ratio REQUIRED (16:9, 9:16, 1:1, 4:3, 3:4, 21:9), 540p or 720p. '
|
|
243
|
-
+ 'higgsfield-genjutsu-motion-transfer / -object-swap: 1-8 images or Visual DNA, 4-30s, 480p/720p/1080p.'
|
|
243
|
+
+ 'higgsfield-genjutsu-motion-transfer / -object-swap: 1-8 images or Visual DNA, 4-30s, 480p/720p/1080p. '
|
|
244
|
+
+ 'STYLES: to restyle a whole video into an animated look (2D toon, painterly 3D, gouache, comic, clay, felt...), pick an id from list_morphious_styles and pass it as style_id with model kolbo-morphious-motion; no reference image or prompt is needed.';
|
|
244
245
|
|
|
245
246
|
function registerGenerateTools(server, client, options = {}) {
|
|
246
247
|
// Every JSON POST from these tools rehosts local file paths into the media
|
|
@@ -1579,6 +1580,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1579
1580
|
preset_id: z.string().optional().describe('Preset ID from list_presets type="video" (optional)'),
|
|
1580
1581
|
enhance_prompt: z.boolean().optional().describe('Enhance the prompt. Default: false — only pass true if the user explicitly asks to enhance/improve the prompt.'),
|
|
1581
1582
|
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.**'),
|
|
1583
|
+
style_id: z.string().optional().describe('Morphious Styles only (kolbo-morphious-motion / -lite-motion): id of a look from list_morphious_styles (Kolbo catalog or a custom style the user made). Restyles the WHOLE video in that look; the style counts as reference image 1, so no reference_images are needed. Prompt optional.'),
|
|
1582
1584
|
draft: z.boolean().optional().describe('Special Draft mode. True forces 480p Draft even if resolution says 1080p; false selects regular video. Only supported when list_models advertises draft capabilities. For Seedance 2.5 editing use model seedance-2-5-video-to-video with generate_video_from_video; the source duration and aspect ratio are preserved. Uses ordinary credits; finalize through draft_quote then draft_enhance.'),
|
|
1583
1585
|
resolution: z.string().optional().describe('Video resolution or named tier: read supported_resolutions from list_models. For Seedance 2.5 Draft use resolution="480p-draft" on the matching public model: seedance-2-5 for creation, seedance-2-5-video-to-video for editing. Plain "480p" generates regular video, NOT Draft. Finalize an actual draft with edit_video operation="draft_quote" then "draft_enhance".'),
|
|
1584
1586
|
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.'),
|
|
@@ -1592,7 +1594,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1592
1594
|
project_id: projectIdField,
|
|
1593
1595
|
session_id: sessionIdField
|
|
1594
1596
|
},
|
|
1595
|
-
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, draft, sound_enabled, keyframes, multi_shots, multi_shot_count, session_name, project_id, session_id }) => {
|
|
1597
|
+
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, style_id, resolution, draft, sound_enabled, keyframes, multi_shots, multi_shot_count, session_name, project_id, session_id }) => {
|
|
1596
1598
|
validateVideoPrompt({ prompt, duration, aspect_ratio, multi_shots, multi_shot_count });
|
|
1597
1599
|
if (draft === true) resolution = '480p-draft';
|
|
1598
1600
|
else if (draft === false && resolution?.endsWith('-draft')) resolution = resolution.slice(0, -6);
|
|
@@ -1638,7 +1640,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1638
1640
|
reference_images: some(urlsOf('image')),
|
|
1639
1641
|
reference_videos: some(urlsOf('video')),
|
|
1640
1642
|
reference_audio_urls: some(urlsOf('audio')),
|
|
1641
|
-
duration, aspect_ratio, motion, preset_id, enhance_prompt, visual_dna_ids,
|
|
1643
|
+
duration, aspect_ratio, motion, preset_id, enhance_prompt, visual_dna_ids, style_id,
|
|
1642
1644
|
resolution, draft, sound_enabled, keyframes, multi_shots, multi_shot_count,
|
|
1643
1645
|
session_name, project_id, session_id
|
|
1644
1646
|
};
|
|
@@ -1994,6 +1996,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
1994
1996
|
duration: z.number().optional().describe('Output duration in seconds. Must be in `supported_durations` from list_models, OR within `min_output_duration`-`max_output_duration`. Default: matches source'),
|
|
1995
1997
|
enhance_prompt: z.boolean().optional().describe('Enhance the prompt. Default: false — only pass true if the user explicitly asks to enhance/improve the prompt.'),
|
|
1996
1998
|
visual_dna_ids: z.array(z.string()).optional().describe('Array of Visual DNA profile IDs to apply for character/style consistency. **Cap: pass at most `max_visual_dna` IDs from list_models for the chosen model; if `supports_visual_dna: false`, DNA is silently ignored.**'),
|
|
1999
|
+
style_id: z.string().optional().describe('Morphious Styles only (kolbo-morphious-motion / -lite-motion): id of a look from list_morphious_styles (Kolbo catalog or a custom style the user made). Restyles the WHOLE video in that look; the style counts as reference image 1, so no reference_images are needed. Prompt optional.'),
|
|
1997
2000
|
draft: z.boolean().optional().describe('Special Draft mode. True forces 480p Draft even if resolution says 1080p; false selects regular video. Only supported when list_models advertises draft capabilities. For Seedance 2.5 editing use model seedance-2-5-video-to-video with generate_video_from_video; the source duration and aspect ratio are preserved. Uses ordinary credits; finalize through draft_quote then draft_enhance.'),
|
|
1998
2001
|
resolution: z.string().optional().describe('Video resolution or named tier: read supported_resolutions from list_models. For Seedance 2.5 Draft use resolution="480p-draft" on the matching public model: seedance-2-5 for creation, seedance-2-5-video-to-video for editing. Plain "480p" generates regular video, NOT Draft. Finalize an actual draft with edit_video operation="draft_quote" then "draft_enhance".'),
|
|
1999
2002
|
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.'),
|
|
@@ -2029,7 +2032,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
2029
2032
|
project_id: projectIdField,
|
|
2030
2033
|
session_id: sessionIdField
|
|
2031
2034
|
},
|
|
2032
|
-
async ({ source_video, prompt, model, aspect_ratio, duration, enhance_prompt = false, visual_dna_ids, resolution, draft, sound_enabled, reference_images, reference_videos, elements, preset, source_language, translation_language, srt_content, srt_file_url, vocabulary, customization, enhancement_model, target_fps, slowdown_factor, output_format, project_id, session_id }) => {
|
|
2035
|
+
async ({ source_video, prompt, model, aspect_ratio, duration, enhance_prompt = false, visual_dna_ids, style_id, resolution, draft, sound_enabled, reference_images, reference_videos, elements, preset, source_language, translation_language, srt_content, srt_file_url, vocabulary, customization, enhancement_model, target_fps, slowdown_factor, output_format, project_id, session_id }) => {
|
|
2033
2036
|
if (draft === true) resolution = '480p-draft';
|
|
2034
2037
|
else if (draft === false && resolution?.endsWith('-draft')) resolution = resolution.slice(0, -6);
|
|
2035
2038
|
model = await canonicalModelId(client, model, 'video_to_video'); // lenient id resolution ("z-image" → "z-image/turbo")
|
|
@@ -2040,7 +2043,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
2040
2043
|
let startResponse;
|
|
2041
2044
|
if (isUrl) {
|
|
2042
2045
|
startResponse = await client.post('/v1/generate/video-from-video', {
|
|
2043
|
-
video_url: source_video, prompt, model, aspect_ratio, duration, enhance_prompt, visual_dna_ids, resolution, draft, sound_enabled,
|
|
2046
|
+
video_url: source_video, prompt, model, aspect_ratio, duration, enhance_prompt, visual_dna_ids, style_id, resolution, draft, sound_enabled,
|
|
2044
2047
|
reference_images, reference_videos, elements, preset, source_language, translation_language,
|
|
2045
2048
|
srt_content, srt_file_url, vocabulary, customization,
|
|
2046
2049
|
enhancement_model, target_fps, slowdown_factor, output_format,
|
|
@@ -2063,6 +2066,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
2063
2066
|
if (duration !== undefined) form.append('duration', String(duration));
|
|
2064
2067
|
if (enhance_prompt !== undefined) form.append('enhance_prompt', String(enhance_prompt));
|
|
2065
2068
|
if (visual_dna_ids) form.append('visual_dna_ids', JSON.stringify(visual_dna_ids));
|
|
2069
|
+
if (style_id) form.append('style_id', style_id);
|
|
2066
2070
|
if (resolution) form.append('resolution', resolution);
|
|
2067
2071
|
if (draft !== undefined) form.append('draft', String(draft));
|
|
2068
2072
|
if (sound_enabled !== undefined) form.append('sound_enabled', String(sound_enabled));
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/* ⛔ BACKWARD COMPATIBILITY: Tool names and arg names below are a PUBLIC
|
|
2
|
+
* CONTRACT. Never rename, remove, or break an existing tool/arg — old cached
|
|
3
|
+
* `npx @kolbo/mcp` installs in the wild will break silently. Add new tools or
|
|
4
|
+
* new OPTIONAL args only. Full rules: ../index.js top-of-file and CLAUDE.md. */
|
|
5
|
+
|
|
6
|
+
// Morphious Styles: restyle a whole video into a look (Kolbo catalog or the user's own custom style).
|
|
7
|
+
// Apply one by passing its id as `style_id` to generate_video_from_video / generate_elements with
|
|
8
|
+
// model kolbo-morphious-motion. Contract: kolbo-api src/modules/morphiousStyles.
|
|
9
|
+
|
|
10
|
+
const { z } = require('zod');
|
|
11
|
+
const { UI, uiResult } = require('../apps');
|
|
12
|
+
|
|
13
|
+
const unwrap = r => (r && r.status === true && r.data !== undefined ? r.data : r);
|
|
14
|
+
const text = value => ({ content: [{ type: 'text', text: JSON.stringify(value, null, 2) }] });
|
|
15
|
+
|
|
16
|
+
function registerMorphiousStyleTools(server, client) {
|
|
17
|
+
server.tool(
|
|
18
|
+
'list_morphious_styles',
|
|
19
|
+
'List Morphious Styles: looks that restyle a WHOLE video (2D toon, painterly 3D, gouache, comic, clay, felt, yarn...). Returns the Kolbo catalog first, then the user\'s own custom styles (custom: true). To apply one, pass its id as style_id to generate_video_from_video with model "kolbo-morphious-motion" and the source video; no reference image or prompt is needed.',
|
|
20
|
+
{},
|
|
21
|
+
async () => {
|
|
22
|
+
const styles = unwrap(await client.get('/v1/morphious-styles')).styles || [];
|
|
23
|
+
return uiResult(UI.mediaGrid, JSON.stringify({ styles, count: styles.length }, null, 2), {
|
|
24
|
+
widget: 'media-grid',
|
|
25
|
+
title: 'Morphious Styles',
|
|
26
|
+
items: styles.map(s => ({
|
|
27
|
+
id: s.id,
|
|
28
|
+
title: s.name,
|
|
29
|
+
subtitle: s.custom ? 'Custom' : undefined,
|
|
30
|
+
thumbnail: s.thumb || s.cover,
|
|
31
|
+
url: s.preview || s.motion || s.cover,
|
|
32
|
+
media_type: s.preview ? 'video' : 'image',
|
|
33
|
+
use_hint: 'Restyle my video in the "{TITLE}" style (style_id: {ID}).',
|
|
34
|
+
})),
|
|
35
|
+
total: styles.length,
|
|
36
|
+
has_more: false,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
server.tool(
|
|
42
|
+
'create_morphious_style',
|
|
43
|
+
'Create a custom Morphious Style from 1-8 image URLs that show the look (an illustration style, a painting technique, a 3D render style). The images define the LOOK only, never the subject. Returns the style id to pass as style_id. Upload local files first with upload_media / create_upload_ticket.',
|
|
44
|
+
{
|
|
45
|
+
name: z.string().min(1).max(60).describe('Style name shown to the user, e.g. "Ink Wash".'),
|
|
46
|
+
image_urls: z.array(z.string().url()).min(1).max(8).describe('1-8 https image URLs that show the look.'),
|
|
47
|
+
},
|
|
48
|
+
async ({ name, image_urls }) => text(unwrap(await client.post('/v1/morphious-styles/custom', { name, image_urls })))
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
server.tool(
|
|
52
|
+
'delete_morphious_style',
|
|
53
|
+
'Delete one of the user\'s own custom Morphious Styles. Catalog styles cannot be deleted. Past generations keep their result.',
|
|
54
|
+
{ style_id: z.string().min(1).max(64).describe('Custom style id from list_morphious_styles (custom: true).') },
|
|
55
|
+
async ({ style_id }) => text(unwrap(await client.delete(`/v1/morphious-styles/custom/${encodeURIComponent(style_id)}`)))
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = { registerMorphiousStyleTools };
|