@productmaker/mcp 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/http.js +22 -5
- package/dist/stdio.js +22 -5
- package/package.json +1 -1
package/dist/http.js
CHANGED
|
@@ -676,7 +676,8 @@ var McpErrorCode = {
|
|
|
676
676
|
META_AD_SET_BUDGET_REQUIRED: "META_AD_SET_BUDGET_REQUIRED",
|
|
677
677
|
META_DAILY_BUDGET_TOO_HIGH: "META_DAILY_BUDGET_TOO_HIGH",
|
|
678
678
|
META_CAMPAIGN_CONFIG_INVALID: "META_CAMPAIGN_CONFIG_INVALID",
|
|
679
|
-
|
|
679
|
+
META_WHATSAPP_INVALID_NUMBER: "META_WHATSAPP_INVALID_NUMBER",
|
|
680
|
+
META_INVALID_CTA: "META_INVALID_CTA",
|
|
680
681
|
// TikTok Ads
|
|
681
682
|
TIKTOK_NOT_CONNECTED: "TIKTOK_NOT_CONNECTED",
|
|
682
683
|
TIKTOK_TOKEN_EXPIRED: "TIKTOK_TOKEN_EXPIRED",
|
|
@@ -726,7 +727,8 @@ var CODE_MESSAGES = {
|
|
|
726
727
|
META_AD_SET_BUDGET_REQUIRED: "This campaign configuration requires ad-set-level budget, not campaign-level.",
|
|
727
728
|
META_DAILY_BUDGET_TOO_HIGH: "The daily budget exceeds the maximum allowed by Meta for this account. Lower it and retry.",
|
|
728
729
|
META_CAMPAIGN_CONFIG_INVALID: "Campaign configuration is invalid. Verify `dailyBudgetUsd`, `targetCountries`, and `campaignName`.",
|
|
729
|
-
|
|
730
|
+
META_WHATSAPP_INVALID_NUMBER: "The WhatsApp `phoneNumber` is invalid. Pass it in international format with the country code (e.g. +573001234567).",
|
|
731
|
+
META_INVALID_CTA: "Meta could not configure the ad button (invalid call-to-action). Try again or contact support.",
|
|
730
732
|
// TikTok
|
|
731
733
|
TIKTOK_NOT_CONNECTED: "TikTok Ads is not connected. Connect it at https://productmaker.app/integrations.",
|
|
732
734
|
TIKTOK_TOKEN_EXPIRED: "The TikTok session expired. Reconnect it at https://productmaker.app/integrations.",
|
|
@@ -789,6 +791,7 @@ var INVALID_PARAM_CODES = /* @__PURE__ */ new Set([
|
|
|
789
791
|
McpErrorCode.META_NO_LANDING_URL,
|
|
790
792
|
McpErrorCode.META_DAILY_BUDGET_TOO_HIGH,
|
|
791
793
|
McpErrorCode.META_CAMPAIGN_CONFIG_INVALID,
|
|
794
|
+
McpErrorCode.META_WHATSAPP_INVALID_NUMBER,
|
|
792
795
|
McpErrorCode.META_BID_STRATEGY_REQUIRES_AMOUNT,
|
|
793
796
|
McpErrorCode.META_CBO_BUDGET_CONFLICT,
|
|
794
797
|
McpErrorCode.META_BUDGET_MODE_CONFLICT,
|
|
@@ -847,7 +850,8 @@ var PASSTHROUGH_CODES = /* @__PURE__ */ new Set([
|
|
|
847
850
|
McpErrorCode.META_AD_SET_BUDGET_REQUIRED,
|
|
848
851
|
McpErrorCode.META_DAILY_BUDGET_TOO_HIGH,
|
|
849
852
|
McpErrorCode.META_CAMPAIGN_CONFIG_INVALID,
|
|
850
|
-
McpErrorCode.
|
|
853
|
+
McpErrorCode.META_WHATSAPP_INVALID_NUMBER,
|
|
854
|
+
McpErrorCode.META_INVALID_CTA,
|
|
851
855
|
// TikTok
|
|
852
856
|
McpErrorCode.TIKTOK_NOT_CONNECTED,
|
|
853
857
|
McpErrorCode.TIKTOK_TOKEN_EXPIRED,
|
|
@@ -1680,7 +1684,10 @@ var MetaInput = z6.object({
|
|
|
1680
1684
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
1681
1685
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
1682
1686
|
* (Meta's primary-text limit). */
|
|
1683
|
-
primaryText: z6.string().trim().min(1).max(500).optional()
|
|
1687
|
+
primaryText: z6.string().trim().min(1).max(500).optional(),
|
|
1688
|
+
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
1689
|
+
* (wa.me) instead of a landing page. */
|
|
1690
|
+
phoneNumber: z6.string().min(8).max(32).optional()
|
|
1684
1691
|
});
|
|
1685
1692
|
var TikTokInput = z6.object({
|
|
1686
1693
|
taskId: z6.string().min(1),
|
|
@@ -1716,7 +1723,7 @@ function registerPublishTools(server, api) {
|
|
|
1716
1723
|
throw translateError(e);
|
|
1717
1724
|
}
|
|
1718
1725
|
});
|
|
1719
|
-
server.tool("publish_to_meta", "Crea una campa\xF1a de Meta Ads (Facebook/Instagram) desde la tarea. La campa\xF1a se crea SIEMPRE en estado PAUSED \u2014 el usuario la activa manualmente en Meta Ads Manager. Use `list_meta_ad_accounts` antes para un adAccountId v\xE1lido. `pixelId` opcional pero recomendado para tracking. `angleIndexes` (opcional): selecciona qu\xE9 \xE1ngulos publicar \u2014 si la tarea gener\xF3 3 \xE1ngulos y el usuario solo quiere los #0 y #2, pasa [0,2]; omitir = publicar todos. `campaignConfig` (opcional): `dailyBudgetUsd` (presupuesto diario en USD, ej. 25), `targetCountries` (c\xF3digos ISO-2, m\xE1x 1 para Meta), `campaignName` (m\xE1x 100 chars). `primaryText` (opcional, m\xE1x 500 chars): override del copy del anuncio \u2014 solo \xFAsalo si el usuario te pas\xF3 un texto espec\xEDfico; si no, ProductMaker usa el copy auto-generado de la tarea. Despu\xE9s de publicar usa `get_meta_campaign_status` para chequear el estado.", MetaInput.shape, async ({ taskId, campaignConfig, primaryText, ...rest }) => {
|
|
1726
|
+
server.tool("publish_to_meta", "Crea una campa\xF1a de Meta Ads (Facebook/Instagram) desde la tarea. La campa\xF1a se crea SIEMPRE en estado PAUSED \u2014 el usuario la activa manualmente en Meta Ads Manager. Use `list_meta_ad_accounts` antes para un adAccountId v\xE1lido. `pixelId` opcional pero recomendado para tracking. `angleIndexes` (opcional): selecciona qu\xE9 \xE1ngulos publicar \u2014 si la tarea gener\xF3 3 \xE1ngulos y el usuario solo quiere los #0 y #2, pasa [0,2]; omitir = publicar todos. `campaignConfig` (opcional): `dailyBudgetUsd` (presupuesto diario en USD, ej. 25), `targetCountries` (c\xF3digos ISO-2, m\xE1x 1 para Meta), `campaignName` (m\xE1x 100 chars). `primaryText` (opcional, m\xE1x 500 chars): override del copy del anuncio \u2014 solo \xFAsalo si el usuario te pas\xF3 un texto espec\xEDfico; si no, ProductMaker usa el copy auto-generado de la tarea. `phoneNumber` (opcional): si el usuario quiere que el bot\xF3n del anuncio abra un chat de WhatsApp en vez de una landing, pasa el n\xFAmero (con c\xF3digo de pa\xEDs, ej. +573001234567) \u2014 no hace falta `landingUrl` en ese caso. Despu\xE9s de publicar usa `get_meta_campaign_status` para chequear el estado.", MetaInput.shape, async ({ taskId, campaignConfig, primaryText, phoneNumber, ...rest }) => {
|
|
1720
1727
|
try {
|
|
1721
1728
|
const body = {
|
|
1722
1729
|
...rest
|
|
@@ -1724,6 +1731,16 @@ function registerPublishTools(server, api) {
|
|
|
1724
1731
|
if (campaignConfig) {
|
|
1725
1732
|
body.campaignOverrides = toMetaCampaignOverrides(campaignConfig);
|
|
1726
1733
|
}
|
|
1734
|
+
if (phoneNumber) {
|
|
1735
|
+
const overrides = isRecord(body.campaignOverrides) ? body.campaignOverrides : {};
|
|
1736
|
+
body.campaignOverrides = {
|
|
1737
|
+
...overrides,
|
|
1738
|
+
destination: {
|
|
1739
|
+
type: "whatsapp",
|
|
1740
|
+
phoneNumber
|
|
1741
|
+
}
|
|
1742
|
+
};
|
|
1743
|
+
}
|
|
1727
1744
|
if (primaryText) body.primaryText = primaryText;
|
|
1728
1745
|
const r = await api.postJson(`/v1/facebook/campaigns/from-task/${encodeURIComponent(taskId)}`, body);
|
|
1729
1746
|
return asText({
|
package/dist/stdio.js
CHANGED
|
@@ -673,7 +673,8 @@ var McpErrorCode = {
|
|
|
673
673
|
META_AD_SET_BUDGET_REQUIRED: "META_AD_SET_BUDGET_REQUIRED",
|
|
674
674
|
META_DAILY_BUDGET_TOO_HIGH: "META_DAILY_BUDGET_TOO_HIGH",
|
|
675
675
|
META_CAMPAIGN_CONFIG_INVALID: "META_CAMPAIGN_CONFIG_INVALID",
|
|
676
|
-
|
|
676
|
+
META_WHATSAPP_INVALID_NUMBER: "META_WHATSAPP_INVALID_NUMBER",
|
|
677
|
+
META_INVALID_CTA: "META_INVALID_CTA",
|
|
677
678
|
// TikTok Ads
|
|
678
679
|
TIKTOK_NOT_CONNECTED: "TIKTOK_NOT_CONNECTED",
|
|
679
680
|
TIKTOK_TOKEN_EXPIRED: "TIKTOK_TOKEN_EXPIRED",
|
|
@@ -723,7 +724,8 @@ var CODE_MESSAGES = {
|
|
|
723
724
|
META_AD_SET_BUDGET_REQUIRED: "This campaign configuration requires ad-set-level budget, not campaign-level.",
|
|
724
725
|
META_DAILY_BUDGET_TOO_HIGH: "The daily budget exceeds the maximum allowed by Meta for this account. Lower it and retry.",
|
|
725
726
|
META_CAMPAIGN_CONFIG_INVALID: "Campaign configuration is invalid. Verify `dailyBudgetUsd`, `targetCountries`, and `campaignName`.",
|
|
726
|
-
|
|
727
|
+
META_WHATSAPP_INVALID_NUMBER: "The WhatsApp `phoneNumber` is invalid. Pass it in international format with the country code (e.g. +573001234567).",
|
|
728
|
+
META_INVALID_CTA: "Meta could not configure the ad button (invalid call-to-action). Try again or contact support.",
|
|
727
729
|
// TikTok
|
|
728
730
|
TIKTOK_NOT_CONNECTED: "TikTok Ads is not connected. Connect it at https://productmaker.app/integrations.",
|
|
729
731
|
TIKTOK_TOKEN_EXPIRED: "The TikTok session expired. Reconnect it at https://productmaker.app/integrations.",
|
|
@@ -786,6 +788,7 @@ var INVALID_PARAM_CODES = /* @__PURE__ */ new Set([
|
|
|
786
788
|
McpErrorCode.META_NO_LANDING_URL,
|
|
787
789
|
McpErrorCode.META_DAILY_BUDGET_TOO_HIGH,
|
|
788
790
|
McpErrorCode.META_CAMPAIGN_CONFIG_INVALID,
|
|
791
|
+
McpErrorCode.META_WHATSAPP_INVALID_NUMBER,
|
|
789
792
|
McpErrorCode.META_BID_STRATEGY_REQUIRES_AMOUNT,
|
|
790
793
|
McpErrorCode.META_CBO_BUDGET_CONFLICT,
|
|
791
794
|
McpErrorCode.META_BUDGET_MODE_CONFLICT,
|
|
@@ -844,7 +847,8 @@ var PASSTHROUGH_CODES = /* @__PURE__ */ new Set([
|
|
|
844
847
|
McpErrorCode.META_AD_SET_BUDGET_REQUIRED,
|
|
845
848
|
McpErrorCode.META_DAILY_BUDGET_TOO_HIGH,
|
|
846
849
|
McpErrorCode.META_CAMPAIGN_CONFIG_INVALID,
|
|
847
|
-
McpErrorCode.
|
|
850
|
+
McpErrorCode.META_WHATSAPP_INVALID_NUMBER,
|
|
851
|
+
McpErrorCode.META_INVALID_CTA,
|
|
848
852
|
// TikTok
|
|
849
853
|
McpErrorCode.TIKTOK_NOT_CONNECTED,
|
|
850
854
|
McpErrorCode.TIKTOK_TOKEN_EXPIRED,
|
|
@@ -1636,7 +1640,10 @@ var MetaInput = z6.object({
|
|
|
1636
1640
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
1637
1641
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
1638
1642
|
* (Meta's primary-text limit). */
|
|
1639
|
-
primaryText: z6.string().trim().min(1).max(500).optional()
|
|
1643
|
+
primaryText: z6.string().trim().min(1).max(500).optional(),
|
|
1644
|
+
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
1645
|
+
* (wa.me) instead of a landing page. */
|
|
1646
|
+
phoneNumber: z6.string().min(8).max(32).optional()
|
|
1640
1647
|
});
|
|
1641
1648
|
var TikTokInput = z6.object({
|
|
1642
1649
|
taskId: z6.string().min(1),
|
|
@@ -1672,7 +1679,7 @@ function registerPublishTools(server, api) {
|
|
|
1672
1679
|
throw translateError(e);
|
|
1673
1680
|
}
|
|
1674
1681
|
});
|
|
1675
|
-
server.tool("publish_to_meta", "Crea una campa\xF1a de Meta Ads (Facebook/Instagram) desde la tarea. La campa\xF1a se crea SIEMPRE en estado PAUSED \u2014 el usuario la activa manualmente en Meta Ads Manager. Use `list_meta_ad_accounts` antes para un adAccountId v\xE1lido. `pixelId` opcional pero recomendado para tracking. `angleIndexes` (opcional): selecciona qu\xE9 \xE1ngulos publicar \u2014 si la tarea gener\xF3 3 \xE1ngulos y el usuario solo quiere los #0 y #2, pasa [0,2]; omitir = publicar todos. `campaignConfig` (opcional): `dailyBudgetUsd` (presupuesto diario en USD, ej. 25), `targetCountries` (c\xF3digos ISO-2, m\xE1x 1 para Meta), `campaignName` (m\xE1x 100 chars). `primaryText` (opcional, m\xE1x 500 chars): override del copy del anuncio \u2014 solo \xFAsalo si el usuario te pas\xF3 un texto espec\xEDfico; si no, ProductMaker usa el copy auto-generado de la tarea. Despu\xE9s de publicar usa `get_meta_campaign_status` para chequear el estado.", MetaInput.shape, async ({ taskId, campaignConfig, primaryText, ...rest }) => {
|
|
1682
|
+
server.tool("publish_to_meta", "Crea una campa\xF1a de Meta Ads (Facebook/Instagram) desde la tarea. La campa\xF1a se crea SIEMPRE en estado PAUSED \u2014 el usuario la activa manualmente en Meta Ads Manager. Use `list_meta_ad_accounts` antes para un adAccountId v\xE1lido. `pixelId` opcional pero recomendado para tracking. `angleIndexes` (opcional): selecciona qu\xE9 \xE1ngulos publicar \u2014 si la tarea gener\xF3 3 \xE1ngulos y el usuario solo quiere los #0 y #2, pasa [0,2]; omitir = publicar todos. `campaignConfig` (opcional): `dailyBudgetUsd` (presupuesto diario en USD, ej. 25), `targetCountries` (c\xF3digos ISO-2, m\xE1x 1 para Meta), `campaignName` (m\xE1x 100 chars). `primaryText` (opcional, m\xE1x 500 chars): override del copy del anuncio \u2014 solo \xFAsalo si el usuario te pas\xF3 un texto espec\xEDfico; si no, ProductMaker usa el copy auto-generado de la tarea. `phoneNumber` (opcional): si el usuario quiere que el bot\xF3n del anuncio abra un chat de WhatsApp en vez de una landing, pasa el n\xFAmero (con c\xF3digo de pa\xEDs, ej. +573001234567) \u2014 no hace falta `landingUrl` en ese caso. Despu\xE9s de publicar usa `get_meta_campaign_status` para chequear el estado.", MetaInput.shape, async ({ taskId, campaignConfig, primaryText, phoneNumber, ...rest }) => {
|
|
1676
1683
|
try {
|
|
1677
1684
|
const body = {
|
|
1678
1685
|
...rest
|
|
@@ -1680,6 +1687,16 @@ function registerPublishTools(server, api) {
|
|
|
1680
1687
|
if (campaignConfig) {
|
|
1681
1688
|
body.campaignOverrides = toMetaCampaignOverrides(campaignConfig);
|
|
1682
1689
|
}
|
|
1690
|
+
if (phoneNumber) {
|
|
1691
|
+
const overrides = isRecord(body.campaignOverrides) ? body.campaignOverrides : {};
|
|
1692
|
+
body.campaignOverrides = {
|
|
1693
|
+
...overrides,
|
|
1694
|
+
destination: {
|
|
1695
|
+
type: "whatsapp",
|
|
1696
|
+
phoneNumber
|
|
1697
|
+
}
|
|
1698
|
+
};
|
|
1699
|
+
}
|
|
1683
1700
|
if (primaryText) body.primaryText = primaryText;
|
|
1684
1701
|
const r = await api.postJson(`/v1/facebook/campaigns/from-task/${encodeURIComponent(taskId)}`, body);
|
|
1685
1702
|
return asText({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@productmaker/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Product Maker MCP server — connect Claude Desktop, Claude Code, ChatGPT, or Gemini to Product Maker AI to generate dropshipping landing pages, UGC videos, and ad creatives, and publish to Shopify and Meta Ads from your AI assistant.",
|