@kolbo/mcp 1.19.0 → 1.19.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolbo/mcp",
3
- "version": "1.19.0",
3
+ "version": "1.19.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": {
@@ -256,24 +256,29 @@ const INLINE_IMG_MAX_BYTES = 8 * 1024 * 1024; // 8 MB per image
256
256
  async function inlineImageBlocks(urls, opts = {}) {
257
257
  if (!opts || !opts.enabled) return [];
258
258
  if (!Array.isArray(urls) || urls.length === 0) return [];
259
- const out = [];
260
- for (const url of urls.slice(0, INLINE_IMG_MAX_COUNT)) {
261
- try {
262
- if (typeof url !== 'string' || !isHttpUrl(url)) continue;
263
- const res = await safeFetch(url);
264
- if (!res.ok) continue;
265
- const contentType = (res.headers.get('content-type') || '').split(';')[0].trim().toLowerCase();
266
- if (!contentType.startsWith('image/')) continue; // never embed non-images
267
- const declaredLen = Number(res.headers.get('content-length') || 0);
268
- if (declaredLen && declaredLen > INLINE_IMG_MAX_BYTES) continue;
269
- const ab = await res.arrayBuffer();
270
- if (ab.byteLength > INLINE_IMG_MAX_BYTES) continue;
271
- out.push({ type: 'image', data: Buffer.from(ab).toString('base64'), mimeType: contentType });
272
- } catch (_) {
273
- // fall back to URL-only for this image
274
- }
275
- }
276
- return out;
259
+ // Fetch the (≤4) images in parallel — they're independent, the cap already
260
+ // bounds concurrency, and this sits on the connector response path right
261
+ // after generation. Order is preserved by map-then-filter; any failure falls
262
+ // back to URL-only for that image.
263
+ const blocks = await Promise.all(
264
+ urls.slice(0, INLINE_IMG_MAX_COUNT).map(async (url) => {
265
+ try {
266
+ if (typeof url !== 'string' || !isHttpUrl(url)) return null;
267
+ const res = await safeFetch(url);
268
+ if (!res.ok) return null;
269
+ const contentType = (res.headers.get('content-type') || '').split(';')[0].trim().toLowerCase();
270
+ if (!contentType.startsWith('image/')) return null; // never embed non-images
271
+ const declaredLen = Number(res.headers.get('content-length') || 0);
272
+ if (declaredLen && declaredLen > INLINE_IMG_MAX_BYTES) return null;
273
+ const ab = await res.arrayBuffer();
274
+ if (ab.byteLength > INLINE_IMG_MAX_BYTES) return null;
275
+ return { type: 'image', data: Buffer.from(ab).toString('base64'), mimeType: contentType };
276
+ } catch (_) {
277
+ return null;
278
+ }
279
+ })
280
+ );
281
+ return blocks.filter(Boolean);
277
282
  }
278
283
 
279
284
  module.exports = {