@kolbo/mcp 1.87.8 → 1.87.9

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.87.8",
3
+ "version": "1.87.9",
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": {
@@ -210,6 +210,75 @@ const BRIDGE_JS = `
210
210
  },
211
211
  hostContext: function () { return hostContext; }
212
212
  };
213
+
214
+ // ChatGPT (OpenAI Apps SDK) host. It mounts the same iframe but speaks no
215
+ // JSON-RPC: tool input / output / theme arrive as window.openai globals plus
216
+ // an 'openai:set_globals' DOM event, and actions are methods on that object.
217
+ // Without this adapter the card rendered, waited for a tool-input that never
218
+ // came, and sat on "Preparing" with no prompt, no settings and no result —
219
+ // even after the tool had returned. Everything here maps onto the same
220
+ // callbacks the JSON-RPC path drives, so widgets need no host-specific code.
221
+ var oa = window.openai && typeof window.openai === 'object' ? window.openai : null;
222
+ if (oa) {
223
+ var oaInputSeen = false, oaOutputSeen = false;
224
+ var oaName = function () {
225
+ var meta = oa.toolResponseMetadata || {};
226
+ return oa.toolName || meta['kolbo/tool'] || (oa.toolOutput && oa.toolOutput.tool) || undefined;
227
+ };
228
+ var oaSync = function () {
229
+ var name = oaName();
230
+ // Same shape claude.ai hands ready(): toolInfo.tool.name is what widgets read.
231
+ hostContext = { theme: oa.theme, displayMode: oa.displayMode, toolInfo: { name: name, tool: { name: name }, arguments: oa.toolInput || {} } };
232
+ if (!initialized) {
233
+ initialized = true;
234
+ queue = [];
235
+ readyFns.forEach(function (f) { try { f(hostContext); } catch (e) {} });
236
+ } else {
237
+ themeFns.forEach(function (f) { try { f(hostContext); } catch (e) {} });
238
+ }
239
+ if (oa.toolInput && !oaInputSeen) {
240
+ oaInputSeen = true;
241
+ toolInputFns.forEach(function (f) { try { f(oa.toolInput, { name: oaName(), arguments: oa.toolInput }); } catch (e) {} });
242
+ }
243
+ if (oa.toolOutput && !oaOutputSeen) {
244
+ oaOutputSeen = true;
245
+ var res = { structuredContent: oa.toolOutput, _meta: oa.toolResponseMetadata || {} };
246
+ toolResultFns.forEach(function (f) { try { f(res); } catch (e) {} });
247
+ }
248
+ };
249
+ var oaCall = function (method) { return typeof oa[method] === 'function'; };
250
+ window.kolbo.callTool = function (name, args) {
251
+ if (!oaCall('callTool')) return Promise.reject(new Error('host cannot call tools'));
252
+ return Promise.resolve(oa.callTool(name, args || {})).then(function (r) {
253
+ // The SDK resolves with the CallToolResult (content + structuredContent);
254
+ // some builds unwrap to the structured payload — normalise either.
255
+ if (r && (r.structuredContent || r.content)) return r;
256
+ return { structuredContent: r, content: [] };
257
+ });
258
+ };
259
+ window.kolbo.sendMessage = function (text) {
260
+ return oaCall('sendFollowUpMessage') ? Promise.resolve(oa.sendFollowUpMessage({ prompt: text })) : Promise.reject(new Error('unsupported'));
261
+ };
262
+ window.kolbo.insertText = function () { return Promise.reject(new Error('unsupported')); };
263
+ window.kolbo.openLink = function (url) {
264
+ return oaCall('openExternal') ? Promise.resolve(oa.openExternal({ href: url })) : Promise.resolve(window.open(url, '_blank'));
265
+ };
266
+ window.kolbo.copyText = function (t) {
267
+ return navigator.clipboard && navigator.clipboard.writeText ? navigator.clipboard.writeText(t) : Promise.reject(new Error('unsupported'));
268
+ };
269
+ window.kolbo.attachMedia = function () { return Promise.reject(new Error('unsupported')); };
270
+ window.kolbo.updateModelContext = function () { return Promise.resolve(); };
271
+ window.kolbo.requestDisplayMode = function (mode) {
272
+ if (!oaCall('requestDisplayMode')) return Promise.resolve({ mode: 'inline' });
273
+ return Promise.resolve(oa.requestDisplayMode({ mode: mode })).then(function (r) { return { mode: (r && r.mode) || mode }; });
274
+ };
275
+ window.addEventListener('openai:set_globals', oaSync);
276
+ // Deferred: the widget's own script (which registers ready/onToolInput/
277
+ // onToolResult) runs AFTER this bridge block in the same document, and a
278
+ // synchronous sync here fired into empty listener lists and marked the
279
+ // input/output as seen.
280
+ setTimeout(oaSync, 0);
281
+ }
213
282
  })();
214
283
  `;
215
284
 
package/src/apps/index.js CHANGED
@@ -71,12 +71,12 @@ const WIDGET_CSP = {
71
71
  // Public hosts owned by Kolbo.
72
72
  'https://api.kolbo.ai',
73
73
  'https://app.kolbo.ai',
74
- 'https://cdn.kolbo.ai',
75
- // Preset thumbnails and library media live on the media-* hosts (prod
76
- // presets still reference media-dev); without these every preset tile
77
- // rendered as a black box. All three are on kolbo-api's download allowlist.
78
- 'https://media.kolbo.ai',
79
- 'https://media-staging.kolbo.ai',
74
+ 'https://cdn.kolbo.ai',
75
+ // Preset thumbnails and library media live on the media-* hosts (prod
76
+ // presets still reference media-dev); without these every preset tile
77
+ // rendered as a black box. All three are on kolbo-api's download allowlist.
78
+ 'https://media.kolbo.ai',
79
+ 'https://media-staging.kolbo.ai',
80
80
  'https://media-dev.kolbo.ai',
81
81
  ...KOLBO_MEDIA_DOMAINS,
82
82
  'https://kolbo-general-media.fra1.digitaloceanspaces.com',
@@ -201,7 +201,9 @@ function uiResult(uri, text, structured) {
201
201
  return {
202
202
  content: [{ type: 'text', text }],
203
203
  structuredContent: structured,
204
- _meta: uiMeta(uri),
204
+ // 'kolbo/tool' reaches ChatGPT widgets as toolResponseMetadata — that host
205
+ // never tells the iframe which tool ran, and the card title depends on it.
206
+ _meta: { ...uiMeta(uri), ...(structured && structured.tool ? { 'kolbo/tool': structured.tool } : {}) },
205
207
  };
206
208
  }
207
209