@kolbo/mcp 1.106.0 → 1.106.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/apps/index.js +64 -48
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolbo/mcp",
3
- "version": "1.106.0",
3
+ "version": "1.106.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": {
package/src/apps/index.js CHANGED
@@ -20,25 +20,25 @@ const { generationWidgetHtml } = require('./widgets/generation');
20
20
  const { mediaGridWidgetHtml } = require('./widgets/mediaGrid');
21
21
  const { catalogWidgetHtml } = require('./widgets/catalog');
22
22
  const { transcriptWidgetHtml } = require('./widgets/transcript');
23
- const { uploadWidgetHtml } = require('./widgets/upload');
24
- const { fontUploadWidgetHtml } = require('./widgets/fontUpload');
23
+ const { uploadWidgetHtml } = require('./widgets/upload');
24
+ const { fontUploadWidgetHtml } = require('./widgets/fontUpload');
25
25
  const { listWidgetHtml } = require('./widgets/list');
26
26
  const { HOST_MAP } = require('../cdn');
27
- const { plansWidgetHtml } = require('./widgets/plans');
28
- const { creditsWidgetHtml } = require('./widgets/credits');
29
- const { ResourceTemplate } = require('@modelcontextprotocol/sdk/server/mcp.js');
30
- const { McpError, ErrorCode } = require('@modelcontextprotocol/sdk/types.js');
27
+ const { plansWidgetHtml } = require('./widgets/plans');
28
+ const { creditsWidgetHtml } = require('./widgets/credits');
29
+ const { ResourceTemplate } = require('@modelcontextprotocol/sdk/server/mcp.js');
30
+ const { McpError, ErrorCode } = require('@modelcontextprotocol/sdk/types.js');
31
31
 
32
32
  const UI = {
33
33
  generation: 'ui://kolbo/generation.html',
34
34
  mediaGrid: 'ui://kolbo/media-grid.html',
35
35
  catalog: 'ui://kolbo/catalog.html',
36
36
  transcript: 'ui://kolbo/transcript.html',
37
- upload: 'ui://kolbo/upload.html',
38
- fontUpload: 'ui://kolbo/font-upload.html',
37
+ upload: 'ui://kolbo/upload.html',
38
+ fontUpload: 'ui://kolbo/font-upload.html',
39
39
  list: 'ui://kolbo/list.html',
40
- plans: 'ui://kolbo/plans.html',
41
- credits: 'ui://kolbo/credits.html',
40
+ plans: 'ui://kolbo/plans.html',
41
+ credits: 'ui://kolbo/credits.html',
42
42
  };
43
43
 
44
44
  const WIDGET_BUILDERS = {
@@ -46,11 +46,11 @@ const WIDGET_BUILDERS = {
46
46
  [UI.mediaGrid]: mediaGridWidgetHtml,
47
47
  [UI.catalog]: catalogWidgetHtml,
48
48
  [UI.transcript]: transcriptWidgetHtml,
49
- [UI.upload]: uploadWidgetHtml,
50
- [UI.fontUpload]: fontUploadWidgetHtml,
49
+ [UI.upload]: uploadWidgetHtml,
50
+ [UI.fontUpload]: fontUploadWidgetHtml,
51
51
  [UI.list]: listWidgetHtml,
52
- [UI.plans]: plansWidgetHtml,
53
- [UI.credits]: creditsWidgetHtml,
52
+ [UI.plans]: plansWidgetHtml,
53
+ [UI.credits]: creditsWidgetHtml,
54
54
  };
55
55
 
56
56
  // Widgets are pure functions of source — build once per process.
@@ -169,11 +169,11 @@ function registerApps(server) {
169
169
  [UI.mediaGrid, 'Kolbo Library Widget'],
170
170
  [UI.catalog, 'Kolbo Model Catalog Widget'],
171
171
  [UI.transcript, 'Kolbo Transcription Widget'],
172
- [UI.upload, 'Kolbo Upload Widget'],
173
- [UI.fontUpload, 'Kolbo Font Upload Widget'],
172
+ [UI.upload, 'Kolbo Upload Widget'],
173
+ [UI.fontUpload, 'Kolbo Font Upload Widget'],
174
174
  [UI.list, 'Kolbo List Widget'],
175
- [UI.plans, 'Kolbo Plans Widget'],
176
- [UI.credits, 'Kolbo Credit Balance Widget'],
175
+ [UI.plans, 'Kolbo Plans Widget'],
176
+ [UI.credits, 'Kolbo Credit Balance Widget'],
177
177
  ]) {
178
178
  for (const u of [versionedUri(uri), uri]) {
179
179
  registerAppResource(
@@ -185,30 +185,30 @@ function registerApps(server) {
185
185
  _meta: { csp: WIDGET_CSP, ui: { csp: WIDGET_CSP } },
186
186
  }],
187
187
  })
188
- );
189
- }
190
- // Published tool definitions and old conversations can retain any previous
191
- // content hash. Keep those addresses readable after deploying new HTML.
192
- // Match only this registered widget and the version format we publish.
193
- registerAppResource(
194
- server, name + ' (previous versions)',
195
- new ResourceTemplate(uri + '{?v}', { list: undefined }),
196
- { mimeType: RESOURCE_MIME_TYPE, _meta: { csp: WIDGET_CSP, ui: { csp: WIDGET_CSP } } },
197
- async (requestedUri) => {
198
- const requested = requestedUri.href;
199
- if (!new RegExp('^' + uri.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\?v=[a-f0-9]{10}$').test(requested)) {
200
- throw new McpError(ErrorCode.InvalidParams, 'Unknown widget version URI');
201
- }
202
- return {
203
- contents: [{
204
- uri: requested, mimeType: RESOURCE_MIME_TYPE, text: widgetHtml(uri),
205
- _meta: { csp: WIDGET_CSP, ui: { csp: WIDGET_CSP } },
206
- }],
207
- };
208
- }
209
- );
210
- }
211
- }
188
+ );
189
+ }
190
+ // Published tool definitions and old conversations can retain any previous
191
+ // content hash. Keep those addresses readable after deploying new HTML.
192
+ // Match only this registered widget and the version format we publish.
193
+ registerAppResource(
194
+ server, name + ' (previous versions)',
195
+ new ResourceTemplate(uri + '{?v}', { list: undefined }),
196
+ { mimeType: RESOURCE_MIME_TYPE, _meta: { csp: WIDGET_CSP, ui: { csp: WIDGET_CSP } } },
197
+ async (requestedUri) => {
198
+ const requested = requestedUri.href;
199
+ if (!new RegExp('^' + uri.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\?v=[a-f0-9]{10}$').test(requested)) {
200
+ throw new McpError(ErrorCode.InvalidParams, 'Unknown widget version URI');
201
+ }
202
+ return {
203
+ contents: [{
204
+ uri: requested, mimeType: RESOURCE_MIME_TYPE, text: widgetHtml(uri),
205
+ _meta: { csp: WIDGET_CSP, ui: { csp: WIDGET_CSP } },
206
+ }],
207
+ };
208
+ }
209
+ );
210
+ }
211
+ }
212
212
 
