your-mail-mcp

Acceso MCP de solo lectura y autoalojado al correo IMAP, reflejado en un maildir local e indexado por notmuch.

Documentación

your-mail-mcp

MCP registry Glama score

Tu correo ya contiene las respuestas: referencias de reservas, códigos de puerta, facturas, períodos de garantía, promesas que la gente hizo por escrito. Este servidor permite que tu asistente de IA las encuentre, y solo puede leer.

Pregúntale cosas como:

  • "Encuentra la referencia de reserva para el ferry de junio."
  • "¿Cuál era la contraseña del wifi que el hotel envió el verano pasado?"
  • "¿Qué respondió el contador sobre el IVA, y cuándo?"
  • "Reúne todo entre yo y el constructor sobre el techo, en orden, y resume quién prometió qué."
  • "¿Qué llegó esta mañana, en todas mis cuentas, que realmente necesita mi atención?"

Úsalo para:

  • Búsqueda que entiende preguntas. Búsqueda de texto completo en todo tu historial, cada cuenta en un solo índice, formulada como piensas.
  • Triaje desde tu teléfono. Un resumen matutino de lo que llegó durante la noche, con el spam ya filtrado, desde donde estés.
  • Correo como contexto para otro trabajo. Extrae los requisitos del cliente del hilo y llévalos a tu sesión de codificación o escritura.
  • Agentes que puedes dejar ejecutándose. El proceso no tiene ninguna ruta que envíe, elimine o mueva un mensaje. Un correo malicioso que llegue a tu asistente se lee, y eso es todo lo que puede sucederle. Los resúmenes programados y los agentes siempre activos son algo tranquilo de ejecutar.

La configuración son dos archivos y docker compose up -d. Consulta Inicio rápido.

Cómo funciona

Un servidor MCP autoalojado. Duplica una o más cuentas IMAP en un maildir local con mbsync, las indexa con notmuch y responde llamadas de herramientas desde ese índice. Las aplicaciones Claude y ChatGPT se conectan por HTTPS con OAuth; Claude Code, Codex, Cursor y Claude Desktop se conectan por stdio en la misma máquina. Cualquier cliente MCP funciona, así que si quieres privacidad total puedes conectar uno respaldado por un LLM local y tu correo nunca sale de tu máquina.

How your-mail-mcp works: mail is pulled from IMAP providers into a local mirror, indexed by notmuch, and served to an MCP client through an OAuth gate, with no write path back to the providers

El correo solo se mueve de izquierda a derecha en esa imagen. La duplicación es solo de extracción por configuración. La única conexión que el código Go hace hacia un proveedor es un IMAP LIST por cuenta, para saber cómo llama ese servidor a sus carpetas de spam y papelera; nunca selecciona un buzón y nunca obtiene un mensaje. Seguridad tiene la lista completa de lo que el proceso no puede hacer. La fuente del diagrama es docs/diagrams/how-it-works.html.

Inicio rápido

En tu máquina, para tu máquina. Docker es el único requisito; la imagen en ghcr.io/wildsurfer/your-mail-mcp está construida por CI para amd64 y arm64.

mkdir your-mail && cd your-mail
curl -fsSLO https://raw.githubusercontent.com/wildsurfer/your-mail-mcp/main/compose.yaml
curl -fsSL https://raw.githubusercontent.com/wildsurfer/your-mail-mcp/main/accounts.example.json -o accounts.json

Pon tus cuentas en accounts.json. ${WORK_PASS} se reemplaza desde el entorno, por lo que el archivo en sí no contiene ninguna contraseña:

{
  "accounts": [
    { "name": "work", "host": "imap.gmail.com", "user": "you@example.com", "password": "${WORK_PASS}" },
    { "name": "personal", "host": "imap.mail.me.com", "user": "you", "password": "${PERSONAL_PASS}" }
  ]
}

Pon las contraseñas en .env junto a compose.yaml:

# .env
WORK_PASS=your-gmail-app-password
PERSONAL_PASS=your-icloud-app-specific-password

compose.yaml pasa WORK_PASS y PERSONAL_PASS al contenedor. Una cuenta con otro nombre de variable necesita que ese nombre se agregue bajo environment: allí también.

Dos detalles del proveedor cuestan a la gente más tiempo. Gmail acepta solo una contraseña de aplicación por IMAP, y las contraseñas de aplicación requieren que la verificación en dos pasos esté activada primero. iCloud quiere el nombre corto antes de @icloud.com como user; la dirección completa falla al iniciar sesión. Cada clave del archivo está en la referencia.

Estos dos archivos contienen las contraseñas de tu correo. Mantén el directorio fuera del control de versiones y fuera de las copias de seguridad que salgan de la máquina.

docker compose up -d
docker compose logs -f     # watch the first sync

