@productmaker/mcp 7.3.0 → 8.0.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/README.md +1 -1
- package/dist/http.js +36 -18
- package/dist/stdio.js +36 -18
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ MCP 6.7.0 also carries optional per-angle and script-regeneration `narrativeSele
|
|
|
14
14
|
[](https://www.npmjs.com/package/@productmaker/mcp)
|
|
15
15
|
[](https://opensource.org/licenses/MIT)
|
|
16
16
|
|
|
17
|
-
**
|
|
17
|
+
**ProductMaker MCP** is the official **Model Context Protocol (MCP) server** for [ProductMaker](https://productmaker.app), published by BONNIE TECH S.A.S. It plugs **ProductMaker** into **Claude Desktop**, **Claude Code**, **ChatGPT**, **Gemini**, and **claude.ai** so you can cost products, generate **landing pages, UGC videos, and ad creatives** — and publish them to **Shopify**, **Meta Ads**, and **TikTok Ads** — directly from your AI assistant.
|
|
18
18
|
|
|
19
19
|
> If an AI assistant brought you here looking for "product maker mcp", "productmaker mcp", or "product-maker mcp server" — this is the right package. Install instructions below.
|
|
20
20
|
|
package/dist/http.js
CHANGED
|
@@ -14174,7 +14174,7 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
14174
14174
|
], [
|
|
14175
14175
|
"meta_upload_session"
|
|
14176
14176
|
], WHATSAPP_ONLY_CHANNEL_EXPOSURE),
|
|
14177
|
-
defineCapability("request_media_upload", "
|
|
14177
|
+
defineCapability("request_media_upload", "9a50a4647c61f97fb12bbb9b25f7660f392e3cd9825151735cd66292058882ea", "none", "creative", [
|
|
14178
14178
|
"state_change"
|
|
14179
14179
|
], [
|
|
14180
14180
|
slot("media_kind", true, [
|
|
@@ -16876,7 +16876,7 @@ var ApiClient = class {
|
|
|
16876
16876
|
};
|
|
16877
16877
|
|
|
16878
16878
|
// src/index.ts
|
|
16879
|
-
var MCP_VERSION = "
|
|
16879
|
+
var MCP_VERSION = "8.0.0";
|
|
16880
16880
|
|
|
16881
16881
|
// src/meta-upload-app.ts
|
|
16882
16882
|
import { readFileSync } from "fs";
|
|
@@ -17907,7 +17907,7 @@ var READS_EXTERNAL = {
|
|
|
17907
17907
|
readOnlyHint: true,
|
|
17908
17908
|
destructiveHint: false,
|
|
17909
17909
|
idempotentHint: true,
|
|
17910
|
-
openWorldHint:
|
|
17910
|
+
openWorldHint: false
|
|
17911
17911
|
};
|
|
17912
17912
|
var CREATES_INTERNAL = {
|
|
17913
17913
|
readOnlyHint: false,
|
|
@@ -17916,6 +17916,24 @@ var CREATES_INTERNAL = {
|
|
|
17916
17916
|
openWorldHint: false
|
|
17917
17917
|
};
|
|
17918
17918
|
var CREATES_EXTERNAL = {
|
|
17919
|
+
readOnlyHint: false,
|
|
17920
|
+
destructiveHint: false,
|
|
17921
|
+
idempotentHint: false,
|
|
17922
|
+
openWorldHint: false
|
|
17923
|
+
};
|
|
17924
|
+
var CREATES_PAID = {
|
|
17925
|
+
readOnlyHint: false,
|
|
17926
|
+
destructiveHint: true,
|
|
17927
|
+
idempotentHint: false,
|
|
17928
|
+
openWorldHint: false
|
|
17929
|
+
};
|
|
17930
|
+
var CREATES_PAID_OPEN_WORLD = {
|
|
17931
|
+
readOnlyHint: false,
|
|
17932
|
+
destructiveHint: true,
|
|
17933
|
+
idempotentHint: false,
|
|
17934
|
+
openWorldHint: true
|
|
17935
|
+
};
|
|
17936
|
+
var CREATES_OPEN_WORLD = {
|
|
17919
17937
|
readOnlyHint: false,
|
|
17920
17938
|
destructiveHint: false,
|
|
17921
17939
|
idempotentHint: false,
|
|
@@ -17931,7 +17949,7 @@ var OVERWRITES_EXTERNAL = {
|
|
|
17931
17949
|
readOnlyHint: false,
|
|
17932
17950
|
destructiveHint: true,
|
|
17933
17951
|
idempotentHint: false,
|
|
17934
|
-
openWorldHint:
|
|
17952
|
+
openWorldHint: false
|
|
17935
17953
|
};
|
|
17936
17954
|
var DailyControlStatusEnum = z70.enum([
|
|
17937
17955
|
"ok",
|
|
@@ -19681,7 +19699,7 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
|
|
|
19681
19699
|
|
|
19682
19700
|
REQUERIDOS: images o projectId expl\xEDcito, language y country. Cuando los outputs incluyen video (tambi\xE9n por default), pregunta SIEMPRE videoAngleCount: 1, 2 o 3; es una decisi\xF3n de costo incluso con aiDecidesAll. Si falta una foto local, llama primero \`request_media_upload\`. Pregunta price, offer, paymentMethods y compareAtPrice cuando aplique; nunca asumas country/language.
|
|
19683
19701
|
|
|
19684
|
-
ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explica que inicia trabajo pagado y espera confirmaci\xF3n expl\xEDcita. aiDecidesAll omitido/false pausa para reviews conversacionales; muestra todos los \xE1ngulos candidatos y permite escoger/editar hasta el m\xE1ximo autorizado. Usa aiDecidesAll=true s\xF3lo si el usuario pidi\xF3 \u201Cdecide todo\u201D o \u201Cno me preguntes\u201D.`, CreateProductTaskInput.shape,
|
|
19702
|
+
ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explica que inicia trabajo pagado y espera confirmaci\xF3n expl\xEDcita. aiDecidesAll omitido/false pausa para reviews conversacionales; muestra todos los \xE1ngulos candidatos y permite escoger/editar hasta el m\xE1ximo autorizado. Usa aiDecidesAll=true s\xF3lo si el usuario pidi\xF3 \u201Cdecide todo\u201D o \u201Cno me preguntes\u201D.`, CreateProductTaskInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
19685
19703
|
try {
|
|
19686
19704
|
const selectedOutputs = input.outputs ?? DEFAULT_PRODUCT_TASK_OUTPUTS;
|
|
19687
19705
|
const videoPreset = selectedOutputs.includes("video") && input.competitorScanEnabled === true ? "auto" : input.videoPreset;
|
|
@@ -19772,7 +19790,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
19772
19790
|
throw translateError(e);
|
|
19773
19791
|
}
|
|
19774
19792
|
});
|
|
19775
|
-
server.tool("create_service_video", createServiceVideoGuidance.summary + " Esta acci\xF3n consume cr\xE9ditos: confirma la intenci\xF3n del usuario antes de llamarla. `automatic` genera directamente; `guided` devuelve conceptos para que el usuario apruebe uno mediante `resolve_pending_action`. La web tambi\xE9n acepta demos y anuncios de referencia; el transporte MCP de video adjunto todav\xEDa falla cerrado hasta poder subir bytes de forma segura.", CreateServiceVideoInput.shape,
|
|
19793
|
+
server.tool("create_service_video", createServiceVideoGuidance.summary + " Esta acci\xF3n consume cr\xE9ditos: confirma la intenci\xF3n del usuario antes de llamarla. `automatic` genera directamente; `guided` devuelve conceptos para que el usuario apruebe uno mediante `resolve_pending_action`. La web tambi\xE9n acepta demos y anuncios de referencia; el transporte MCP de video adjunto todav\xEDa falla cerrado hasta poder subir bytes de forma segura.", CreateServiceVideoInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
19776
19794
|
try {
|
|
19777
19795
|
await requirePaidCreativeConfirmation(server, `Video de servicio en ${input.language}. Modo: ${input.reviewMode === "automatic" ? "la IA decide todo" : "reviews conversacionales"}.`);
|
|
19778
19796
|
const created = await api.postJson("/v2/ingest", {
|
|
@@ -20697,7 +20715,7 @@ function resolveLandingSetup(setup) {
|
|
|
20697
20715
|
}
|
|
20698
20716
|
__name(resolveLandingSetup, "resolveLandingSetup");
|
|
20699
20717
|
function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
20700
|
-
server.tool("generate_free_video", generateFreeVideoGuidance.summary + ' Si el usuario adjunta o menciona una imagen local, llama primero request_media_upload con mediaKind=image y usa el assetId devuelto; no pidas path ni URL. Devuelve un taskId y procesa el job de forma as\xEDncrona.\n\nREQUERIDOS: rawPrompt, quality, durationSeconds y videoResolution.\n\nCALIDAD: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan). Economy admite 6/8/10/15s; Medium admite cualquier duraci\xF3n entera de 4 a 15s; Pro admite enteros de 2 a 30s y audio natural. `freeProModel` se elimin\xF3 \u2014 usa `modelId` (ver su descripci\xF3n); Seedance 2.5 est\xE1 inactivo y se rechaza con un error claro.\n\nSUBT\xCDTULOS: si addSubtitles=true, el rawPrompt completo se usa como texto exacto de subt\xEDtulos y debe tener m\xE1ximo 500 caracteres; no existe una pregunta adicional de transcripci\xF3n.\n\nPara videos normales con narrativa/\xE1ngulo usa generate_video_creative. Para tareas combinadas de producto usa create_product_task.', FreeVideoInput.shape,
|
|
20718
|
+
server.tool("generate_free_video", generateFreeVideoGuidance.summary + ' Si el usuario adjunta o menciona una imagen local, llama primero request_media_upload con mediaKind=image y usa el assetId devuelto; no pidas path ni URL. Devuelve un taskId y procesa el job de forma as\xEDncrona.\n\nREQUERIDOS: rawPrompt, quality, durationSeconds y videoResolution.\n\nCALIDAD: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan). Economy admite 6/8/10/15s; Medium admite cualquier duraci\xF3n entera de 4 a 15s; Pro admite enteros de 2 a 30s y audio natural. `freeProModel` se elimin\xF3 \u2014 usa `modelId` (ver su descripci\xF3n); Seedance 2.5 est\xE1 inactivo y se rechaza con un error claro.\n\nSUBT\xCDTULOS: si addSubtitles=true, el rawPrompt completo se usa como texto exacto de subt\xEDtulos y debe tener m\xE1ximo 500 caracteres; no existe una pregunta adicional de transcripci\xF3n.\n\nPara videos normales con narrativa/\xE1ngulo usa generate_video_creative. Para tareas combinadas de producto usa create_product_task.', FreeVideoInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
20701
20719
|
try {
|
|
20702
20720
|
if (input.freeProModel) {
|
|
20703
20721
|
throw new Error("freeProModel se elimin\xF3 en MCP 7.0.0. Usa `modelId` para elegir el modelo expl\xEDcitamente (ver la descripci\xF3n del par\xE1metro).");
|
|
@@ -20745,7 +20763,7 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
20745
20763
|
throw translateError(e);
|
|
20746
20764
|
}
|
|
20747
20765
|
});
|
|
20748
|
-
server.tool("generate_video_creative", generateVideoCreativeGuidance.summary + " Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), title, primaryAngle, language, country, aspectRatio, videoAngleCount y creativeSetup. Pregunta SIEMPRE cu\xE1ntos videos quiere (1, 2 o 3): la cantidad cambia el costo y no forma parte de \u2018la IA decide todo\u2019. Si falta una foto local, llama primero `request_media_upload` y usa los assetId; no pidas path ni URL. PREGUNTA price y offer si faltan; no asumas country/language.\n\nFORMATO Y CALIDAD: pregunta videoStructure (Un solo clip o Multiescena) y videoQuality (Econ\xF3mico, Medio o Pro). Un solo clip se genera completo y puede incluir cambios de plano. El sistema elige el proveedor internamente.\n\nCONFIGURACI\xD3N: salvo que el usuario diga expl\xEDcitamente que la IA decida todo, usa creativeSetup.mode=guided y pregunta narrativa solo si no hay estudio de mercado; recoge p\xFAblico comprador, presentador (actor guardado, descripci\xF3n o ninguno) y direcci\xF3n creativa. Si el usuario dice qui\xE9n debe aparecer (mujer, hombre o ambos), env\xEDa creativeGender; no lo preguntes si no lo menciona. creativeDirection=null s\xF3lo despu\xE9s de que el usuario delegue esa decisi\xF3n concreta. No inventes valores de setup.\n\nANTES de invocar, muestra un resumen compacto que incluya cantidad, planificaci\xF3n (estudio de mercado o narrativa), p\xFAblico, presentador y direcci\xF3n y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. Multiescena se factura por escena, as\xED que avisa ese mayor costo. Advierte tambi\xE9n que, si luego el usuario confirma que las fotos son de varios productos (combo), el pipeline r\xE1pido actualmente omite la pausa de guion aunque mantiene las dem\xE1s revisiones.\n\nREVIEWS: guided muestra los \xE1ngulos candidatos y permite escoger hasta videoAngleCount, editar cada \xE1ngulo y revisar sus guiones. automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite ambas reviews. scriptNotes agrega restricciones al guion; get_video_script y approve_video_script manejan la review palabra por palabra.", VideoInput.shape,
|
|
20766
|
+
server.tool("generate_video_creative", generateVideoCreativeGuidance.summary + " Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), title, primaryAngle, language, country, aspectRatio, videoAngleCount y creativeSetup. Pregunta SIEMPRE cu\xE1ntos videos quiere (1, 2 o 3): la cantidad cambia el costo y no forma parte de \u2018la IA decide todo\u2019. Si falta una foto local, llama primero `request_media_upload` y usa los assetId; no pidas path ni URL. PREGUNTA price y offer si faltan; no asumas country/language.\n\nFORMATO Y CALIDAD: pregunta videoStructure (Un solo clip o Multiescena) y videoQuality (Econ\xF3mico, Medio o Pro). Un solo clip se genera completo y puede incluir cambios de plano. El sistema elige el proveedor internamente.\n\nCONFIGURACI\xD3N: salvo que el usuario diga expl\xEDcitamente que la IA decida todo, usa creativeSetup.mode=guided y pregunta narrativa solo si no hay estudio de mercado; recoge p\xFAblico comprador, presentador (actor guardado, descripci\xF3n o ninguno) y direcci\xF3n creativa. Si el usuario dice qui\xE9n debe aparecer (mujer, hombre o ambos), env\xEDa creativeGender; no lo preguntes si no lo menciona. creativeDirection=null s\xF3lo despu\xE9s de que el usuario delegue esa decisi\xF3n concreta. No inventes valores de setup.\n\nANTES de invocar, muestra un resumen compacto que incluya cantidad, planificaci\xF3n (estudio de mercado o narrativa), p\xFAblico, presentador y direcci\xF3n y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. Multiescena se factura por escena, as\xED que avisa ese mayor costo. Advierte tambi\xE9n que, si luego el usuario confirma que las fotos son de varios productos (combo), el pipeline r\xE1pido actualmente omite la pausa de guion aunque mantiene las dem\xE1s revisiones.\n\nREVIEWS: guided muestra los \xE1ngulos candidatos y permite escoger hasta videoAngleCount, editar cada \xE1ngulo y revisar sus guiones. automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite ambas reviews. scriptNotes agrega restricciones al guion; get_video_script y approve_video_script manejan la review palabra por palabra.", VideoInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
20749
20767
|
try {
|
|
20750
20768
|
if (!input.images && !input.winnerReference) {
|
|
20751
20769
|
throw new Error("images o winnerReference es requerido.");
|
|
@@ -20809,7 +20827,7 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
20809
20827
|
throw translateError(e);
|
|
20810
20828
|
}
|
|
20811
20829
|
});
|
|
20812
|
-
server.tool("generate_image_creatives", generateImageCreativesGuidance.summary + " Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), productTitle, language, country y creativeSetup. Si falta una foto local, llama primero `request_media_upload` y usa los assetId. Pregunta price, offer y compareAtPrice cuando aplique; no asumas country/language. primaryAngle es opcional: si falta, ProductMaker lo genera y guided lo muestra para revisi\xF3n.\n\nCONFIGURACI\xD3N: usa guided salvo delegaci\xF3n total expl\xEDcita. No hagas un interrogatorio campo por campo: presenta UN checklist compacto con arquetipo, tratamiento visual, formato, cantidad, calidad, mezcla condicional, copy, competencia, contexto, direcci\xF3n, colores y copy exacto; propone los defaults recomendados y permite que el usuario delegue los campos con ai_decides o null donde el schema lo admite. La UI ofrece 1, 2, 3, 4 o 6 variantes: para 2\u20134 pregunta styleMix; para 1 o 6 usa null, y 6 activa autom\xE1ticamente una imagen de cada estilo. Premium 2K no admite 4:5.\n\nANTES de invocar, muestra el resumen de esas decisiones y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. guided pausa para revisar el \xE1ngulo; automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite la review.", ImageInput.shape,
|
|
20830
|
+
server.tool("generate_image_creatives", generateImageCreativesGuidance.summary + " Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), productTitle, language, country y creativeSetup. Si falta una foto local, llama primero `request_media_upload` y usa los assetId. Pregunta price, offer y compareAtPrice cuando aplique; no asumas country/language. primaryAngle es opcional: si falta, ProductMaker lo genera y guided lo muestra para revisi\xF3n.\n\nCONFIGURACI\xD3N: usa guided salvo delegaci\xF3n total expl\xEDcita. No hagas un interrogatorio campo por campo: presenta UN checklist compacto con arquetipo, tratamiento visual, formato, cantidad, calidad, mezcla condicional, copy, competencia, contexto, direcci\xF3n, colores y copy exacto; propone los defaults recomendados y permite que el usuario delegue los campos con ai_decides o null donde el schema lo admite. La UI ofrece 1, 2, 3, 4 o 6 variantes: para 2\u20134 pregunta styleMix; para 1 o 6 usa null, y 6 activa autom\xE1ticamente una imagen de cada estilo. Premium 2K no admite 4:5.\n\nANTES de invocar, muestra el resumen de esas decisiones y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. guided pausa para revisar el \xE1ngulo; automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite la review.", ImageInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
20813
20831
|
try {
|
|
20814
20832
|
if (!input.images && !input.winnerReference) {
|
|
20815
20833
|
throw new Error("images o winnerReference es requerido.");
|
|
@@ -20855,7 +20873,7 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
20855
20873
|
throw translateError(e);
|
|
20856
20874
|
}
|
|
20857
20875
|
});
|
|
20858
|
-
server.tool("generate_landing", generateLandingGuidance.summary + " No expone landing editable/code mientras siga siendo admin-only. Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), language, country y creativeSetup. Ante \u201Ccrea una landing con este producto\u201D y una foto local, llama primero `request_media_upload` y usa los assetId. Pregunta price, offer y compareAtPrice cuando aplique; no asumas country/language.\n\nCONFIGURACI\xD3N: usa guided salvo delegaci\xF3n total expl\xEDcita. Presenta UN checklist compacto \u2014no preguntas seriales\u2014 con estrategia, formato, competencia, m\xE9todos de pago, contexto, direcci\xF3n creativa y headline/subheadline exactos opcionales. Prop\xF3n defaults recomendados; null significa que el usuario deleg\xF3 esa decisi\xF3n concreta, nunca que el agente la olvid\xF3.\n\nANTES de invocar, muestra el resumen y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. guided pausa para revisar el \xE1ngulo; automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite la review.", LandingInput.shape,
|
|
20876
|
+
server.tool("generate_landing", generateLandingGuidance.summary + " No expone landing editable/code mientras siga siendo admin-only. Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), language, country y creativeSetup. Ante \u201Ccrea una landing con este producto\u201D y una foto local, llama primero `request_media_upload` y usa los assetId. Pregunta price, offer y compareAtPrice cuando aplique; no asumas country/language.\n\nCONFIGURACI\xD3N: usa guided salvo delegaci\xF3n total expl\xEDcita. Presenta UN checklist compacto \u2014no preguntas seriales\u2014 con estrategia, formato, competencia, m\xE9todos de pago, contexto, direcci\xF3n creativa y headline/subheadline exactos opcionales. Prop\xF3n defaults recomendados; null significa que el usuario deleg\xF3 esa decisi\xF3n concreta, nunca que el agente la olvid\xF3.\n\nANTES de invocar, muestra el resumen y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. guided pausa para revisar el \xE1ngulo; automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite la review.", LandingInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
20859
20877
|
try {
|
|
20860
20878
|
if (!input.images && !input.winnerReference) {
|
|
20861
20879
|
throw new Error("images o winnerReference es requerido.");
|
|
@@ -21133,7 +21151,7 @@ function registerCreativeVariantTools(server, api) {
|
|
|
21133
21151
|
throw translateError(error);
|
|
21134
21152
|
}
|
|
21135
21153
|
});
|
|
21136
|
-
server.tool("create_creative_variant", createCreativeVariantGuidance.summary + " ES UNA ACCI\xD3N DE PAGO: primero llama estimate_creative_variant, muestra el rango de cr\xE9ditos al usuario y solo despu\xE9s invoca este tool con confirm=true. Las recomendaciones IA tambi\xE9n son acciones pagas a 2x del costo real. clientRequestId es obligatorio: genera un UUID por intenci\xF3n y reutiliza el mismo ante timeouts o transporte ambiguo. Si recibes status=error, pide confirmaci\xF3n para un intento nuevo y usa otro UUID. Reutiliza el producto y referencias del task origen; crea un child task independiente y devuelve variantTaskId. Para landing puedes enviar instructions en texto libre y omitir sectionKey: el backend lo clasifica con IA. No expone ni permite cambiar videoModel, videoTier, videoStyle o narrativeStyle; esos valores se heredan del task origen.", CreateCreativeVariantInputBase.shape,
|
|
21154
|
+
server.tool("create_creative_variant", createCreativeVariantGuidance.summary + " ES UNA ACCI\xD3N DE PAGO: primero llama estimate_creative_variant, muestra el rango de cr\xE9ditos al usuario y solo despu\xE9s invoca este tool con confirm=true. Las recomendaciones IA tambi\xE9n son acciones pagas a 2x del costo real. clientRequestId es obligatorio: genera un UUID por intenci\xF3n y reutiliza el mismo ante timeouts o transporte ambiguo. Si recibes status=error, pide confirmaci\xF3n para un intento nuevo y usa otro UUID. Reutiliza el producto y referencias del task origen; crea un child task independiente y devuelve variantTaskId. Para landing puedes enviar instructions en texto libre y omitir sectionKey: el backend lo clasifica con IA. No expone ni permite cambiar videoModel, videoTier, videoStyle o narrativeStyle; esos valores se heredan del task origen.", CreateCreativeVariantInputBase.shape, CREATES_PAID, async (input) => {
|
|
21137
21155
|
try {
|
|
21138
21156
|
const validatedInput = parseVariantInput(CreateCreativeVariantInput, input);
|
|
21139
21157
|
const estimateInput = EstimateCreativeVariantInput.parse({
|
|
@@ -21288,9 +21306,9 @@ function registerScriptReviewTools(server, api) {
|
|
|
21288
21306
|
// Not CREATES_INTERNAL: approving the script is what STARTS the render, so
|
|
21289
21307
|
// this call dispatches jobs to the video providers and burns credits. Its own
|
|
21290
21308
|
// description says so ("Tras llamarlo, el render arranca y consume créditos").
|
|
21291
|
-
//
|
|
21292
|
-
//
|
|
21293
|
-
|
|
21309
|
+
// `destructiveHint` keeps a host from treating the credit charge as a
|
|
21310
|
+
// reversible bookkeeping update.
|
|
21311
|
+
CREATES_PAID,
|
|
21294
21312
|
async (input) => {
|
|
21295
21313
|
try {
|
|
21296
21314
|
await requirePaidCreativeConfirmation(server, `Aprobar ${input.scenes.length} escena(s) y comenzar el render pagado del video.`);
|
|
@@ -22119,7 +22137,7 @@ var UploadSessionInputBase = z80.object({
|
|
|
22119
22137
|
maxFiles: z80.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
22120
22138
|
});
|
|
22121
22139
|
var OpenAiFileReference = z80.object({
|
|
22122
|
-
download_url: z80.string().url().
|
|
22140
|
+
download_url: z80.string().url().describe("Required by ChatGPT's openai/fileParams schema. The App prefers getFileDownloadUrl(file_id) for a fresh URL, and the server never fetches this value."),
|
|
22123
22141
|
file_id: z80.string().min(1),
|
|
22124
22142
|
mime_type: z80.string().min(1).optional(),
|
|
22125
22143
|
file_name: z80.string().min(1).optional()
|
|
@@ -22234,7 +22252,7 @@ __name(resolveEndpointForSession, "resolveEndpointForSession");
|
|
|
22234
22252
|
function registerMediaUploadTools(server, api) {
|
|
22235
22253
|
registerAppTool(server, "request_media_upload", {
|
|
22236
22254
|
title: "Subir archivos",
|
|
22237
|
-
description: requestMediaUploadGuidance.summary + " Cuando la foto o el video sea el siguiente dato faltante, ll\xE1malo en esa misma respuesta: no te limites a pedir que lo adjunte en el chat y esperar otro turno. Ll\xE1malo tambi\xE9n autom\xE1ticamente y antes de preguntar por campos faltantes adicionales cuando una petici\xF3n natural adjunte o mencione un archivo local, por ejemplo \u2018crea una landing con este producto\u2019, \u2018haz creativos con esta foto\u2019 o \u2018sube este video a Meta\u2019; hazlo aunque el usuario diga que todav\xEDa no generes ni publiques, porque esta herramienta solo prepara el archivo y no consume cr\xE9ditos, salvo que proh\xEDba expl\xEDcitamente subir, compartir o almacenar el archivo; no pidas una ruta local ni URL. Es la \xFAnica ruta de carga para create_product_task, generate_image_creatives, generate_video_creative, generate_free_video, generate_landing y publish_creatives_to_meta. Pasa las referencias
|
|
22255
|
+
description: requestMediaUploadGuidance.summary + " Cuando la foto o el video sea el siguiente dato faltante, ll\xE1malo en esa misma respuesta: no te limites a pedir que lo adjunte en el chat y esperar otro turno. Ll\xE1malo tambi\xE9n autom\xE1ticamente y antes de preguntar por campos faltantes adicionales cuando una petici\xF3n natural adjunte o mencione un archivo local, por ejemplo \u2018crea una landing con este producto\u2019, \u2018haz creativos con esta foto\u2019 o \u2018sube este video a Meta\u2019; hazlo aunque el usuario diga que todav\xEDa no generes ni publiques, porque esta herramienta solo prepara el archivo y no consume cr\xE9ditos, salvo que proh\xEDba expl\xEDcitamente subir, compartir o almacenar el archivo; no pidas una ruta local ni URL. Es la \xFAnica ruta de carga para create_product_task, generate_image_creatives, generate_video_creative, generate_free_video, generate_landing y publish_creatives_to_meta. Pasa las referencias de ChatGPT en files con download_url y file_id. Si otro host no puede proporcionar ambos, omite files para que el App abra el selector inline o el enlace de carga. Usa uploadPurpose=product_reference para fotos de producto y landings, creative para creativos o anuncios, y generic solo cuando ninguno aplique. Usa mediaKind=image para referencias de producto y landings; mixed solo cuando el consumidor acepte ambos tipos. El App NO te avisa cuando termina: en cuanto el usuario diga que ya subi\xF3 el archivo o que sigas, llama `check_media_upload` con este sessionId para obtener los assetId, y reanuda la intenci\xF3n original usando \xFAnicamente assetId y mediaKind, sin pedir que vuelva a subir ni mostrar datos t\xE9cnicos. El enlace externo es fallback solo si el App inline falla. Esta herramienta no genera, publica ni consume cr\xE9ditos.",
|
|
22238
22256
|
inputSchema: UploadSessionToolInputShape,
|
|
22239
22257
|
annotations: CREATES_INTERNAL,
|
|
22240
22258
|
outputSchema: UniversalUploadStructuredResponse.shape,
|
|
@@ -23362,7 +23380,7 @@ async function pollUntilTerminal(api, runId, waitSeconds) {
|
|
|
23362
23380
|
}
|
|
23363
23381
|
__name(pollUntilTerminal, "pollUntilTerminal");
|
|
23364
23382
|
function registerProductResearchTools(server, api) {
|
|
23365
|
-
server.tool("find_winning_products", `${findWinningProductsGuidance.summary} CUESTA ${PRICE_CREDITS} CR\xC9DITOS por ejecuci\xF3n. ANTES de invocar, dile al usuario el costo y espera su aceptaci\xF3n expl\xEDcita; s\xF3lo entonces pasa confirmed: true. Consulta primero list_product_research_runs (GRATIS) \u2014 puede que el usuario ya tenga un reporte pagado para ese pa\xEDs/categor\xEDa y no necesites cobrar de nuevo. Pa\xEDses disponibles: CO, MX, PE, EC, CL. Tarda varios minutos: usa waitSeconds para esperar, y si expira consulta el resultado con get_product_research_run \u2014 el reporte NO se pierde.`, FindInput.shape,
|
|
23383
|
+
server.tool("find_winning_products", `${findWinningProductsGuidance.summary} CUESTA ${PRICE_CREDITS} CR\xC9DITOS por ejecuci\xF3n. ANTES de invocar, dile al usuario el costo y espera su aceptaci\xF3n expl\xEDcita; s\xF3lo entonces pasa confirmed: true. Consulta primero list_product_research_runs (GRATIS) \u2014 puede que el usuario ya tenga un reporte pagado para ese pa\xEDs/categor\xEDa y no necesites cobrar de nuevo. Pa\xEDses disponibles: CO, MX, PE, EC, CL. Tarda varios minutos: usa waitSeconds para esperar, y si expira consulta el resultado con get_product_research_run \u2014 el reporte NO se pierde.`, FindInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
23366
23384
|
const parsed = FindInput.parse(input);
|
|
23367
23385
|
if (!parsed.confirmed) {
|
|
23368
23386
|
throw mcp(McpErrorCode.INVALID_INPUT, `This research run costs ${PRICE_CREDITS} credits. Tell the user the cost, get an explicit yes, then call again with confirmed: true.`);
|
|
@@ -23417,7 +23435,7 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
23417
23435
|
throw translateError(error);
|
|
23418
23436
|
}
|
|
23419
23437
|
});
|
|
23420
|
-
server.tool("prepare_winning_product_image", prepareWinningProductImageGuidance.summary + " GRATIS. \xDAsalo s\xF3lo despu\xE9s de que el usuario elija un candidato del reporte. Importa de forma segura la foto exacta a ProductMaker, la muestra y luego pide elegir: usarla, usarla y agregar m\xE1s, o subir s\xF3lo fotos propias.", WinnerReferenceInput.shape,
|
|
23438
|
+
server.tool("prepare_winning_product_image", prepareWinningProductImageGuidance.summary + " GRATIS. \xDAsalo s\xF3lo despu\xE9s de que el usuario elija un candidato del reporte. Importa de forma segura la foto exacta a ProductMaker, la muestra y luego pide elegir: usarla, usarla y agregar m\xE1s, o subir s\xF3lo fotos propias.", WinnerReferenceInput.shape, CREATES_OPEN_WORLD, async (input) => {
|
|
23421
23439
|
const parsed = WinnerReferenceInput.parse(input);
|
|
23422
23440
|
try {
|
|
23423
23441
|
const prepared = WinningProductPreparedImageSchema.parse(await api.postJson(`/v1/product-research/runs/${encodeURIComponent(parsed.runId)}/candidates/${encodeURIComponent(parsed.candidateSourceId)}/image-asset`, {}));
|
package/dist/stdio.js
CHANGED
|
@@ -14196,7 +14196,7 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
14196
14196
|
], [
|
|
14197
14197
|
"meta_upload_session"
|
|
14198
14198
|
], WHATSAPP_ONLY_CHANNEL_EXPOSURE),
|
|
14199
|
-
defineCapability("request_media_upload", "
|
|
14199
|
+
defineCapability("request_media_upload", "9a50a4647c61f97fb12bbb9b25f7660f392e3cd9825151735cd66292058882ea", "none", "creative", [
|
|
14200
14200
|
"state_change"
|
|
14201
14201
|
], [
|
|
14202
14202
|
slot("media_kind", true, [
|
|
@@ -15255,7 +15255,7 @@ var ApiClient = class {
|
|
|
15255
15255
|
};
|
|
15256
15256
|
|
|
15257
15257
|
// src/index.ts
|
|
15258
|
-
var MCP_VERSION = "
|
|
15258
|
+
var MCP_VERSION = "8.0.0";
|
|
15259
15259
|
|
|
15260
15260
|
// src/meta-upload-app.ts
|
|
15261
15261
|
import { readFileSync } from "fs";
|
|
@@ -16286,7 +16286,7 @@ var READS_EXTERNAL = {
|
|
|
16286
16286
|
readOnlyHint: true,
|
|
16287
16287
|
destructiveHint: false,
|
|
16288
16288
|
idempotentHint: true,
|
|
16289
|
-
openWorldHint:
|
|
16289
|
+
openWorldHint: false
|
|
16290
16290
|
};
|
|
16291
16291
|
var CREATES_INTERNAL = {
|
|
16292
16292
|
readOnlyHint: false,
|
|
@@ -16295,6 +16295,24 @@ var CREATES_INTERNAL = {
|
|
|
16295
16295
|
openWorldHint: false
|
|
16296
16296
|
};
|
|
16297
16297
|
var CREATES_EXTERNAL = {
|
|
16298
|
+
readOnlyHint: false,
|
|
16299
|
+
destructiveHint: false,
|
|
16300
|
+
idempotentHint: false,
|
|
16301
|
+
openWorldHint: false
|
|
16302
|
+
};
|
|
16303
|
+
var CREATES_PAID = {
|
|
16304
|
+
readOnlyHint: false,
|
|
16305
|
+
destructiveHint: true,
|
|
16306
|
+
idempotentHint: false,
|
|
16307
|
+
openWorldHint: false
|
|
16308
|
+
};
|
|
16309
|
+
var CREATES_PAID_OPEN_WORLD = {
|
|
16310
|
+
readOnlyHint: false,
|
|
16311
|
+
destructiveHint: true,
|
|
16312
|
+
idempotentHint: false,
|
|
16313
|
+
openWorldHint: true
|
|
16314
|
+
};
|
|
16315
|
+
var CREATES_OPEN_WORLD = {
|
|
16298
16316
|
readOnlyHint: false,
|
|
16299
16317
|
destructiveHint: false,
|
|
16300
16318
|
idempotentHint: false,
|
|
@@ -16310,7 +16328,7 @@ var OVERWRITES_EXTERNAL = {
|
|
|
16310
16328
|
readOnlyHint: false,
|
|
16311
16329
|
destructiveHint: true,
|
|
16312
16330
|
idempotentHint: false,
|
|
16313
|
-
openWorldHint:
|
|
16331
|
+
openWorldHint: false
|
|
16314
16332
|
};
|
|
16315
16333
|
var DailyControlStatusEnum = z69.enum([
|
|
16316
16334
|
"ok",
|
|
@@ -18113,7 +18131,7 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
|
|
|
18113
18131
|
|
|
18114
18132
|
REQUERIDOS: images o projectId expl\xEDcito, language y country. Cuando los outputs incluyen video (tambi\xE9n por default), pregunta SIEMPRE videoAngleCount: 1, 2 o 3; es una decisi\xF3n de costo incluso con aiDecidesAll. Si falta una foto local, llama primero \`request_media_upload\`. Pregunta price, offer, paymentMethods y compareAtPrice cuando aplique; nunca asumas country/language.
|
|
18115
18133
|
|
|
18116
|
-
ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explica que inicia trabajo pagado y espera confirmaci\xF3n expl\xEDcita. aiDecidesAll omitido/false pausa para reviews conversacionales; muestra todos los \xE1ngulos candidatos y permite escoger/editar hasta el m\xE1ximo autorizado. Usa aiDecidesAll=true s\xF3lo si el usuario pidi\xF3 \u201Cdecide todo\u201D o \u201Cno me preguntes\u201D.`, CreateProductTaskInput.shape,
|
|
18134
|
+
ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explica que inicia trabajo pagado y espera confirmaci\xF3n expl\xEDcita. aiDecidesAll omitido/false pausa para reviews conversacionales; muestra todos los \xE1ngulos candidatos y permite escoger/editar hasta el m\xE1ximo autorizado. Usa aiDecidesAll=true s\xF3lo si el usuario pidi\xF3 \u201Cdecide todo\u201D o \u201Cno me preguntes\u201D.`, CreateProductTaskInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
18117
18135
|
try {
|
|
18118
18136
|
const selectedOutputs = input.outputs ?? DEFAULT_PRODUCT_TASK_OUTPUTS;
|
|
18119
18137
|
const videoPreset = selectedOutputs.includes("video") && input.competitorScanEnabled === true ? "auto" : input.videoPreset;
|
|
@@ -18204,7 +18222,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
18204
18222
|
throw translateError(e);
|
|
18205
18223
|
}
|
|
18206
18224
|
});
|
|
18207
|
-
server.tool("create_service_video", createServiceVideoGuidance.summary + " Esta acci\xF3n consume cr\xE9ditos: confirma la intenci\xF3n del usuario antes de llamarla. `automatic` genera directamente; `guided` devuelve conceptos para que el usuario apruebe uno mediante `resolve_pending_action`. La web tambi\xE9n acepta demos y anuncios de referencia; el transporte MCP de video adjunto todav\xEDa falla cerrado hasta poder subir bytes de forma segura.", CreateServiceVideoInput.shape,
|
|
18225
|
+
server.tool("create_service_video", createServiceVideoGuidance.summary + " Esta acci\xF3n consume cr\xE9ditos: confirma la intenci\xF3n del usuario antes de llamarla. `automatic` genera directamente; `guided` devuelve conceptos para que el usuario apruebe uno mediante `resolve_pending_action`. La web tambi\xE9n acepta demos y anuncios de referencia; el transporte MCP de video adjunto todav\xEDa falla cerrado hasta poder subir bytes de forma segura.", CreateServiceVideoInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
18208
18226
|
try {
|
|
18209
18227
|
await requirePaidCreativeConfirmation(server, `Video de servicio en ${input.language}. Modo: ${input.reviewMode === "automatic" ? "la IA decide todo" : "reviews conversacionales"}.`);
|
|
18210
18228
|
const created = await api.postJson("/v2/ingest", {
|
|
@@ -19129,7 +19147,7 @@ function resolveLandingSetup(setup) {
|
|
|
19129
19147
|
}
|
|
19130
19148
|
__name(resolveLandingSetup, "resolveLandingSetup");
|
|
19131
19149
|
function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
19132
|
-
server.tool("generate_free_video", generateFreeVideoGuidance.summary + ' Si el usuario adjunta o menciona una imagen local, llama primero request_media_upload con mediaKind=image y usa el assetId devuelto; no pidas path ni URL. Devuelve un taskId y procesa el job de forma as\xEDncrona.\n\nREQUERIDOS: rawPrompt, quality, durationSeconds y videoResolution.\n\nCALIDAD: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan). Economy admite 6/8/10/15s; Medium admite cualquier duraci\xF3n entera de 4 a 15s; Pro admite enteros de 2 a 30s y audio natural. `freeProModel` se elimin\xF3 \u2014 usa `modelId` (ver su descripci\xF3n); Seedance 2.5 est\xE1 inactivo y se rechaza con un error claro.\n\nSUBT\xCDTULOS: si addSubtitles=true, el rawPrompt completo se usa como texto exacto de subt\xEDtulos y debe tener m\xE1ximo 500 caracteres; no existe una pregunta adicional de transcripci\xF3n.\n\nPara videos normales con narrativa/\xE1ngulo usa generate_video_creative. Para tareas combinadas de producto usa create_product_task.', FreeVideoInput.shape,
|
|
19150
|
+
server.tool("generate_free_video", generateFreeVideoGuidance.summary + ' Si el usuario adjunta o menciona una imagen local, llama primero request_media_upload con mediaKind=image y usa el assetId devuelto; no pidas path ni URL. Devuelve un taskId y procesa el job de forma as\xEDncrona.\n\nREQUERIDOS: rawPrompt, quality, durationSeconds y videoResolution.\n\nCALIDAD: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan). Economy admite 6/8/10/15s; Medium admite cualquier duraci\xF3n entera de 4 a 15s; Pro admite enteros de 2 a 30s y audio natural. `freeProModel` se elimin\xF3 \u2014 usa `modelId` (ver su descripci\xF3n); Seedance 2.5 est\xE1 inactivo y se rechaza con un error claro.\n\nSUBT\xCDTULOS: si addSubtitles=true, el rawPrompt completo se usa como texto exacto de subt\xEDtulos y debe tener m\xE1ximo 500 caracteres; no existe una pregunta adicional de transcripci\xF3n.\n\nPara videos normales con narrativa/\xE1ngulo usa generate_video_creative. Para tareas combinadas de producto usa create_product_task.', FreeVideoInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
19133
19151
|
try {
|
|
19134
19152
|
if (input.freeProModel) {
|
|
19135
19153
|
throw new Error("freeProModel se elimin\xF3 en MCP 7.0.0. Usa `modelId` para elegir el modelo expl\xEDcitamente (ver la descripci\xF3n del par\xE1metro).");
|
|
@@ -19177,7 +19195,7 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
19177
19195
|
throw translateError(e);
|
|
19178
19196
|
}
|
|
19179
19197
|
});
|
|
19180
|
-
server.tool("generate_video_creative", generateVideoCreativeGuidance.summary + " Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), title, primaryAngle, language, country, aspectRatio, videoAngleCount y creativeSetup. Pregunta SIEMPRE cu\xE1ntos videos quiere (1, 2 o 3): la cantidad cambia el costo y no forma parte de \u2018la IA decide todo\u2019. Si falta una foto local, llama primero `request_media_upload` y usa los assetId; no pidas path ni URL. PREGUNTA price y offer si faltan; no asumas country/language.\n\nFORMATO Y CALIDAD: pregunta videoStructure (Un solo clip o Multiescena) y videoQuality (Econ\xF3mico, Medio o Pro). Un solo clip se genera completo y puede incluir cambios de plano. El sistema elige el proveedor internamente.\n\nCONFIGURACI\xD3N: salvo que el usuario diga expl\xEDcitamente que la IA decida todo, usa creativeSetup.mode=guided y pregunta narrativa solo si no hay estudio de mercado; recoge p\xFAblico comprador, presentador (actor guardado, descripci\xF3n o ninguno) y direcci\xF3n creativa. Si el usuario dice qui\xE9n debe aparecer (mujer, hombre o ambos), env\xEDa creativeGender; no lo preguntes si no lo menciona. creativeDirection=null s\xF3lo despu\xE9s de que el usuario delegue esa decisi\xF3n concreta. No inventes valores de setup.\n\nANTES de invocar, muestra un resumen compacto que incluya cantidad, planificaci\xF3n (estudio de mercado o narrativa), p\xFAblico, presentador y direcci\xF3n y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. Multiescena se factura por escena, as\xED que avisa ese mayor costo. Advierte tambi\xE9n que, si luego el usuario confirma que las fotos son de varios productos (combo), el pipeline r\xE1pido actualmente omite la pausa de guion aunque mantiene las dem\xE1s revisiones.\n\nREVIEWS: guided muestra los \xE1ngulos candidatos y permite escoger hasta videoAngleCount, editar cada \xE1ngulo y revisar sus guiones. automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite ambas reviews. scriptNotes agrega restricciones al guion; get_video_script y approve_video_script manejan la review palabra por palabra.", VideoInput.shape,
|
|
19198
|
+
server.tool("generate_video_creative", generateVideoCreativeGuidance.summary + " Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), title, primaryAngle, language, country, aspectRatio, videoAngleCount y creativeSetup. Pregunta SIEMPRE cu\xE1ntos videos quiere (1, 2 o 3): la cantidad cambia el costo y no forma parte de \u2018la IA decide todo\u2019. Si falta una foto local, llama primero `request_media_upload` y usa los assetId; no pidas path ni URL. PREGUNTA price y offer si faltan; no asumas country/language.\n\nFORMATO Y CALIDAD: pregunta videoStructure (Un solo clip o Multiescena) y videoQuality (Econ\xF3mico, Medio o Pro). Un solo clip se genera completo y puede incluir cambios de plano. El sistema elige el proveedor internamente.\n\nCONFIGURACI\xD3N: salvo que el usuario diga expl\xEDcitamente que la IA decida todo, usa creativeSetup.mode=guided y pregunta narrativa solo si no hay estudio de mercado; recoge p\xFAblico comprador, presentador (actor guardado, descripci\xF3n o ninguno) y direcci\xF3n creativa. Si el usuario dice qui\xE9n debe aparecer (mujer, hombre o ambos), env\xEDa creativeGender; no lo preguntes si no lo menciona. creativeDirection=null s\xF3lo despu\xE9s de que el usuario delegue esa decisi\xF3n concreta. No inventes valores de setup.\n\nANTES de invocar, muestra un resumen compacto que incluya cantidad, planificaci\xF3n (estudio de mercado o narrativa), p\xFAblico, presentador y direcci\xF3n y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. Multiescena se factura por escena, as\xED que avisa ese mayor costo. Advierte tambi\xE9n que, si luego el usuario confirma que las fotos son de varios productos (combo), el pipeline r\xE1pido actualmente omite la pausa de guion aunque mantiene las dem\xE1s revisiones.\n\nREVIEWS: guided muestra los \xE1ngulos candidatos y permite escoger hasta videoAngleCount, editar cada \xE1ngulo y revisar sus guiones. automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite ambas reviews. scriptNotes agrega restricciones al guion; get_video_script y approve_video_script manejan la review palabra por palabra.", VideoInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
19181
19199
|
try {
|
|
19182
19200
|
if (!input.images && !input.winnerReference) {
|
|
19183
19201
|
throw new Error("images o winnerReference es requerido.");
|
|
@@ -19241,7 +19259,7 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
19241
19259
|
throw translateError(e);
|
|
19242
19260
|
}
|
|
19243
19261
|
});
|
|
19244
|
-
server.tool("generate_image_creatives", generateImageCreativesGuidance.summary + " Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), productTitle, language, country y creativeSetup. Si falta una foto local, llama primero `request_media_upload` y usa los assetId. Pregunta price, offer y compareAtPrice cuando aplique; no asumas country/language. primaryAngle es opcional: si falta, ProductMaker lo genera y guided lo muestra para revisi\xF3n.\n\nCONFIGURACI\xD3N: usa guided salvo delegaci\xF3n total expl\xEDcita. No hagas un interrogatorio campo por campo: presenta UN checklist compacto con arquetipo, tratamiento visual, formato, cantidad, calidad, mezcla condicional, copy, competencia, contexto, direcci\xF3n, colores y copy exacto; propone los defaults recomendados y permite que el usuario delegue los campos con ai_decides o null donde el schema lo admite. La UI ofrece 1, 2, 3, 4 o 6 variantes: para 2\u20134 pregunta styleMix; para 1 o 6 usa null, y 6 activa autom\xE1ticamente una imagen de cada estilo. Premium 2K no admite 4:5.\n\nANTES de invocar, muestra el resumen de esas decisiones y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. guided pausa para revisar el \xE1ngulo; automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite la review.", ImageInput.shape,
|
|
19262
|
+
server.tool("generate_image_creatives", generateImageCreativesGuidance.summary + " Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), productTitle, language, country y creativeSetup. Si falta una foto local, llama primero `request_media_upload` y usa los assetId. Pregunta price, offer y compareAtPrice cuando aplique; no asumas country/language. primaryAngle es opcional: si falta, ProductMaker lo genera y guided lo muestra para revisi\xF3n.\n\nCONFIGURACI\xD3N: usa guided salvo delegaci\xF3n total expl\xEDcita. No hagas un interrogatorio campo por campo: presenta UN checklist compacto con arquetipo, tratamiento visual, formato, cantidad, calidad, mezcla condicional, copy, competencia, contexto, direcci\xF3n, colores y copy exacto; propone los defaults recomendados y permite que el usuario delegue los campos con ai_decides o null donde el schema lo admite. La UI ofrece 1, 2, 3, 4 o 6 variantes: para 2\u20134 pregunta styleMix; para 1 o 6 usa null, y 6 activa autom\xE1ticamente una imagen de cada estilo. Premium 2K no admite 4:5.\n\nANTES de invocar, muestra el resumen de esas decisiones y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. guided pausa para revisar el \xE1ngulo; automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite la review.", ImageInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
19245
19263
|
try {
|
|
19246
19264
|
if (!input.images && !input.winnerReference) {
|
|
19247
19265
|
throw new Error("images o winnerReference es requerido.");
|
|
@@ -19287,7 +19305,7 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
19287
19305
|
throw translateError(e);
|
|
19288
19306
|
}
|
|
19289
19307
|
});
|
|
19290
|
-
server.tool("generate_landing", generateLandingGuidance.summary + " No expone landing editable/code mientras siga siendo admin-only. Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), language, country y creativeSetup. Ante \u201Ccrea una landing con este producto\u201D y una foto local, llama primero `request_media_upload` y usa los assetId. Pregunta price, offer y compareAtPrice cuando aplique; no asumas country/language.\n\nCONFIGURACI\xD3N: usa guided salvo delegaci\xF3n total expl\xEDcita. Presenta UN checklist compacto \u2014no preguntas seriales\u2014 con estrategia, formato, competencia, m\xE9todos de pago, contexto, direcci\xF3n creativa y headline/subheadline exactos opcionales. Prop\xF3n defaults recomendados; null significa que el usuario deleg\xF3 esa decisi\xF3n concreta, nunca que el agente la olvid\xF3.\n\nANTES de invocar, muestra el resumen y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. guided pausa para revisar el \xE1ngulo; automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite la review.", LandingInput.shape,
|
|
19308
|
+
server.tool("generate_landing", generateLandingGuidance.summary + " No expone landing editable/code mientras siga siendo admin-only. Devuelve un taskId. Esta solicitud es directa: nunca busques, reutilices ni menciones un DropshippingProject.\n\nREQUERIDOS: images (1-5 fotos), language, country y creativeSetup. Ante \u201Ccrea una landing con este producto\u201D y una foto local, llama primero `request_media_upload` y usa los assetId. Pregunta price, offer y compareAtPrice cuando aplique; no asumas country/language.\n\nCONFIGURACI\xD3N: usa guided salvo delegaci\xF3n total expl\xEDcita. Presenta UN checklist compacto \u2014no preguntas seriales\u2014 con estrategia, formato, competencia, m\xE9todos de pago, contexto, direcci\xF3n creativa y headline/subheadline exactos opcionales. Prop\xF3n defaults recomendados; null significa que el usuario deleg\xF3 esa decisi\xF3n concreta, nunca que el agente la olvid\xF3.\n\nANTES de invocar, muestra el resumen y espera confirmaci\xF3n expl\xEDcita porque inicia trabajo pagado. guided pausa para revisar el \xE1ngulo; automatic equivale al toggle web \u201CDejar que la IA decida todo\u201D y omite la review.", LandingInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
19291
19309
|
try {
|
|
19292
19310
|
if (!input.images && !input.winnerReference) {
|
|
19293
19311
|
throw new Error("images o winnerReference es requerido.");
|
|
@@ -19565,7 +19583,7 @@ function registerCreativeVariantTools(server, api) {
|
|
|
19565
19583
|
throw translateError(error);
|
|
19566
19584
|
}
|
|
19567
19585
|
});
|
|
19568
|
-
server.tool("create_creative_variant", createCreativeVariantGuidance.summary + " ES UNA ACCI\xD3N DE PAGO: primero llama estimate_creative_variant, muestra el rango de cr\xE9ditos al usuario y solo despu\xE9s invoca este tool con confirm=true. Las recomendaciones IA tambi\xE9n son acciones pagas a 2x del costo real. clientRequestId es obligatorio: genera un UUID por intenci\xF3n y reutiliza el mismo ante timeouts o transporte ambiguo. Si recibes status=error, pide confirmaci\xF3n para un intento nuevo y usa otro UUID. Reutiliza el producto y referencias del task origen; crea un child task independiente y devuelve variantTaskId. Para landing puedes enviar instructions en texto libre y omitir sectionKey: el backend lo clasifica con IA. No expone ni permite cambiar videoModel, videoTier, videoStyle o narrativeStyle; esos valores se heredan del task origen.", CreateCreativeVariantInputBase.shape,
|
|
19586
|
+
server.tool("create_creative_variant", createCreativeVariantGuidance.summary + " ES UNA ACCI\xD3N DE PAGO: primero llama estimate_creative_variant, muestra el rango de cr\xE9ditos al usuario y solo despu\xE9s invoca este tool con confirm=true. Las recomendaciones IA tambi\xE9n son acciones pagas a 2x del costo real. clientRequestId es obligatorio: genera un UUID por intenci\xF3n y reutiliza el mismo ante timeouts o transporte ambiguo. Si recibes status=error, pide confirmaci\xF3n para un intento nuevo y usa otro UUID. Reutiliza el producto y referencias del task origen; crea un child task independiente y devuelve variantTaskId. Para landing puedes enviar instructions en texto libre y omitir sectionKey: el backend lo clasifica con IA. No expone ni permite cambiar videoModel, videoTier, videoStyle o narrativeStyle; esos valores se heredan del task origen.", CreateCreativeVariantInputBase.shape, CREATES_PAID, async (input) => {
|
|
19569
19587
|
try {
|
|
19570
19588
|
const validatedInput = parseVariantInput(CreateCreativeVariantInput, input);
|
|
19571
19589
|
const estimateInput = EstimateCreativeVariantInput.parse({
|
|
@@ -19720,9 +19738,9 @@ function registerScriptReviewTools(server, api) {
|
|
|
19720
19738
|
// Not CREATES_INTERNAL: approving the script is what STARTS the render, so
|
|
19721
19739
|
// this call dispatches jobs to the video providers and burns credits. Its own
|
|
19722
19740
|
// description says so ("Tras llamarlo, el render arranca y consume créditos").
|
|
19723
|
-
//
|
|
19724
|
-
//
|
|
19725
|
-
|
|
19741
|
+
// `destructiveHint` keeps a host from treating the credit charge as a
|
|
19742
|
+
// reversible bookkeeping update.
|
|
19743
|
+
CREATES_PAID,
|
|
19726
19744
|
async (input) => {
|
|
19727
19745
|
try {
|
|
19728
19746
|
await requirePaidCreativeConfirmation(server, `Aprobar ${input.scenes.length} escena(s) y comenzar el render pagado del video.`);
|
|
@@ -20551,7 +20569,7 @@ var UploadSessionInputBase = z79.object({
|
|
|
20551
20569
|
maxFiles: z79.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
20552
20570
|
});
|
|
20553
20571
|
var OpenAiFileReference = z79.object({
|
|
20554
|
-
download_url: z79.string().url().
|
|
20572
|
+
download_url: z79.string().url().describe("Required by ChatGPT's openai/fileParams schema. The App prefers getFileDownloadUrl(file_id) for a fresh URL, and the server never fetches this value."),
|
|
20555
20573
|
file_id: z79.string().min(1),
|
|
20556
20574
|
mime_type: z79.string().min(1).optional(),
|
|
20557
20575
|
file_name: z79.string().min(1).optional()
|
|
@@ -20666,7 +20684,7 @@ __name(resolveEndpointForSession, "resolveEndpointForSession");
|
|
|
20666
20684
|
function registerMediaUploadTools(server, api) {
|
|
20667
20685
|
registerAppTool(server, "request_media_upload", {
|
|
20668
20686
|
title: "Subir archivos",
|
|
20669
|
-
description: requestMediaUploadGuidance.summary + " Cuando la foto o el video sea el siguiente dato faltante, ll\xE1malo en esa misma respuesta: no te limites a pedir que lo adjunte en el chat y esperar otro turno. Ll\xE1malo tambi\xE9n autom\xE1ticamente y antes de preguntar por campos faltantes adicionales cuando una petici\xF3n natural adjunte o mencione un archivo local, por ejemplo \u2018crea una landing con este producto\u2019, \u2018haz creativos con esta foto\u2019 o \u2018sube este video a Meta\u2019; hazlo aunque el usuario diga que todav\xEDa no generes ni publiques, porque esta herramienta solo prepara el archivo y no consume cr\xE9ditos, salvo que proh\xEDba expl\xEDcitamente subir, compartir o almacenar el archivo; no pidas una ruta local ni URL. Es la \xFAnica ruta de carga para create_product_task, generate_image_creatives, generate_video_creative, generate_free_video, generate_landing y publish_creatives_to_meta. Pasa las referencias
|
|
20687
|
+
description: requestMediaUploadGuidance.summary + " Cuando la foto o el video sea el siguiente dato faltante, ll\xE1malo en esa misma respuesta: no te limites a pedir que lo adjunte en el chat y esperar otro turno. Ll\xE1malo tambi\xE9n autom\xE1ticamente y antes de preguntar por campos faltantes adicionales cuando una petici\xF3n natural adjunte o mencione un archivo local, por ejemplo \u2018crea una landing con este producto\u2019, \u2018haz creativos con esta foto\u2019 o \u2018sube este video a Meta\u2019; hazlo aunque el usuario diga que todav\xEDa no generes ni publiques, porque esta herramienta solo prepara el archivo y no consume cr\xE9ditos, salvo que proh\xEDba expl\xEDcitamente subir, compartir o almacenar el archivo; no pidas una ruta local ni URL. Es la \xFAnica ruta de carga para create_product_task, generate_image_creatives, generate_video_creative, generate_free_video, generate_landing y publish_creatives_to_meta. Pasa las referencias de ChatGPT en files con download_url y file_id. Si otro host no puede proporcionar ambos, omite files para que el App abra el selector inline o el enlace de carga. Usa uploadPurpose=product_reference para fotos de producto y landings, creative para creativos o anuncios, y generic solo cuando ninguno aplique. Usa mediaKind=image para referencias de producto y landings; mixed solo cuando el consumidor acepte ambos tipos. El App NO te avisa cuando termina: en cuanto el usuario diga que ya subi\xF3 el archivo o que sigas, llama `check_media_upload` con este sessionId para obtener los assetId, y reanuda la intenci\xF3n original usando \xFAnicamente assetId y mediaKind, sin pedir que vuelva a subir ni mostrar datos t\xE9cnicos. El enlace externo es fallback solo si el App inline falla. Esta herramienta no genera, publica ni consume cr\xE9ditos.",
|
|
20670
20688
|
inputSchema: UploadSessionToolInputShape,
|
|
20671
20689
|
annotations: CREATES_INTERNAL,
|
|
20672
20690
|
outputSchema: UniversalUploadStructuredResponse.shape,
|
|
@@ -21794,7 +21812,7 @@ async function pollUntilTerminal(api, runId, waitSeconds) {
|
|
|
21794
21812
|
}
|
|
21795
21813
|
__name(pollUntilTerminal, "pollUntilTerminal");
|
|
21796
21814
|
function registerProductResearchTools(server, api) {
|
|
21797
|
-
server.tool("find_winning_products", `${findWinningProductsGuidance.summary} CUESTA ${PRICE_CREDITS} CR\xC9DITOS por ejecuci\xF3n. ANTES de invocar, dile al usuario el costo y espera su aceptaci\xF3n expl\xEDcita; s\xF3lo entonces pasa confirmed: true. Consulta primero list_product_research_runs (GRATIS) \u2014 puede que el usuario ya tenga un reporte pagado para ese pa\xEDs/categor\xEDa y no necesites cobrar de nuevo. Pa\xEDses disponibles: CO, MX, PE, EC, CL. Tarda varios minutos: usa waitSeconds para esperar, y si expira consulta el resultado con get_product_research_run \u2014 el reporte NO se pierde.`, FindInput.shape,
|
|
21815
|
+
server.tool("find_winning_products", `${findWinningProductsGuidance.summary} CUESTA ${PRICE_CREDITS} CR\xC9DITOS por ejecuci\xF3n. ANTES de invocar, dile al usuario el costo y espera su aceptaci\xF3n expl\xEDcita; s\xF3lo entonces pasa confirmed: true. Consulta primero list_product_research_runs (GRATIS) \u2014 puede que el usuario ya tenga un reporte pagado para ese pa\xEDs/categor\xEDa y no necesites cobrar de nuevo. Pa\xEDses disponibles: CO, MX, PE, EC, CL. Tarda varios minutos: usa waitSeconds para esperar, y si expira consulta el resultado con get_product_research_run \u2014 el reporte NO se pierde.`, FindInput.shape, CREATES_PAID_OPEN_WORLD, async (input) => {
|
|
21798
21816
|
const parsed = FindInput.parse(input);
|
|
21799
21817
|
if (!parsed.confirmed) {
|
|
21800
21818
|
throw mcp(McpErrorCode.INVALID_INPUT, `This research run costs ${PRICE_CREDITS} credits. Tell the user the cost, get an explicit yes, then call again with confirmed: true.`);
|
|
@@ -21849,7 +21867,7 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
21849
21867
|
throw translateError(error);
|
|
21850
21868
|
}
|
|
21851
21869
|
});
|
|
21852
|
-
server.tool("prepare_winning_product_image", prepareWinningProductImageGuidance.summary + " GRATIS. \xDAsalo s\xF3lo despu\xE9s de que el usuario elija un candidato del reporte. Importa de forma segura la foto exacta a ProductMaker, la muestra y luego pide elegir: usarla, usarla y agregar m\xE1s, o subir s\xF3lo fotos propias.", WinnerReferenceInput.shape,
|
|
21870
|
+
server.tool("prepare_winning_product_image", prepareWinningProductImageGuidance.summary + " GRATIS. \xDAsalo s\xF3lo despu\xE9s de que el usuario elija un candidato del reporte. Importa de forma segura la foto exacta a ProductMaker, la muestra y luego pide elegir: usarla, usarla y agregar m\xE1s, o subir s\xF3lo fotos propias.", WinnerReferenceInput.shape, CREATES_OPEN_WORLD, async (input) => {
|
|
21853
21871
|
const parsed = WinnerReferenceInput.parse(input);
|
|
21854
21872
|
try {
|
|
21855
21873
|
const prepared = WinningProductPreparedImageSchema.parse(await api.postJson(`/v1/product-research/runs/${encodeURIComponent(parsed.runId)}/candidates/${encodeURIComponent(parsed.candidateSourceId)}/image-asset`, {}));
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@productmaker/mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
|
-
"description": "
|
|
6
|
+
"description": "ProductMaker MCP server — cost products, generate landing pages, UGC videos, and ad creatives, and publish to Shopify, Meta Ads, and TikTok Ads.",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"mcp",
|
|
9
9
|
"mcp-server",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"bugs": {
|
|
37
37
|
"email": "infoapp@productmaker.app"
|
|
38
38
|
},
|
|
39
|
-
"author": "
|
|
39
|
+
"author": "BONNIE TECH S.A.S <infoapp@productmaker.app> (https://productmaker.app)",
|
|
40
40
|
"license": "MIT",
|
|
41
41
|
"bin": {
|
|
42
42
|
"productmaker-mcp": "./dist/stdio.js"
|