Si ya tienes tu OpenClaw leyendo tus notas de Notion y chateando por WhatsApp, el siguiente paso lógico es darle acceso a tu correo. Imagínate pedirle "resúmeme los correos no leídos de hoy" desde WhatsApp y que te responda con un resumen ejecutivo sin abrir Gmail. O que detecte un correo de tu banco y te mande una alerta.
Esta guía cubre cómo instalar y configurar el skill imap-smtp-email para conectar tu OpenClaw a Gmail, Outlook, o cualquier servidor de correo que hable IMAP/SMTP. Incluye todos los errores que encontré en el camino y cómo los resolví — porque los tutoriales que solo muestran el happy path no sirven de mucho.
Spoiler: fueron bastantes errores. Pero al final la langosta lee correos. 🦞
Antes de empezar: IMAP y SMTP (los carteros del internet)
Si ya sabes qué son IMAP y SMTP, sáltate esta sección. Si no, aquí va la versión para humanos:
IMAP (Internet Message Access Protocol) es el protocolo para leer correos. Imagínate que tu bandeja de entrada es un estante de biblioteca. IMAP te deja ir, leer los libros, marcarlos como leídos, moverlos... pero los libros se quedan en la biblioteca. Por eso puedes ver los mismos correos desde tu teléfono, laptop y OpenClaw — todos leen del mismo estante.
SMTP (Simple Mail Transfer Protocol) es el protocolo para enviar correos. Si IMAP es el cartero que te entrega cartas, SMTP es el cartero al que tú le das cartas para que las lleve.
Juntos forman el dynamic duo del email: uno lee, otro envía. El skill se llama imap-smtp-email — cero azúcar sintáctica en el nombre.
Pre-requisitos
- OpenClaw corriendo en Docker (en mi caso: AlmaLinux, 2GB RAM, 2GB swap, 2 vCores, 100GB SSD — el mismo VPS de la guía de instalación)
- Acceso al dashboard web de OpenClaw
- Una cuenta de correo con acceso IMAP/SMTP habilitado
- Para Gmail: un App Password (contraseña de aplicación) — tu contraseña normal no funciona
Paso 1 — Generar un App Password en Gmail
Si usas Gmail con verificación en dos pasos (2FA), Google bloquea los accesos IMAP con tu contraseña normal. Necesitas generar un App Password — una contraseña desechable de 16 caracteres dedicada exclusivamente a esta aplicación.
- Ve a myaccount.google.com/apppasswords
- Selecciona "Otro" y ponle un nombre como "OpenClaw"
- Google te genera algo tipo
abcd efgh ijkl mnop - Cópialo y guárdalo — lo necesitarás en el Paso 4
⚠️ Importante: Copia el App Password sin espacios. Google te lo muestra con espacios para que sea legible, pero al configurarlo va todo junto: abcdefghijklmnop.
Si usas Outlook, Zoho o un servidor propio, no necesitas App Password — usas tu contraseña normal o el mecanismo de autenticación de tu proveedor.

