# Marketing: herramientas MCP

Las herramientas MCP de Marketing y sus operaciones: campañas, listas, plantillas, automatizaciones, pruebas A/B, informes, entregabilidad y medición.

Marketing no tiene API externa con clave: para automatizarlo desde tu código o desde un asistente de IA se usan las herramientas MCP del servidor **Marketing** (`POST /api/mcp/marketing`), con el token de OAuth de una persona y sus permisos. Esta página es el catálogo de esas herramientas y sus operaciones; cómo se conecta, cómo se autoriza y los casos completos están en [Servidor MCP Marketing](https://os.utilia.ai/docs/developers/mcp/marketing).

Cada operación se controla con su permiso concreto y con el scope del token; las que crean fichas del CRM o disparan envíos masivos exigen permisos adicionales o `confirm: true`.

## Herramientas y operaciones

### `marketing_campaigns`

Gestión completa de campañas. Operaciones: `list`, `get`, `create`, `update`,
`delete`, `send`, `get_send_status`, `schedule`, `pause`, `resume`, `cancel`,
`duplicate`, `test_send`, `preview`, `preview_html`, `by_contact`,
`get_branding`, `update_branding`, `conversion_candidates`, `convert_clicks`,
`delivery_summary`, `export`, `list_recipients`, `recipients_preview`,
`add_recipients`, `remove_recipient`, `remove_recipients`, `retry_failed`,
`failure_summary`, `sending_quota`, `edit_content`, `engagement_breakdown`,
`resend_preview`, `create_resend` y `list_resends`.

`create` y `update` aceptan además `utmMode`, `utmParams` y
`trackingIdentityEnabled` (los tres anulables, donde `null` significa «hereda de
la organización»), y `get` devuelve el bloque `tracking` con la configuración
efectiva ya resuelta. **No son operaciones nuevas**: son campos del mismo
`create` y `update` de siempre.

- **`pause` / `resume`**: pausan y reanudan un envío en curso sin perder el
  progreso (a diferencia de `cancel`, que es irreversible). Exigen
  `EMAIL_MARKETING_SEND`, igual que el envío.
- **`conversion_candidates`**: lectura del resumen de clicantes (permiso
  `EMAIL_MARKETING_VIEW`).
- **`convert_clicks`**: crea oportunidades y/o leads. Exige los permisos del
  CRM (`LEADS_CREATE` u `OPPORTUNITIES_CREATE`), no un permiso de marketing.
- **`preview_html`**: devuelve el HTML renderizado, opcionalmente con un
  branding de prueba sin persistir nada.
- **`get_branding` / `update_branding`**: consultan y modifican el branding
  propio de la campaña (que hereda del branding de la organización).
- **`export`**: descarga el informe de la campaña en CSV (permiso
  `EMAIL_MARKETING_EXPORT`).
- **`engagement_breakdown`**: reparto de la audiencia en los siete grupos de
  comportamiento. **No son porciones de una tarta**: `opened` ya contiene a
  `clicked` y a `opened_not_clicked`. Y `not_opened` **excluye siempre a quien
  pulsó**. Permiso `EMAIL_MARKETING_VIEW`, **sin capacidad de plan**.
- **`resend_preview` / `create_resend` / `list_resends`**: los segundos
  intentos. Solo admiten los grupos `not_opened` y `opened_not_clicked` —a
  quien se quejó, se dio de baja o rebotó no se le vuelve a escribir—, exigen
  un asunto distinto del original, admiten como mucho dos por campaña y **no
  tocan los contadores de la campaña original**. Los dos primeros exigen la
  capacidad **Analítica avanzada de Marketing**; `create_resend` pide además
  `EMAIL_MARKETING_CREATE`.
- **`list_recipients`**: gana los filtros `isExcluded` (incluidos frente a
  excluidos del envío) y `engagement` (qué hizo la persona), que es
  **ortogonal** a `sendStatus`. Filtrar por `engagement` exige la capacidad
  **Analítica avanzada de Marketing**; el resto de filtros, no. Los campos
  `deviceType`, `emailClient` y `country` de cada destinatario **se omiten**
  sin el permiso `EMAIL_MARKETING_VIEW_RECIPIENT_DETAIL` y el scope
  `marketing:recipients:detail:view`: la operación responde igual, esos tres
  campos no viajan y llega `recipientDetailIncluded: false`. **Nunca devuelve
  un 403 por eso.**

### `marketing_lists`

Listas, segmentos del CRM, suscriptores e interés. Operaciones: `list`, `get`,
`create`, `update`, `delete`, `preview_segment`, `add_contact`,
`remove_contact`, `add_subscribers`, `members`, `list_subscribers`,
`update_subscriber`, `crm_countries`, `calculate`, `engagement_summary`,
`set_aside_inactive` y `reactivate_subscriber`.

| Operación | Qué devuelve | Permiso | Capacidad de plan |
| - | - | - | - |
| `list_subscribers` | Suscriptores con su interés y su estado de apartado. Filtros `engagementBand` y `setAside` | `EMAIL_MARKETING_VIEW` | — |
| `members` | Audiencia EFECTIVA: activos manuales más el segmento del CRM resuelto | `EMAIL_MARKETING_VIEW` | — |
| `engagement_summary` | Recuento por banda, apartados y fecha del cálculo | `EMAIL_MARKETING_VIEW` | Analítica avanzada de Marketing |
| `set_aside_inactive` | Aparta inactivos. `dryRun` por defecto | `EMAIL_MARKETING_LISTS_MANAGE` | Analítica avanzada de Marketing |
| `reactivate_subscriber` | Vuelve a incluir a un apartado | `EMAIL_MARKETING_LISTS_MANAGE` | Analítica avanzada de Marketing |

`members` y `list_subscribers` no son lo mismo: `members` devuelve la
audiencia **efectiva** de la lista y no admite filtrar por suscriptor;
`list_subscribers` devuelve los **suscriptores** con su interés y su
estado de apartado, y es la única forma de volver a encontrar a quien
se apartó.

Apartar no es dar de baja: `set_aside_inactive` **no toca** el estado de
suscripción, ni la base jurídica, ni la prueba del consentimiento, ni la
fecha de confirmación. Esas personas siguen suscritas, dejan de recibir
campañas y se pueden reincorporar cuando quieras. Los mínimos (90 días y
2 correos recibidos) los aplica el servidor, no la interfaz.

### `marketing_deliverability`

Reputación, rebotes, quejas, comprobación de direcciones, control de frecuencia
y política de quejas. Operaciones: `reputation_summary`, `bounce_rate`,
`complaint_rate`, `score_by_domain`, `blocklist_check`, `dashboard_summary`,
`measurement_coverage`, `address_check`, `frequency_cap_get`,
`frequency_cap_set`, `campaign_deliverability`, `campaign_bounce_analysis`,
`get_complaint_policy` y `set_complaint_policy`.

**Esta herramienta ha dejado de ser de solo lectura**: `set_complaint_policy`
cambia la configuración de envío de la organización.

| Operación | Qué devuelve | Permiso | Scope OAuth |
| - | - | - | - |
| `get_complaint_policy` | Umbral propio, pausa automática, techo de la plataforma, y si hay bloqueo vigente, por qué y hasta cuándo | `EMAIL_MARKETING_DELIVERABILITY_MANAGE` o `EMAIL_MARKETING_VIEW` | `marketing:deliverability:view` o `marketing:campaigns:view` |
| `set_complaint_policy` | Solo `thresholdBps` (10 a 30) y `autoPauseEnabled` | `EMAIL_MARKETING_DELIVERABILITY_MANAGE` | `marketing:deliverability:manage` |

`set_complaint_policy` solo permite ser **más estricto**. El 0,3 % que
aplican Gmail y Yahoo y el bloqueo del servidor compartido protegen el
correo de todas las organizaciones que lo comparten, así que no se
configuran por API. Un bloqueo se revisa a diario y **se levanta solo**
en cuanto la tasa baja, o cuando deja de poder evaluarse por falta de
volumen.

### `marketing_reports`

Informes y analítica de campañas. Es el espejo exacto de los endpoints de la
sección anterior: mismas cifras, mismos permisos y mismo ámbito de filas.
Operaciones: `campaign_stats`, `engagement_overview`, `click_through`,
`top_campaigns`, `engagement_heatmap`, `engagement_trends`,
`campaign_attribution`, `attribution_summary`, `entity_origin`, `complaints`,
`link_heatmap` y `audience_tech`. Todas son de **solo lectura**. Las seis
primeras y `complaints` **no exigen capacidad de plan**; las de atribución y
las dos de F4 sí (ver más abajo).

- **`complaints`**: quejas por correo no deseado del periodo, agrupadas por
  campaña o por **dominio del destinatario** (`complaintsGroupBy`). La tasa
  llega como `null` —**nunca como 0**— cuando la organización no tiene ninguna
  vía por la que enterarse, y cuando hay medición es un **suelo**. Permiso
  `EMAIL_MARKETING_ANALYTICS`.
- **`link_heatmap`**: qué enlace concreto se pulsa, con su posición, su texto
  visible y el reparto de la atención. Distingue **dos botones que llevan al
  mismo sitio**, que es lo que `click_through` no puede hacer. Permiso
  `EMAIL_MARKETING_VIEW` y capacidad **Analítica avanzada de Marketing**. El
  desglose por dirección de destino de siempre (`click_through`) **sigue siendo
  gratuito**.
- **`audience_tech`**: aparato, programa de correo o país (`dimension`), a
  partir de los clics por defecto (`source`). El país es **aproximado** y sale
  de una base de datos local, nunca de una consulta a un tercero. Con menos de
  20 clics llega `sufficientSample: false` y no debe presentarse. Permiso
  `EMAIL_MARKETING_VIEW` y capacidad **Analítica avanzada de Marketing**.

| Operación | Qué devuelve | Permiso | Scope OAuth |
| - | - | - | - |
| `campaign_stats` | Métricas de una campaña (`campaignId`). | `EMAIL_MARKETING_VIEW` | `marketing:reports:view` o `marketing:campaigns:view` |
| `engagement_overview` | Agregados del periodo (`dateFrom`, `dateTo`). | `EMAIL_MARKETING_VIEW` | `marketing:reports:view` o `marketing:campaigns:view` |
| `click_through` | Clics por dirección de destino de una campaña. | `EMAIL_MARKETING_VIEW` | `marketing:reports:view` o `marketing:campaigns:view` |
| `top_campaigns` | Ranking del periodo (`limit`, `metric`, `minSent`). | `EMAIL_MARKETING_ANALYTICS` | `marketing:reports:view` |
| `engagement_heatmap` | Mapa por hora o por día (`groupBy`). | `EMAIL_MARKETING_ANALYTICS` | `marketing:reports:view` |
| `engagement_trends` | Serie temporal (`granularity`: `day`, `week` o `month`). | `EMAIL_MARKETING_ANALYTICS` | `marketing:reports:view` |
| `campaign_attribution` | Negocio originado por una campaña (`campaignId`; con `breakdown`, la lista paginada). Capacidad **Negocio por campaña**. | `EMAIL_MARKETING_ANALYTICS` | `marketing:reports:view` |
| `attribution_summary` | El mismo agregado para un periodo (`days` o `dateFrom`/`dateTo`). Capacidad **Negocio por campaña**. | `EMAIL_MARKETING_ANALYTICS` | `marketing:reports:view` |
| `entity_origin` | De qué campaña vino una oportunidad o un cliente (`entityType` + `entityId`). Sin capacidad de plan. | `EMAIL_MARKETING_VIEW` más el de la ficha | `marketing:reports:view` o `marketing:campaigns:view` |

- **`campaign_stats`** devuelve el bloque `stats` con los recuentos
  (`accepted`, `delivered`, `sent`, `opened`, `clicked`, `bounced`,
  `unsubscribed`), las tasas (`acceptanceRate`, `openRate`, `clickRate`,
  `clickToOpenRate`, `bounceRate`, `unsubscribeRate`), el bloque
  `metricsAvailability` y la señal `bounceDetectionEnabled`. **Una métrica que
  `metricsAvailability` marca como no disponible no es un cero**: preséntela
  como «sin datos» o su asistente afirmará algo que nadie ha medido.
- **`clickToOpenRate`** («Clics por apertura») se divide entre las **aperturas
  únicas**, no entre los correos aceptados, y **puede superar el 100 %** cuando
  hay gente que pulsa sin que se registre su apertura. No lo recorte.
- **`top_campaigns`** admite `metric: OPENS | CLICKS | CTR | CONVERSIONS |
  REVENUE_ISSUED | REVENUE_COLLECTED`. `CONVERSIONS` ordena por
  **oportunidades originadas**, no por ventas cerradas; hasta agosto de 2026
  devolvía un error diciendo que el producto no registra conversiones, y eso ya
  no es cierto. Las dos métricas de dinero exigen `INVOICES_VIEW` y la
  capacidad de plan. El ranking **excluye los reenvíos y las variantes de una
  prueba A/B**, que competirían contra su propia campaña madre. `minSent` deja
  fuera las campañas de poco volumen, donde una tasa altísima sobre tres envíos
  no dice nada.
- **`click_through`** agrupa por la dirección **original** del enlace, no por
  la dirección de redirección con la que se mide el clic: dos destinatarios que
  pulsan el mismo enlace cuentan en la misma fila.

**Los importes no viajan por el servidor MCP de marketing.** El token de `/api/mcp/marketing` solo admite scopes `marketing:*`,
`org:email-senders:*` y `crm:*:view`: **nunca puede portar
`finance:invoices:view`**. Por ese carril llegan los recuentos y las tasas de
conversión, y el bloque de dinero se declara ausente en `excludedBlocks` con
`reason: "missing_scope"`. No lo presentes como un cero. Las cifras están en la
pantalla de Marketing y en los endpoints REST de la sección anterior.

Por el mismo motivo, `entity_origin` cubre **oportunidad y cliente, pero no
factura**: el origen comercial de una factura está solo en
`GET /api/finance/invoices/:id/commercial-origin`.

> **Atención: Las facturas creadas desde fuera quedan fuera del negocio originado**
>
> La API externa v1 de facturas (`POST /external/v1/invoices`, `sdk.invoices.create()`)
> **no admite `opportunityId` ni `projectId`**, así que una factura emitida por una
> integración externa nace **sin vínculo comercial** y no aparecerá en el negocio
> originado por ninguna campaña.
>
> No es un fallo de medición: es que nadie escribió el vínculo. Si facturas desde
> fuera y quieres que ese dinero cuente, crea la factura desde el producto, desde
> la conversión de un presupuesto, desde la generación de una suscripción o por
> MCP con `crm_invoices`, que sí acepta `opportunityId`.

### `marketing_tracking_settings`

Configuración de medición de **la organización**. Tres operaciones: `get`,
`update` y `preview_link`.

| Operación | Qué hace | Permiso | Scope OAuth |
| - | - | - | - |
| `get` | Configuración vigente, con `capabilityActive` y `canManage` resueltos. | `EMAIL_MARKETING_VIEW` | `marketing:tracking:manage` o `marketing:campaigns:view` |
| `update` | Cambia `utmEnabled`, `utmTemplate`, `recipientTokenEnabled` y `recipientTokenTtlDays`. | `EMAIL_MARKETING_TRACKING_MANAGE` | `marketing:tracking:manage` |
| `preview_link` | Cómo quedaría un enlace (`url`, `campaignId` opcional). | `EMAIL_MARKETING_VIEW` | `marketing:tracking:manage` o `marketing:campaigns:view` |

- **`preview_link` es una función pura**: no escribe nada, no firma nada y **no emite ningún identificador de destinatario real**.
- **`update` solo exige capacidad de plan si la llamada trae `recipientTokenEnabled`.** Apagar los parámetros de origen no está detrás de ningún muro de pago.
- La plantilla admite cinco marcadores y ninguno más: `{{campaign.name}}`, `{{campaign.id}}`, `{{campaign.type}}`, `{{variant}}` y `{{date}}`.

Los formularios de captación reciben `captureUtm` y `utmPersistence` como
**propiedades** de `org_integrations_settings` → `lead_forms_create` y
`lead_forms_update`. **No hay operaciones nuevas** en esa herramienta.

**Con tipos en los dos SDK.** `marketing_reports` está cubierta **entera** en el SDK de JavaScript
(`sdk.mcp.marketing.reports.campaignStats(...)`, `engagementOverview`,
`clickThrough`, `topCampaigns`, `engagementHeatmap`, `engagementTrends`,
`campaignAttribution`, `attributionSummary` y `entityOrigin`), y también
`marketing_tracking_settings` (`sdk.mcp.marketing.trackingSettings.get()`,
`update(...)` y `previewLink(...)`) y `email_tracking_domains`
(`sdk.mcp.marketing.trackingDomains`, sus ocho operaciones). Los mismos nombres
en `snake_case` en el SDK de Python, en las variantes asíncrona y síncrona. Más en la
[referencia del SDK](https://os.utilia.ai/docs/developers/sdk/reference).

### `email_tracking_domains`

El dominio propio por el que **vuelve el clic**. Ocho operaciones: `list`,
`get`, `get_setup_instructions`, `create`, `verify`, `set_emission`,
`retry_certificate` y `retire`. Espejo exacto del controlador REST de arriba.

| Operación | Permiso | Scope OAuth |
| - | - | - |
| `list`, `get` | `EMAIL_MARKETING_VIEW` o cualquiera de los dos de gestión | `marketing:deliverability:view` o `marketing:campaigns:view` |
| `get_setup_instructions` | Los dos de gestión | `marketing:deliverability:view` |
| `create`, `verify`, `set_emission`, `retry_certificate`, `retire` | Los dos de gestión | `marketing:deliverability:manage` |

- **`verify` y `retire` exigen `confirm: true`**: la primera consulta el DNS
  real y tiene tope de cinco por minuto; la segunda pone fecha al fin del
  servicio.
- **Ninguna operación borra nada.** La herramienta declara
  `destructiveHint: false` y es literal, no un descuido de anotación.
- **No se inventa ningún scope**: se reutilizan los dos de entregabilidad, que
  a diferencia de `org:email-senders:*` **no** los expanden `crm:full` ni
  `dev:full`.
- **Cuatro escrituras exigen capacidad de plan**, igual que en el REST:
  `create`, `verify`, `set_emission` y `retry_certificate` necesitan las dos
  capacidades del lote de medición, **Analítica avanzada de Marketing** y
  **Negocio por campaña**. Las lecturas y `retire` no llevan esa puerta:
  retirar es la salida y tiene que poder hacerse aunque cambie el plan.

### `marketing_automations`

Diseño y gestión de automatizaciones. Operaciones: `list`, `get`, `validate`,
`create`, `update`, `replace_steps`, `delete`, `activate`, `pause`,
`bulk_set_status`, `test_trigger`, `duplicate`, `add_step`, `update_step`,
`remove_step`, `list_templates`, `create_from_template`, `list_runs`,
`get_run`, `retry_run`, `cancel_run`, `stats`.

- **`validate`**: comprueba una definición entera (nombre, disparador,
  `triggerConfig` y pasos) con los mismos validadores que el guardado, sin
  persistir nada; devuelve la lista de problemas en castellano. Solo lectura
  (`EMAIL_MARKETING_VIEW`).
- **`replace_steps`**: sustituye el flujo entero de pasos en una llamada
  (equivale a `update` con `steps`); exige `EMAIL_MARKETING_EDIT`.
- **`bulk_set_status`**: activa o pausa hasta 25 automatizaciones con
  resultado por id (los fallos no detienen el resto); con
  `action: "activate"` exige `confirm: true`. Permiso
  `EMAIL_MARKETING_EDIT`.
- **`duplicate`**: crea una copia en borrador («X (copia)») con disparador,
  configuración y pasos; exige `EMAIL_MARKETING_CREATE`.
- **`list_templates`**: catálogo de plantillas de flujo (permiso
  `EMAIL_MARKETING_VIEW`).
- **`create_from_template`**: crea la automatización en borrador desde una
  plantilla (`templateKey`); exige `EMAIL_MARKETING_CREATE`. Acepta `name` y
  `departmentIds` opcionales.
- **`test_trigger`**: prueba el flujo contra un contacto; con
  `dryRun: true` (por defecto) solo simula, y con `dryRun: false` ejecuta un
  run de prueba real marcado como test, fuera de las métricas. Exige
  `EMAIL_MARKETING_EDIT`.
- **`list_runs` / `get_run` / `retry_run` / `cancel_run`**: consultan las
  ejecuciones de una automatización, reintentan una concreta o la cancelan. Las
  dos lecturas van con `EMAIL_MARKETING_VIEW`; `cancel_run` exige
  `EMAIL_MARKETING_EDIT` y **`retry_run` exige `EMAIL_MARKETING_SEND`**, porque
  reenvía correos reales.

### `marketing_ab_testing`

Ciclo completo de pruebas A/B sobre una campaña. Operaciones: `setup`,
`add_variant`, `remove_variant`, `split_recipients`, `comparison`,
`determine_winner`, `send_winner`, `disable`.

- **`comparison`** es de solo lectura (`EMAIL_MARKETING_VIEW`).
- El resto de operaciones exigen `EMAIL_MARKETING_AB_TESTING`.
- **`send_winner`** dispara un envío masivo y requiere `confirm: true`.

### El resto de herramientas del servidor

Las ocho anteriores son las que cubre esta página en detalle, pero el servidor
Marketing expone **quince** en total. Estas siete no se documentan aquí; su
esquema completo (parámetros, permisos y descripciones) viaja en el propio
`tools/list` del servidor MCP:

| Herramienta | Para qué sirve | Operaciones |
| - | - | - |
| `marketing_templates` | Plantillas de correo reutilizables | `list`, `get`, `create`, `update`, `delete`, `render_preview`, `duplicate`, `list_categories` |
| `marketing_suppressions` | Rebotes y bajas: la lista de a quién no se escribe | `list_bounces`, `list_unsubscribes`, `add_unsubscribe`, `remove_unsubscribe`, `check_email`, `clean_bounced_from_list`, `remove_bounce`, `export_problematic` |
| `marketing_bounce_settings` | Configuración de la detección de devueltos | `get`, `update`, `test_imap`, `regenerate_webhook_secret` |
| `marketing_assets` | Imágenes y adjuntos de las campañas | `upload`, `list`, `get`, `delete` |
| `marketing_overview` | Estado del módulo de un vistazo | `overview` |
| `marketing_audience_search` | Búsqueda de audiencia | `overview` |
| `marketing_recipients_preview` | Previsualización de destinatarios | `overview` |

## Relación con otros módulos

- El cierre comercial conecta Marketing con el
  [CRM](https://os.utilia.ai/docs/guides/crm/opportunities): un clic interesado se
  convierte en oportunidad o en lead.
- El filtro de facturación de los segmentos se apoya en
  [Finanzas](https://os.utilia.ai/docs/guides/finance/overview) para segmentar
  por estado real de cobro.
- La guía de uso del módulo, con el flujo completo de la interfaz, está en
  [Campañas de correo](https://os.utilia.ai/docs/guides/marketing/overview).
- Qué cuenta exactamente cada cifra de `marketing_reports` y sobre qué se
  divide, en
  [Definiciones de las métricas de Marketing](https://os.utilia.ai/docs/guides/marketing/metrics).

## Siguiente paso

Si vas a trabajar con Marketing por MCP, empieza por los
[primeros pasos con MCP](https://os.utilia.ai/docs/developers/mcp/quickstart) para la
autenticación y el formato de las llamadas, y luego usa las herramientas
de arriba para crear campañas, consultar sus resultados, lanzar pruebas
A/B y diseñar automatizaciones desde código.
