Saltar al contenido principal

Guía Cursor + Claude Code

Deja que tu agente de código
conecte email, SMS y WhatsApp.

Conecta el servidor MCP de Unlimited Messaging a Cursor, Claude Code o Windsurf, pega un prompt y el agente escribe un módulo notify, envía una prueba real desde tus propias cuentas y comprueba que ha llegado.

¿Con prisa? Resume este artículo con una IA

La respuesta corta

¿Cómo añaden Cursor y Claude Code email, SMS y WhatsApp a una app?

Dale dos cosas al agente: el servidor MCP de Unlimited Messaging en https://mcp.unlimitedmessaging.app, para que vea tus cuentas y envíe un mensaje de prueba, y una clave de API en tu .env, que el código que escribe lee para llamar a POST /message. Una sola petición envía entonces email, WhatsApp y SMS desde tus propias cuentas, con un plan gratis.

Los agentes de código escriben muy bien una llamada fetch y adivinan muy mal si ha funcionado. La conexión MCP cierra ese hueco: mientras construye, el agente puede listar los buzones, números de WhatsApp y móviles Android que conectaste, enviar una prueba cuando tú confirmas y leer el estado de entrega, todo con OAuth y sin pegar ninguna clave en el chat.

En tu app, el código usa la API REST o los SDK de TypeScript y Python con una clave de API leída del entorno. Unlimited Messaging envía desde cuentas que ya tienes: email desde tu buzón de Gmail o de tu dominio por IMAP/SMTP, WhatsApp desde tu número vinculado como WhatsApp Web, SMS desde la SIM de tu móvil Android. El plan gratis no cobra por mensaje; los mensajes terminan con una línea corta "Sent with UnlimitedMessaging.app".

Funciona igual en Cursor, Claude Code y Windsurf, y en cualquier cliente MCP que admita servidores remotos con OAuth. Ninguno tiene una colaboración oficial con Unlimited Messaging: hablan el protocolo abierto MCP, y con eso basta.

El servidor MCP en detalle: guía MCP. En las apps de Claude: configuración en Claude. Cliente tipado para tu código: el SDK TypeScript.

Ilustración: un asistente de IA conectado al chat, el correo, el calendario y los contactos, con el titular «Tu agente de código conecta los mensajes».

Por qué no programarlo a mano

¿Por qué es lento dejar que un agente programe a mano SMTP, Twilio y Meta?

El agente escribe la integración en un minuto. Luego empieza el trabajo de verdad: cuentas, verificaciones, reglas de plataforma y fallos silenciosos que no puede ver.

  1. Email: el fragmento SMTP falla en producción

    A los agentes les encanta nodemailer, pero Vercel bloquea el SMTP saliente por el puerto 25 y las Edge Functions de Supabase rechazan los puertos 25 y 587. Pasar a una API de email implica un dominio verificado y registros DNS antes de que alguien que no seas tú reciba correo.

  2. SMS: un número, un registro, una tarifa por segmento

    Twilio cobra 0,0083 $ por segmento en Estados Unidos más las tarifas del operador, con un número que alquilas. Enviar a números de Estados Unidos desde un número largo normal exige además el registro A2P 10DLC, con una tarifa de marca de 4,50 $ y una verificación.

  3. WhatsApp: plantillas y una cola de revisión

    La Cloud API de Meta necesita una plantilla aprobada para cualquier mensaje fuera de la ventana de atención al cliente de 24 horas, con una revisión de hasta 24 horas y un precio por mensaje de plantilla. Las cuentas nuevas empiezan con 250 destinatarios únicos cada 24 horas.

  4. El agente no puede comprobar su propio trabajo

    Sin forma de ver el lado del proveedor, el agente da la tarea por hecha cuando el código compila. Tres proveedores son además tres claves en .env, tres formatos de error y tres handlers de webhook que revisar.

Dos vías

¿MCP o API: cuál usa el agente, y cuándo?

El servidor MCP es para el agente mientras construye. La clave de API es para tu app cuando ya funciona. La mayoría de los proyectos usan las dos.

¿MCP o API: cuál usa el agente, y cuándo?
Proveedores a manoSMTP, Twilio, MetaMCP de Unlimited MessagingEn el agente de códigoAPI de Unlimited MessagingEn el código de tu app
Quién envíaTu app, a través de tres proveedoresEl agente, después de que confirmesTu app, a través de un solo endpoint
AutenticaciónTres juegos de credencialesOAuth en el navegador, sin clave en archivosUna clave de API leída del entorno
CanalesUn proveedor por canalEmail, WhatsApp y SMSEmail, WhatsApp y SMS en una sola petición
Puede comprobar la entregaSolo en el panel de cada proveedorSí, list-messages con los estadosSí, GET /message y webhooks en los planes de pago
Coste para probarPruebas, luego por mensajePlan gratisPlan gratis, línea de pie en los mensajes

