@kolbo/mcp 1.31.6 → 1.31.7
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/skill/GENERATED.md +1 -1
- package/skill/SKILL.md +5 -2
- package/skill/VERSION +1 -1
- package/skill/references/models/music.md +4 -1
- package/src/apps/theme.js +13 -9
- package/src/apps/widgets/generation.js +0 -4
- package/src/apps/widgets/transcript.js +3 -2
- package/src/tools/_shared.js +53 -0
- package/src/tools/generate.js +3 -2
package/package.json
CHANGED
package/skill/GENERATED.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AUTO-GENERATED — do not edit
|
|
2
2
|
|
|
3
3
|
This skill/ tree is mirrored from kolbo-code (the single source of truth)
|
|
4
|
-
by .github/workflows/sync-skill-to-plugin.yml — synced from kolbo-code@
|
|
4
|
+
by .github/workflows/sync-skill-to-plugin.yml — synced from kolbo-code@53720a8.
|
|
5
5
|
|
|
6
6
|
It is the skill that 'npx @kolbo/mcp install' deploys into the user's agent.
|
|
7
7
|
To change it, edit packages/opencode/skills/kolbo/ in kolbo-code and push;
|
package/skill/SKILL.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
version: 0.5.
|
|
2
|
+
version: 0.5.1
|
|
3
3
|
name: kolbo
|
|
4
4
|
description: |
|
|
5
5
|
Generate, edit, or analyze creative media via the Kolbo AI MCP server:
|
|
@@ -113,6 +113,7 @@ Each `references/models/*.md` mirrors the matching skill prompt in `kolbo-api/sr
|
|
|
113
113
|
| `upload_media` / `list_media` / `get_media` / `get_media_stats` / `favorite_media` / `unfavorite_media` / `delete_media` / `restore_media` / `permanently_delete_media` / `move_media` / `bulk_*_media` / `*_media_folder` | Media library — see `workflows/media-library.md` |
|
|
114
114
|
| `create_visual_dna` / `list_visual_dnas` / `get_visual_dna` / `delete_visual_dna` | Visual DNA — see `workflows/visual-dna.md` |
|
|
115
115
|
| `list_moodboards` / `get_moodboard` / `list_presets` | Style overlays |
|
|
116
|
+
| `search_stock_media` / `get_stock_sources` / `get_stock_categories` / `get_stock_collections` / `get_stock_asset` / `analyze_script_for_stock` / `import_stock_asset` | Stock library (free, no credits) — EXISTING photos / videos / 3D / SFX / music. For stock **music** use `search_stock_media` with `mediaType: "music"` (semantic vibe query, e.g. "uplifting corporate background") → `get_stock_asset` for downloads. The older `*_music_library` tools are deprecated adapters over this — prefer the stock tools. |
|
|
116
117
|
| `chat_send_message` / `chat_list_conversations` / `chat_get_messages` | Kolbo chat with optional `media_urls` (up to 10 per call) |
|
|
117
118
|
| `app_builder_*` (9 tools) | Full React app generation — see `workflows/app-builder.md` |
|
|
118
119
|
| `publish_html_artifact` | Publish HTML / SVG / Mermaid to `sites.kolbo.ai`. Server dedupes by content hash. Strict CSP. |
|
|
@@ -149,7 +150,7 @@ A user-named tool — in any language — overrides every other rule. Recognized
|
|
|
149
150
|
1. **Check credits** ONCE per conversation (Step 0). Skip if already checked.
|
|
150
151
|
2. **Discover models** with `list_models` using a `type` filter — but **skip when the user names a specific model**.
|
|
151
152
|
3. **Pick the model**:
|
|
152
|
-
- User named one → use it.
|
|
153
|
+
- User named one → use it. Model identifiers resolve leniently — shorthand like `"z-image"` or `"nano banana 2"` auto-resolves to the exact identifier, so don't over-engineer exact-id lookups (`list_models` is still authoritative for constraints, caps, and pricing).
|
|
153
154
|
- Auto-select → only from "Auto-selectable" section (models with a `summary`). Cheapest fit. Prefer `[RECOMMENDED]` when cost is similar.
|
|
154
155
|
- Never auto-select from "Named-only" section.
|
|
155
156
|
4. **Validate inputs** against model caps — see `references/workflows/cost-and-validation.md`.
|
|
@@ -203,6 +204,8 @@ Existing video → modify → **single `generate_video_from_video` call** with s
|
|
|
203
204
|
|
|
204
205
|
**Use a TRUE video-to-video model.** Image-to-video models reject with `WRONG_MODEL_TYPE`. Valid: `wan/2-7-videoedit`, `happyhorse/video-edit`, `kling-video/o3-video-to-video`, or any model whose DB `type` includes `video_to_video` (use `list_models({ type: "video_to_video" })`).
|
|
205
206
|
|
|
207
|
+
**Motion-control / animate-move models invert the inputs**: `reference_images[0]` = the CHARACTER IMAGE to animate, `source_video` = the driving/reference video whose motion is transferred. Omitting the character image returns a `MOTION_CONTROL_INPUTS` error.
|
|
208
|
+
|
|
206
209
|
**Do NOT** decompose into frames. **Do NOT** re-fire if the first call returned URLs.
|
|
207
210
|
|
|
208
211
|
## ⚠️ Character-Driven Video — Frames First, Then Animate (CRITICAL)
|
package/skill/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.5.
|
|
1
|
+
0.5.1
|
|
@@ -8,9 +8,12 @@ Load this file when the user wants AI-generated **music** — full songs, lyrics
|
|
|
8
8
|
|
|
9
9
|
**Kolbo MCP routing:** call `generate_music`. Suno is a model option — use `list_models({ type: "music_gen" })` to see versions. Pass `instrumental` and `duration` as separate params; pass the Style/Description text as `style` and the Lyrics as `lyrics`.
|
|
10
10
|
|
|
11
|
+
**Wants an EXISTING track, not a new song?** ("background music", "stock music", "royalty-free track") → don't generate. Use `search_stock_media` with `mediaType: "music"` (semantic vibe query — "tense cinematic pulse", "uplifting corporate background") → `get_stock_asset` for download URLs. Free, no credits. The older `*_music_library` tools are deprecated adapters over the stock library — prefer the stock tools.
|
|
12
|
+
|
|
11
13
|
## CRITICAL Kolbo Platform Rules
|
|
12
14
|
|
|
13
15
|
- **Model version, duration, and instrumental toggle are MCP-tool params.** Don't write `v4.5`, `30 seconds`, or `instrumental: true` inside the prompt fields themselves.
|
|
16
|
+
- **Exact track length = `duration_seconds`** (clamped 5–300s). Only length-controllable models honor it (e.g. ElevenLabs Music, `music-v1`) — without it those models default to a ~10s track, so ALWAYS pass it for jingles/beds on those models. Suno ignores it and picks its own length.
|
|
14
17
|
- Suno generations have **two separate input fields**: a **Style / Description** field (`style` param) and a **Lyrics** field (`lyrics` param). Output your prompt as **TWO separate fenced code blocks** so the user (and the tool call) know exactly what goes where.
|
|
15
18
|
- Tell the user to run the prompt multiple times — Suno output varies significantly between generations, that's a feature. Use `num_generations` if the tool supports it, or fire 2–4 parallel `generate_music` calls.
|
|
16
19
|
|
|
@@ -85,7 +88,7 @@ Use Suno's section tags to control structure. Each tag goes on its own line, con
|
|
|
85
88
|
### Jingle / ad music (15–30s)
|
|
86
89
|
- `style`: short, punchy descriptor (`upbeat retail pop jingle, female vocal, claps, glossy production, summer energy`)
|
|
87
90
|
- `lyrics`: 2–4 short lines max, often just chorus
|
|
88
|
-
- Pass the shortest `duration` the tool supports.
|
|
91
|
+
- Pass the shortest `duration` the tool supports — or, on a length-controllable model (ElevenLabs Music), pass the exact `duration_seconds` (e.g. `15` or `30`).
|
|
89
92
|
|
|
90
93
|
### Cinematic trailer / score
|
|
91
94
|
- `style`: `cinematic orchestral trailer, swelling strings, taiko drums, hybrid choir, dramatic build, modern hybrid score`
|
package/src/apps/theme.js
CHANGED
|
@@ -180,17 +180,21 @@ body {
|
|
|
180
180
|
border-radius: 12px; background: #000; border: 1px solid var(--border); cursor: zoom-in; }
|
|
181
181
|
.k-viewer video { cursor: default; }
|
|
182
182
|
|
|
183
|
-
/* ---- Fullscreen (ui/request-display-mode granted) ----
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
html.k-fullscreen .k-body {
|
|
187
|
-
html.k-fullscreen .k-
|
|
183
|
+
/* ---- Fullscreen (ui/request-display-mode granted) ----
|
|
184
|
+
position:fixed pins the card to the iframe viewport regardless of document
|
|
185
|
+
flow/host sizing quirks — the media physically cannot exceed the screen. */
|
|
186
|
+
html.k-fullscreen, html.k-fullscreen body { height: 100%; overflow: hidden; }
|
|
187
|
+
html.k-fullscreen .k-card { position: fixed; inset: 0; display: flex; flex-direction: column; border-radius: 0; }
|
|
188
|
+
html.k-fullscreen .k-body { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
|
|
189
|
+
html.k-fullscreen .k-prompt, html.k-fullscreen .k-chips { flex: none; }
|
|
190
|
+
html.k-fullscreen #stage { flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
|
191
|
+
html.k-fullscreen .k-viewer { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; margin-bottom: 6px; }
|
|
188
192
|
html.k-fullscreen .k-viewer img, html.k-fullscreen .k-viewer video {
|
|
189
|
-
|
|
190
|
-
host's chrome, whatever the host's iframe sizing does */
|
|
191
|
-
max-height: min(100%, calc(100dvh - 130px)); max-width: 100%;
|
|
193
|
+
max-height: 100%; max-width: 100%; height: auto;
|
|
192
194
|
width: auto; margin: 0 auto; cursor: zoom-out; object-fit: contain; }
|
|
193
|
-
html.k-fullscreen .k-thumbs
|
|
195
|
+
html.k-fullscreen .k-thumbs { flex: none; }
|
|
196
|
+
html.k-fullscreen .k-thumbs .k-thumb { width: 56px; height: 56px; }
|
|
197
|
+
html.k-fullscreen .k-actions { flex: none; padding-top: 8px; }
|
|
194
198
|
.k-expand-hint { display: none; }
|
|
195
199
|
.k-thumbs { display: flex; gap: 6px; margin: 10px 0 2px; }
|
|
196
200
|
.k-thumbs .k-thumb { width: 48px; height: 48px; border-radius: 8px; overflow: hidden; cursor: pointer;
|
|
@@ -387,7 +387,6 @@ function renderActions(sc) {
|
|
|
387
387
|
}
|
|
388
388
|
if (sc.kind === 'video') {
|
|
389
389
|
a.push('<button class="k-btn primary" id="btn-download">⬇ Download</button>');
|
|
390
|
-
a.push('<button class="k-btn" id="btn-analyze">📊 Analyze</button>');
|
|
391
390
|
} else if (hasSingleUrl) {
|
|
392
391
|
// Scenes (Creative Director) have no single "current" url — per-item hover
|
|
393
392
|
// download buttons cover them instead.
|
|
@@ -421,9 +420,6 @@ function renderActions(sc) {
|
|
|
421
420
|
'\\nEdit instruction: ' + text);
|
|
422
421
|
});
|
|
423
422
|
});
|
|
424
|
-
bind('btn-analyze', function () {
|
|
425
|
-
window.kolbo.sendMessage('Analyze this video and give me an engagement/virality read — hook strength, pacing, retention risks, and concrete improvement tips:\\n' + currentUrl());
|
|
426
|
-
});
|
|
427
423
|
}
|
|
428
424
|
function bind(id, fn) { var b = el(id); if (b) b.onclick = fn; }
|
|
429
425
|
|
|
@@ -8,7 +8,8 @@ const { widgetPage } = require('../html');
|
|
|
8
8
|
* structuredContent: {
|
|
9
9
|
* widget: 'transcript', phase: 'completed'|'generating'|'failed',
|
|
10
10
|
* generation_id, poll_tool, text, duration, audio_url, srt_url,
|
|
11
|
-
* word_by_word_srt_url, txt_url, credits_used, error
|
|
11
|
+
* word_by_word_srt_url, txt_url, credits_used, error,
|
|
12
|
+
* open_url // "Open in Kolbo" session deep link (optional)
|
|
12
13
|
* }
|
|
13
14
|
*/
|
|
14
15
|
|
|
@@ -34,7 +35,7 @@ const BODY = `
|
|
|
34
35
|
|
|
35
36
|
const SCRIPT = `
|
|
36
37
|
el('logo').innerHTML = KOLBO_LOGO + '<span>Kolbo</span>';
|
|
37
|
-
el('kolbo-link').onclick = function (e) { e.preventDefault(); window.kolbo.openLink('https://app.kolbo.ai'); };
|
|
38
|
+
el('kolbo-link').onclick = function (e) { e.preventDefault(); window.kolbo.openLink((state && state.open_url) || 'https://app.kolbo.ai'); };
|
|
38
39
|
var state = null, pollTimer = null;
|
|
39
40
|
|
|
40
41
|
function boot(sc) {
|
package/src/tools/_shared.js
CHANGED
|
@@ -305,6 +305,56 @@ async function inlineImageBlocks(urls, opts = {}) {
|
|
|
305
305
|
return blocks.filter(Boolean);
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
+
// ─── "Open in Kolbo" deep links ───────────────────────────────────────────────
|
|
309
|
+
// kolbo-api submit responses include `session_id` + `project_id`. Map each MCP
|
|
310
|
+
// tool to the frontend page + tool slug whose session view can RESUME that
|
|
311
|
+
// session (mirrors kolbo-map src/constants/sessionTypes.js resumeUrl map — the
|
|
312
|
+
// route must match the SESSION MODEL the SDK created, per sdkSessionManager):
|
|
313
|
+
// ImageSession → /image-tools?tool=text-to-image
|
|
314
|
+
// imgEditSession (image_edit AND edit_image/global_image_edit) → /image-tools?tool=image-editing
|
|
315
|
+
// textToVideoSession → /video-tools?tool=text-to-video
|
|
316
|
+
// imgToVideoSession (video_from_image, elements, first_last_frame) → /video-tools?tool=image-to-video
|
|
317
|
+
// videoToVideoSession → /video-tools?tool=video-to-video
|
|
318
|
+
// lipsyncSession → /video-tools?tool=lipsync
|
|
319
|
+
// MusicGeneratorSession / TextToSpeechSession / textToSoundSession /
|
|
320
|
+
// speechToTextSession → /audio-tools with the matching slug
|
|
321
|
+
// CreativeDirectorSession → /creative-director?session=... (no tool param)
|
|
322
|
+
// Intentionally ABSENT (no deep-linkable session page — widget falls back to
|
|
323
|
+
// plain https://app.kolbo.ai): edit_video (GlobalVideoEditSession has no
|
|
324
|
+
// session deep-link), generate_3d (project-scoped, no session), shorts render.
|
|
325
|
+
const APP_BASE_URL = 'https://app.kolbo.ai';
|
|
326
|
+
const OPEN_URL_ROUTES = {
|
|
327
|
+
generate_image: { path: '/image-tools', tool: 'text-to-image' },
|
|
328
|
+
generate_image_edit: { path: '/image-tools', tool: 'image-editing' },
|
|
329
|
+
edit_image: { path: '/image-tools', tool: 'image-editing' },
|
|
330
|
+
generate_video: { path: '/video-tools', tool: 'text-to-video' },
|
|
331
|
+
generate_video_from_image: { path: '/video-tools', tool: 'image-to-video' },
|
|
332
|
+
generate_elements: { path: '/video-tools', tool: 'image-to-video' },
|
|
333
|
+
generate_first_last_frame: { path: '/video-tools', tool: 'image-to-video' },
|
|
334
|
+
generate_video_from_video: { path: '/video-tools', tool: 'video-to-video' },
|
|
335
|
+
generate_lipsync: { path: '/video-tools', tool: 'lipsync' },
|
|
336
|
+
generate_music: { path: '/audio-tools', tool: 'music-generator' },
|
|
337
|
+
generate_speech: { path: '/audio-tools', tool: 'text-to-speech' },
|
|
338
|
+
generate_sound: { path: '/audio-tools', tool: 'text-to-sound' },
|
|
339
|
+
transcribe_audio: { path: '/audio-tools', tool: 'speech-to-text' },
|
|
340
|
+
generate_creative_director: { path: '/creative-director' },
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Build the "Open in Kolbo" deep link for a generation's actual session.
|
|
345
|
+
* Returns undefined (widget falls back to app.kolbo.ai) when the tool has no
|
|
346
|
+
* deep-linkable page or the submit response carried no session_id (older
|
|
347
|
+
* kolbo-api, shorts render, 3D).
|
|
348
|
+
*/
|
|
349
|
+
function buildOpenUrl(tool, gen) {
|
|
350
|
+
const route = OPEN_URL_ROUTES[tool];
|
|
351
|
+
if (!route || !gen || !gen.session_id) return undefined;
|
|
352
|
+
let url = `${APP_BASE_URL}${route.path}?session=${encodeURIComponent(gen.session_id)}`;
|
|
353
|
+
if (route.tool) url += `&tool=${route.tool}`;
|
|
354
|
+
if (gen.project_id) url += `&project=${encodeURIComponent(gen.project_id)}`;
|
|
355
|
+
return url;
|
|
356
|
+
}
|
|
357
|
+
|
|
308
358
|
// ─── MCP Apps generation widget helpers ──────────────────────────────────────
|
|
309
359
|
// When the host renders MCP Apps (claude.ai via the remote connector, Claude
|
|
310
360
|
// Desktop over stdio), generation tools return IMMEDIATELY after submit and the
|
|
@@ -341,6 +391,7 @@ async function uiGenerating(p) {
|
|
|
341
391
|
count: p.count || 1,
|
|
342
392
|
settings: p.settings || {},
|
|
343
393
|
reference_image: p.reference_image,
|
|
394
|
+
open_url: buildOpenUrl(p.tool, p.gen),
|
|
344
395
|
};
|
|
345
396
|
const text = JSON.stringify({
|
|
346
397
|
status: 'submitted',
|
|
@@ -373,6 +424,7 @@ async function uiCompleted(p, textPayload) {
|
|
|
373
424
|
duration: p.duration,
|
|
374
425
|
scenes: p.scenes,
|
|
375
426
|
credits_used: p.credits_used,
|
|
427
|
+
open_url: buildOpenUrl(p.tool, p.gen),
|
|
376
428
|
};
|
|
377
429
|
return uiResult(UI.generation, textPayload, structured);
|
|
378
430
|
}
|
|
@@ -389,6 +441,7 @@ module.exports = {
|
|
|
389
441
|
creditFields,
|
|
390
442
|
projectIdField,
|
|
391
443
|
inlineImageBlocks,
|
|
444
|
+
buildOpenUrl,
|
|
392
445
|
uiGenerating,
|
|
393
446
|
uiCompleted,
|
|
394
447
|
appsEnabled,
|
package/src/tools/generate.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
const { z } = require('zod');
|
|
7
7
|
const FormData = require('form-data');
|
|
8
8
|
const { pollUntilDone } = require('../polling');
|
|
9
|
-
const { resolveToBuffer, creditFields, projectIdField, inlineImageBlocks, uiGenerating, uiCompleted, appsEnabled } = require('./_shared');
|
|
9
|
+
const { resolveToBuffer, creditFields, projectIdField, inlineImageBlocks, buildOpenUrl, uiGenerating, uiCompleted, appsEnabled } = require('./_shared');
|
|
10
10
|
const { UI, uiResult, canonicalModelId } = require('../apps');
|
|
11
11
|
|
|
12
12
|
function registerGenerateTools(server, client, options = {}) {
|
|
@@ -178,7 +178,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
178
178
|
// through get_generation_status, so it stays blocking on UI hosts too and
|
|
179
179
|
// renders the completed scene gallery.
|
|
180
180
|
if (ui()) return uiCompleted({
|
|
181
|
-
tool: 'generate_creative_director', kind: 'scenes', client, model, prompt,
|
|
181
|
+
tool: 'generate_creative_director', kind: 'scenes', gen, client, model, prompt,
|
|
182
182
|
settings: { duration, resolution, mode: workflow_type }, scenes,
|
|
183
183
|
credits_used: creditFields(result).credits_used
|
|
184
184
|
}, cdText);
|
|
@@ -839,6 +839,7 @@ function registerGenerateTools(server, client, options = {}) {
|
|
|
839
839
|
generation_id: startResponse.generation_id,
|
|
840
840
|
poll_tool: 'get_generation_status',
|
|
841
841
|
audio_url: isUrl ? source : undefined,
|
|
842
|
+
open_url: buildOpenUrl('transcribe_audio', startResponse),
|
|
842
843
|
});
|
|
843
844
|
}
|
|
844
845
|
|