@productmaker/mcp 1.5.0 → 1.6.0
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/dist/http.js +24 -3
- package/dist/stdio.js +24 -3
- package/package.json +2 -2
package/dist/http.js
CHANGED
|
@@ -113,7 +113,7 @@ var ApiClient = class {
|
|
|
113
113
|
};
|
|
114
114
|
|
|
115
115
|
// src/index.ts
|
|
116
|
-
var MCP_VERSION = "1.
|
|
116
|
+
var MCP_VERSION = "1.6.0";
|
|
117
117
|
|
|
118
118
|
// src/tools/tasks.ts
|
|
119
119
|
import { z as z2 } from "zod";
|
|
@@ -1216,7 +1216,18 @@ var PendingActionPayload = z2.discriminatedUnion("kind", [
|
|
|
1216
1216
|
z2.object({
|
|
1217
1217
|
kind: z2.literal("product_reference_confirmation"),
|
|
1218
1218
|
userChoice: ProductReferenceUserChoiceEnum,
|
|
1219
|
-
confirmedProductNames: z2.array(z2.string().min(1).max(120)).min(2).max(8).optional()
|
|
1219
|
+
confirmedProductNames: z2.array(z2.string().min(1).max(120)).min(2).max(8).optional(),
|
|
1220
|
+
// SCOPED multi-scene opt-in — the ONLY way STANDARD ("Multiescena") is
|
|
1221
|
+
// reachable via MCP. Valid ONLY together with userChoice='variants' (same
|
|
1222
|
+
// product in several colors): renders one shot per color and stitches them,
|
|
1223
|
+
// so every variant color is shown off. Ignored for any other userChoice.
|
|
1224
|
+
// We deliberately do NOT expose the raw `standard` tier on the MCP video
|
|
1225
|
+
// knobs (VideoTierEnum stays {basic}) because a general tier dial with no
|
|
1226
|
+
// cost surface caused a prod over-spend incident (2026-07-04); this flag is
|
|
1227
|
+
// safe because multi-scene IS the intended render for a color variant set,
|
|
1228
|
+
// not a blind quality upsell. Maps to `videoTier: 'standard'` on the
|
|
1229
|
+
// confirm call; the backend re-gates it (variants + variant_set only).
|
|
1230
|
+
useMultiSceneShowcase: z2.boolean().optional().describe('Opcional (SOLO con userChoice="variants"). true = render Multiescena: una toma por color, mostrando todas las variantes, hasta 30s. Se factura POR ESCENA (m\xE1s caro que el render normal de una sola toma) \u2014 AV\xCDSALE del mayor costo al usuario antes de activarlo. Omitir = render est\xE1ndar de una sola toma. Se ignora si userChoice no es "variants".')
|
|
1220
1231
|
}),
|
|
1221
1232
|
z2.object({
|
|
1222
1233
|
kind: z2.literal("angle_review_approval"),
|
|
@@ -1234,6 +1245,10 @@ var ResolvePendingActionInput = z2.object({
|
|
|
1234
1245
|
taskId: z2.string().min(1),
|
|
1235
1246
|
action: PendingActionPayload
|
|
1236
1247
|
}).strict();
|
|
1248
|
+
function resolveVariantConfirmVideoTier(action) {
|
|
1249
|
+
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
1250
|
+
}
|
|
1251
|
+
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
1237
1252
|
var StatusForResolveSchema = z2.object({
|
|
1238
1253
|
pendingUserAction: z2.object({
|
|
1239
1254
|
kind: z2.string(),
|
|
@@ -1368,7 +1383,7 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
|
|
|
1368
1383
|
throw translateError(e);
|
|
1369
1384
|
}
|
|
1370
1385
|
});
|
|
1371
|
-
server.tool("resolve_pending_action", 'Resuelve una acci\xF3n que el pipeline est\xE1 esperando del usuario. La llamas cuando `get_task_status` devuelve `pendingUserAction` (sin esto la tarea NUNCA avanza por m\xE1s que esperes). El `action.kind` que mandas DEBE coincidir con el `pendingUserAction.kind` que viste en el status \u2014 es el contrato de simetr\xEDa que mantiene este tool como \xFAnica superficie de resoluci\xF3n de gates.\n\nKINDS soportados hoy:\n\n\u2022 `product_reference_confirmation` \u2014 el clasificador no est\xE1 seguro si las fotos son variantes del mismo producto o productos distintos. Payload: `userChoice` \u2208 { "same_product" (mismo producto, fotos son s\xF3lo \xE1ngulos distintos), "variants" (mismo producto, distintos colores/tallas/sabores), "combo_distinct" (son 2 productos distintos vendidos juntos como combo \u2014 marca la tarea como combo), "different_products" (productos distintos y el usuario quiere generar s\xF3lo uno \u2014 el backend bloquea hasta que selecciones im\xE1genes de un solo producto; normalmente NO es la respuesta correcta para destrabar) }. PREG\xDANTALE al usuario antes de invocar \u2014 `pendingUserAction.targetProductLabel` y `reason` te dan contexto para formularle la pregunta en lenguaje natural. Usa SOLO valores presentes en `pendingUserAction.options`. Si el status trae `proposedProductNames` (lista propuesta de nombres), el combo es INCIERTO: mu\xE9strale los nombres al usuario y, si confirma que son productos distintos, manda `userChoice: "combo_distinct"` JUNTO CON `confirmedProductNames` (la lista confirmada o editada, 2-8 nombres) para separarlo en productos distintos; si el usuario dice que es un solo producto, manda `userChoice: "same_product"` (sin `confirmedProductNames`).\n\n\u2022 `angle_review_approval` \u2014 el usuario opto por `pauseForAngleReview: true` al crear el creativo (en `generate_image_creatives`, `generate_video_creative` o `generate_landing`). La IA ya gener\xF3 el \xE1ngulo + pain points + benefits + features y la tarea est\xE1 pausada esperando que el usuario apruebe o edite antes de renderizar. Lee `customAngleDraft`, `painPointsDraft`, `benefitsDraft`, `featuresDraft` del `pendingUserAction` para mostr\xE1rselos al usuario en lenguaje natural ("la IA propuso este \xE1ngulo: ... \xBFlo apruebas o cambias algo?"). Payload (TODOS opcionales \u2014 sin nada = aprobar tal cual; con campos = aprobar con ediciones): `customAngle` (override del \xE1ngulo), `painPoints`, `benefits`, `features` (array de 1-10 bullets). Llamar sin ning\xFAn campo es v\xE1lido y aprueba el draft sin cambios.\n\nFuturos kinds (no implementados a\xFAn) se agregar\xE1n como nuevas variantes del `action` discriminated union \u2014 el flujo "lee kind del status \u2192 manda mismo kind aqu\xED" sigue igual.', ResolvePendingActionInput.shape, async (input) => {
|
|
1386
|
+
server.tool("resolve_pending_action", 'Resuelve una acci\xF3n que el pipeline est\xE1 esperando del usuario. La llamas cuando `get_task_status` devuelve `pendingUserAction` (sin esto la tarea NUNCA avanza por m\xE1s que esperes). El `action.kind` que mandas DEBE coincidir con el `pendingUserAction.kind` que viste en el status \u2014 es el contrato de simetr\xEDa que mantiene este tool como \xFAnica superficie de resoluci\xF3n de gates.\n\nKINDS soportados hoy:\n\n\u2022 `product_reference_confirmation` \u2014 el clasificador no est\xE1 seguro si las fotos son variantes del mismo producto o productos distintos. Payload: `userChoice` \u2208 { "same_product" (mismo producto, fotos son s\xF3lo \xE1ngulos distintos), "variants" (mismo producto, distintos colores/tallas/sabores), "combo_distinct" (son 2 productos distintos vendidos juntos como combo \u2014 marca la tarea como combo), "different_products" (productos distintos y el usuario quiere generar s\xF3lo uno \u2014 el backend bloquea hasta que selecciones im\xE1genes de un solo producto; normalmente NO es la respuesta correcta para destrabar) }. PREG\xDANTALE al usuario antes de invocar \u2014 `pendingUserAction.targetProductLabel` y `reason` te dan contexto para formularle la pregunta en lenguaje natural. Usa SOLO valores presentes en `pendingUserAction.options`. Si el status trae `proposedProductNames` (lista propuesta de nombres), el combo es INCIERTO: mu\xE9strale los nombres al usuario y, si confirma que son productos distintos, manda `userChoice: "combo_distinct"` JUNTO CON `confirmedProductNames` (la lista confirmada o editada, 2-8 nombres) para separarlo en productos distintos; si el usuario dice que es un solo producto, manda `userChoice: "same_product"` (sin `confirmedProductNames`). Cuando el producto son VARIANTES DE COLOR (mismo producto, distintos colores) puedes ofrecer un video "Multiescena" que muestra una toma por color: manda `userChoice: "variants"` JUNTO CON `useMultiSceneShowcase: true`. AVISA al usuario que ese modo se factura por escena (m\xE1s caro que el render normal de una sola toma) antes de activarlo; si prefiere el render normal, manda solo `userChoice: "variants"` sin el flag.\n\n\u2022 `angle_review_approval` \u2014 el usuario opto por `pauseForAngleReview: true` al crear el creativo (en `generate_image_creatives`, `generate_video_creative` o `generate_landing`). La IA ya gener\xF3 el \xE1ngulo + pain points + benefits + features y la tarea est\xE1 pausada esperando que el usuario apruebe o edite antes de renderizar. Lee `customAngleDraft`, `painPointsDraft`, `benefitsDraft`, `featuresDraft` del `pendingUserAction` para mostr\xE1rselos al usuario en lenguaje natural ("la IA propuso este \xE1ngulo: ... \xBFlo apruebas o cambias algo?"). Payload (TODOS opcionales \u2014 sin nada = aprobar tal cual; con campos = aprobar con ediciones): `customAngle` (override del \xE1ngulo), `painPoints`, `benefits`, `features` (array de 1-10 bullets). Llamar sin ning\xFAn campo es v\xE1lido y aprueba el draft sin cambios.\n\nFuturos kinds (no implementados a\xFAn) se agregar\xE1n como nuevas variantes del `action` discriminated union \u2014 el flujo "lee kind del status \u2192 manda mismo kind aqu\xED" sigue igual.', ResolvePendingActionInput.shape, async (input) => {
|
|
1372
1387
|
try {
|
|
1373
1388
|
const raw = await api.getJson(`/v1/status/${encodeURIComponent(input.taskId)}`);
|
|
1374
1389
|
const status = StatusForResolveSchema.parse(raw);
|
|
@@ -1397,6 +1412,12 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
|
|
|
1397
1412
|
},
|
|
1398
1413
|
...input.action.confirmedProductNames ? {
|
|
1399
1414
|
confirmedProductNames: input.action.confirmedProductNames
|
|
1415
|
+
} : {},
|
|
1416
|
+
// Multi-scene color showcase → upgrade to STANDARD. Gated to the
|
|
1417
|
+
// variants choice client-side so the wire body stays coherent; the
|
|
1418
|
+
// backend re-gates on variant_set grouping.
|
|
1419
|
+
...resolveVariantConfirmVideoTier(input.action) === "standard" ? {
|
|
1420
|
+
videoTier: "standard"
|
|
1400
1421
|
} : {}
|
|
1401
1422
|
});
|
|
1402
1423
|
return asText(r);
|
package/dist/stdio.js
CHANGED
|
@@ -110,7 +110,7 @@ var ApiClient = class {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
// src/index.ts
|
|
113
|
-
var MCP_VERSION = "1.
|
|
113
|
+
var MCP_VERSION = "1.6.0";
|
|
114
114
|
|
|
115
115
|
// src/tools/tasks.ts
|
|
116
116
|
import { z as z2 } from "zod";
|
|
@@ -1172,7 +1172,18 @@ var PendingActionPayload = z2.discriminatedUnion("kind", [
|
|
|
1172
1172
|
z2.object({
|
|
1173
1173
|
kind: z2.literal("product_reference_confirmation"),
|
|
1174
1174
|
userChoice: ProductReferenceUserChoiceEnum,
|
|
1175
|
-
confirmedProductNames: z2.array(z2.string().min(1).max(120)).min(2).max(8).optional()
|
|
1175
|
+
confirmedProductNames: z2.array(z2.string().min(1).max(120)).min(2).max(8).optional(),
|
|
1176
|
+
// SCOPED multi-scene opt-in — the ONLY way STANDARD ("Multiescena") is
|
|
1177
|
+
// reachable via MCP. Valid ONLY together with userChoice='variants' (same
|
|
1178
|
+
// product in several colors): renders one shot per color and stitches them,
|
|
1179
|
+
// so every variant color is shown off. Ignored for any other userChoice.
|
|
1180
|
+
// We deliberately do NOT expose the raw `standard` tier on the MCP video
|
|
1181
|
+
// knobs (VideoTierEnum stays {basic}) because a general tier dial with no
|
|
1182
|
+
// cost surface caused a prod over-spend incident (2026-07-04); this flag is
|
|
1183
|
+
// safe because multi-scene IS the intended render for a color variant set,
|
|
1184
|
+
// not a blind quality upsell. Maps to `videoTier: 'standard'` on the
|
|
1185
|
+
// confirm call; the backend re-gates it (variants + variant_set only).
|
|
1186
|
+
useMultiSceneShowcase: z2.boolean().optional().describe('Opcional (SOLO con userChoice="variants"). true = render Multiescena: una toma por color, mostrando todas las variantes, hasta 30s. Se factura POR ESCENA (m\xE1s caro que el render normal de una sola toma) \u2014 AV\xCDSALE del mayor costo al usuario antes de activarlo. Omitir = render est\xE1ndar de una sola toma. Se ignora si userChoice no es "variants".')
|
|
1176
1187
|
}),
|
|
1177
1188
|
z2.object({
|
|
1178
1189
|
kind: z2.literal("angle_review_approval"),
|
|
@@ -1190,6 +1201,10 @@ var ResolvePendingActionInput = z2.object({
|
|
|
1190
1201
|
taskId: z2.string().min(1),
|
|
1191
1202
|
action: PendingActionPayload
|
|
1192
1203
|
}).strict();
|
|
1204
|
+
function resolveVariantConfirmVideoTier(action) {
|
|
1205
|
+
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
1206
|
+
}
|
|
1207
|
+
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
1193
1208
|
var StatusForResolveSchema = z2.object({
|
|
1194
1209
|
pendingUserAction: z2.object({
|
|
1195
1210
|
kind: z2.string(),
|
|
@@ -1324,7 +1339,7 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
|
|
|
1324
1339
|
throw translateError(e);
|
|
1325
1340
|
}
|
|
1326
1341
|
});
|
|
1327
|
-
server.tool("resolve_pending_action", 'Resuelve una acci\xF3n que el pipeline est\xE1 esperando del usuario. La llamas cuando `get_task_status` devuelve `pendingUserAction` (sin esto la tarea NUNCA avanza por m\xE1s que esperes). El `action.kind` que mandas DEBE coincidir con el `pendingUserAction.kind` que viste en el status \u2014 es el contrato de simetr\xEDa que mantiene este tool como \xFAnica superficie de resoluci\xF3n de gates.\n\nKINDS soportados hoy:\n\n\u2022 `product_reference_confirmation` \u2014 el clasificador no est\xE1 seguro si las fotos son variantes del mismo producto o productos distintos. Payload: `userChoice` \u2208 { "same_product" (mismo producto, fotos son s\xF3lo \xE1ngulos distintos), "variants" (mismo producto, distintos colores/tallas/sabores), "combo_distinct" (son 2 productos distintos vendidos juntos como combo \u2014 marca la tarea como combo), "different_products" (productos distintos y el usuario quiere generar s\xF3lo uno \u2014 el backend bloquea hasta que selecciones im\xE1genes de un solo producto; normalmente NO es la respuesta correcta para destrabar) }. PREG\xDANTALE al usuario antes de invocar \u2014 `pendingUserAction.targetProductLabel` y `reason` te dan contexto para formularle la pregunta en lenguaje natural. Usa SOLO valores presentes en `pendingUserAction.options`. Si el status trae `proposedProductNames` (lista propuesta de nombres), el combo es INCIERTO: mu\xE9strale los nombres al usuario y, si confirma que son productos distintos, manda `userChoice: "combo_distinct"` JUNTO CON `confirmedProductNames` (la lista confirmada o editada, 2-8 nombres) para separarlo en productos distintos; si el usuario dice que es un solo producto, manda `userChoice: "same_product"` (sin `confirmedProductNames`).\n\n\u2022 `angle_review_approval` \u2014 el usuario opto por `pauseForAngleReview: true` al crear el creativo (en `generate_image_creatives`, `generate_video_creative` o `generate_landing`). La IA ya gener\xF3 el \xE1ngulo + pain points + benefits + features y la tarea est\xE1 pausada esperando que el usuario apruebe o edite antes de renderizar. Lee `customAngleDraft`, `painPointsDraft`, `benefitsDraft`, `featuresDraft` del `pendingUserAction` para mostr\xE1rselos al usuario en lenguaje natural ("la IA propuso este \xE1ngulo: ... \xBFlo apruebas o cambias algo?"). Payload (TODOS opcionales \u2014 sin nada = aprobar tal cual; con campos = aprobar con ediciones): `customAngle` (override del \xE1ngulo), `painPoints`, `benefits`, `features` (array de 1-10 bullets). Llamar sin ning\xFAn campo es v\xE1lido y aprueba el draft sin cambios.\n\nFuturos kinds (no implementados a\xFAn) se agregar\xE1n como nuevas variantes del `action` discriminated union \u2014 el flujo "lee kind del status \u2192 manda mismo kind aqu\xED" sigue igual.', ResolvePendingActionInput.shape, async (input) => {
|
|
1342
|
+
server.tool("resolve_pending_action", 'Resuelve una acci\xF3n que el pipeline est\xE1 esperando del usuario. La llamas cuando `get_task_status` devuelve `pendingUserAction` (sin esto la tarea NUNCA avanza por m\xE1s que esperes). El `action.kind` que mandas DEBE coincidir con el `pendingUserAction.kind` que viste en el status \u2014 es el contrato de simetr\xEDa que mantiene este tool como \xFAnica superficie de resoluci\xF3n de gates.\n\nKINDS soportados hoy:\n\n\u2022 `product_reference_confirmation` \u2014 el clasificador no est\xE1 seguro si las fotos son variantes del mismo producto o productos distintos. Payload: `userChoice` \u2208 { "same_product" (mismo producto, fotos son s\xF3lo \xE1ngulos distintos), "variants" (mismo producto, distintos colores/tallas/sabores), "combo_distinct" (son 2 productos distintos vendidos juntos como combo \u2014 marca la tarea como combo), "different_products" (productos distintos y el usuario quiere generar s\xF3lo uno \u2014 el backend bloquea hasta que selecciones im\xE1genes de un solo producto; normalmente NO es la respuesta correcta para destrabar) }. PREG\xDANTALE al usuario antes de invocar \u2014 `pendingUserAction.targetProductLabel` y `reason` te dan contexto para formularle la pregunta en lenguaje natural. Usa SOLO valores presentes en `pendingUserAction.options`. Si el status trae `proposedProductNames` (lista propuesta de nombres), el combo es INCIERTO: mu\xE9strale los nombres al usuario y, si confirma que son productos distintos, manda `userChoice: "combo_distinct"` JUNTO CON `confirmedProductNames` (la lista confirmada o editada, 2-8 nombres) para separarlo en productos distintos; si el usuario dice que es un solo producto, manda `userChoice: "same_product"` (sin `confirmedProductNames`). Cuando el producto son VARIANTES DE COLOR (mismo producto, distintos colores) puedes ofrecer un video "Multiescena" que muestra una toma por color: manda `userChoice: "variants"` JUNTO CON `useMultiSceneShowcase: true`. AVISA al usuario que ese modo se factura por escena (m\xE1s caro que el render normal de una sola toma) antes de activarlo; si prefiere el render normal, manda solo `userChoice: "variants"` sin el flag.\n\n\u2022 `angle_review_approval` \u2014 el usuario opto por `pauseForAngleReview: true` al crear el creativo (en `generate_image_creatives`, `generate_video_creative` o `generate_landing`). La IA ya gener\xF3 el \xE1ngulo + pain points + benefits + features y la tarea est\xE1 pausada esperando que el usuario apruebe o edite antes de renderizar. Lee `customAngleDraft`, `painPointsDraft`, `benefitsDraft`, `featuresDraft` del `pendingUserAction` para mostr\xE1rselos al usuario en lenguaje natural ("la IA propuso este \xE1ngulo: ... \xBFlo apruebas o cambias algo?"). Payload (TODOS opcionales \u2014 sin nada = aprobar tal cual; con campos = aprobar con ediciones): `customAngle` (override del \xE1ngulo), `painPoints`, `benefits`, `features` (array de 1-10 bullets). Llamar sin ning\xFAn campo es v\xE1lido y aprueba el draft sin cambios.\n\nFuturos kinds (no implementados a\xFAn) se agregar\xE1n como nuevas variantes del `action` discriminated union \u2014 el flujo "lee kind del status \u2192 manda mismo kind aqu\xED" sigue igual.', ResolvePendingActionInput.shape, async (input) => {
|
|
1328
1343
|
try {
|
|
1329
1344
|
const raw = await api.getJson(`/v1/status/${encodeURIComponent(input.taskId)}`);
|
|
1330
1345
|
const status = StatusForResolveSchema.parse(raw);
|
|
@@ -1353,6 +1368,12 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
|
|
|
1353
1368
|
},
|
|
1354
1369
|
...input.action.confirmedProductNames ? {
|
|
1355
1370
|
confirmedProductNames: input.action.confirmedProductNames
|
|
1371
|
+
} : {},
|
|
1372
|
+
// Multi-scene color showcase → upgrade to STANDARD. Gated to the
|
|
1373
|
+
// variants choice client-side so the wire body stays coherent; the
|
|
1374
|
+
// backend re-gates on variant_set grouping.
|
|
1375
|
+
...resolveVariantConfirmVideoTier(input.action) === "standard" ? {
|
|
1376
|
+
videoTier: "standard"
|
|
1356
1377
|
} : {}
|
|
1357
1378
|
});
|
|
1358
1379
|
return asText(r);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@productmaker/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Product Maker MCP server — connect Claude Desktop, Claude Code, ChatGPT, or Gemini to Product Maker AI to generate dropshipping landing pages, UGC videos, and ad creatives, and publish to Shopify and Meta Ads from your AI assistant.",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"msw": "^2.4.0",
|
|
61
61
|
"tsup": "^8.3.0",
|
|
62
62
|
"tsx": "^4.16.0",
|
|
63
|
-
"typescript": "^
|
|
63
|
+
"typescript": "^7.0.2",
|
|
64
64
|
"vitest": "^2.1.9",
|
|
65
65
|
"@packages/types": "0.1.0"
|
|
66
66
|
},
|