@kolbo/mcp
Advanced tools
+1
-1
| { | ||
| "name": "@kolbo/mcp", | ||
| "version": "1.53.0", | ||
| "version": "1.53.1", | ||
| "description": "Kolbo AI MCP Server - Generate images, videos, music, speech, and sound effects from Claude Code", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -34,5 +34,16 @@ 'use strict'; | ||
| function boot(sc) { | ||
| if (!sc || !sc.groups) return; | ||
| if (!sc || !sc.groups || !sc.groups.length) return false; | ||
| state = sc; | ||
| el('title').textContent = sc.title || 'AI Models'; | ||
| // Internal lookup (Claude checking caps mid-task): a full catalog card would | ||
| // be chat spam, an empty card would look broken. One expandable row instead. | ||
| if (sc.compact) { | ||
| el('stage').innerHTML = '<div class="k-audio-row" id="expand" style="cursor:pointer;padding:8px">' + | ||
| '<div class="k-audio-meta"><div class="k-audio-title" style="font-size:12px">Kolbo AI models</div>' + | ||
| '<div class="k-audio-sub" style="font-size:10.5px">Tap to browse what you can generate</div></div>' + | ||
| '<span class="k-chip" style="flex:none;padding:2px 7px;font-size:10px">Browse</span></div>'; | ||
| el('expand').onclick = function () { sc.compact = false; boot(sc); }; | ||
| window.kolbo.notifySize(); | ||
| return true; | ||
| } | ||
| var shown = sc.groups.reduce(function (n, g) { return n + g.models.length; }, 0); | ||
@@ -64,9 +75,9 @@ el('count-chip').style.display = ''; | ||
| window.kolbo.notifySize(); | ||
| return true; | ||
| } | ||
| window.kolbo.onToolResult(function (result) { | ||
| var sc = result.structuredContent || structured(result); | ||
| if (sc && sc.groups) return boot(sc); | ||
| // Internal lookup (Claude checking constraints mid-task) — no catalog data | ||
| // was attached on purpose. Collapse instead of showing a dead card. | ||
| if (boot(result.structuredContent || structured(result))) return; | ||
| // No catalog data reached the iframe (host/version mismatch, or a filter | ||
| // that matched nothing) — collapse instead of showing a dead card. | ||
| var card = document.querySelector('.k-card'); | ||
@@ -73,0 +84,0 @@ if (card) card.style.display = 'none'; |
+12
-6
@@ -52,3 +52,3 @@ /* ⛔ BACKWARD COMPATIBILITY: Tool names and arg names below are a PUBLIC | ||
| // metadata used to read just "Auto". | ||
| function buildCatalogStructured(models, type) { | ||
| function buildCatalogStructured(models, type, compact) { | ||
| const groups = []; | ||
@@ -82,2 +82,3 @@ const byName = new Map(); | ||
| total_available: models.length, | ||
| compact: compact === true, | ||
| groups, | ||
@@ -96,7 +97,12 @@ }; | ||
| format: z.enum(['text', 'json']).optional().describe('Output format. "text" (default) returns a human-readable summary with the most-used caps. "json" returns the raw model documents from the API — use this when you need to programmatically verify caps (max_reference_images, max_visual_dna, max_video_duration, supported_aspect_ratios, etc.) before passing an array/value that might exceed a model-specific limit. The JSON form is the source of truth; the text form is a convenience preview.'), | ||
| display_catalog: z.boolean().optional().describe('Set true ONLY when the USER explicitly asked to see/browse the available models — it renders a visual model catalog to them. Leave unset for internal lookups (verifying a model name, checking caps before a generation): those should stay invisible to the user.') | ||
| display_catalog: z.boolean().optional().describe('Set true when the USER explicitly asked to see/browse the available models — the visual catalog opens expanded. Leave unset for internal lookups (verifying a model name, checking caps before a generation): the catalog stays collapsed to a single row the user can tap to browse.') | ||
| }, | ||
| async ({ type, format, display_catalog }) => { | ||
| // Widget only when the user asked to browse — internal validation | ||
| // lookups were spamming the chat with a full catalog card. | ||
| // The tool DECLARATION always carries widget meta, so hosts that mount | ||
| // from tools/list (Claude Code desktop) prepare an iframe on EVERY call. | ||
| // Returning plain text for internal lookups left that iframe with no | ||
| // data — a dead, empty "Widget from Kolbo list_models" shell. Always | ||
| // ship structuredContent; `compact` tells the widget to render a single | ||
| // "Browse models" row (expandable) instead of the full catalog, which is | ||
| // what display_catalog was really asking for. | ||
| const showCatalog = display_catalog === true; | ||
@@ -112,3 +118,3 @@ const path = type ? `/v1/models?type=${encodeURIComponent(type)}` : '/v1/models'; | ||
| const text = JSON.stringify({ count: result.count, models: result.models }, null, 2); | ||
| if (ui() && showCatalog) return uiResult(UI.catalog, text, buildCatalogStructured(result.models, type)); | ||
| if (ui()) return uiResult(UI.catalog, text, buildCatalogStructured(result.models, type, !showCatalog)); | ||
| return { content: [{ type: 'text', text }] }; | ||
@@ -284,3 +290,3 @@ } | ||
| const text = `Available models (${result.count}):\n\n${sections.join('\n\n')}\n\nUse the "identifier" value as the "model" parameter in generate tools. For programmatic cap validation, re-call with format: "json".`; | ||
| if (ui() && showCatalog) return uiResult(UI.catalog, text, buildCatalogStructured(result.models, type)); | ||
| if (ui()) return uiResult(UI.catalog, text, buildCatalogStructured(result.models, type, !showCatalog)); | ||
| return { content: [{ type: 'text', text }] }; | ||
@@ -287,0 +293,0 @@ } |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
766237
0.15%8412
0.2%