@kolbo/mcp 1.53.1 → 1.54.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolbo/mcp",
3
- "version": "1.53.1",
3
+ "version": "1.54.0",
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": {
package/src/index.js CHANGED
@@ -124,7 +124,7 @@ function createServer(opts = {}) {
124
124
  '7. SESSION CONTINUITY — one task, one session, always: every generation tool returns a `session_id`. For ANY follow-up, refinement, retry, or next step on the SAME task, pass that session_id back — never start fresh. BATCH RULE (critical): when a single user request produces multiple parallel generations (e.g. "animate these 5 images", "generate 3 variants"), do NOT launch them all at once without a session_id. Instead: (1) run the FIRST generation without session_id to create the session, (2) capture the session_id from its response, (3) pass that session_id to ALL remaining generations in the batch. This keeps the entire batch in one session. Exception: only omit session_id and start fresh when the user explicitly starts an unrelated new task.',
125
125
  '8. LOCAL FILES / REFERENCE MEDIA — HOW TO HANDLE EVERY CASE: (A) User has a LOCAL file (audio, video, image, document) on their machine: if you have filesystem access (Claude Desktop / Code / IDE / any stdio MCP client) → call `upload_media` with the absolute local path OR pass the path directly to tools like `transcribe_audio` which accept local paths natively. If you have NO filesystem access (claude.ai browser/mobile) → call `media_upload_widget` IMMEDIATELY, an upload card appears, the user uploads, and a `media.kolbo.ai` CDN URL comes back — use that URL for any follow-up tool call. (B) You already have a public URL (media.kolbo.ai, any CDN, any direct link) → pass it directly to the tool. All Kolbo tools accept public URLs. NEVER search for DO Spaces keys, DigitalOcean credentials, or server-side upload credentials. NEVER ask the user to put the file on Google Drive, Dropbox, or Loom. NEVER invent or guess a URL. NEVER base64 a large file — use upload_media instead.',
126
126
  '9. MODEL SELECTION: ALWAYS pass a specific `model` on every generation tool — do NOT omit it. Omitting falls back to "Smart Select" auto-routing, which we deliberately avoid because it hides the model choice from the user and often picks a generic default. Choose the model that best fits the task and the user\'s intent (quality, speed, style, capability). If you are unsure which model to use for a given type, call `list_models` with the matching `type` and pick the recommended/flagship one, then pass its `identifier`. Only use Smart Select (omit `model`) if the user EXPLICITLY asks you to auto-pick.',
127
- '10. IMAGE EDITING: for ANY prompt-driven / content edit of an existing image — "make it night", changing scene/lighting/colors, adding/removing/replacing objects, restyling — use `generate_image_edit` (it runs on strong dedicated editing models, same as image generation). Do NOT use `edit_image` for content edits — `edit_image` is ONLY for mechanical enhancements (upscale, reframe, remove-background, skin retouch). Its `magic_edit` operation is deprecated in favor of `generate_image_edit`.'
127
+ '10. IMAGE EDITING: for ANY prompt-driven / content edit of an existing image — "make it night", changing scene/lighting/colors, adding/removing/replacing objects, restyling — use `generate_image_edit` (it runs on strong dedicated editing models, same as image generation). Do NOT use `edit_image` for content edits — `edit_image` is ONLY for mechanical enhancements (upscale, expand/outpaint, remove-background, skin retouch). Its `magic_edit` operation is deprecated in favor of `generate_image_edit`. EXPANDING AN IMAGE: to widen/extend/uncrop an image or fit it into a wider frame while KEEPING the existing artwork, use `edit_image` with operation="zoom_out" (outpainting — original pixels preserved; size it with `zoom_out_percentage` or the `expand_left/right/top/bottom` pixel args). The "reframe" operation is NOT this: it re-generates the whole picture at a new aspect ratio and the subject comes back re-imagined. Only pick "reframe" when the user wants the shot re-taken, never when they want their image extended.'
128
128
  ].join('\n')
129
129
  });
130
130
 