Tarifas de proveedores tomadas de las páginas de Twilio y de Meta, revisadas el 9 de noviembre de 2026.

Paso a paso

De cero a una integración probada en cinco pasos

  1. 01

    Conecta el servidor MCP

    Claude Code: ejecuta el comando claude mcp add de una línea que verás abajo. Cursor: añade el bloque a .cursor/mcp.json. Windsurf: añádelo a mcp_config.json con serverUrl.

  2. 02

    Inicia sesión con OAuth

    En la primera llamada a una herramienta, tu navegador abre el inicio de sesión de Unlimited Messaging. ¿Aún no tienes cuenta? Se crea con el plan gratis, sin tarjeta. En Claude Code, /mcp lanza el inicio de sesión.

  3. 03

    Conecta tus canales

    Pide al agente que conecte tu buzón o tu WhatsApp (te muestra el código QR) e instala la app Android en un móvil con SIM para los SMS.

  4. 04

    Crea una clave de API para la app

    En la sección API del panel, crea una clave y ponla tú mismo en .env como UM_API_KEY. El agente solo necesita el nombre de la variable.

  5. 05

    Pega el prompt

    El agente escribe el módulo, lo conecta a tu disparador, luego te envía una prueba por MCP y confirma el estado.

Copiar y pegar

¿Qué prompt pegas en Cursor o Claude Code?

Pega esto en el chat del agente, en modo Agent. Funciona en Cursor, Claude Code y Windsurf. Indica el evento que debe disparar el mensaje.

Prompt para Cursor, Claude Code o WindsurfPrompt
Añade Unlimited Messaging a este proyecto para que pueda enviar email, WhatsApp y SMS (documentación: https://docs.unlimitedmessaging.app).

1. Crea un módulo de servidor, src/lib/notify.ts (o notify.py), que llame a POST https://api.unlimitedmessaging.app/message con "Authorization: Bearer ${UM_API_KEY}" y el cuerpo { "to": { "phone": "<E.164>", "email": "<email>" }, "subject": "...", "text": "...", "channels": [{ "channel": "EMAIL" }, { "channel": "WHATSAPP" }, { "channel": "SMS" }] }. Lanza un error si la respuesta no es 2xx, con el cuerpo en el mensaje.
2. Lee UM_API_KEY del entorno. Añádela a .env.example con un valor vacío, comprueba que .env está en .gitignore y nunca leas, muestres ni escribas en el código la clave real.
3. Llama a notify() cuando <tu evento: registro, nuevo pedido, pago fallido...>, solo desde código de servidor.
4. Usa las herramientas MCP de unlimited-messaging: list-accounts para ver qué canales conecté (quita los demás de la llamada), luego, después de preguntarme, send-message a mi propio contacto como prueba, y list-messages para confirmar su estado.
El paso 4 es lo que aporta MCP: el agente comprueba tus canales conectados y verifica una entrega real en lugar de suponer que el código funciona.
MCPClaude Code / Cursor / Windsurf
# Claude Code
claude mcp add --transport http unlimited-messaging https://mcp.unlimitedmessaging.app

# Cursor: ~/.cursor/mcp.json or .cursor/mcp.json
{ "mcpServers": { "unlimited-messaging": { "url": "https://mcp.unlimitedmessaging.app" } } }

# Windsurf: mcp_config.json
{ "mcpServers": { "unlimited-messaging": { "serverUrl": "https://mcp.unlimitedmessaging.app" } } }
Conectar el servidor alojado en cada herramienta. Las tres inician sesión con OAuth en el primer uso, así que ninguna clave va en estos archivos.
notify.tsTypeScript
// src/lib/notify.ts (server-side only)
type Channel = 'EMAIL' | 'WHATSAPP' | 'SMS';

export async function notify(
  to: { phone?: string; email?: string },
  text: string,
  channels: Channel[],
  subject?: string,
) {
  const res = await fetch('https://api.unlimitedmessaging.app/message', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.UM_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      to, text, subject,
      channels: channels.map((channel) => ({ channel })),
    }),
  });
  if (!res.ok) throw new Error(`notify failed: ${res.status} ${await res.text()}`);
  return res.json(); // one message per channel, sharing a dispatchId
}
El tipo de módulo que debería escribir el agente: en el servidor, una sola petición, la clave desde el entorno y los errores a la vista.

Seguridad

¿Cómo mantienes la clave de API lejos del agente y del repositorio?