Paso 2 — Agregar volumen persistente para skills (CRÍTICO)
Este paso no aparece en ningún tutorial y me costó una reinstalación completa descubrirlo.
El skill imap-smtp-email se instala en /home/node/.agents/ dentro del contenedor. Por defecto, esa ruta no tiene un volumen de Docker, lo que significa que todo lo que instales ahí se pierde al reiniciar el contenedor. Es efímero — como trabajar en un archivo sin hacer Ctrl+S.
Primero, crea la carpeta en tu VPS:
mkdir -p ~/openclaw/agents⚠️ Error EACCES: Si al arrancar el contenedor obtienes un error tipo EACCES: permission denied, es porque Docker corre como usuario node (UID 1000) dentro del contenedor y la carpeta la creaste como tu usuario del host. El fix está justo abajo.
sudo chown -R 1000:1000 ~/openclaw/agentsAhora agrega el volumen a tu docker-compose.yml:
services:
openclaw:
image: ghcr.io/openclaw/openclaw:latest
container_name: openclaw-gateway
restart: always
ports:
- "127.0.0.1:18789:18789"
volumes:
- ~/openclaw/data:/home/node/.openclaw
- ~/openclaw/workspace:/home/node/.openclaw/workspace
- ~/openclaw/agents:/home/node/.agents
environment:
- NODE_ENV=production
- OPENCLAW_GATEWAY_BIND=0.0.0.0
- NOTION_API_KEY=${NOTION_API_KEY}
- TZ=America/MeridaNota la última variable: TZ=America/Merida. Los contenedores Docker arrancan en UTC por defecto, independientemente de la zona horaria de tu VPS. Sin esto, cuando le pidas "mis correos de hoy" puede que te traiga los del mañana porque para él ya cambió el día. Ajusta TZ a tu zona horaria.
Recrea el contenedor:
cd ~/openclaw && docker compose down && docker compose up -dℹ️ Nota: Para aplicar cambios al docker-compose.yml siempre usa docker compose down && docker compose up -d. Un simple docker compose restart no aplica cambios de volúmenes ni variables de entorno.
Paso 3 — Instalar el skill
Entra al contenedor:
docker exec -it openclaw-gateway /bin/bashInstala el skill desde el registro de ClawHub:
npx playbooks add skill openclaw/skills --skill imap-smtp-emailTe va a hacer varias preguntas:
- "Need to install playbooks@x.x.x. Ok to proceed?" → y (es el CLI del registro, no un virus)
- "Instalar a todos los agentes" → Sí
- "Install scope" → global (si pusiste el volumen del Paso 2, sobrevivirá los reinicios)
- "Método de instalación" → symlink
⚠️ Gotcha del scope: Si seleccionas project en vez de global, el skill se instala en el workspace, que sí está persistido. Puede ser una alternativa si no quieres agregar el volumen de agents. Pero global + volumen es la solución correcta a largo plazo.
Ahora viene el paso que el instalador no hace por ti: instalar las dependencias de Node:
cd ~/.agents/skills/imap-smtp-email && npm installSin esto, al ejecutar cualquier script del skill obtendrás:
Error: Cannot find module 'imap'Es el equivalente a hacer git clone sin npm install — tienes el código pero la despensa de node_modules está vacía.
Paso 4 — Configurar las credenciales
El skill trae un asistente de configuración:
bash setup.shTe pedirá host IMAP, puerto, usuario, contraseña, etc. Para Gmail y Outlook los valores son:
Campo | Valor Gmail | Valor Outlook |
|---|---|---|
IMAP Host |
|
|
IMAP Port |
|
|
SMTP Host |
|
|
SMTP Port |
|
|
Password | Tu App Password (sin espacios) | Tu contraseña normal |
Preguntas del asistente:
- "Accept self-signed certificates?" → Sí para Gmail. Esto suena contradictorio (Gmail tiene certificados legítimos) pero Node.js dentro del contenedor Docker a veces no confía en los CA certificates del sistema. Sin aceptar esto, obtienes el error
IMAP connection failed: self-signed certificate. No es un riesgo real de seguridad en este contexto — es Node.js siendo paranoico. - "Allowed directories for reading/writing files" →
~/Downloads,~/Documents(valores conservadores para empezar)
🚨 Bug del setup.sh: En mi experiencia, el asistente a veces no guarda lo que ingresaste y escribe valores default de un proveedor chino (qq.com) en vez de tu configuración. Después del setup, verifica con el comando de abajo. Si dice 123456@qq.com en vez de tu correo, el setup te trolleó y necesitas editar el .env a mano.
cat .env | grep USEREl problema: el contenedor no trae nano ni ningún editor de texto. Tienes dos opciones:
Opción A — Instalar nano (necesitas entrar como root):
# Sal del contenedor primero, luego:
docker exec -it -u root openclaw-gateway /bin/bash
apt-get update && apt-get install -y nano
exit
# Vuelve a entrar como usuario normal:
docker exec -it openclaw-gateway /bin/bash⚠️ Nano se pierde al recrear el contenedor. Si lo necesitas de nuevo, repite el proceso.
Opción B — Usar sed (sin instalar nada):
sed -i 's/IMAP_HOST=imap.qq.com/IMAP_HOST=imap.gmail.com/' .env
sed -i 's/123456@qq.com/tu_correo@gmail.com/g' .env
# etc.Paso 5 — Probar la conexión (con cuidado)
Antes de probar, un aviso importante: no corras el check sin filtros.
# ❌ ESTO SE VA A COLGAR:
node scripts/imap.js check --limit 3
# ✅ ESTO SÍ FUNCIONA:
node scripts/imap.js check --limit 3 --recent 24h¿Por qué? Porque el script tiene un bug de rendimiento: cuando no le pasas --recent ni --unseen, primero descarga TODOS los correos de tu bandeja y después aplica el --limit. Si tienes 5,000 correos, va a intentar descargar los 5,000 antes de mostrarte 3. Es como hacer SELECT * FROM correos sin WHERE en una base de datos con miles de registros — un clásico código espagueti de rendimiento.
El flag --recent manda el filtro a nivel de protocolo IMAP, así que Gmail filtra en su servidor y solo te devuelve los resultados relevantes. Úsalo siempre.
Para probar SMTP (enviar):
node scripts/smtp.js send --to tu_correo@gmail.com --subject "Test OpenClaw" --body "La langosta ya envía correos 🦞"Revisa tu bandeja — si llegó, SMTP funciona.
Paso 6 — Registrar el skill en openclaw.json (EL PASO MÁS IMPORTANTE)
Aquí está el twist que me tomó más tiempo descubrir: aunque el skill esté instalado, aparezca en skills list, y funcione desde la terminal... el agente no lo usa. Si le pides que lea tus correos, te va a decir que no puede.
¿Por qué? Porque el script del skill usa dotenv para leer el .env del directorio del skill. Pero el gateway de OpenClaw tiene su propio sistema de configuración. El gateway no lee ese .env — necesita que las variables estén registradas en openclaw.json.
En el dashboard, el skill aparece con un tag que dice "blocked" y la leyenda Missing: env:IMAP_HOST, env:IMAP_USER, env:IMAP_PASS, env:SMTP_HOST, env:SMTP_USER, env:SMTP_PASS.

