@kolbo/mcp 1.82.3 → 1.82.5

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.82.3",
3
+ "version": "1.82.5",
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": {
@@ -794,7 +794,7 @@ function fillBatchCell(sc, i, g) {
794
794
  // the user is meant to watch, and without it the tile was a muted poster with
795
795
  // no way to play, seek or unmute until the whole batch finished and repainted.
796
796
  cell.innerHTML = (sc.kind === 'video'
797
- ? '<video class="k-cell-fill" src="' + esc(u) + '"' + (r.thumbnail_url ? ' poster="' + esc(r.thumbnail_url) + '"' : '') + ' controls playsinline preload="metadata"></video>'
797
+ ? '<video class="k-cell-fill" src="' + esc(playableAt(r, r.urls || [], 0)) + '"' + (r.thumbnail_url ? ' poster="' + esc(r.thumbnail_url) + '"' : '') + ' controls playsinline preload="metadata"></video>'
798
798
  : '<img class="k-cell-fill" src="' + esc(u) + '" alt="">') + cap;
799
799
  window.kolbo.notifySize();
800
800
  }
@@ -862,10 +862,28 @@ function renderImages(sc, urls) {
862
862
  });
863
863
  }
864
864
 
865
+ /**
866
+ * The url to PLAY, which is not always the url to DOWNLOAD.
867
+ *
868
+ * Seedance 2.5 at 1080p returns HEVC Main 10 (10-bit). Chrome and Edge decode HEVC in
869
+ * hardware only — with no software fallback — and Firefox on Windows not at all, so the
870
+ * widget showed a black frame with sound. The API therefore returns playback_urls
871
+ * alongside urls whenever it had to build an H.264 proxy.
872
+ *
873
+ * urls stays the MASTER and is what every download button must keep using: handing
874
+ * someone the 8-bit proxy for a file they paid the 1080p multiplier for is a silent
875
+ * quality downgrade. Backend: kolbo-api/src/services/webPlaybackProxy.js
876
+ */
877
+ function playableAt(src, urls, i) {
878
+ var proxies = (src && src.playback_urls) || [];
879
+ return proxies[i] || (urls || [])[i];
880
+ }
881
+
865
882
  function renderVideo(sc, urls) {
866
883
  // preload="none" behind a poster: the card shows the still until the user
867
884
  // hits play, instead of pulling the video header on mount.
868
- el('stage').innerHTML = '<div class="k-viewer"><video id="main-video" src="' + esc(urls[0]) + '"' +
885
+ // PLAY the proxy when there is one; the download button below keeps urls[0] (master).
886
+ el('stage').innerHTML = '<div class="k-viewer"><video id="main-video" src="' + esc(playableAt(sc, urls, 0)) + '"' +
869
887
  (sc.thumbnail_url ? ' poster="' + esc(sc.thumbnail_url) + '" preload="none"' : ' preload="metadata"') + ' controls playsinline></video>' +
870
888
  dlBtnHTML(urls[0]) + '</div>';
871
889
  wireDlButtons(el('stage'));
@@ -89,7 +89,7 @@ async function pollBatch(client, batch, { interval, timeout }, toolName) {
89
89
  const polls = await Promise.all(batch.ids.map((id) => pollOrTimedOut(client, id, { interval, timeout })));
90
90
  const generations = polls.map((p, i) => p.timedOut
91
91
  ? { prompt: batch.ok[i].prompt, generation_id: batch.ids[i], status: 'processing', note: 'Still running — call get_generation_status with wait=true to collect it.' }
92
- : { prompt: batch.ok[i].prompt, generation_id: batch.ids[i], status: 'completed', ...creditFields(polls[i].result), urls: p.result.result.urls });
92
+ : { prompt: batch.ok[i].prompt, generation_id: batch.ids[i], status: 'completed', ...creditFields(polls[i].result), urls: p.result.result.urls, playback_urls: p.result.result.playback_urls });
93
93
  const text = JSON.stringify({
94
94
  batch: true,
95
95
  session_id: batch.ok[0].gen.session_id,
@@ -290,11 +290,13 @@ function registerGenerateTools(server, client, options = {}) {
290
290
  // input arg is only what the caller happened to name.
291
291
  reference_images: result.result.reference_images || reference_images,
292
292
  urls: result.result.urls,
293
+ playback_urls: result.result.playback_urls,
293
294
  credits_used: creditFields(result).credits_used,
294
295
  }, JSON.stringify({
295
296
  ...creditFields(result),
296
297
  session_id: gen.session_id,
297
298
  urls: result.result.urls,
299
+ playback_urls: result.result.playback_urls,
298
300
  model: result.result.model,
299
301
  prompt_used: result.result.prompt_used,
300
302
  _followup_hint: 'If the user asks to edit/change/modify this image next (scene, lighting, objects, style, color — any content edit), pass urls[0] to generate_image_edit. Use edit_image ONLY for mechanical ops (upscale/reframe/removebg/enhance_skin). Do NOT call generate_image again.'
@@ -380,11 +382,13 @@ function registerGenerateTools(server, client, options = {}) {
380
382
  reference_images: result.result.reference_images
381
383
  || [...(source_images || []), ...(reference_images || [])],
382
384
  urls: result.result.urls,
385
+ playback_urls: result.result.playback_urls,
383
386
  credits_used: creditFields(result).credits_used,
384
387
  }, JSON.stringify({
385
388
  ...creditFields(result),
386
389
  session_id: gen.session_id,
387
390
  urls: result.result.urls,
391
+ playback_urls: result.result.playback_urls,
388
392
  model: result.result.model,
389
393
  prompt_used: result.result.prompt_used,
390
394
  _followup_hint: 'If the user asks for another edit on this output, pass urls[0] back into generate_image_edit as source_images. For targeted ops (upscale/reframe/removebg/enhance_skin) use edit_image instead. Do NOT call generate_image from scratch.'
@@ -627,6 +631,7 @@ function registerGenerateTools(server, client, options = {}) {
627
631
  settings: videoSettings(shared),
628
632
  reference_images,
629
633
  urls: result.result.urls,
634
+ playback_urls: result.result.playback_urls,
630
635
  thumbnail_url: result.result.thumbnail_url,
631
636
  duration: result.result.duration,
632
637
  credits_used: creditFields(result).credits_used,
@@ -634,6 +639,7 @@ function registerGenerateTools(server, client, options = {}) {
634
639
  ...creditFields(result),
635
640
  session_id: gen.session_id,
636
641
  urls: result.result.urls,
642
+ playback_urls: result.result.playback_urls,
637
643
  model: result.result.model,
638
644
  duration: result.result.duration,
639
645
  thumbnail_url: result.result.thumbnail_url,
@@ -714,6 +720,7 @@ function registerGenerateTools(server, client, options = {}) {
714
720
  settings: videoSettings({ duration, resolution, aspect_ratio, enhance_prompt, visual_dna_ids }),
715
721
  reference_images: [image_url],
716
722
  urls: result.result.urls,
723
+ playback_urls: result.result.playback_urls,
717
724
  thumbnail_url: result.result.thumbnail_url,
718
725
  duration: result.result.duration,
719
726
  credits_used: creditFields(result).credits_used,
@@ -721,6 +728,7 @@ function registerGenerateTools(server, client, options = {}) {
721
728
  ...creditFields(result),
722
729
  session_id: gen.session_id,
723
730
  urls: result.result.urls,
731
+ playback_urls: result.result.playback_urls,
724
732
  model: result.result.model,
725
733
  duration: result.result.duration,
726
734
  thumbnail_url: result.result.thumbnail_url,
@@ -781,6 +789,7 @@ function registerGenerateTools(server, client, options = {}) {
781
789
  tool: 'generate_music', kind: 'audio', gen, client, model: model || 'Suno', prompt,
782
790
  settings: { mode: instrumental ? 'instrumental' : (style || undefined), preset_id },
783
791
  urls: result.result.urls,
792
+ playback_urls: result.result.playback_urls,
784
793
  title: result.result.title,
785
794
  duration: result.result.duration,
786
795
  credits_used: creditFields(result).credits_used,
@@ -788,6 +797,7 @@ function registerGenerateTools(server, client, options = {}) {
788
797
  ...creditFields(result),
789
798
  session_id: gen.session_id,
790
799
  urls: result.result.urls,
800
+ playback_urls: result.result.playback_urls,
791
801
  title: result.result.title,
792
802
  duration: result.result.duration,
793
803
  lyrics: result.result.lyrics
@@ -899,12 +909,14 @@ function registerGenerateTools(server, client, options = {}) {
899
909
  language,
900
910
  },
901
911
  urls: result.result.urls,
912
+ playback_urls: result.result.playback_urls,
902
913
  duration: result.result.duration,
903
914
  credits_used: creditFields(result).credits_used,
904
915
  }, JSON.stringify({
905
916
  ...creditFields(result),
906
917
  session_id: gen.session_id,
907
918
  urls: result.result.urls,
919
+ playback_urls: result.result.playback_urls,
908
920
  voice: result.result.voice,
909
921
  duration: result.result.duration,
910
922
  ...(unknownVoice ? { _warning: unknownVoice } : {})
@@ -964,12 +976,14 @@ function registerGenerateTools(server, client, options = {}) {
964
976
  settings: { duration },
965
977
  reference_images: seed_reference_image_url ? [seed_reference_image_url] : [],
966
978
  urls: result.result.urls,
979
+ playback_urls: result.result.playback_urls,
967
980
  duration: result.result.duration,
968
981
  credits_used: creditFields(result).credits_used,
969
982
  }, JSON.stringify({
970
983
  ...creditFields(result),
971
984
  session_id: gen.session_id,
972
985
  urls: result.result.urls,
986
+ playback_urls: result.result.playback_urls,
973
987
  duration: result.result.duration
974
988
  }, null, 2));
975
989
  }