La clave va en .env, leída por código de servidor. Cada herramienta te da una forma de mantener al agente fuera de ese archivo.

  1. MCP no necesita ninguna clave

    La conexión del agente usa OAuth: los tokens los guarda el cliente y se pueden revocar, en Claude Code desde el menú /mcp. Nada secreto entra en .cursor/mcp.json ni en .mcp.json, así que puedes hacer commit de esos archivos sin riesgo.

  2. Claude Code: prohíbe leer .env

    La documentación de ajustes de Anthropic muestra reglas de permisos como Read(./.env) y Read(./.env.*) en deny. Añádelas a .claude/settings.json y Claude Code no podrá abrir el archivo.

  3. Cursor: .cursorignore, con sus límites

    Los archivos listados en .cursorignore quedan bloqueados para Agent, Tab, Inline Edit y las menciones con @. La documentación de Cursor avisa de que el terminal y las herramientas MCP que usa el agente no están cubiertos, así que no te fíes solo de eso.

  4. Solo código de servidor

    Nunca pongas a la clave el prefijo NEXT_PUBLIC_ o VITE_, y nunca importes el módulo notify desde componentes de cliente. Revisa eso en el diff del agente antes de hacer commit.

  5. Mantén la confirmación activada

    send-message envía mensajes reales desde tus cuentas. El servidor indica a los asistentes que confirmen cada envío, y tu editor puede pedirte permiso antes de cada llamada a una herramienta: no apruebes esta automáticamente.

Respuestas

¿Cómo recibe tu app las respuestas?

Las respuestas siempre aparecen en la bandeja de Unlimited Messaging, y el agente puede leerlas con list-messages mientras construyes. Para que tu app reaccione a ellas en producción necesitas webhooks, incluidos en los planes de pago: Medium a 19 € al mes y Max a 29 € al mes.

Pide al agente una ruta de webhook, registra su URL pública en la página Webhooks del panel y suscríbete a message.received (un mensaje entrante) y message.status (enviado, entregado, leído, fallido). Guarda el secreto whsec_ como UM_WEBHOOK_SECRET en .env.

Las entregas van firmadas según la especificación Standard Webhooks, con un HMAC-SHA256 sobre el cuerpo en bruto en la cabecera webhook-signature. Responde 2xx en menos de 10 segundos y procesa después. Los reintentos duran algo más de 3 días, así que deduplica por eventId.

message.receivedJSON
{
  "type": "message.received",
  "eventId": "whd_...",
  "occurredAt": "2026-11-09T10:00:01.000Z",
  "data": {
    "channel": "WHATSAPP",
    "message": {
      "text": "Yes, see you Monday!"
    }
  }
}
Un evento message.received, abreviado. data.message lleva el remitente y el texto, y en un email también el asunto y los adjuntos.
verify-webhook.tsTypeScript
import { createHmac } from 'node:crypto';
import { Buffer } from 'node:buffer';

// Standard Webhooks signature check, before trusting the body.
export function isValid(rawBody: string, h: Headers, secret: string) {
  const id = h.get('webhook-id');
  const ts = h.get('webhook-timestamp');
  const sig = h.get('webhook-signature') ?? '';
  if (!id || !ts || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64');
  const expected = createHmac('sha256', key)
    .update(`${id}.${ts}.${rawBody}`)
    .digest('base64');
  return sig.split(' ').some((s) => s === `v1,${expected}`);
}
La comprobación de firma que debes pedir. Lee primero el cuerpo en bruto, verifica y solo después parsea el JSON.

Límites

¿Cuáles son los límites, sinceramente?

Unlimited Messaging envía desde cuentas personales a ritmo humano: bien para notificaciones y conversaciones, mal para envíos masivos.

  1. WhatsApp no es oficial

    Tu número se vincula como un dispositivo, igual que WhatsApp Web, fuera de la Business Platform de Meta. Los mensajes no solicitados hacen que bloqueen números. Para WhatsApp oficial a gran escala, usa la Cloud API de Meta.

  2. El email sigue a tu buzón

    Una cuenta personal de Gmail envía hasta 500 emails al día. Las newsletters y los grandes volúmenes son cosa de un proveedor de email.

  3. SMS al ritmo de Android

    Android pide confirmación a partir de 30 SMS en 30 minutos, así que la app espacia los mensajes. Los SMS cuentan en tu plan del operador, y el móvil que envía tiene que ser Android.

  4. Lo que implica el plan gratis

    Los mensajes del plan Gratis terminan con "Sent with UnlimitedMessaging.app". Los archivos multimedia, las notas de voz y los webhooks requieren Medium o Max, que además quitan el pie.

FAQ

Preguntas sobre la mensajería con agentes de código

Ilian, ingeniero de software senior

Escrito por

· Ingeniero de software senior

Ingeniero de software senior, funda y dirige varias empresas tecnológicas. Diseña productos en torno a las API de mensajería, la automatización y la integración de la IA, y comparte aquí lo que aprende construyendo.

Ver el perfil de LinkedInActualizado el

Dale a tu agente un buzón, un número y un móvil.

Crea una cuenta gratis, conecta el servidor MCP en tu editor y pega el prompt.