@@ -1266,7 +1266,7 @@ function registerGenerateTools(server, client, options = {}) {
1266
1266
  // ─── edit_image ────────────────────────────────────────────
1267
1267
  server.tool(
1268
1268
  'edit_image',
1269
- 'Apply a targeted AI edit to an existing image. Covers mechanical enhancements (upscale, reframe, remove background, skin retouching) AND creative operations (inpaint, erase, face swap, background replace, camera angle, zoom out, multi-shot grid, split/upscale). ⚠️ For open-ended PROMPT-DRIVEN content edits — "make it night", restyling, adding/removing objects — use `generate_image_edit` instead; it runs on stronger dedicated editing models and produces better results.',
1269
+ 'Apply a targeted AI edit to an existing image. Covers mechanical enhancements (upscale, remove background, skin retouching) AND creative operations (expand/outpaint, reframe, inpaint, erase, face swap, background replace, camera angle, multi-shot grid, split/upscale). ⚠️ To EXPAND an image / add space / widen it to a new aspect ratio while keeping the existing artwork intact, use operation="zoom_out" — NOT "reframe" (reframe re-generates the whole picture). ⚠️ For open-ended PROMPT-DRIVEN content edits — "make it night", restyling, adding/removing objects — use `generate_image_edit` instead; it runs on stronger dedicated editing models and produces better results.',
1270
1270
  {
1271
1271
  image_url: z.string().describe('URL of the primary source image to edit.'),
1272
1272
 
@@ -1284,8 +1284,8 @@ function registerGenerateTools(server, client, options = {}) {
1284
1284
  ]).describe([
1285
1285
  'Edit operation:',
1286
1286
  '"upscale" — increase resolution by 2×, 3×, or 4× (use `scale`). "clarity_upscale" — AI-powered clarity upscale with detail enhancement (use `resolution`).',
1287
- '"reframe" — change aspect ratio (requires `aspect_ratio`, e.g. "16:9" or "9:16").',
1288
- '"zoom_out" — expand the image outward, filling new areas with AI-generated content.',
1287
+ '"zoom_out" — THE default way to expand / extend / outpaint / uncrop / widen an image, or to grow it into a wider or taller frame. The original pixels are PRESERVED and only the new area around them is generated. Expand uniformly with `zoom_out_percentage`, or in one direction with `expand_left` / `expand_right` / `expand_top` / `expand_bottom` (pixels — this is how you hit a target aspect ratio: read the source width/height, then add the missing pixels on the side you want). `prompt` describes what should appear in the NEW space only. Note: `aspect_ratio` is ignored by this operation.',
1288
+ '"reframe" — RE-GENERATES the entire picture at a new aspect ratio (Luma Photon). The subject is re-imagined, not preserved — expect a different-looking image. Use ONLY when the user explicitly wants the shot re-taken in another format. If they said "expand", "extend", "widen", "uncrop", "add space", "fill the sides", or "keep it the same but 16:9", they want "zoom_out" instead. Requires `aspect_ratio`.',
1289
1289
  '"removebg" — remove the image background, output is transparent PNG.',
1290
1290
  '"background_replace" — remove background and replace it with AI-generated content from `prompt`.',
1291
1291
  '"enhance_skin" — portrait skin retouching (use `skin_strength`: "subtle" | "realistic" | "pimple" | "freckle").',
@@ -1310,7 +1310,23 @@ function registerGenerateTools(server, client, options = {}) {
1310
1310
 
1311
1311
  // ── reframe ────────────────────────────────────────────
1312
1312
  aspect_ratio: z.string().optional()
1313
- .describe('Target aspect ratio (e.g. "16:9", "9:16", "1:1", "4:3"). Required for operation="reframe".'),
1313
+ .describe('Target aspect ratio (e.g. "16:9", "9:16", "1:1", "4:3"). Required for operation="reframe". Ignored by "zoom_out" — size that expansion with `zoom_out_percentage` or the `expand_*` pixel args.'),
1314
+
1315
+ // ── zoom_out (outpaint / expand) ───────────────────────
1316
+ zoom_out_percentage: z.number().optional()
1317
+ .describe('How much to expand outward on ALL sides, as a percentage (0-90). Used with operation="zoom_out". Default: 20. Ignored when any `expand_*` arg is set.'),
1318
+
1319
+ expand_left: z.number().optional()
1320
+ .describe('Pixels of new AI-generated content to add on the LEFT. Used with operation="zoom_out" (0-700). This is how you widen an image asymmetrically, e.g. to turn a 16:9 frame into 21:9 without touching the subject.'),
1321
+
1322
+ expand_right: z.number().optional()
1323
+ .describe('Pixels of new AI-generated content to add on the RIGHT. Used with operation="zoom_out" (0-700).'),
1324
+
1325
+ expand_top: z.number().optional()
1326
+ .describe('Pixels of new AI-generated content to add on TOP. Used with operation="zoom_out" (0-700).'),
1327
+
1328
+ expand_bottom: z.number().optional()
1329
+ .describe('Pixels of new AI-generated content to add on the BOTTOM. Used with operation="zoom_out" (0-700).'),
1314
1330
 
1315
1331
  // ── enhance_skin ───────────────────────────────────────
1316
1332
  skin_strength: z.enum(['subtle', 'realistic', 'pimple', 'freckle']).optional()
@@ -1318,7 +1334,7 @@ function registerGenerateTools(server, client, options = {}) {
1318
1334
 
1319
1335
  // ── inpaint / erase / face_swap / background_replace / zoom_out / camera_angle / magic_edit ──
1320
1336
  prompt: z.string().optional()
1321
- .describe('Text instruction guiding the edit. Required for "background_replace". Used with "inpaint", "zoom_out", "camera_angle", and the deprecated "magic_edit".'),
1337
+ .describe('Text instruction guiding the edit. Required for "background_replace". Used with "inpaint", "zoom_out", "camera_angle", and the deprecated "magic_edit". For "zoom_out" it describes what fills the NEW space only — the original image is left as-is.'),
1322
1338
 
1323
1339
  mask_image_url: z.string().optional()
1324
1340
  .describe('URL of a mask image (black & white; white = affected area). Required for "inpaint" and "erase". For "face_swap", this is the face reference image.'),
@@ -1342,6 +1358,7 @@ function registerGenerateTools(server, client, options = {}) {
1342
1358
  async ({
1343
1359
  image_url, operation, model, scale, aspect_ratio, skin_strength, prompt,
1344
1360
  mask_image_url, additional_images, generate_all_angles, resolution, quality, ai_optimize,
1361
+ zoom_out_percentage, expand_left, expand_right, expand_top, expand_bottom,
1345
1362
  project_id
1346
1363
  }) => {
1347
1364
  model = await canonicalModelId(client, model);
@@ -1356,6 +1373,7 @@ function registerGenerateTools(server, client, options = {}) {
1356
1373
  const gen = await client.post('/v1/edit/image', {
1357
1374
  image_url, operation, model, scale, aspect_ratio, skin_strength, prompt,
1358
1375
  mask_image_url, additional_images, generate_all_angles, resolution, quality, ai_optimize,
1376
+ zoom_out_percentage, expand_left, expand_right, expand_top, expand_bottom,
1359
1377
  project_id
1360
1378
  });
1361
1379