Para solucionarlo, edita el openclaw.json desde tu VPS (fuera del contenedor, ya que el archivo está en el volumen persistido):
nano ~/openclaw/data/openclaw.jsonAgrega una sección "skills" al final del JSON, justo antes de la última }. Asegúrate de poner una coma después de la sección anterior (en mi caso "plugins"):
"plugins": {
"entries": {
"whatsapp": {
"enabled": true
}
}
},
"skills": {
"entries": {
"imap-smtp-email": {
"enabled": true,
"env": {
"IMAP_HOST": "imap.gmail.com",
"IMAP_PORT": "993",
"IMAP_USER": "tu_correo@gmail.com",
"IMAP_PASS": "tu_app_password",
"IMAP_TLS": "true",
"IMAP_REJECT_UNAUTHORIZED": "false",
"IMAP_MAILBOX": "INBOX",
"SMTP_HOST": "smtp.gmail.com",
"SMTP_PORT": "587",
"SMTP_SECURE": "false",
"SMTP_USER": "tu_correo@gmail.com",
"SMTP_PASS": "tu_app_password",
"SMTP_FROM": "tu_correo@gmail.com",
"SMTP_REJECT_UNAUTHORIZED": "true"
}
}
}
}🚨 Los valores DEBEN ser strings. Si intentas usar objetos como {"source": "env", "id": "IMAP_HOST"} (como funciona con apiKey), el gateway crashea con Config invalid: expected string, received object y tu contenedor entra en un restart loop. Si eso pasa, edita el JSON desde el host (nano ~/openclaw/data/openclaw.json), corrige el error, y reinicia.
⚠️ A diferencia de Notion, donde la API key se puede referenciar con interpolación de variables desde el .env del host, las variables de skills.entries.env van hardcodeadas como strings. Es una limitación del esquema de validación del gateway. Si cambias tu App Password, actualiza aquí también.
Reinicia:
cd ~/openclaw && docker compose down && docker compose up -dRevisa que no haya errores:
docker compose logs --tail=10
Paso 7 — Probar con el agente
Ahora sí, ve al chat de OpenClaw (dashboard o WhatsApp) y dile:
Dame un resumen de mis correos no leídos de hoySi todo está bien configurado, OpenClaw va a ejecutar el skill, conectarse a tu Gmail por IMAP, leer los correos del día, y devolverte un resumen generado por el LLM.
También puedes probar:
"¿Tengo correos de Amazon de esta semana?""Busca correos con asunto factura de los últimos 7 días""Envía un correo afulano@ejemplo.comcon el asunto Test y el cuerpo Hola mundo"