El correo de la bandeja de entrada de hoy se puede buscar en minutos. El historial completo sigue al ritmo que el proveedor permita, y la herramienta status informa hasta dónde ha llegado. Una cuenta grande de Gmail tarda días, porque Google limita las descargas IMAP a unos 2.5GB por día; establece SYNC_TIMEOUT=8h en .env para esa primera duplicación. Notas del proveedor tiene los detalles.

Luego conecta un cliente. Claude Code:

claude mcp add your-mail -- docker exec -i your-mail-mcp your-mail-mcp stdio

Cursor y VS Code lo agregan con un clic, una vez que la pila está activa:

Add to Cursor Install in VS Code

Claude Desktop, Cursor, Codex y otros clientes stdio

Cualquier cliente que inicie un servidor MCP como comando:

{ "command": "docker", "args": ["exec", "-i", "your-mail-mcp", "your-mail-mcp", "stdio"] }

Cada sesión es un puente hacia el contenedor en ejecución, por lo que cada cliente ve el mismo índice y la misma sincronización. Cierra el cliente y la sesión se va con él.

Claude Code también puede tomarlo como complemento, lo que agrega el servidor y una habilidad email que conoce la sintaxis de consulta:

/plugin marketplace add wildsurfer/your-mail-mcp
/plugin install your-mail@your-mail-mcp

Sin una pila en ejecución, docker run -i --rm --env-file .env -v index:/index -v mail:/mail -v ./accounts.json:/config/accounts.json:ro ghcr.io/wildsurfer/your-mail-mcp inicia un demonio para la vida de una sesión. Está bien para echar un vistazo; usa compose para cualquier cosa que quieras mantener actualizada.

Úsalo desde tu teléfono

Las aplicaciones de smartphone Claude y ChatGPT alcanzan un conector a través de los servidores del proveedor, por lo que el servidor necesita una dirección HTTPS pública. Un túnel le da una: el túnel llama hacia afuera, nada escucha en tu red doméstica y el correo permanece en tu máquina.

Con Tailscale instalado, un comando, igual en macOS y Linux:

tailscale funnel --bg 8080

Imprime un nombre de host como https://your-machine.your-tailnet.ts.net, y --bg lo mantiene ejecutándose entre reinicios. Pon ese nombre de host en .env junto con una frase de contraseña, luego reinicia:

# .env
PUBLIC_URL=https://your-machine.your-tailnet.ts.net
OAUTH_PASSPHRASE=pick-a-long-one-you-can-type-on-a-smartphone
docker compose up -d

OAUTH_PASSPHRASE es la única credencial entre internet y tu correo. Una suposición incorrecta cuesta un segundo y las suposiciones se serializan, y ninguna de esas cosas salva una frase de contraseña corta. Usa una larga que aún puedas escribir en un teléfono.

Funnel necesita certificados HTTPS y el atributo de nodo Funnel habilitado para tu tailnet; la CLI ofrece agregar la línea de política la primera vez. tailscale funnel status muestra lo que está expuesto, y tailscale funnel --https=443 off lo desactiva.

Ahora agrega el conector. Ni la aplicación de smartphone Claude ni la de ChatGPT pueden agregar uno, así que lo haces una vez en la web, y luego aparece en el teléfono.

  1. En claude.ai o en Claude Desktop, abre Configuración → Conectores y agrega un conector personalizado.
  2. Dale un nombre y la URL <PUBLIC_URL>/mcp. Deja los campos avanzados de OAuth vacíos; el servidor registra clientes por sí mismo.
  3. Claude abre la página de consentimiento. Ingresa tu OAUTH_PASSPHRASE.
  4. Abre la aplicación Claude en tu teléfono. El conector ya está allí; actívalo para una conversación desde el menú de herramientas en el compositor.

PUBLIC_URL tiene que coincidir exactamente con lo que escribes en el cliente. El servidor publica PUBLIC_URL + /mcp como el resource en sus metadatos OAuth, y una discrepancia allí es la razón más común por la que un conector se niega a agregarse.

Cloudflare Tunnel en lugar de Tailscale, en tu propio dominio

Usa esto para un nombre de host en un dominio que poseas. mail.example.com a continuación tiene que ser tu dominio, ya agregado a tu cuenta de Cloudflare; Cloudflare no entrega nombres de host para túneles con nombre.

cloudflared tunnel login
cloudflared tunnel create your-mail

create imprime el UUID del túnel y la ruta del archivo de credenciales que escribió; cloudflared tunnel list imprime el UUID nuevamente si lo pierdes. Enruta el nombre de host, luego escribe ~/.cloudflared/config.yml:

cloudflared tunnel route dns your-mail mail.example.com
tunnel: your-mail
credentials-file: /Users/you/.cloudflared/f9e2….json   # the path create printed
url: http://localhost:8080
cloudflared tunnel run your-mail

