@kolbo/mcp 1.94.1 → 1.96.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/README.md CHANGED
@@ -356,3 +356,7 @@ Both are optional — the local install logs in via the browser on first use.
356
356
  | `update_video_editor_session` | Atomic rename, settings, tracks, clips, trims, speed, captions and effects |
357
357
 
358
358
  `create_video_editor_session` also accepts optional advanced `session_data` instead of clips/audio/texts. Read the schema and saved revision before editing. Changes affect saved state; reload an already-open editor before manual editing. Existing create/export names and arguments remain supported.
359
+
360
+ ### URL downloads
361
+
362
+ `download_media_from_url` starts a server download for a public media page URL. Use `get_download_status` with the returned `job_id` (not `get_generation_status`) and wait for `completed` before using `resultUrl`. `cancel_download` cancels an active job. This produces a cloud file and saves it to the account library when library sync succeeds; it does not write to the caller's computer. Video returns a verified MP4, audio returns MP3; maximum 500 MB. Existing `upload_media` still handles local/direct-file uploads. SDK routes reuse the authenticated utility pipeline at `POST /v1/downloads`, `GET /v1/downloads/:jobId`, and `DELETE /v1/downloads/:jobId`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolbo/mcp",
3
- "version": "1.94.1",
3
+ "version": "1.96.1",
4
4
  "description": "Kolbo AI MCP Server - Generate images, videos, music, speech, and sound effects from Claude Code",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  # AUTO-GENERATED — do not edit
2
2
 
3
- This tree is mirrored from kolbo-code@d6af561, the single source of truth.
3
+ This tree is mirrored from kolbo-code@8d24f6e, the single source of truth.
4
4
  Canonical source: packages/opencode/skills/kolbo/
5
5
  Distribution: .github/workflows/sync-skill-to-plugin.yml
6
6
 
package/skill/SKILL.md CHANGED
@@ -142,6 +142,7 @@ Font tools (when exposed by the installed MCP): `list_fonts`, `get_font`, `uploa
142
142
  | Tool | Purpose |
143
143
  |------|---------|
144
144
  | `list_models` / `list_voices` / `check_credits` / `show_plans` / `get_generation_status` / `cancel_generation` / `get_session_usage` | Discovery + status. `list_models` with no args returns the recommended shortlist out of ~428 — pass `type` for a full category with per-model caps. `cancel_generation` stops an in-flight job and refunds what it can: use it when the user changes their mind mid-generation instead of letting it run. `show_plans` renders the balance + upgrade card for pricing/plan/upgrade questions. |
145
+ | `download_media_from_url` / `get_download_status` / `cancel_download` | Download a public social/video page URL to Kolbo storage. Async job; use download status, not generation status. See `workflows/media-library.md`. |
145
146
  | `upload_media` / `create_upload_ticket` / `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`. Getting a LOCAL file in depends on where the server runs: `upload_media` with a path only works on a local (stdio) install; over a remote connector use `create_upload_ticket` and POST the file yourself. |
146
147
  | `create_visual_dna` / `update_visual_dna` / `generate_character_sheet` / `list_visual_dnas` / `get_visual_dna` / `delete_visual_dna` / `*_visual_dna_folder` (5 folder tools) | Visual DNA (+ character sheet, character folders) — see `workflows/visual-dna.md`. Edit with `update_visual_dna`; never delete+recreate. |
147
148
  | `list_moodboards` / `get_moodboard` / `list_presets` / `list_cinematic_presets` | Style overlays + presets. `list_presets` spans FOUR distinct catalogs (`image`, `image_edit`, `video`, `music`; `text_to_video` is an alias for `video`, `shorts` is empty) — the `video` one holds 200+ Seedance shot recipes. `list_cinematic_presets` is a separate tool feeding the `cinematic` arg, never `preset_id`. Full doctrine + intent→catalog map: `references/workflows/presets.md`. Never omit `preset_id` after claiming a preset was used. |
@@ -124,3 +124,12 @@ The `*_music_library` tools (`search_music_library` / `browse_music_library` / `
124
124
  - `import_music_track_to_library` charges the same way AND also copies the clean track into the media library.
125
125
  - `analyze_script_for_music` turns a script into search terms for `search_music_library`.
126
126
  - Use this family when the user needs music cleared for commercial use. When free stock will do, use `search_stock_media` with `mediaType: "music"` instead.