213
213
  /** `_meta` for a tool RESULT (and optionally for tool registration). */
214
214
  function uiMeta(uri) {
@@ -371,9 +371,25 @@ async function modelInfo(client, modelName) {
371
371
  const rows = catalog.all || [];
372
372
  return rows.find((row) => normId(row.id) === want || normId(row.name) === want)
373
373
  || rows.find((row) => normId(row.id).startsWith(want) || normId(row.name).startsWith(want))
374
+ || variantBase(rows, modelName)
374
375
  || { icon: null, eta: null, name: null };
375
376
  }
376
377
 
378
+ // A finished generation can report an internal variant of a catalog model —
379
+ // "seedance-2-5-draft-enhance" (draft tier + prompt enhance) is not itself in
380
+ // /v1/models, so the chip showed a letter monogram and the raw id. Resolve it
381
+ // to the LONGEST catalog identifier it extends at a "-" boundary
382
+ // ("seedance-2-5", not "seedance-2").
383
+ function variantBase(rows, modelName) {
384
+ const raw = String(modelName).toLowerCase();
385
+ let best = null;
386
+ for (const row of rows) {
387
+ const id = row.id && String(row.id).toLowerCase();
388
+ if (id && raw.startsWith(id + '-') && (!best || id.length > best.id.length)) best = row;
389
+ }
390
+ return best;
391
+ }
392
+
377
393
  /**
378
394
  * Snap a requested aspect ratio onto the catalog enum for that model.
379
395
  * Every image/video generate_* tool must call this after canonicalModelId —
@@ -621,8 +637,8 @@ async function canonicalModelId(client, input, type) {
621
637
  if (!input || typeof input !== 'string') return input;
622
638
  const key = input.toLowerCase().trim();
623
639
  const want = normId(key);
624
- if (!want || AUTO_ALIASES.has(want)) return input;
625
- // Exact native-workflow ids pass through: the near-miss check below would reject an
640
+ if (!want || AUTO_ALIASES.has(want)) return input;
641
+ // Exact native-workflow ids pass through: the near-miss check below would reject an
626
642
  // unpublished or cached-out 'kolbo-*' id as unknown.
627
643
  if (NATIVE_WORKFLOW_MODEL_IDS.has(key)) return input;
628
644
 
@@ -769,8 +785,8 @@ const TOOL_WIDGETS = {
769
785
  // never saw it as widget-carrying. Result-level _meta alone isn't enough.
770
786
  list_color_palettes: UI.mediaGrid,
771
787
  // upload widget
772
- media_upload_widget: UI.upload,
773
- font_upload_widget: UI.fontUpload,
788
+ media_upload_widget: UI.upload,
789
+ font_upload_widget: UI.fontUpload,
774
790
  // generic list widget — flat record lists with no natural thumbnail
775
791
  list_projects: UI.list,
776
792
  // Must stay list.html — mapping this to generation.html mounts "Kolbo Generation /
@@ -782,8 +798,8 @@ const TOOL_WIDGETS = {
782
798
  list_docs: UI.list,
783
799
  list_media_folders: UI.list,
784
800
  list_visual_dna_folders: UI.list,
785
- show_plans: UI.plans,
786
- check_credits: UI.credits,
801
+ show_plans: UI.plans,
802
+ check_credits: UI.credits,
787
803
  list_project_assets: UI.list,
788
804
  };
789
805