@productmaker/mcp 1.6.0 → 1.7.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 CHANGED
@@ -113,7 +113,7 @@ var ApiClient = class {
113
113
  };
114
114
 
115
115
  // src/index.ts
116
- var MCP_VERSION = "1.6.0";
116
+ var MCP_VERSION = "1.7.0";
117
117
 
118
118
  // src/tools/tasks.ts
119
119
  import { z as z2 } from "zod";
@@ -396,6 +396,15 @@ import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
396
396
  import { z } from "zod";
397
397
  var Lang = z.string().min(2).max(10);
398
398
  var Country = z.string().min(2).max(3);
399
+ var LandingStrategyEnum = z.enum([
400
+ "auto",
401
+ "classic",
402
+ "pain_solution",
403
+ "social_proof",
404
+ "benefits_clarity",
405
+ "offer_value",
406
+ "lifestyle_identity"
407
+ ]);
399
408
  var VideoPresetEnum = z.enum([
400
409
  "auto",
401
410
  "ugc_dynamic",
@@ -584,7 +593,7 @@ function isRecord(v) {
584
593
  }
585
594
  __name(isRecord, "isRecord");
586
595
  function escapeMdLabel(s) {
587
- return s.replace(/[\[\]\(\)\{\}`<>\r\n\\*_]/g, " ").replace(/\s+/g, " ").trim();
596
+ return s.replace(/[[\](){}\x60<>\r\n\\*_]/g, " ").replace(/\s+/g, " ").trim();
588
597
  }
589
598
  __name(escapeMdLabel, "escapeMdLabel");
590
599
  function flatten(obj) {
@@ -1187,7 +1196,8 @@ var CreateProductTaskInput = z2.object({
1187
1196
  ])).min(2).max(3).optional().describe('Opcional. Qu\xE9 outputs generar. Default: todos ["landing","video","image"]. Para 2 outputs: ["landing","image"] (sin video), ["video","image"] (sin landing), ["landing","video"] (sin imagen). Para 1 solo output, usa generate_landing / generate_video_creative / generate_image_creatives.'),
1188
1197
  competitorScanEnabled: z2.boolean().optional().describe("Opcional. Si true (default), el sistema analiza ads de competencia en Meta Ad Library y enriquece los \xE1ngulos generados con hooks y painPoints validados por el mercado (\u2248$0.20-0.48 extra por task \u2014 var\xEDa con cu\xE1ntas transcripciones de video se capturen). Si false, el pipeline genera \xE1ngulos sin esa se\xF1al \u2014 usa esto SOLO si el usuario ya tiene su propia investigaci\xF3n de mercado o quiere ahorrar costos en productos muy nicho sin presencia en Meta. Default true."),
1189
1198
  brandId: z2.string().uuid().optional().describe("Opcional. ID de una marca del usuario; si se env\xEDa, el sistema usa su voz, colores y persona para enriquecer los outputs generados."),
1190
- creativeDirection: z2.string().max(500).optional().describe('Opcional. Direcci\xF3n creativa en texto libre (colores, mood, estilo) que aplica a los outputs de IMAGEN y LANDING (no al video \u2014 el estilo/ambiente del video se dirige con scriptNotes). M\xC1XIMA PRIORIDAD: anula marca, colores y estilo por defecto. Ej. "amarillo y azul, minimalista". M\xE1x 500 caracteres.')
1199
+ creativeDirection: z2.string().max(500).optional().describe('Opcional. Direcci\xF3n creativa en texto libre (colores, mood, estilo) que aplica a los outputs de IMAGEN y LANDING (no al video \u2014 el estilo/ambiente del video se dirige con scriptNotes). M\xC1XIMA PRIORIDAD: anula marca, colores y estilo por defecto. Ej. "amarillo y azul, minimalista". M\xE1x 500 caracteres.'),
1200
+ landingStrategy: LandingStrategyEnum.default("auto").describe('Opcional. Estructura de la landing cl\xE1sica cuando landing est\xE1 entre outputs: "auto", "classic" (estructura original probada), "pain_solution", "social_proof", "benefits_clarity", "offer_value" o "lifestyle_identity". Default "auto".')
1191
1201
  }).strict();
1192
1202
  var GetTaskStatusInput = z2.object({
1193
1203
  taskId: z2.string().min(1),
@@ -1309,6 +1319,7 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
1309
1319
  "options.competitorScanEnabled": input.competitorScanEnabled,
1310
1320
  "options.brandId": input.brandId,
1311
1321
  "options.creativeDirection": input.creativeDirection,
1322
+ "options.landingStrategy": input.landingStrategy,
1312
1323
  url: input.productUrl
1313
1324
  });
1314
1325
  const r = await api.postMultipart("/v1/ingest", {
@@ -1539,7 +1550,8 @@ var LandingInput = z3.object({
1539
1550
  isCombo: CreativeRefs.isCombo,
1540
1551
  competitorScanEnabled: CreativeRefs.competitorScanEnabled,
1541
1552
  brandId: CreativeRefs.brandId,
1542
- creativeDirection: CreativeRefs.creativeDirection
1553
+ creativeDirection: CreativeRefs.creativeDirection,
1554
+ landingStrategy: LandingStrategyEnum.default("auto").describe('Opcional. Estructura de la landing cl\xE1sica: "auto" (la IA decide), "classic" (estructura original probada), "pain_solution" (problema\u2192soluci\xF3n), "social_proof" (confianza y evidencia), "benefits_clarity" (beneficios claros), "offer_value" (promoci\xF3n/valor) o "lifestyle_identity" (estilo de vida). Default "auto".')
1543
1555
  });
1544
1556
  function registerCreativeTools(server, api, { transport = "http" } = {}) {
1545
1557
  server.tool("generate_video_creative", 'Genera UN video creativo independiente. Devuelve un taskId.\n\nREQUERIDOS: images (array de 1-5 fotos), title, primaryAngle, language, country, aspectRatio.\n\nANTES de invocar, PREG\xDANTALE al usuario por price y offer si no los mencion\xF3 \u2014 son los inputs de mayor impacto en conversi\xF3n y nunca debes asumirlos. NO defaultes country/language desde el contexto: preg\xFAntale expl\xEDcitamente. Si el usuario te dice "t\xFA elige" para price/offer, om\xEDtelos.\n\nOTROS OPCIONALES (puedes invocar sin ellos y dejar que la IA elija defaults sensatos): durationSeconds (m\xE1x 15), videoPreset (tipo/narrativa del video), features, cta, scriptNotes (dirige el guion Y el ambiente/escenario/est\xE9tica del video, ej. "en una playa, opulento").\n\nESTILO: v\xEDa MCP todos los videos se generan en estilo "Realista" (render \xFAnico de 15s con audio nativo). El estilo "Multiescena" (30s, multi-toma) NO est\xE1 disponible por MCP por su costo \u2014 si el usuario lo pide, dile que lo genere desde la web.\n\nGUION: el usuario NO escribe el guion desde cero \u2014 la IA lo redacta. Si quiere REVISARLO/EDITARLO antes de renderizar (igual que en la web), pasa `pauseForVideoScriptReview: true`; cuando la tarea quede pausada, usa get_video_script para leer las escenas, ofr\xE9celas al usuario, y llama approve_video_script con las ediciones. Para dirigir el guion ANTES de generar (sin pausar), usa scriptNotes.', VideoInput.shape, async (input) => {
@@ -1578,7 +1590,7 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
1578
1590
  throw translateError(e);
1579
1591
  }
1580
1592
  });
1581
- server.tool("generate_landing", 'Genera una landing page lista para Shopify. Devuelve un taskId.\n\nREQUERIDOS: images (array de 1-5 fotos), language, country.\n\nANTES de invocar, PREG\xDANTALE al usuario por price, offer y paymentMethods si no los mencion\xF3 \u2014 son los inputs de mayor impacto en conversi\xF3n y nunca debes asumirlos. NO defaultes country/language desde el contexto: preg\xFAntale expl\xEDcitamente. Si el usuario te dice "t\xFA elige" para esos campos, om\xEDtelos.\n\nOTROS OPCIONALES (puedes invocar sin ellos y dejar que la IA elija defaults): salesAngle, buyerPersona, isCombo, creativeDirection.', LandingInput.shape, async (input) => {
1593
+ server.tool("generate_landing", 'Genera una landing page cl\xE1sica basada en im\xE1genes, lista para Shopify. Devuelve un taskId.\n\nREQUERIDOS: images (array de 1-5 fotos), language, country.\n\nANTES de invocar, PREG\xDANTALE al usuario por price, offer y paymentMethods si no los mencion\xF3 \u2014 son los inputs de mayor impacto en conversi\xF3n y nunca debes asumirlos. NO defaultes country/language desde el contexto: preg\xFAntale expl\xEDcitamente. Si el usuario te dice "t\xFA elige" para esos campos, om\xEDtelos.\n\nOTROS OPCIONALES (puedes invocar sin ellos y dejar que la IA elija defaults): salesAngle, buyerPersona, isCombo, creativeDirection, landingStrategy.', LandingInput.shape, async (input) => {
1582
1594
  try {
1583
1595
  return await submitCreative(api, {
1584
1596
  path: "/v1/creatives/landing",
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.6.0";
113
+ var MCP_VERSION = "1.7.0";
114
114
 
115
115
  // src/tools/tasks.ts
116
116
  import { z as z2 } from "zod";
@@ -393,6 +393,15 @@ import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
393
393
  import { z } from "zod";
394
394
  var Lang = z.string().min(2).max(10);
395
395
  var Country = z.string().min(2).max(3);
396
+ var LandingStrategyEnum = z.enum([
397
+ "auto",
398
+ "classic",
399
+ "pain_solution",
400
+ "social_proof",
401
+ "benefits_clarity",
402
+ "offer_value",
403
+ "lifestyle_identity"
404
+ ]);
396
405
  var VideoPresetEnum = z.enum([
397
406
  "auto",
398
407
  "ugc_dynamic",
@@ -581,7 +590,7 @@ function isRecord(v) {
581
590
  }
582
591
  __name(isRecord, "isRecord");
583
592
  function escapeMdLabel(s) {
584
- return s.replace(/[\[\]\(\)\{\}`<>\r\n\\*_]/g, " ").replace(/\s+/g, " ").trim();
593
+ return s.replace(/[[\](){}\x60<>\r\n\\*_]/g, " ").replace(/\s+/g, " ").trim();
585
594
  }
586
595
  __name(escapeMdLabel, "escapeMdLabel");
587
596
  function flatten(obj) {
@@ -1143,7 +1152,8 @@ var CreateProductTaskInput = z2.object({
1143
1152
  ])).min(2).max(3).optional().describe('Opcional. Qu\xE9 outputs generar. Default: todos ["landing","video","image"]. Para 2 outputs: ["landing","image"] (sin video), ["video","image"] (sin landing), ["landing","video"] (sin imagen). Para 1 solo output, usa generate_landing / generate_video_creative / generate_image_creatives.'),
1144
1153
  competitorScanEnabled: z2.boolean().optional().describe("Opcional. Si true (default), el sistema analiza ads de competencia en Meta Ad Library y enriquece los \xE1ngulos generados con hooks y painPoints validados por el mercado (\u2248$0.20-0.48 extra por task \u2014 var\xEDa con cu\xE1ntas transcripciones de video se capturen). Si false, el pipeline genera \xE1ngulos sin esa se\xF1al \u2014 usa esto SOLO si el usuario ya tiene su propia investigaci\xF3n de mercado o quiere ahorrar costos en productos muy nicho sin presencia en Meta. Default true."),
1145
1154
  brandId: z2.string().uuid().optional().describe("Opcional. ID de una marca del usuario; si se env\xEDa, el sistema usa su voz, colores y persona para enriquecer los outputs generados."),
1146
- creativeDirection: z2.string().max(500).optional().describe('Opcional. Direcci\xF3n creativa en texto libre (colores, mood, estilo) que aplica a los outputs de IMAGEN y LANDING (no al video \u2014 el estilo/ambiente del video se dirige con scriptNotes). M\xC1XIMA PRIORIDAD: anula marca, colores y estilo por defecto. Ej. "amarillo y azul, minimalista". M\xE1x 500 caracteres.')
1155
+ creativeDirection: z2.string().max(500).optional().describe('Opcional. Direcci\xF3n creativa en texto libre (colores, mood, estilo) que aplica a los outputs de IMAGEN y LANDING (no al video \u2014 el estilo/ambiente del video se dirige con scriptNotes). M\xC1XIMA PRIORIDAD: anula marca, colores y estilo por defecto. Ej. "amarillo y azul, minimalista". M\xE1x 500 caracteres.'),
1156
+ landingStrategy: LandingStrategyEnum.default("auto").describe('Opcional. Estructura de la landing cl\xE1sica cuando landing est\xE1 entre outputs: "auto", "classic" (estructura original probada), "pain_solution", "social_proof", "benefits_clarity", "offer_value" o "lifestyle_identity". Default "auto".')
1147
1157
  }).strict();
