@productmaker/mcp 12.1.1 → 12.1.2
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/README.md +7 -0
- package/dist/http.js +1 -1
- package/dist/stdio.js +1 -1
- package/dist/ui/task-results-app.html +71 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -309,6 +309,13 @@ The `base64` field was removed. MCP JSON-RPC transports truncate large tool argu
|
|
|
309
309
|
|
|
310
310
|
## Version history
|
|
311
311
|
|
|
312
|
+
### 12.1.2 — ChatGPT result metadata compatibility
|
|
313
|
+
|
|
314
|
+
- The result viewer reads ChatGPT's canonical `toolResponseMetadata` envelopes as well as direct metadata and standard MCP App notifications. Initial results and later updates retain the same media validation and cleanup.
|
|
315
|
+
- The bridge answers trusted parent JSON-RPC pings and accepts initialization only from its matching response, once. A host request reusing the same ID cannot initialize it.
|
|
316
|
+
- After changing a development connector's tool descriptors, refresh its tools in ChatGPT. A successful server deployment alone does not prove that the installed connector has discovered the new viewer.
|
|
317
|
+
- Hosted playback remains a separate release check; local bridge fixtures do not establish it.
|
|
318
|
+
|
|
312
319
|
### 12.1.1 — Real media in chat and service landing quote parity
|
|
313
320
|
|
|
314
321
|
- `get_task_status` attaches a read-only MCP App with the delivered ProductMaker images and playable videos, plus original native image bytes and protected download fallbacks. It never generates replacement media.
|
package/dist/http.js
CHANGED
|
@@ -25883,7 +25883,7 @@ var ApiClient = class {
|
|
|
25883
25883
|
};
|
|
25884
25884
|
|
|
25885
25885
|
// src/index.ts
|
|
25886
|
-
var MCP_VERSION = "12.1.
|
|
25886
|
+
var MCP_VERSION = "12.1.2";
|
|
25887
25887
|
|
|
25888
25888
|
// src/meta-upload-app.ts
|
|
25889
25889
|
import { readFileSync } from "fs";
|
package/dist/stdio.js
CHANGED
|
@@ -24210,7 +24210,7 @@ var ApiClient = class {
|
|
|
24210
24210
|
};
|
|
24211
24211
|
|
|
24212
24212
|
// src/index.ts
|
|
24213
|
-
var MCP_VERSION = "12.1.
|
|
24213
|
+
var MCP_VERSION = "12.1.2";
|
|
24214
24214
|
|
|
24215
24215
|
// src/meta-upload-app.ts
|
|
24216
24216
|
import { readFileSync } from "fs";
|
|
@@ -117,9 +117,18 @@
|
|
|
117
117
|
const media = document.getElementById("media");
|
|
118
118
|
let receivedResult = false;
|
|
119
119
|
let hostReady = false;
|
|
120
|
+
let initializationSettled = false;
|
|
120
121
|
let disposed = false;
|
|
122
|
+
const initializeRequestId = 1;
|
|
121
123
|
const isRecord = (value) =>
|
|
122
124
|
value !== null && typeof value === "object" && !Array.isArray(value);
|
|
125
|
+
const resultStates = new Set([
|
|
126
|
+
"ready",
|
|
127
|
+
"empty",
|
|
128
|
+
"pending",
|
|
129
|
+
"awaiting_review",
|
|
130
|
+
"error",
|
|
131
|
+
]);
|
|
123
132
|
const safeUrl = (value) => {
|
|
124
133
|
if (typeof value !== "string") return null;
|
|
125
134
|
try {
|
|
@@ -257,9 +266,7 @@
|
|
|
257
266
|
!isRecord(result) ||
|
|
258
267
|
result.isError ||
|
|
259
268
|
!isRecord(data) ||
|
|
260
|
-
!
|
|
261
|
-
data.state,
|
|
262
|
-
)
|
|
269
|
+
!resultStates.has(data.state)
|
|
263
270
|
) {
|
|
264
271
|
setState(
|
|
265
272
|
"error",
|
|
@@ -321,10 +328,44 @@
|
|
|
321
328
|
}
|
|
322
329
|
reportSize();
|
|
323
330
|
}
|
|
331
|
+
function applyOpenAiMetadata(metadata) {
|
|
332
|
+
if (!isRecord(metadata) || disposed) return;
|
|
333
|
+
// ChatGPT preserves the MCP envelope in toolResponseMetadata:
|
|
334
|
+
// https://developers.openai.com/plugins/reference#capabilities
|
|
335
|
+
// Read only the known wrappers; never search arbitrary nested data.
|
|
336
|
+
const callResult = isRecord(metadata.call_tool_result)
|
|
337
|
+
? metadata.call_tool_result
|
|
338
|
+
: null;
|
|
339
|
+
const candidates = [
|
|
340
|
+
metadata.mcp_tool_result,
|
|
341
|
+
callResult?.mcp_tool_result,
|
|
342
|
+
callResult,
|
|
343
|
+
metadata,
|
|
344
|
+
{ _meta: metadata },
|
|
345
|
+
];
|
|
346
|
+
const result = candidates.find((candidate) => {
|
|
347
|
+
if (!isRecord(candidate)) return false;
|
|
348
|
+
if (candidate.isError === true) return true;
|
|
349
|
+
const data = isRecord(candidate._meta)
|
|
350
|
+
? candidate._meta.taskResults
|
|
351
|
+
: null;
|
|
352
|
+
return (
|
|
353
|
+
isRecord(data) &&
|
|
354
|
+
resultStates.has(data.state) &&
|
|
355
|
+
Array.isArray(data.images) &&
|
|
356
|
+
Array.isArray(data.videos) &&
|
|
357
|
+
Array.isArray(data.links)
|
|
358
|
+
);
|
|
359
|
+
});
|
|
360
|
+
// Globals can arrive before a result or with unrelated host updates.
|
|
361
|
+
// Keep delivered playback until a valid result or explicit error.
|
|
362
|
+
if (result) applyResult(result);
|
|
363
|
+
}
|
|
324
364
|
function handleMessage(event) {
|
|
325
365
|
if (
|
|
326
366
|
event.source !== window.parent ||
|
|
327
367
|
!isRecord(event.data) ||
|
|
368
|
+
event.data.jsonrpc !== "2.0" ||
|
|
328
369
|
disposed
|
|
329
370
|
)
|
|
330
371
|
return;
|
|
@@ -343,7 +384,30 @@
|
|
|
343
384
|
);
|
|
344
385
|
}
|
|
345
386
|
disposed = true;
|
|
346
|
-
} else if (message.
|
|
387
|
+
} else if (message.method === "ping") {
|
|
388
|
+
if (
|
|
389
|
+
(typeof message.id === "string" ||
|
|
390
|
+
Number.isInteger(message.id)) &&
|
|
391
|
+
!Object.prototype.hasOwnProperty.call(message, "result") &&
|
|
392
|
+
!Object.prototype.hasOwnProperty.call(message, "error") &&
|
|
393
|
+
(message.params === undefined || isRecord(message.params))
|
|
394
|
+
)
|
|
395
|
+
window.parent.postMessage(
|
|
396
|
+
{ jsonrpc: "2.0", id: message.id, result: {} },
|
|
397
|
+
"*",
|
|
398
|
+
);
|
|
399
|
+
} else if (
|
|
400
|
+
!initializationSettled &&
|
|
401
|
+
message.id === initializeRequestId &&
|
|
402
|
+
!Object.prototype.hasOwnProperty.call(message, "method") &&
|
|
403
|
+
((isRecord(message.result) &&
|
|
404
|
+
!Object.prototype.hasOwnProperty.call(message, "error")) ||
|
|
405
|
+
(isRecord(message.error) &&
|
|
406
|
+
Number.isInteger(message.error.code) &&
|
|
407
|
+
typeof message.error.message === "string" &&
|
|
408
|
+
!Object.prototype.hasOwnProperty.call(message, "result")))
|
|
409
|
+
) {
|
|
410
|
+
initializationSettled = true;
|
|
347
411
|
window.clearTimeout(initializeTimeout);
|
|
348
412
|
if (message.error) {
|
|
349
413
|
if (!receivedResult) applyResult({ isError: true });
|
|
@@ -366,7 +430,7 @@
|
|
|
366
430
|
"toolResponseMetadata",
|
|
367
431
|
)
|
|
368
432
|
)
|
|
369
|
-
|
|
433
|
+
applyOpenAiMetadata(globals.toolResponseMetadata);
|
|
370
434
|
}
|
|
371
435
|
const resultTimeout = window.setTimeout(() => {
|
|
372
436
|
if (!receivedResult) applyResult({ isError: true });
|
|
@@ -380,7 +444,7 @@
|
|
|
380
444
|
window.parent.postMessage(
|
|
381
445
|
{
|
|
382
446
|
jsonrpc: "2.0",
|
|
383
|
-
id:
|
|
447
|
+
id: initializeRequestId,
|
|
384
448
|
method: "ui/initialize",
|
|
385
449
|
params: {
|
|
386
450
|
appInfo: { name: "ProductMaker task results", version: "1.0.0" },
|
|
@@ -390,8 +454,7 @@
|
|
|
390
454
|
},
|
|
391
455
|
"*",
|
|
392
456
|
);
|
|
393
|
-
|
|
394
|
-
applyResult({ _meta: window.openai.toolResponseMetadata });
|
|
457
|
+
applyOpenAiMetadata(window.openai?.toolResponseMetadata);
|
|
395
458
|
})();
|
|
396
459
|
</script>
|
|
397
460
|
</body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@productmaker/mcp",
|
|
3
|
-
"version": "12.1.
|
|
3
|
+
"version": "12.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "ProductMaker MCP server — cost products, generate landing pages, UGC videos, and ad creatives, and publish to Shopify, Meta Ads, and TikTok Ads.",
|