@productmaker/mcp 8.13.0 → 9.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 +6 -2
- package/dist/http.js +140 -122
- package/dist/stdio.js +140 -122
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -137,7 +137,7 @@ separate release step.
|
|
|
137
137
|
| `get_task_status` | Check task progress (optional `waitSeconds` for near-sync polling) |
|
|
138
138
|
| `list_tasks` | List recent tasks |
|
|
139
139
|
| `edit_task_draft` | Edit angle / pain point / persona before generation |
|
|
140
|
-
| `create_service_video` |
|
|
140
|
+
| `create_service_video` | **Hidden from the MCP since 9.0.0** (owner decision 2026-10-08, still on WhatsApp): use `create_animated_video` for a service video. |
|
|
141
141
|
| `create_animated_video` | Animated _service_ video ("Video animado", motion graphics: text, shapes and the site's visual identity, music, no presenter) from its landing page URL. Choose `format` (vertical/square/horizontal), `durationSec` (10/15/30/45/60), `language` (es/en/pt) and optional `notes`. **Paid action** — flat price by duration (listed in the tool description, refunded on failure); takes minutes in a queue. Follow it with `get_task_status` (stage, queue position, render %, activity, preview, final MP4). In closed testing: other accounts get `FEATURE_NOT_AVAILABLE` |
|
|
142
142
|
| `generate_video_creative` | Standalone UGC video creative |
|
|
143
143
|
| `generate_free_video` | One free-form video from an exact prompt/script, optionally with a reference image (async: returns a `taskId`) |
|
|
@@ -284,6 +284,10 @@ The `base64` field was removed. MCP JSON-RPC transports truncate large tool argu
|
|
|
284
284
|
|
|
285
285
|
## Version history
|
|
286
286
|
|
|
287
|
+
### 8.13.1 — Guías de demostración para single take
|
|
288
|
+
|
|
289
|
+
- Sin nuevas herramientas ni opciones públicas. Actualiza la versión del paquete junto con los contratos internos de preparación de referencias; conserva la edición con IA y sus niveles de 8.13.0.
|
|
290
|
+
|
|
287
291
|
### 8.13.0 — Dos niveles de Edición con IA (`generateAiEdit`: `"economy"` | `"pro"`)
|
|
288
292
|
|
|
289
293
|
- `generateAiEdit` acepta `"economy"` (Económica: Sonnet 5.5 en esfuerzo alto, más barata) o `"pro"` (Opus 5.5, mejor calidad, ~10 min), además del booleano de siempre: `true` equivale a `"pro"` y `false`/omitido = sin edición. Aplica a `generate_free_video`, `generate_video_creative`, `create_product_task` y `estimate_market_study_cost` (la cotización cambia con el nivel).
|
|
@@ -386,7 +390,7 @@ Release metadata synchronized with per-store Meta controls. MCP tool inputs, res
|
|
|
386
390
|
|
|
387
391
|
### 8.3.0 — Idempotencia de tools pagadas + refresh OAuth
|
|
388
392
|
|
|
389
|
-
- Tools pagadas (`create_product_task`, `
|
|
393
|
+
- Tools pagadas (`create_product_task`, `create_animated_video` (sin `notes` en la llave), `generate_video_creative`, `generate_free_video`, `generate_image_creatives`, `generate_landing`, `create_creative_variant`): envían un `Idempotency-Key` derivado de los argumentos semánticos (ventana de 15 min). Un reintento con los mismos argumentos devuelve la misma tarea (`replayed: true`) sin segundo cargo; una tarea en `error` sí se reintenta.
|
|
390
394
|
- OAuth alojado: se anuncia `offline_access` + grant `refresh_token`; un token a punto de expirar responde `401` + `WWW-Authenticate` para que el host refresque en silencio (`MCP_SUBJECT_TOKEN_REAUTH_WINDOW_MS`, por defecto 180000; `0` lo desactiva).
|
|
391
395
|
|
|
392
396
|
### 8.2.0 — Fase 3 (modelos)
|
package/dist/http.js
CHANGED
|
@@ -8797,6 +8797,7 @@ var KIE_SUBMIT_IMAGE_TASK_TARGETS = [
|
|
|
8797
8797
|
"rapid_master_anchor",
|
|
8798
8798
|
"clean_product_image",
|
|
8799
8799
|
"single_call_anchor",
|
|
8800
|
+
"single_take_demo_guide",
|
|
8800
8801
|
"product_view_reference",
|
|
8801
8802
|
// Generated service-video presenter (text-to-image portrait). Task-owned, so
|
|
8802
8803
|
// it lives here and not beside `actor_candidate`; it mirrors that target's
|
|
@@ -15273,44 +15274,58 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
15273
15274
|
"product"
|
|
15274
15275
|
]
|
|
15275
15276
|
),
|
|
15276
|
-
defineCapability(
|
|
15277
|
+
defineCapability(
|
|
15278
|
+
"create_service_video",
|
|
15279
|
+
"c3d81a4f698e01658fa04ebb613a91c8ba43320d21cacda522e72d198036eb21",
|
|
15277
15280
|
"credit_consuming",
|
|
15278
|
-
"
|
|
15279
|
-
|
|
15280
|
-
|
|
15281
|
-
"
|
|
15282
|
-
]
|
|
15283
|
-
|
|
15284
|
-
"
|
|
15285
|
-
|
|
15286
|
-
|
|
15287
|
-
"
|
|
15288
|
-
|
|
15289
|
-
|
|
15290
|
-
"
|
|
15291
|
-
|
|
15292
|
-
|
|
15293
|
-
"
|
|
15294
|
-
|
|
15295
|
-
|
|
15296
|
-
"
|
|
15297
|
-
|
|
15298
|
-
|
|
15299
|
-
"
|
|
15300
|
-
|
|
15301
|
-
|
|
15302
|
-
|
|
15303
|
-
|
|
15304
|
-
|
|
15305
|
-
|
|
15306
|
-
"
|
|
15307
|
-
|
|
15308
|
-
|
|
15309
|
-
|
|
15310
|
-
|
|
15311
|
-
|
|
15312
|
-
|
|
15313
|
-
|
|
15281
|
+
"creative",
|
|
15282
|
+
[
|
|
15283
|
+
"credit_consuming",
|
|
15284
|
+
"state_change"
|
|
15285
|
+
],
|
|
15286
|
+
[
|
|
15287
|
+
slot("service_landing", true, [
|
|
15288
|
+
"landingUrl"
|
|
15289
|
+
]),
|
|
15290
|
+
slot("locale", true, [
|
|
15291
|
+
"language"
|
|
15292
|
+
]),
|
|
15293
|
+
slot("service_context", false, [
|
|
15294
|
+
"additionalContext"
|
|
15295
|
+
]),
|
|
15296
|
+
slot("voice", false, [
|
|
15297
|
+
"voiceId"
|
|
15298
|
+
]),
|
|
15299
|
+
slot("brand", false, [
|
|
15300
|
+
"brandId"
|
|
15301
|
+
]),
|
|
15302
|
+
slot("review_mode", false, [
|
|
15303
|
+
"reviewMode"
|
|
15304
|
+
]),
|
|
15305
|
+
slot("video_preset", false, [
|
|
15306
|
+
"videoPreset"
|
|
15307
|
+
]),
|
|
15308
|
+
// MCP-only for now: WhatsApp's service flow keeps the economy default.
|
|
15309
|
+
slot("video_quality", false, [
|
|
15310
|
+
"videoQuality"
|
|
15311
|
+
], []),
|
|
15312
|
+
slot("video_resolution", false, [
|
|
15313
|
+
"videoResolution"
|
|
15314
|
+
], [])
|
|
15315
|
+
],
|
|
15316
|
+
[
|
|
15317
|
+
"service_context"
|
|
15318
|
+
],
|
|
15319
|
+
[
|
|
15320
|
+
"task",
|
|
15321
|
+
"video"
|
|
15322
|
+
],
|
|
15323
|
+
// Owner decision 2026-10-08: the presenter service video is hidden from the
|
|
15324
|
+
// MCP for now — dropshipping sellers ordered it for products and cancelled.
|
|
15325
|
+
// MCP clients get `create_animated_video` instead. Flip back to
|
|
15326
|
+
// SHARED_CHANNEL_EXPOSURE to restore it.
|
|
15327
|
+
WHATSAPP_ONLY_CHANNEL_EXPOSURE
|
|
15328
|
+
),
|
|
15314
15329
|
defineCapability("edit_image_creative", "50eca473829328dfb63b9cbae03a9835b79c510e29528563e09b7eb3e5e9bca4", "credit_consuming", "creative", [
|
|
15315
15330
|
"credit_consuming",
|
|
15316
15331
|
"state_change"
|
|
@@ -19788,7 +19803,7 @@ var ApiClient = class {
|
|
|
19788
19803
|
};
|
|
19789
19804
|
|
|
19790
19805
|
// src/index.ts
|
|
19791
|
-
var MCP_VERSION = "
|
|
19806
|
+
var MCP_VERSION = "9.0.0";
|
|
19792
19807
|
|
|
19793
19808
|
// src/meta-upload-app.ts
|
|
19794
19809
|
import { readFileSync } from "fs";
|
|
@@ -22337,7 +22352,7 @@ function renderAnimatedVideoStatus(result) {
|
|
|
22337
22352
|
__name(renderAnimatedVideoStatus, "renderAnimatedVideoStatus");
|
|
22338
22353
|
function registerAnimatedVideoTools(server, api) {
|
|
22339
22354
|
server.registerTool("create_animated_video", {
|
|
22340
|
-
description: guidance.summary + ` Hace un video animado (motion graphics) de un SERVICIO a partir del enlace de su p\xE1gina: textos, formas y la identidad visual del sitio, con m\xFAsica y efectos, sin presentador ni voz en off. Esta acci\xF3n consume cr\xE9ditos: confirma formato, duraci\xF3n, idioma y precio con el usuario antes de llamarla. Precio fijo por duraci\xF3n: ${describeAnimatedVideoPrices()}; si falla, se devuelve. Tarda varios minutos, m\xE1s si hay otros videos en la cola. Devuelve un taskId: sigue el avance con get_task_status (etapa, posici\xF3n en la cola, % de render, lo que va haciendo y vista previa) hasta done, que trae el enlace del MP4, o error, que trae el motivo.
|
|
22355
|
+
description: guidance.summary + ` Hace un video animado (motion graphics) de un SERVICIO a partir del enlace de su p\xE1gina: textos, formas y la identidad visual del sitio, con m\xFAsica y efectos, sin presentador ni voz en off. Esta acci\xF3n consume cr\xE9ditos: confirma formato, duraci\xF3n, idioma y precio con el usuario antes de llamarla. Precio fijo por duraci\xF3n: ${describeAnimatedVideoPrices()}; si falla, se devuelve. Tarda varios minutos, m\xE1s si hay otros videos en la cola. Devuelve un taskId: sigue el avance con get_task_status (etapa, posici\xF3n en la cola, % de render, lo que va haciendo y vista previa) hasta done, que trae el enlace del MP4, o error, que trae el motivo. Es el \xFAnico video de servicio disponible por ahora: no ofrezcas un video con presentador. Puede no estar disponible para todas las cuentas: si responde que la funci\xF3n no est\xE1 disponible, dilo y no ofrezcas alternativas pagadas.`,
|
|
22341
22356
|
inputSchema: CreateAnimatedVideoInput.shape,
|
|
22342
22357
|
annotations: CREATES_PAID_OPEN_WORLD
|
|
22343
22358
|
}, async (input) => {
|
|
@@ -22442,7 +22457,7 @@ function renderCreateProductTaskAvoidWhenForMcp(fragment) {
|
|
|
22442
22457
|
__name(renderCreateProductTaskAvoidWhenForMcp, "renderCreateProductTaskAvoidWhenForMcp");
|
|
22443
22458
|
var createProductTaskDefaultDescription = renderCreateProductTaskDefaultForMcp(createProductTaskGuidance.defaults[0]);
|
|
22444
22459
|
var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenForMcp(createProductTaskGuidance.avoidWhen[0]);
|
|
22445
|
-
var
|
|
22460
|
+
var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
|
|
22446
22461
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
22447
22462
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
22448
22463
|
var CreateProductTaskInput = z87.object({
|
|
@@ -22877,7 +22892,7 @@ async function fetchAnimatedVideoResult(api, taskId, signal, serviceMode = void
|
|
|
22877
22892
|
}
|
|
22878
22893
|
}
|
|
22879
22894
|
__name(fetchAnimatedVideoResult, "fetchAnimatedVideoResult");
|
|
22880
|
-
function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http" } = {}) {
|
|
22895
|
+
function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http", serviceVideo = CREATE_SERVICE_VIDEO_ON_MCP } = {}) {
|
|
22881
22896
|
server.registerTool("create_product_task", {
|
|
22882
22897
|
description: createProductTaskGuidance.summary + ` ${createProductTaskDefaultDescription} \xDAsala cuando el usuario pide todo o varios outputs, no creando tareas individuales. Usa images para solicitudes directas. Usa projectId \xFAnicamente si el usuario pidi\xF3 expl\xEDcitamente continuar el proyecto guiado que acaba de costear; nunca busques, infieras ni menciones proyectos previos.
|
|
22883
22898
|
|
|
@@ -23000,97 +23015,100 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
23000
23015
|
throw translateError(e);
|
|
23001
23016
|
}
|
|
23002
23017
|
});
|
|
23003
|
-
|
|
23004
|
-
|
|
23005
|
-
|
|
23006
|
-
|
|
23007
|
-
|
|
23008
|
-
|
|
23009
|
-
|
|
23010
|
-
|
|
23011
|
-
|
|
23012
|
-
|
|
23013
|
-
|
|
23014
|
-
|
|
23015
|
-
|
|
23016
|
-
|
|
23017
|
-
|
|
23018
|
-
|
|
23019
|
-
|
|
23020
|
-
|
|
23021
|
-
|
|
23022
|
-
|
|
23023
|
-
|
|
23024
|
-
|
|
23025
|
-
|
|
23026
|
-
|
|
23027
|
-
|
|
23028
|
-
|
|
23029
|
-
|
|
23030
|
-
|
|
23031
|
-
|
|
23032
|
-
|
|
23033
|
-
|
|
23034
|
-
|
|
23035
|
-
|
|
23036
|
-
|
|
23037
|
-
|
|
23038
|
-
|
|
23039
|
-
|
|
23040
|
-
|
|
23041
|
-
|
|
23042
|
-
|
|
23043
|
-
|
|
23044
|
-
|
|
23045
|
-
|
|
23046
|
-
|
|
23047
|
-
|
|
23048
|
-
|
|
23049
|
-
|
|
23050
|
-
|
|
23051
|
-
|
|
23052
|
-
if (
|
|
23053
|
-
|
|
23054
|
-
|
|
23055
|
-
|
|
23056
|
-
|
|
23018
|
+
if (serviceVideo) {
|
|
23019
|
+
const createServiceVideoGuidance = getProductMakerCapabilityModelGuidance("create_service_video");
|
|
23020
|
+
server.registerTool("create_service_video", {
|
|
23021
|
+
description: 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.",
|
|
23022
|
+
inputSchema: CreateServiceVideoInput.shape,
|
|
23023
|
+
annotations: CREATES_PAID_OPEN_WORLD
|
|
23024
|
+
}, async (input) => {
|
|
23025
|
+
try {
|
|
23026
|
+
if (input.videoQuality === "medium" && input.videoResolution === "720p") {
|
|
23027
|
+
throw mcp(McpErrorCode.INVALID_INPUT, 'videoResolution "720p" no est\xE1 disponible con videoQuality "medium" en videos de servicio (Medio = 768P). Usa "480p" o elige "economy"/"pro".');
|
|
23028
|
+
}
|
|
23029
|
+
await requirePaidCreativeConfirmation(server, `Video de servicio en ${input.language}. Modo: ${input.reviewMode === "automatic" ? "la IA decide todo" : "reviews conversacionales"}.`);
|
|
23030
|
+
const created = await api.postJson("/v2/ingest", {
|
|
23031
|
+
taskType: "service",
|
|
23032
|
+
serviceLandingUrl: input.landingUrl,
|
|
23033
|
+
...input.additionalContext ? {
|
|
23034
|
+
additionalContext: input.additionalContext
|
|
23035
|
+
} : {},
|
|
23036
|
+
lang: input.language,
|
|
23037
|
+
...input.voiceId ? {
|
|
23038
|
+
voiceId: input.voiceId
|
|
23039
|
+
} : {},
|
|
23040
|
+
videoPreset: input.videoPreset,
|
|
23041
|
+
videoQuality: input.videoQuality,
|
|
23042
|
+
videoResolution: input.videoResolution,
|
|
23043
|
+
reviewMode: input.reviewMode,
|
|
23044
|
+
...input.brandId ? {
|
|
23045
|
+
brandId: input.brandId
|
|
23046
|
+
} : {},
|
|
23047
|
+
media: {
|
|
23048
|
+
assets: []
|
|
23049
|
+
},
|
|
23050
|
+
appDemoVideos: []
|
|
23051
|
+
}, {
|
|
23052
|
+
// The 2026-09-25 incident: four retries of this exact tool created
|
|
23053
|
+
// four charged service tasks because the host rephrased
|
|
23054
|
+
// `additionalContext` and flipped the landing between `/` and
|
|
23055
|
+
// `/es`. The derived key is stable across both rewrites (see
|
|
23056
|
+
// request-key.ts).
|
|
23057
|
+
idempotencyKey: derivePaidRequestKey({
|
|
23058
|
+
fingerprint: api.fingerprint(),
|
|
23059
|
+
tool: "create_service_video",
|
|
23060
|
+
input,
|
|
23061
|
+
nowMs: Date.now()
|
|
23062
|
+
})
|
|
23063
|
+
});
|
|
23064
|
+
const angles = await api.postJson(`/v1/tasks/${encodeURIComponent(created.taskId)}/service-angles`, {});
|
|
23065
|
+
const first = angles[0];
|
|
23066
|
+
const replayed = created.replayed === true;
|
|
23067
|
+
if (input.reviewMode === "automatic") {
|
|
23068
|
+
if (!first) throw new Error("ProductMaker no pudo crear un concepto para este servicio.");
|
|
23069
|
+
if (!(replayed && created.status !== "queued")) {
|
|
23070
|
+
await api.postJson(`/v1/tasks/${encodeURIComponent(created.taskId)}/service-angles/select`, {
|
|
23071
|
+
angleIds: [
|
|
23072
|
+
first.id
|
|
23073
|
+
]
|
|
23074
|
+
});
|
|
23075
|
+
}
|
|
23076
|
+
return asText({
|
|
23077
|
+
taskId: created.taskId,
|
|
23078
|
+
status: replayed ? created.status ?? "processing" : "processing",
|
|
23079
|
+
...replayed ? {
|
|
23080
|
+
replayed: true
|
|
23081
|
+
} : {},
|
|
23082
|
+
reviewMode: input.reviewMode,
|
|
23083
|
+
selectedConcept: first
|
|
23084
|
+
});
|
|
23085
|
+
}
|
|
23086
|
+
if (replayed && created.status !== "queued") {
|
|
23087
|
+
return asText({
|
|
23088
|
+
taskId: created.taskId,
|
|
23089
|
+
status: created.status,
|
|
23090
|
+
replayed: true,
|
|
23091
|
+
reviewMode: input.reviewMode,
|
|
23092
|
+
angles
|
|
23057
23093
|
});
|
|
23058
23094
|
}
|
|
23059
23095
|
return asText({
|
|
23060
23096
|
taskId: created.taskId,
|
|
23061
|
-
status:
|
|
23097
|
+
status: "waiting_for_user",
|
|
23062
23098
|
...replayed ? {
|
|
23063
23099
|
replayed: true
|
|
23064
23100
|
} : {},
|
|
23065
23101
|
reviewMode: input.reviewMode,
|
|
23066
|
-
|
|
23067
|
-
|
|
23068
|
-
|
|
23069
|
-
|
|
23070
|
-
return asText({
|
|
23071
|
-
taskId: created.taskId,
|
|
23072
|
-
status: created.status,
|
|
23073
|
-
replayed: true,
|
|
23074
|
-
reviewMode: input.reviewMode,
|
|
23075
|
-
angles
|
|
23102
|
+
pendingUserAction: {
|
|
23103
|
+
kind: "service_angle_approval",
|
|
23104
|
+
angles
|
|
23105
|
+
}
|
|
23076
23106
|
});
|
|
23107
|
+
} catch (e) {
|
|
23108
|
+
throw translateError(e);
|
|
23077
23109
|
}
|
|
23078
|
-
|
|
23079
|
-
|
|
23080
|
-
status: "waiting_for_user",
|
|
23081
|
-
...replayed ? {
|
|
23082
|
-
replayed: true
|
|
23083
|
-
} : {},
|
|
23084
|
-
reviewMode: input.reviewMode,
|
|
23085
|
-
pendingUserAction: {
|
|
23086
|
-
kind: "service_angle_approval",
|
|
23087
|
-
angles
|
|
23088
|
-
}
|
|
23089
|
-
});
|
|
23090
|
-
} catch (e) {
|
|
23091
|
-
throw translateError(e);
|
|
23092
|
-
}
|
|
23093
|
-
});
|
|
23110
|
+
});
|
|
23111
|
+
}
|
|
23094
23112
|
server.registerTool("verify_landing_commerce", {
|
|
23095
23113
|
description: getProductMakerCapabilityModelGuidance("verify_landing_commerce").summary + " Verifica una correcci\xF3n manual de precios, tachados o packs de una landing editable existente. Solo relee Shopify y los recibos externos; no cambia precios, inventario, SKU ni compra una edici\xF3n. Pasa taskId y editId de la edici\xF3n ya conocida; nunca inventes IDs ni pidas repetir el cambio. Devuelve el estado can\xF3nico por proveedor: conserva el aviso pendiente hasta confirmar los valores reales. Solo despu\xE9s de confirmar todos los valores, el servidor puede volver a habilitar la compra. Web guardada no demuestra publicaci\xF3n p\xFAblica ni checkout; muestra las correcciones y enlaces pendientes sin c\xF3digos t\xE9cnicos. La disponibilidad del editor conserva sus permisos actuales.",
|
|
23096
23114
|
inputSchema: {
|
package/dist/stdio.js
CHANGED
|
@@ -8819,6 +8819,7 @@ var KIE_SUBMIT_IMAGE_TASK_TARGETS = [
|
|
|
8819
8819
|
"rapid_master_anchor",
|
|
8820
8820
|
"clean_product_image",
|
|
8821
8821
|
"single_call_anchor",
|
|
8822
|
+
"single_take_demo_guide",
|
|
8822
8823
|
"product_view_reference",
|
|
8823
8824
|
// Generated service-video presenter (text-to-image portrait). Task-owned, so
|
|
8824
8825
|
// it lives here and not beside `actor_candidate`; it mirrors that target's
|
|
@@ -15295,44 +15296,58 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
15295
15296
|
"product"
|
|
15296
15297
|
]
|
|
15297
15298
|
),
|
|
15298
|
-
defineCapability(
|
|
15299
|
+
defineCapability(
|
|
15300
|
+
"create_service_video",
|
|
15301
|
+
"c3d81a4f698e01658fa04ebb613a91c8ba43320d21cacda522e72d198036eb21",
|
|
15299
15302
|
"credit_consuming",
|
|
15300
|
-
"
|
|
15301
|
-
|
|
15302
|
-
|
|
15303
|
-
"
|
|
15304
|
-
]
|
|
15305
|
-
|
|
15306
|
-
"
|
|
15307
|
-
|
|
15308
|
-
|
|
15309
|
-
"
|
|
15310
|
-
|
|
15311
|
-
|
|
15312
|
-
"
|
|
15313
|
-
|
|
15314
|
-
|
|
15315
|
-
"
|
|
15316
|
-
|
|
15317
|
-
|
|
15318
|
-
"
|
|
15319
|
-
|
|
15320
|
-
|
|
15321
|
-
"
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
|
|
15325
|
-
|
|
15326
|
-
|
|
15327
|
-
|
|
15328
|
-
"
|
|
15329
|
-
|
|
15330
|
-
|
|
15331
|
-
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
|
|
15303
|
+
"creative",
|
|
15304
|
+
[
|
|
15305
|
+
"credit_consuming",
|
|
15306
|
+
"state_change"
|
|
15307
|
+
],
|
|
15308
|
+
[
|
|
15309
|
+
slot("service_landing", true, [
|
|
15310
|
+
"landingUrl"
|
|
15311
|
+
]),
|
|
15312
|
+
slot("locale", true, [
|
|
15313
|
+
"language"
|
|
15314
|
+
]),
|
|
15315
|
+
slot("service_context", false, [
|
|
15316
|
+
"additionalContext"
|
|
15317
|
+
]),
|
|
15318
|
+
slot("voice", false, [
|
|
15319
|
+
"voiceId"
|
|
15320
|
+
]),
|
|
15321
|
+
slot("brand", false, [
|
|
15322
|
+
"brandId"
|
|
15323
|
+
]),
|
|
15324
|
+
slot("review_mode", false, [
|
|
15325
|
+
"reviewMode"
|
|
15326
|
+
]),
|
|
15327
|
+
slot("video_preset", false, [
|
|
15328
|
+
"videoPreset"
|
|
15329
|
+
]),
|
|
15330
|
+
// MCP-only for now: WhatsApp's service flow keeps the economy default.
|
|
15331
|
+
slot("video_quality", false, [
|
|
15332
|
+
"videoQuality"
|
|
15333
|
+
], []),
|
|
15334
|
+
slot("video_resolution", false, [
|
|
15335
|
+
"videoResolution"
|
|
15336
|
+
], [])
|
|
15337
|
+
],
|
|
15338
|
+
[
|
|
15339
|
+
"service_context"
|
|
15340
|
+
],
|
|
15341
|
+
[
|
|
15342
|
+
"task",
|
|
15343
|
+
"video"
|
|
15344
|
+
],
|
|
15345
|
+
// Owner decision 2026-10-08: the presenter service video is hidden from the
|
|
15346
|
+
// MCP for now — dropshipping sellers ordered it for products and cancelled.
|
|
15347
|
+
// MCP clients get `create_animated_video` instead. Flip back to
|
|
15348
|
+
// SHARED_CHANNEL_EXPOSURE to restore it.
|
|
15349
|
+
WHATSAPP_ONLY_CHANNEL_EXPOSURE
|
|
15350
|
+
),
|
|
15336
15351
|
defineCapability("edit_image_creative", "50eca473829328dfb63b9cbae03a9835b79c510e29528563e09b7eb3e5e9bca4", "credit_consuming", "creative", [
|
|
15337
15352
|
"credit_consuming",
|
|
15338
15353
|
"state_change"
|
|
@@ -18120,7 +18135,7 @@ var ApiClient = class {
|
|
|
18120
18135
|
};
|
|
18121
18136
|
|
|
18122
18137
|
// src/index.ts
|
|
18123
|
-
var MCP_VERSION = "
|
|
18138
|
+
var MCP_VERSION = "9.0.0";
|
|
18124
18139
|
|
|
18125
18140
|
// src/meta-upload-app.ts
|
|
18126
18141
|
import { readFileSync } from "fs";
|
|
@@ -20722,7 +20737,7 @@ function renderAnimatedVideoStatus(result) {
|
|
|
20722
20737
|
__name(renderAnimatedVideoStatus, "renderAnimatedVideoStatus");
|
|
20723
20738
|
function registerAnimatedVideoTools(server, api) {
|
|
20724
20739
|
server.registerTool("create_animated_video", {
|
|
20725
|
-
description: guidance.summary + ` Hace un video animado (motion graphics) de un SERVICIO a partir del enlace de su p\xE1gina: textos, formas y la identidad visual del sitio, con m\xFAsica y efectos, sin presentador ni voz en off. Esta acci\xF3n consume cr\xE9ditos: confirma formato, duraci\xF3n, idioma y precio con el usuario antes de llamarla. Precio fijo por duraci\xF3n: ${describeAnimatedVideoPrices()}; si falla, se devuelve. Tarda varios minutos, m\xE1s si hay otros videos en la cola. Devuelve un taskId: sigue el avance con get_task_status (etapa, posici\xF3n en la cola, % de render, lo que va haciendo y vista previa) hasta done, que trae el enlace del MP4, o error, que trae el motivo.
|
|
20740
|
+
description: guidance.summary + ` Hace un video animado (motion graphics) de un SERVICIO a partir del enlace de su p\xE1gina: textos, formas y la identidad visual del sitio, con m\xFAsica y efectos, sin presentador ni voz en off. Esta acci\xF3n consume cr\xE9ditos: confirma formato, duraci\xF3n, idioma y precio con el usuario antes de llamarla. Precio fijo por duraci\xF3n: ${describeAnimatedVideoPrices()}; si falla, se devuelve. Tarda varios minutos, m\xE1s si hay otros videos en la cola. Devuelve un taskId: sigue el avance con get_task_status (etapa, posici\xF3n en la cola, % de render, lo que va haciendo y vista previa) hasta done, que trae el enlace del MP4, o error, que trae el motivo. Es el \xFAnico video de servicio disponible por ahora: no ofrezcas un video con presentador. Puede no estar disponible para todas las cuentas: si responde que la funci\xF3n no est\xE1 disponible, dilo y no ofrezcas alternativas pagadas.`,
|
|
20726
20741
|
inputSchema: CreateAnimatedVideoInput.shape,
|
|
20727
20742
|
annotations: CREATES_PAID_OPEN_WORLD
|
|
20728
20743
|
}, async (input) => {
|
|
@@ -20827,7 +20842,7 @@ function renderCreateProductTaskAvoidWhenForMcp(fragment) {
|
|
|
20827
20842
|
__name(renderCreateProductTaskAvoidWhenForMcp, "renderCreateProductTaskAvoidWhenForMcp");
|
|
20828
20843
|
var createProductTaskDefaultDescription = renderCreateProductTaskDefaultForMcp(createProductTaskGuidance.defaults[0]);
|
|
20829
20844
|
var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenForMcp(createProductTaskGuidance.avoidWhen[0]);
|
|
20830
|
-
var
|
|
20845
|
+
var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
|
|
20831
20846
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
20832
20847
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
20833
20848
|
var CreateProductTaskInput = z86.object({
|
|
@@ -21262,7 +21277,7 @@ async function fetchAnimatedVideoResult(api, taskId, signal, serviceMode = void
|
|
|
21262
21277
|
}
|
|
21263
21278
|
}
|
|
21264
21279
|
__name(fetchAnimatedVideoResult, "fetchAnimatedVideoResult");
|
|
21265
|
-
function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http" } = {}) {
|
|
21280
|
+
function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http", serviceVideo = CREATE_SERVICE_VIDEO_ON_MCP } = {}) {
|
|
21266
21281
|
server.registerTool("create_product_task", {
|
|
21267
21282
|
description: createProductTaskGuidance.summary + ` ${createProductTaskDefaultDescription} \xDAsala cuando el usuario pide todo o varios outputs, no creando tareas individuales. Usa images para solicitudes directas. Usa projectId \xFAnicamente si el usuario pidi\xF3 expl\xEDcitamente continuar el proyecto guiado que acaba de costear; nunca busques, infieras ni menciones proyectos previos.
|
|
21268
21283
|
|
|
@@ -21385,97 +21400,100 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
21385
21400
|
throw translateError(e);
|
|
21386
21401
|
}
|
|
21387
21402
|
});
|
|
21388
|
-
|
|
21389
|
-
|
|
21390
|
-
|
|
21391
|
-
|
|
21392
|
-
|
|
21393
|
-
|
|
21394
|
-
|
|
21395
|
-
|
|
21396
|
-
|
|
21397
|
-
|
|
21398
|
-
|
|
21399
|
-
|
|
21400
|
-
|
|
21401
|
-
|
|
21402
|
-
|
|
21403
|
-
|
|
21404
|
-
|
|
21405
|
-
|
|
21406
|
-
|
|
21407
|
-
|
|
21408
|
-
|
|
21409
|
-
|
|
21410
|
-
|
|
21411
|
-
|
|
21412
|
-
|
|
21413
|
-
|
|
21414
|
-
|
|
21415
|
-
|
|
21416
|
-
|
|
21417
|
-
|
|
21418
|
-
|
|
21419
|
-
|
|
21420
|
-
|
|
21421
|
-
|
|
21422
|
-
|
|
21423
|
-
|
|
21424
|
-
|
|
21425
|
-
|
|
21426
|
-
|
|
21427
|
-
|
|
21428
|
-
|
|
21429
|
-
|
|
21430
|
-
|
|
21431
|
-
|
|
21432
|
-
|
|
21433
|
-
|
|
21434
|
-
|
|
21435
|
-
|
|
21436
|
-
|
|
21437
|
-
if (
|
|
21438
|
-
|
|
21439
|
-
|
|
21440
|
-
|
|
21441
|
-
|
|
21403
|
+
if (serviceVideo) {
|
|
21404
|
+
const createServiceVideoGuidance = getProductMakerCapabilityModelGuidance("create_service_video");
|
|
21405
|
+
server.registerTool("create_service_video", {
|
|
21406
|
+
description: 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.",
|
|
21407
|
+
inputSchema: CreateServiceVideoInput.shape,
|
|
21408
|
+
annotations: CREATES_PAID_OPEN_WORLD
|
|
21409
|
+
}, async (input) => {
|
|
21410
|
+
try {
|
|
21411
|
+
if (input.videoQuality === "medium" && input.videoResolution === "720p") {
|
|
21412
|
+
throw mcp(McpErrorCode.INVALID_INPUT, 'videoResolution "720p" no est\xE1 disponible con videoQuality "medium" en videos de servicio (Medio = 768P). Usa "480p" o elige "economy"/"pro".');
|
|
21413
|
+
}
|
|
21414
|
+
await requirePaidCreativeConfirmation(server, `Video de servicio en ${input.language}. Modo: ${input.reviewMode === "automatic" ? "la IA decide todo" : "reviews conversacionales"}.`);
|
|
21415
|
+
const created = await api.postJson("/v2/ingest", {
|
|
21416
|
+
taskType: "service",
|
|
21417
|
+
serviceLandingUrl: input.landingUrl,
|
|
21418
|
+
...input.additionalContext ? {
|
|
21419
|
+
additionalContext: input.additionalContext
|
|
21420
|
+
} : {},
|
|
21421
|
+
lang: input.language,
|
|
21422
|
+
...input.voiceId ? {
|
|
21423
|
+
voiceId: input.voiceId
|
|
21424
|
+
} : {},
|
|
21425
|
+
videoPreset: input.videoPreset,
|
|
21426
|
+
videoQuality: input.videoQuality,
|
|
21427
|
+
videoResolution: input.videoResolution,
|
|
21428
|
+
reviewMode: input.reviewMode,
|
|
21429
|
+
...input.brandId ? {
|
|
21430
|
+
brandId: input.brandId
|
|
21431
|
+
} : {},
|
|
21432
|
+
media: {
|
|
21433
|
+
assets: []
|
|
21434
|
+
},
|
|
21435
|
+
appDemoVideos: []
|
|
21436
|
+
}, {
|
|
21437
|
+
// The 2026-09-25 incident: four retries of this exact tool created
|
|
21438
|
+
// four charged service tasks because the host rephrased
|
|
21439
|
+
// `additionalContext` and flipped the landing between `/` and
|
|
21440
|
+
// `/es`. The derived key is stable across both rewrites (see
|
|
21441
|
+
// request-key.ts).
|
|
21442
|
+
idempotencyKey: derivePaidRequestKey({
|
|
21443
|
+
fingerprint: api.fingerprint(),
|
|
21444
|
+
tool: "create_service_video",
|
|
21445
|
+
input,
|
|
21446
|
+
nowMs: Date.now()
|
|
21447
|
+
})
|
|
21448
|
+
});
|
|
21449
|
+
const angles = await api.postJson(`/v1/tasks/${encodeURIComponent(created.taskId)}/service-angles`, {});
|
|
21450
|
+
const first = angles[0];
|
|
21451
|
+
const replayed = created.replayed === true;
|
|
21452
|
+
if (input.reviewMode === "automatic") {
|
|
21453
|
+
if (!first) throw new Error("ProductMaker no pudo crear un concepto para este servicio.");
|
|
21454
|
+
if (!(replayed && created.status !== "queued")) {
|
|
21455
|
+
await api.postJson(`/v1/tasks/${encodeURIComponent(created.taskId)}/service-angles/select`, {
|
|
21456
|
+
angleIds: [
|
|
21457
|
+
first.id
|
|
21458
|
+
]
|
|
21459
|
+
});
|
|
21460
|
+
}
|
|
21461
|
+
return asText({
|
|
21462
|
+
taskId: created.taskId,
|
|
21463
|
+
status: replayed ? created.status ?? "processing" : "processing",
|
|
21464
|
+
...replayed ? {
|
|
21465
|
+
replayed: true
|
|
21466
|
+
} : {},
|
|
21467
|
+
reviewMode: input.reviewMode,
|
|
21468
|
+
selectedConcept: first
|
|
21469
|
+
});
|
|
21470
|
+
}
|
|
21471
|
+
if (replayed && created.status !== "queued") {
|
|
21472
|
+
return asText({
|
|
21473
|
+
taskId: created.taskId,
|
|
21474
|
+
status: created.status,
|
|
21475
|
+
replayed: true,
|
|
21476
|
+
reviewMode: input.reviewMode,
|
|
21477
|
+
angles
|
|
21442
21478
|
});
|
|
21443
21479
|
}
|
|
21444
21480
|
return asText({
|
|
21445
21481
|
taskId: created.taskId,
|
|
21446
|
-
status:
|
|
21482
|
+
status: "waiting_for_user",
|
|
21447
21483
|
...replayed ? {
|
|
21448
21484
|
replayed: true
|
|
21449
21485
|
} : {},
|
|
21450
21486
|
reviewMode: input.reviewMode,
|
|
21451
|
-
|
|
21452
|
-
|
|
21453
|
-
|
|
21454
|
-
|
|
21455
|
-
return asText({
|
|
21456
|
-
taskId: created.taskId,
|
|
21457
|
-
status: created.status,
|
|
21458
|
-
replayed: true,
|
|
21459
|
-
reviewMode: input.reviewMode,
|
|
21460
|
-
angles
|
|
21487
|
+
pendingUserAction: {
|
|
21488
|
+
kind: "service_angle_approval",
|
|
21489
|
+
angles
|
|
21490
|
+
}
|
|
21461
21491
|
});
|
|
21492
|
+
} catch (e) {
|
|
21493
|
+
throw translateError(e);
|
|
21462
21494
|
}
|
|
21463
|
-
|
|
21464
|
-
|
|
21465
|
-
status: "waiting_for_user",
|
|
21466
|
-
...replayed ? {
|
|
21467
|
-
replayed: true
|
|
21468
|
-
} : {},
|
|
21469
|
-
reviewMode: input.reviewMode,
|
|
21470
|
-
pendingUserAction: {
|
|
21471
|
-
kind: "service_angle_approval",
|
|
21472
|
-
angles
|
|
21473
|
-
}
|
|
21474
|
-
});
|
|
21475
|
-
} catch (e) {
|
|
21476
|
-
throw translateError(e);
|
|
21477
|
-
}
|
|
21478
|
-
});
|
|
21495
|
+
});
|
|
21496
|
+
}
|
|
21479
21497
|
server.registerTool("verify_landing_commerce", {
|
|
21480
21498
|
description: getProductMakerCapabilityModelGuidance("verify_landing_commerce").summary + " Verifica una correcci\xF3n manual de precios, tachados o packs de una landing editable existente. Solo relee Shopify y los recibos externos; no cambia precios, inventario, SKU ni compra una edici\xF3n. Pasa taskId y editId de la edici\xF3n ya conocida; nunca inventes IDs ni pidas repetir el cambio. Devuelve el estado can\xF3nico por proveedor: conserva el aviso pendiente hasta confirmar los valores reales. Solo despu\xE9s de confirmar todos los valores, el servidor puede volver a habilitar la compra. Web guardada no demuestra publicaci\xF3n p\xFAblica ni checkout; muestra las correcciones y enlaces pendientes sin c\xF3digos t\xE9cnicos. La disponibilidad del editor conserva sus permisos actuales.",
|
|
21481
21499
|
inputSchema: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@productmaker/mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "ProductMaker MCP server — cost products, generate landing pages, UGC videos, and ad creatives, and publish to Shopify, Meta Ads, and TikTok Ads.",
|