1148
1158
  var GetTaskStatusInput = z2.object({
1149
1159
  taskId: z2.string().min(1),
@@ -1265,6 +1275,7 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
1265
1275
  "options.competitorScanEnabled": input.competitorScanEnabled,
1266
1276
  "options.brandId": input.brandId,
1267
1277
  "options.creativeDirection": input.creativeDirection,
1278
+ "options.landingStrategy": input.landingStrategy,
1268
1279
  url: input.productUrl
1269
1280
  });
1270
1281
  const r = await api.postMultipart("/v1/ingest", {
@@ -1495,7 +1506,8 @@ var LandingInput = z3.object({
1495
1506
  isCombo: CreativeRefs.isCombo,
1496
1507
  competitorScanEnabled: CreativeRefs.competitorScanEnabled,
1497
1508
  brandId: CreativeRefs.brandId,
1498
- creativeDirection: CreativeRefs.creativeDirection
1509
+ creativeDirection: CreativeRefs.creativeDirection,
1510
+ landingStrategy: LandingStrategyEnum.default("auto").describe('Opcional. Estructura de la landing cl\xE1sica: "auto" (la IA decide), "classic" (estructura original probada), "pain_solution" (problema\u2192soluci\xF3n), "social_proof" (confianza y evidencia), "benefits_clarity" (beneficios claros), "offer_value" (promoci\xF3n/valor) o "lifestyle_identity" (estilo de vida). Default "auto".')
1499
1511
  });
1500
1512
  function registerCreativeTools(server, api, { transport = "http" } = {}) {
1501
1513
  server.tool("generate_video_creative", 'Genera UN video creativo independiente. Devuelve un taskId.\n\nREQUERIDOS: images (array de 1-5 fotos), title, primaryAngle, language, country, aspectRatio.\n\nANTES de invocar, PREG\xDANTALE al usuario por price y offer si no los mencion\xF3 \u2014 son los inputs de mayor impacto en conversi\xF3n y nunca debes asumirlos. NO defaultes country/language desde el contexto: preg\xFAntale expl\xEDcitamente. Si el usuario te dice "t\xFA elige" para price/offer, om\xEDtelos.\n\nOTROS OPCIONALES (puedes invocar sin ellos y dejar que la IA elija defaults sensatos): durationSeconds (m\xE1x 15), videoPreset (tipo/narrativa del video), features, cta, scriptNotes (dirige el guion Y el ambiente/escenario/est\xE9tica del video, ej. "en una playa, opulento").\n\nESTILO: v\xEDa MCP todos los videos se generan en estilo "Realista" (render \xFAnico de 15s con audio nativo). El estilo "Multiescena" (30s, multi-toma) NO est\xE1 disponible por MCP por su costo \u2014 si el usuario lo pide, dile que lo genere desde la web.\n\nGUION: el usuario NO escribe el guion desde cero \u2014 la IA lo redacta. Si quiere REVISARLO/EDITARLO antes de renderizar (igual que en la web), pasa `pauseForVideoScriptReview: true`; cuando la tarea quede pausada, usa get_video_script para leer las escenas, ofr\xE9celas al usuario, y llama approve_video_script con las ediciones. Para dirigir el guion ANTES de generar (sin pausar), usa scriptNotes.', VideoInput.shape, async (input) => {
@@ -1534,7 +1546,7 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
1534
1546
  throw translateError(e);
1535
1547
  }
1536
1548
  });
1537
- server.tool("generate_landing", 'Genera una landing page lista para Shopify. Devuelve un taskId.\n\nREQUERIDOS: images (array de 1-5 fotos), language, country.\n\nANTES de invocar, PREG\xDANTALE al usuario por price, offer y paymentMethods si no los mencion\xF3 \u2014 son los inputs de mayor impacto en conversi\xF3n y nunca debes asumirlos. NO defaultes country/language desde el contexto: preg\xFAntale expl\xEDcitamente. Si el usuario te dice "t\xFA elige" para esos campos, om\xEDtelos.\n\nOTROS OPCIONALES (puedes invocar sin ellos y dejar que la IA elija defaults): salesAngle, buyerPersona, isCombo, creativeDirection.', LandingInput.shape, async (input) => {
1549
+ server.tool("generate_landing", 'Genera una landing page cl\xE1sica basada en im\xE1genes, lista para Shopify. Devuelve un taskId.\n\nREQUERIDOS: images (array de 1-5 fotos), language, country.\n\nANTES de invocar, PREG\xDANTALE al usuario por price, offer y paymentMethods si no los mencion\xF3 \u2014 son los inputs de mayor impacto en conversi\xF3n y nunca debes asumirlos. NO defaultes country/language desde el contexto: preg\xFAntale expl\xEDcitamente. Si el usuario te dice "t\xFA elige" para esos campos, om\xEDtelos.\n\nOTROS OPCIONALES (puedes invocar sin ellos y dejar que la IA elija defaults): salesAngle, buyerPersona, isCombo, creativeDirection, landingStrategy.', LandingInput.shape, async (input) => {
1538
1550
  try {
1539
1551
  return await submitCreative(api, {
1540
1552
  path: "/v1/creatives/landing",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@productmaker/mcp",
3
- "version": "1.6.0",
3
+ "version": "1.7.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.",