💡 Tip para el SOUL.md: Agrega reglas para que el agente siempre use filtros de fecha y nunca haga un check sin --recent. El bloque de reglas está justo abajo.
## Email Rules
- Al revisar correos, SIEMPRE usa --recent con máximo 7d
- Nunca ejecutes imap.js check sin --recent o --unseen
- Default: --recent 1d para resúmenes diarios, --recent 7d para semanales
- Siempre usa --limit con máximo 20Errores comunes (los que me salieron a mí)
Error | Causa | Solución |
|---|---|---|
| Falta |
|
| Node.js del contenedor no confía en los CA certs | Pon |
El | Descarga TODOS los correos antes del limit | Siempre usa |
Skill desaparece al reiniciar Docker | No hay volumen para | Agrega |
| La carpeta agents no pertenece al UID 1000 |
|
Skill dice "blocked" en dashboard | Variables de entorno no registradas en | Agregar sección |
| Usaste objetos en vez de strings en | Los valores deben ser strings planos, no objetos |
Setup escribe valores de | Bug del | Verifica con |
Agente dice que no puede leer correos | Gateway no recargó los skills |
|
Correos del "día equivocado" | Contenedor en UTC, no tu zona horaria | Agrega |
Configuración multi-cuenta (el multi-tenancy del pobre)
Si quieres conectar más de un correo (personal + trabajo), el skill soporta múltiples cuentas usando prefijos en las variables de entorno. En tu openclaw.json:
"env": {
"IMAP_HOST": "imap.gmail.com",
"IMAP_USER": "personal@gmail.com",
"IMAP_PASS": "app_password_personal",
"WORK_IMAP_HOST": "outlook.office365.com",
"WORK_IMAP_USER": "tu@empresa.com",
"WORK_IMAP_PASS": "password_trabajo",
"WORK_SMTP_HOST": "smtp.office365.com"
}Para usar una cuenta específica: node scripts/imap.js --account work check. Es como tener varios remotes en Git — origin, upstream, work — cada uno apunta a un lugar diferente pero usas el mismo CLI.
Resumen
- Generar App Password — en Gmail, tu contraseña normal no funciona con IMAP
- Agregar volumen —
~/openclaw/agents:/home/node/.agentspara que los skills sobrevivan reinicios - Instalar skill —
npx playbooks add skill openclaw/skills --skill imap-smtp-email+npm install - Configurar credenciales —
bash setup.sh, verificar que no escriba defaults deqq.com - Probar con filtros — siempre
--recento--unseen, nunca check sin filtros - Registrar en openclaw.json — la pieza que falta para que el agente reconozca el skill
- Probar con el agente — "Dame un resumen de mis correos de hoy"
Escrito mientras mi langosta lee mis correos sin que yo abra Gmail. 🦞📧
Comentarios
Sé la primera persona en comentar.