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.

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.
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.
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.
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.
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.
| Proveedores a manoSMTP, Twilio, Meta | MCP de Unlimited MessagingEn el agente de código | API de Unlimited MessagingEn el código de tu app | |
|---|---|---|---|
| Quién envía | Tu app, a través de tres proveedores | El agente, después de que confirmes | Tu app, a través de un solo endpoint |
| Autenticación | Tres juegos de credenciales | OAuth en el navegador, sin clave en archivos | Una clave de API leída del entorno |
| Canales | Un proveedor por canal | Email, WhatsApp y SMS | Email, WhatsApp y SMS en una sola petición |
| Puede comprobar la entrega | Solo en el panel de cada proveedor | Sí, list-messages con los estados | Sí, GET /message y webhooks en los planes de pago |
| Coste para probar | Pruebas, luego por mensaje | Plan gratis | Plan 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
- 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.
- 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.
- 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.
- 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.
- 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.
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.# 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" } } }// 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
}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.
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.
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.
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.
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.
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.
{
"type": "message.received",
"eventId": "whd_...",
"occurredAt": "2026-11-09T10:00:01.000Z",
"data": {
"channel": "WHATSAPP",
"message": {
"text": "Yes, see you Monday!"
}
}
}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}`);
}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.
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.
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.
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.
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
Fuentes
Fuentes y referencias
Para verificar por ti mismo la información de este artículo:
- Model Context Protocol - documentación oficialModel Context Protocol
- Connect Claude Code to tools via MCP (claude mcp add --transport http, OAuth con /mcp)Documentación de Claude Code - Anthropic
- Settings (permisos deny Read(./.env))Documentación de Claude Code - Anthropic
- Model Context Protocol (mcp.json, url remota, OAuth)Documentación de Cursor
- Ignore files (.cursorignore y lo que no cubre)Documentación de Cursor
- Integración MCP de Cascade (serverUrl, OAuth para servidores remotos)Documentación de Windsurf
- Servidor MCP de Unlimited Messaging - configuraciones de clientesGitHub - UnlimitedMessaging
- Can I use SMTP with Vercel? (puerto 25 bloqueado)Vercel Knowledge Base
- Límites de las Edge Functions (puertos 25 y 587 no permitidos)Documentación de Supabase
- Precios de SMS en Estados Unidos (0,0083 $ por segmento)Twilio
- A2P 10DLC Brand Registration (tarifa de marca de 4,50 $)Twilio
- Revisión de plantillas de mensajes (decisión en 24 horas)Meta for Developers
- Límites de mensajería de WhatsApp (250 destinatarios únicos cada 24 horas al empezar)Meta for Developers
- Límites de envío y recepción de correo (500 emails al día)Ayuda de Gmail
- SmsUsageMonitor (umbral de 30 SMS en 30 minutos)Android Open Source Project
- Especificación Standard WebhooksStandard Webhooks

Escrito por
Ilian · 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.
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.