Para mantenerlo ejecutándose: en Linux, sudo cloudflared service install. En macOS, instálalo a través de Homebrew y usa brew services start cloudflared, porque la ruta de instalación de sudo busca su certificado bajo el directorio inicio del usuario root y no encontrará el que cloudflared tunnel login escribió en el tuyo.

Luego establece PUBLIC_URL=https://mail.example.com en .env y docker compose up -d.

ChatGPT, y Claude Code o Codex desde otra máquina

ChatGPT. Los conectores MCP personalizados están detrás del modo desarrollador, que necesita una cuenta Pro, Plus, Business, Enterprise o Education y solo está disponible en la web.

  1. En ChatGPT en la web, abre Configuración → Seguridad e inicio de sesión y activa Modo desarrollador. En espacios de trabajo Business y Enterprise, un administrador puede tener que permitirlo primero.
  2. Agrega un conector para un servidor MCP remoto con la URL <PUBLIC_URL>/mcp y OAuth como autenticación. ChatGPT admite registro dinámico de clientes, por lo que no hay nada que pegar.
  3. Aprueba la página de consentimiento con tu OAUTH_PASSPHRASE.
  4. Abre ChatGPT en tu teléfono y habilita el conector en un chat.

Estos menús se mueven. Si los nombres anteriores no coinciden con lo que ves, busca el modo desarrollador en la configuración, luego el lugar que agrega un conector por URL. ChatGPT desactiva algunas acciones de escritura MCP en móvil, lo que no cambia nada aquí porque este servidor no tiene ninguna.

Claude Code:

claude mcp add --transport http your-mail https://your-host/mcp

Codex:

codex mcp add your-mail --url https://your-host/mcp
codex mcp login your-mail

Ejecútalo en un servidor

Elige esto cuando la duplicación deba permanecer activa esté o no encendida tu máquina. Cuesta unos pocos dólares al mes y un verdadero intercambio: una copia completa en texto plano de tu correo se mueve a un disco alquilado, con las contraseñas de aplicación al lado. La instalación es el inicio rápido más un túnel, en la computadora de otra persona, y la máquina necesita endurecimiento antes de que contenga tu correo. Ambos están en docs/server.md.

Las herramientas

Once herramientas, todas de solo lectura:

HerramientaQué hace
searchBusca correo. Devuelve resúmenes de hilos como JSON.
idsDevuelve los ids de mensajes que coinciden con una consulta.
filesDevuelve las rutas de archivo maildir que coinciden con una consulta.
countCuenta los mensajes que coinciden con una consulta.
showMuestra un mensaje: encabezados y cuerpo decodificado, como JSON.
threadMuestra el hilo completo que contiene un mensaje. Excluye respuestas de spam/papelera por defecto; establece include_excluded para incluirlas.
textDevuelve el cuerpo de texto plano de un mensaje, convirtiendo HTML.
foldersLista cuentas, sus carpetas, etiquetas de índice, y la última sincronización y último error de cada cuenta.
refreshSincroniza cada carpeta de una cuenta o todas las cuentas ahora, luego reindexa. Espera hasta 20 segundos; si el pase aún se está ejecutando, lo dice.
statusSalud de sincronización por cuenta: finalización de la primera sincronización, última sincronización, mensajes indexados, errores y retroceso.
attachmentUn adjunto o parte MIME de un mensaje, por número de parte de show. Imágenes en línea, texto (JSON y XML incluidos) como bloque marcado, otros binarios como enlace de descarga firmado.

search, ids, files y count toman una consulta notmuch (from:, to:, subject:, tag:, folder:, date:2026-01-01..2026-06-30, combinadas con y/o/no), un account opcional para limitar a una cuenta, y pueden incluir spam y papelera con include_excluded. El spam y la papelera se descubren por cuenta a través de RFC 6154 SPECIAL-USE, por lo que la exclusión funciona sean cuales sean los nombres de esas carpetas y en cualquier idioma. Mientras la duplicación de una cuenta aún se está llenando, estas cuatro herramientas anteponen una nota que nombra la cuenta y cuántos mensajes están indexados hasta ahora.

Los adjuntos se enumeran en show y thread y se sirven con la herramienta attachment una parte a la vez: imágenes en línea hasta 5MB, partes textuales como texto marcado, y otros binarios como un enlace firmado de corta duración a GET /attachment/{id}/{part} (un token de portador también funciona allí). Sin un listener HTTP, un binario sobredimensionado se guarda bajo /index/attachments/ y la herramienta devuelve la ruta a docker cp. Ese directorio está limitado a 1GB; los archivos más antiguos se eliminan primero.

Por qué no uno de los otros

