@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 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
- META_WHATSAPP_DESTINATION_DISABLED: "META_WHATSAPP_DESTINATION_DISABLED",
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
- META_WHATSAPP_DESTINATION_DISABLED: "WhatsApp destination is not enabled for this Meta account. Change the ad destination or enable WhatsApp Business on the account.",
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.META_WHATSAPP_DESTINATION_DISABLED,
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
- META_WHATSAPP_DESTINATION_DISABLED: "META_WHATSAPP_DESTINATION_DISABLED",
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
- META_WHATSAPP_DESTINATION_DISABLED: "WhatsApp destination is not enabled for this Meta account. Change the ad destination or enable WhatsApp Business on the account.",
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.META_WHATSAPP_DESTINATION_DISABLED,
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.1.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.",