127
+
128
+
129
+ ## Download a public video or audio page
130
+
131
+ For a YouTube, Instagram, TikTok, Facebook, X or other supported public media page, call `download_media_from_url`. Use `output_type: "video"` (default) for MP4 or `"audio"` for MP3; choose an optional resolution through `quality`. This is a download, not AI generation. Maximum output size is 500 MB.
132
+
133
+ Keep the returned `job_id`. Check `get_download_status` at reasonable intervals (at least two seconds); never use `get_generation_status` for these jobs or start another download while the first is pending. Only `completed` means the returned `resultUrl` is ready. Use `cancel_download` if the user cancels. Do not repeatedly retry unavailable/private media.
134
+
135
+ The result is hosted by Kolbo, not saved to the user's local folder automatically. If a local file was requested and your host supports filesystem downloads, save the completed result URL there. Never claim local delivery from a cloud URL alone. For an existing local file or direct file upload, keep using `upload_media` instead.
@@ -9,6 +9,7 @@
9
9
  */
10
10
 
11
11
  const READ_ONLY = [
12
+ 'get_download_status',
12
13
  'get_video_editor_schema', 'list_video_editor_sessions', 'get_video_editor_session',
13
14
  'list_fonts', 'get_font', 'get_font_upload_status',
14
15
  'get_creative_director_status', 'get_generation_status', 'list_models',
@@ -70,6 +71,7 @@ const PRIVATE_WRITE = [
70
71
  ];
71
72
 
72
73
  const DESTRUCTIVE_WRITE = [
74
+ 'cancel_download',
73
75
  'extend_music', 'cover_music',
74
76
  'update_video_editor_session',
75
77
  'delete_font',
@@ -102,6 +104,7 @@ const DESTRUCTIVE_WRITE = [
102
104
  ];
103
105
 
104
106
  const OPEN_WORLD_WRITE = [
107
+ 'download_media_from_url',
105
108
  'import_music_audio',
106
109
  'publish_html_artifact', 'create_review_share_link', 'blender_capture_viewport',
107
110
  // Adobe edits add bins, clips, sequences or caption tracks; none delete or overwrite.
@@ -626,7 +626,7 @@ function registerGenerateTools(server, client, options = {}) {
626
626
  duration: z.number().optional().describe('Duration in seconds. Must be a value in `supported_durations` from list_models, OR within `min_output_duration`-`max_output_duration` (whichever the model exposes). Default: 5'),
627
627
  enhance_prompt: z.boolean().optional().describe('Enhance the prompt. Default: false — only pass true if the user explicitly asks to enhance/improve the prompt.'),
628
628
  reference_images: z.array(z.string()).optional().describe('Array of images (URLs or absolute local paths) 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.**'),
629
- 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.'),
629
+ resolution: z.string().optional().describe('Video resolution or named tier. Read supported_resolutions and resolution_multipliers from list_models. Seedance 2.5 offers "480p-draft" on the same model: ordinary credits, then optional paid draft_quote/draft_enhance finalization. Regular "480p" remains a normal generation.'),
630
630
  preset_id: z.string().optional().describe('Preset ID from list_presets type="video" to apply a saved motion/style preset to this generation.'),
631
631
  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.**'),
632
632
  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.'),
@@ -715,7 +715,7 @@ function registerGenerateTools(server, client, options = {}) {
715
715
  duration: z.number().optional().describe('Duration in seconds. Must be in `supported_durations` from list_models, OR within `min_output_duration`-`max_output_duration`. Default: 5'),
716
716
  enhance_prompt: z.boolean().optional().describe('Enhance the motion prompt. Default: false — only pass true if the user explicitly asks to enhance/improve the prompt.'),
717
717
  visual_dna_ids: z.array(z.string()).optional().describe('Array of Visual DNA profile IDs to maintain consistency with prior characters / styles. **Cap: pass at most `max_visual_dna` IDs from list_models for the chosen model; if `supports_visual_dna: false` the model ignores DNA entirely.**'),
718
- 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.'),
718
+ resolution: z.string().optional().describe('Video resolution or named tier. Read supported_resolutions from list_models. Seedance 2.5 offers "480p-draft" on the same model, with optional paid finalization through draft_quote/draft_enhance. Regular "480p" is not draft.'),
719
719
  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 Lite, Kling V3 4K, 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.'),
720
720
  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.'),
721
721
  project_id: projectIdField,
@@ -2358,9 +2358,11 @@ function registerGenerateTools(server, client, options = {}) {
2358
2358
  'generate_audio', 'remove_watermark',
2359
2359
  'face_swap', 'extend', 'magic_edit',
2360
2360
  'lipsync', 'remove_background',
2361
- 'inpaint', 'retake'
2361
+ 'inpaint', 'retake', 'draft_enhance', 'draft_quote'
2362
2362
  ]).describe([
2363
2363
  'Edit operation:',
2364
+ '"draft_enhance" — render an owned saved draft at full quality in its original project. Pass `resolution` from the draft model capabilities; the server selects its finalization engine. No prompt or provider task ID is needed.',
2365
+ '"draft_quote" — check a saved draft’s supported final resolutions, expiry and exact credit cost without starting a render. Use this before draft_enhance.',
2364
2366
  '"upscale" — boost to 4K/2K resolution (use `scale` for factor, `resolution` for target, `target_fps` for frame rate). On model "blackforestlabs/flux-video-upscale" (Flux Video Upscale): `scale` is 1.5-3x (no named `resolution` target — billed on the OUTPUT tier it lands in), `mode` is "precise" (source-faithful, default) or "creative" (reimagines detail — a pricier tier), and `prompt` optionally guides the creative-mode enhancement.',
2365
2367
  '"reframe" — change aspect ratio (requires `aspect_ratio`; use `grid_position_x`/`grid_position_y` to control where the original sits).',
2366
2368
  '"generate_audio" — add AI-generated audio from `prompt`. Optionally split into `sound_effect_prompt` and `background_music_prompt`. Set `original_sound=true` to keep original audio alongside.',
@@ -2499,6 +2501,7 @@ function registerGenerateTools(server, client, options = {}) {
2499
2501
  project_id, session_id
2500
2502
  });
2501
2503
 
2504
+ if (operation === 'draft_quote') return { content: [{ type: 'text', text: JSON.stringify(gen, null, 2) }] };
2502
2505
  if (returnsImmediately()) return submittedResult({
2503
2506
  tool: 'edit_video', kind: 'video', gen, client, model,
2504
2507
  prompt: prompt || operation,
@@ -64,6 +64,23 @@ function uploadTicketPayload(ticket) {
64
64
  }
65
65
 
66
66
  function registerMediaTools(server, client, options = {}) {
67
+
68
+ server.tool('download_media_from_url',
69
+ 'Download a public YouTube, Instagram, TikTok, Facebook, X or other supported media page through Kolbo servers. Use this for social page URLs; upload_media is for existing files or direct file URLs. Returns an asynchronous download job, NOT a finished file. Call get_download_status with job_id until terminal; do not use get_generation_status or resubmit while pending. Completed video output is one MP4 with its expected audio, audio output is MP3, maximum 500 MB. Returns a cloud URL, not a local filesystem path. Private/login-restricted or unavailable media may fail.',
70
+ { url: z.string().url(), quality: z.enum(['best','2160','1440','1080','720','480','360']).optional(), output_type: z.enum(['video','audio']).optional() },
71
+ async ({ url, quality = 'best', output_type = 'video' }) => {
72
+ const result = await client.post('/v1/downloads', { url, quality, outputType: output_type });
73
+ return { content: [{ type: 'text', text: JSON.stringify({ ...result, job_id: result.jobId, next_tool: 'get_download_status' }) }] };
74
+ });
75
+ server.tool('get_download_status',
76
+ 'Read a URL-download job owned by this account. Use the job_id returned by download_media_from_url. pending/processing means wait before checking again; completed includes resultUrl/url; failed/cancelled is terminal. Do not report a file ready until completed. This is separate from AI generation status.',
77
+ { job_id: z.string().min(1).max(100) },
78
+ async ({ job_id }) => ({ content: [{ type: 'text', text: JSON.stringify(await client.get(`/v1/downloads/${encodeURIComponent(job_id)}`)) }] }));
79
+ server.tool('cancel_download',
80
+ "Cancel this account's pending or processing URL-download job. Does not delete a previously completed file.",
81
+ { job_id: z.string().min(1).max(100) },
82
+ async ({ job_id }) => ({ content: [{ type: 'text', text: JSON.stringify(await client.delete(`/v1/downloads/${encodeURIComponent(job_id)}`)) }] }));
83
+
67
84
  // `opts.apps` is set only by kolbo-api's per-request server (see createServer
68
85
  // in ../index.js), which makes it a TRANSPORT signal — deliberately not
69
86
  // `appsEnabled()`, which also returns true for stdio hosts that advertise UI.