Hay alrededor de cuarenta servidores MCP de correo en GitHub. Casi todos hablan IMAP en vivo y incluyen una ruta de envío, que es lo opuesto a ambas elecciones en las que se basa este servidor. Dos están lo suficientemente cerca como para mencionarlos. igor47/notmuchproxy es lo más parecido que ya existía, y una gran parte de la razón por la que este tiene la forma que tiene. Lee un archivo de notmuch que mantienes actualizado tú mismo, no tiene ruta de escritura, y acepta un token de portador o OIDC completo. Su validación de consultas, que rechaza un prefijo desconocido con una explicación, se reimplementa aquí como validateQuery. Dos cosas difieren: asume que ya ejecutas mbsync y notmuch, mientras que este servidor genera la configuración de mbsync, sincroniza cada cuenta en paralelo y descubre basura y papelera a través de IMAP; y no tiene parámetro account. Si ya tienes una configuración de notmuch con la que estás contento, notmuchproxy es lo más pequeño de implementar y deberías usarlo en lugar de este.

hgn/mcp-server-notmuch es solo stdio, así que un cliente en una máquina, y su manejo de contenido no confiable es el mejor del estudio. El único punto de estrangulamiento render() aquí, que marca cada byte de texto de correo en un solo lugar para que ninguna herramienta individual pueda olvidar hacerlo, proviene de su render.py.

El estudio completo, incluyendo qué afirmaciones se leyeron en el código fuente y cuáles se tomaron de un README, está en docs/research/email-mcp-landscape.md.

Seguridad

Lee esto antes de apuntarlo a un buzón que te importa.

No puede escribir. La configuración de mbsync generada para cada cuenta lleva Sync Pull, Create Near, Remove None y Expunge None (o, para una cuenta con expunge_local configurado, Expunge Near, que elimina archivos locales solo), y el programa escribe ese archivo él mismo, así que nada en él puede ser editado para convertirse en un push. La única operación IMAP en el código Go es LIST, emitida por cuenta al inicio y cada hora para encontrar las carpetas de basura y papelera; una cuenta con exclude_folders configurado a mano omite incluso eso. El proceso no tiene ninguna ruta que envíe, elimine, mueva o etiquete un mensaje, y nada en él tiene acceso de escritura a ninguna cuenta.

El correo eliminado permanece en el espejo. El correo que eliminas en el servidor se mantiene en disco y se oculta de la búsqueda mediante la etiqueta deleted de notmuch. Configura expunge_local: true en una cuenta para eliminar físicamente esas copias locales en su lugar. La cuenta nunca se escribe, pero el espejo entonces deja de ser una copia de seguridad: lo que desaparece remotamente desaparece localmente en la siguiente pasada.

Qué tan probado está esto. Un autor, un operador, tres cuentas reales: una iCloud y dos Gmail. Sin revisión de seguridad de terceros, y nadie más lo ha implementado. notmuchproxy tiene cero estrellas y una historia de producción más convincente que esta.

Las contraseñas son texto plano dentro del contenedor. Las contraseñas de las cuentas provienen del entorno y se escriben al inicio en una configuración de mbsync generada con modo de archivo 0600. Ese archivo no está cifrado. Cualquier cosa que pueda leer el entorno del contenedor, o ese archivo, puede leerlas. El cifrado del disco, quién puede ejecutar comandos dentro del contenedor y el acceso al host son responsabilidad del operador; el servidor no afirma cifrar credenciales en reposo.

Una frase de contraseña, un consentimiento. OAUTH_PASSPHRASE se verifica en tiempo constante y controla todo el servidor con un único secreto compartido. No es un sistema de credenciales por usuario, y todos los que tengan la frase de contraseña ven todo el buzón. No cifra nada en reposo. Trátala a ella y a las contraseñas de correo con el mismo cuidado.

Un buzón es un almacén de secretos. Los restablecimientos de contraseña, los códigos de inicio de sesión y los enlaces mágicos llegan por correo, así que solo el acceso de lectura es suficiente para tomar el control de cuentas si cae en las manos equivocadas o en la sesión de IA equivocada. El diseño de solo lectura y los marcadores de contenido no confiable eliminan la ruta de escritura y el canal de instrucciones; no hacen que los contenidos del correo sean inofensivos. Conecta clientes en los que confíes. Los flujos de trabajo de agentes que necesitan sus propios buzones necesitan sus propias direcciones, lo cual es una herramienta diferente.

Una brecha conocida. Los resúmenes de hilos de search incluyen un nombre para mostrar para cada mensaje en un hilo coincidente, que el remitente controla. Un mensaje en una carpeta excluida por defecto (basura, papelera) aún puede poner su propio nombre elegido por el atacante frente a ti de esta manera, aunque su cuerpo nunca lo haga. thread y show no están sujetos a esto. No está corregido en esta versión.

Para un servidor que enfrenta internet, docs/server.md enumera los pasos de endurecimiento en el orden de cuánto te aporta cada uno.

Referencia