Gmail Manager

Servidor MCP de Gmail (33 herramientas) con lista de destinatarios permitidos opcional y registro de auditoría local

Documentación

mcp-gmail-manager

🌐 Leia em português (pt-BR) →

PyPI version Python versions License: MIT MCP Compatible

Un servidor integral de Gmail Model Context Protocol: 35 herramientas que cubren enviar/vista previa/confirmar, responder, reenviar, borradores, búsqueda, lectura, adjuntos, papelera, etiquetas, filtros, firma y respuesta automática de vacaciones.

Características de defensa en profundidad que lo distinguen de otros MCP de Gmail:

  • Registro de auditoría a prueba de manipulación (activado por defecto): cada operación de escritura/envío/modificación/descarga añade una línea JSON a audit.jsonl, encadenada por SHA-256 para que la manipulación parcial sea detectable. Incluye rotación de registros, verificación de cadena al inicio, auditoría de lectura opcional y una CLI de mcp-gmail-manager-verify-log.
  • Lista de permitidos de destinatarios (desactivada por defecto): cuando está habilitada, cada operación saliente (send_email, create_draft, reply_to_message, forward_message, create_filter con una acción forward, además de direcciones incrustadas en la firma y el cuerpo de vacaciones) verifica los destinatarios contra dominios configurados y direcciones explícitas.
  • Lista de permitidos + lista de denegados de rutas de adjuntos (lista de denegados activada por defecto): el MCP se niega a adjuntar o sobrescribir archivos de credenciales obvios (~/.ssh/, ~/.aws/, id_rsa, .env, token.json, etc.), cerrando el ataque de "LLM exfiltra clave SSH como adjunto". Consulte Notas de seguridad para el conjunto completo de denegaciones por defecto.
  • Marcadores de contenido contaminado por inyección de prompts: las herramientas de lectura (get_message, get_thread, search_threads, list_drafts) envuelven los cuerpos y fragmentos de mensajes en etiquetas <untrusted-email-content>...</untrusted-email-content>. Las descripciones de herramientas instruyen al LLM a tratar el contenido envuelto como datos, no como instrucciones.
  • Escaneo de contenido saliente (desactivado por defecto): detección basada en regex de secretos en el asunto/cuerpo/firma/contenido de vacaciones (claves de acceso de AWS, tokens de Stripe/OpenAI/Anthropic/GitHub/GitLab/Google/Twilio, claves privadas PEM, JWTs, credenciales incrustadas en URLs). Bloquea el envío antes de que llegue a Gmail si un patrón coincide.
  • Flujo de vista previa + confirmación de envío (desactivado por defecto): preview_send_email ejecuta todas las salvaguardas y almacena la carga útil; confirm_send_email(preview_id) la entrega. Cuando send_confirmation.required=true, el send_email directo está deshabilitado para que un LLM comprometido no pueda "vista previa X, luego enviar Y".
  • Limitación de velocidad (desactivada por defecto): limita los envíos salientes por hora para evitar que los bucles de agentes descontrolados agoten la cuota de Gmail.
  • Ámbitos OAuth de privilegio mínimo: solicita solo gmail.modify + gmail.settings.basic. NO solicita mail.google.com, por lo que la eliminación permanente no está disponible intencionalmente.

Consulte examples/config.with-allowlist.json para una configuración de modo institucional.

Herramientas (33)

GrupoHerramientas
Enviar / responder / reenviarsend_email, preview_send_email, confirm_send_email, reply_to_message, forward_message
Borradorescreate_draft, list_drafts, send_draft, update_draft, delete_draft
Leer / perfilget_profile, get_message, search_threads, get_thread
Adjuntosget_message_attachments, download_attachment
Papeleratrash_message, untrash_message, trash_thread, untrash_thread
Etiquetaslist_labels, create_label, update_label, delete_label, label_message, unlabel_message, label_thread, unlabel_thread
Filtroslist_filters, create_filter, delete_filter
Firmaget_signature, update_signature
Respuesta de vacacionesget_vacation_responder, set_vacation_responder

Ámbitos OAuth solicitados: gmail.modify + gmail.settings.basic. NO solicita el ámbito de superusuario https://mail.google.com/: la eliminación permanente no es compatible intencionalmente.

Requisitos

  • Python ≥ 3.10
  • Un proyecto de Google Cloud con la API de Gmail habilitada y un cliente OAuth 2.0 (tipo Desktop)
  • Una forma de reenviar localhost:8765 a su host de autenticación (normalmente ssh -L 8765:localhost:8765 user@host)

Instalación

📖 ¿Prefiere un tutorial paso a paso con capturas de pantalla para cada etapa de la configuración de Google Cloud? Consulte la Guía de instalación. La sección siguiente cubre solo la instalación del paquete; la guía completa explica GCP, credenciales, OAuth, configuración de VM y registro en Claude Code.

Compatible con Linux, macOS y Windows. La ruta recomendada es pipx, que instala la CLI en un venv aislado y expone los puntos de entrada en $PATH.

Linux (Debian / Ubuntu / Mint / Fedora / Arch)

sudo apt install pipx        # Debian / Ubuntu / Mint
sudo dnf install pipx        # Fedora
sudo pacman -S python-pipx   # Arch
pipx ensurepath              # adds ~/.local/bin to PATH
# reopen shell or: source ~/.bashrc

pipx install mcp-gmail-manager

macOS

brew install pipx            # or: python3 -m pip install --user pipx
pipx ensurepath              # adds ~/.local/bin to PATH
# reopen shell or: source ~/.zshrc

pipx install mcp-gmail-manager

Windows (PowerShell)

# If you don't have Python yet:  winget install --id Python.Python.3.12
python -m pip install --user pipx
python -m pipx ensurepath
# close and reopen PowerShell

pipx install mcp-gmail-manager

Advertencias de Windows: todo funciona, con tres notas:

  • Permisos del archivo de token. En Linux/macOS el MCP escribe token.json con chmod 0o600. En Windows no hay chmod POSIX, por lo que el archivo hereda su ACL de %USERPROFILE%: protegido contra otras cuentas de usuario, pero cualquier proceso que se ejecute como su usuario puede leerlo. Misma postura efectiva que la mayoría de las herramientas CLI de Windows que almacenan tokens OAuth.
  • La lista de denegados de rutas de adjuntos funciona. A partir de v0.3.2, la coincidencia de listas de denegados/permitidos normaliza las rutas a formato de barra diagonal mediante Path.as_posix(), por lo que una ruta de Windows como C:\Users\me\.ssh\id_rsa se detecta correctamente con el patrón de denegación ~/.ssh/ por defecto. Confirmado por la suite de humo en ambas plataformas.
  • El puerto 8765 puede estar reservado por Windows. Hyper-V, WSL2 y Docker Desktop reservan rangos de puertos dinámicos que a veces incluyen 8765, lo que da bind [127.0.0.1]:8765: Permission denied en el extremo local de un reenvío SSH -L. Verifique con netsh interface ipv4 show excludedportrange protocol=tcp. Si 8765 está reservado, establezca GMAIL_MCP_AUTH_PORT a un puerto libre en ambos extremos (v0.3.3+): set GMAIL_MCP_AUTH_PORT=18765 en el servidor antes de ejecutar mcp-gmail-manager-auth, y reenvíe ese mismo puerto: ssh -L 18765:localhost:18765 user@server.

Alternativa en cualquier sistema operativo: venv manual

python3 -m venv ~/.venv-mcp-gmail
~/.venv-mcp-gmail/bin/pip install mcp-gmail-manager
# Windows: python -m venv %USERPROFILE%\.venv-mcp-gmail
# Use the absolute path when registering with Claude Code (see below)

¿Por qué no un pip install simple a nivel de sistema? En distribuciones modernas basadas en Debian y Homebrew Python falla con error: externally-managed-environment (PEP 668): el sistema operativo protege su Python. Los métodos pipx y venv anteriores son las soluciones canónicas.

Desde el código fuente:

git clone https://github.com/arthjhon/mcp-gmail-manager.git
cd mcp-gmail-manager
pipx install .

Configuración de Google Cloud (una sola vez, ~10 minutos)

  1. Vaya a Google Cloud Console y cree un nuevo proyecto (o elija uno existente).
  2. Habilite la API de Gmail (no "Gmail MCP API": esa es el MCP remoto propio de Google; no es lo que queremos).
  3. Configure la pantalla de consentimiento OAuth:
    • Tipo de usuario: Interno si su cuenta es parte de Google Workspace (sin expiración de token); de lo contrario Externo en modo Prueba (hasta 100 usuarios, los tokens de actualización expiran cada 7 días: consulte Expiración de token más abajo).
    • Ámbitos: agregue https://www.googleapis.com/auth/gmail.modify y https://www.googleapis.com/auth/gmail.settings.basic. No agregue nada más.
    • Usuarios de prueba (solo Externo): agregue la dirección de Gmail con la que se autenticará.
  4. Cree un ID de cliente OAuth:
    • Tipo de aplicación: Aplicación de escritorio
    • Descargue el JSON. Guárdelo como credentials.json.

Autenticación inicial

Mueva sus credenciales al directorio de configuración (por defecto ~/.config/mcp-gmail-manager/):

mkdir -p ~/.config/mcp-gmail-manager
mv ~/Downloads/client_secret_*.json ~/.config/mcp-gmail-manager/credentials.json
chmod 600 ~/.config/mcp-gmail-manager/credentials.json

Ejecute el flujo de autenticación:

mcp-gmail-manager-auth

Esto se vincula a localhost:8765 e imprime una URL de autorización de Google. Ábrala en un navegador en una máquina que pueda alcanzar localhost:8765 en el host de autenticación:

  • Escritorio local: la URL impresa funciona directamente.
  • Servidor remoto / sin cabeza: reenvíe el puerto desde su portátil primero:
    ssh -L 8765:localhost:8765 user@your-server
    
    Luego ejecute mcp-gmail-manager-auth dentro de esa sesión SSH.

Autorice con la cuenta de Google que será propietaria del correo saliente. Al tener éxito, el script escribe token.json y sale.

Expiración de token

La vida útil del token de actualización depende de cómo esté configurada la pantalla de consentimiento OAuth:

ConfiguraciónVida útil del token de actualización¿Requiere reautenticación?
Interno (Google Workspace)Sin expiraciónNunca (hasta que el usuario revoque)
Externo + Prueba7 días (política de Google para aplicaciones no verificadas)Sí: semanalmente
Externo + Producción verificadaSin expiraciónNunca, pero la verificación requiere una evaluación de seguridad de Google de pago

Cuando el token de actualización expire en modo Prueba, verá errores de invalid_grant o Token has been expired or revoked. Para recuperarse:

rm ~/.config/mcp-gmail-manager/token.json
mcp-gmail-manager-auth

Tarda ~30 segundos. Su credentials.json no se ve afectado: solo el token del usuario.

Cómo evitar la rotación semanal

  • Usuarios de Workspace: configure la pantalla de consentimiento como Interno en lugar de Externo. El token nunca expira.
  • Usuarios personales de Gmail: la reautenticación semanal es la única opción práctica hoy. La verificación de producción para gmail.modify requiere una evaluación de seguridad de Google (de pago, semanas de proceso): no es factible para la mayoría de los proyectos personales.
  • Establezca un recordatorio de calendario o un trabajo cron para avisarle semanalmente. Una versión futura puede agregar advertencias proactivas en la herramienta antes de la expiración.

Registro con Claude Code

Si se instaló mediante pipx:

claude mcp add gmail-manager -- mcp-gmail-manager

Si se instaló en un venv manual que no está en $PATH:

claude mcp add gmail-manager -- ~/.venv-mcp-gmail/bin/mcp-gmail-manager

Reinicie su sesión de Claude Code para que se carguen los nuevos esquemas de herramientas.

Múltiples cuentas de Gmail

Cada instancia del MCP maneja una cuenta de Gmail. Para usar varias cuentas desde la misma sesión de Claude Code (por ejemplo, personal + trabajo), registre el MCP una vez por cuenta con un GMAIL_MCP_CONFIG_DIR distinto. Cada instancia obtiene sus propias credenciales, token, registro de auditoría y configuración: totalmente aisladas.

Configuración por cuenta

# 1. Dedicated config directory
mkdir -p ~/.config/mcp-gmail-<name> && chmod 700 ~/.config/mcp-gmail-<name>

# 2. Reuse the same OAuth client (one credentials.json works for any user in the same GCP project)
cp ~/.config/mcp-gmail-<other>/credentials.json ~/.config/mcp-gmail-<name>/
chmod 600 ~/.config/mcp-gmail-<name>/credentials.json

# 3. Authenticate with the target Gmail account
GMAIL_MCP_CONFIG_DIR=$HOME/.config/mcp-gmail-<name> mcp-gmail-manager-auth

# 4. Register with the env override
claude mcp add gmail-<name> -s user \
  -e GMAIL_MCP_CONFIG_DIR=$HOME/.config/mcp-gmail-<name> \
  -- mcp-gmail-manager

Reinicie Claude Code. Las herramientas aparecen bajo espacios de nombres separados:

  • mcp__gmail-personal__send_email → envía desde la cuenta personal
  • mcp__gmail-work__send_email → envía desde la cuenta de trabajo

Puede indicar a Claude "enviar vía gmail-work" y elige el espacio de nombres correcto.

Configuración por cuenta

Cada <config_dir>/config.json es independiente. Patrones útiles:

// ~/.config/mcp-gmail-work/config.json — strict allowlist
{
  "allowlist": {
    "enabled": true,
    "domains": ["yourcompany.com"]
  }
}
// ~/.config/mcp-gmail-personal/config.json — silence the audit log
{
  "audit_log": { "enabled": false }
}

El compromiso del token de una cuenta no filtra el de la otra: cada uno vive en un directorio separado con chmod 600.

Configuración

~/.config/mcp-gmail-manager/config.json es opcional: si no existe, se aplican valores predeterminados sensatos (sin lista de permitidos, registro de auditoría habilitado). Se proporcionan dos ejemplos listos para copiar:

  • examples/config.example.json: valores predeterminados endurecidos (punto de partida recomendado). Todas las salvaguardas activadas; lista de permitidos habilitada pero vacía, por lo que la advertencia de inicio le indicará qué configurar primero.
  • examples/config.with-allowlist.json: ejemplo institucional completamente poblado con dominios de marcador de posición.
  • examples/config.permissive.json: exclusión explícita para usuarios que no quieren salvaguardas (lista de permitidos desactivada, escaneo de contenido desactivado, límite de velocidad desactivado, sin confirmación de envío). Considere esto solo si comprende el radio de explosión.

Referencia de esquema:

{
  "allowlist": {
    "enabled": false,
    "domains": [],
    "emails": []
  },
  "audit_log": {
    "enabled": true,
    "include_reads": false,
    "path": null
  },
  "attachments": {
    "max_total_bytes": 20971520,
    "allowed_paths": [],
    "deny_patterns": [],
    "use_default_deny_patterns": true
  }
}
CampoPredeterminadoSignificado
allowlist.enabledfalseCuando false, se acepta cualquier destinatario. Habilítalo explícitamente para uso institucional.
allowlist.domains[]Sufijos de dominio en minúsculas aceptados como destinatarios.
allowlist.emails[]Direcciones de correo explícitas en minúsculas aceptadas independientemente del dominio.
audit_log.enabledtrueAñade cada escritura/envío/modificación a JSONL.
audit_log.include_readsfalseTambién registra operaciones de lectura (get_message, search_threads, get_thread, list_drafts, get_message_attachments). Útil para detectar reconocimiento silencioso.
audit_log.pathnullnull<config_dir>/audit.jsonl. Anula para centralizar registros.
audit_log.max_size_bytes10485760 (10 MB)Rota a audit.jsonl.1..N cuando el archivo actual supera este tamaño. La cadena se reinicia entre rotaciones; verifica cada archivo por separado con la CLI.
audit_log.max_backups5Número de copias de seguridad rotadas a conservar. Las más antiguas se sobrescriben.
audit_log.verify_on_startupfalseRecorre la cadena al iniciar el servidor y emite una advertencia en stderr si está rota. Económico para registros de hasta unos pocos MB.
attachments.max_total_bytes20971520 (20 MB)Límite de tamaño combinado por envío. El límite estricto de Gmail es de 25 MB en bruto.
attachments.allowed_paths[]Cuando se completa, los orígenes y destinos de adjuntos/descargas DEBEN estar bajo una de estas bases. Vacío = solo se aplican patrones de denegación.
attachments.deny_patterns[]Patrones regex adicionales para rechazar (coinciden con la ruta absoluta). Se añaden además de los predeterminados.
attachments.use_default_deny_patternstrueIncluye el conjunto de denegación integrado (~/.ssh/, ~/.aws/, id_rsa, .env, token.json, archivos de credenciales, almacenes de navegador).
rate_limit.enabledfalseCuando true, limita los envíos salientes por hora por instancia en ejecución. Ventana deslizante en memoria: se reinicia al reiniciar el servidor.
rate_limit.sends_per_hour60Se aplica a send_email, reply_to_message, forward_message y send_draft combinados.
content_scan.enabledfalseCuando true, escanea asuntos, cuerpos, firmas y contenido de vacaciones salientes en busca de patrones secretos. Las coincidencias bloquean la operación antes de que llegue a Gmail.
content_scan.use_default_patternstrueIncluye las expresiones regulares secretas integradas (claves de acceso de AWS, tokens de Stripe/OpenAI/Anthropic/GitHub/GitLab/Google/Twilio, claves privadas PEM, JWT, credenciales incrustadas en URL).
content_scan.patterns[]Patrones adicionales definidos por el usuario. Cada entrada: {"name": "...", "regex": "..."}. Los nombres aparecen en mensajes de error para depuración.
content_scan.scan_subject / scan_body / scan_signature / scan_vacationtrueAlternancias por ámbito. Útil para deshabilitar una ubicación mientras se mantienen otras activas.
send_confirmation.requiredfalseCuando true, el send_email directo está deshabilitado: debe pasar por preview_send_emailconfirm_send_email(preview_id).
send_confirmation.preview_ttl_seconds300Cuánto tiempo sigue siendo válida una vista previa antes de que deba reemitirse.
signature.auto_appendfalseCuando true, obtiene la firma configurada en la Configuración de Gmail y la añade a cada cuerpo saliente (enviar/responder/reenviar/crear_borrador/actualizar_borrador/vista_previa). La interfaz web de Gmail aplica firmas automáticamente; la API de Gmail NO: habilítalo para que coincida.
signature.cache_ttl_seconds3600Cuánto tiempo almacenar en caché la firma obtenida en memoria antes de volver a obtenerla.
signature.strip_htmltrueGmail almacena firmas como HTML. Cuando true, el MCP reduce a texto plano (preservando saltos de línea) y envía un mensaje solo de texto/plano. Cuando false (v0.3.5+), el MCP envía multipart/alternative: una parte de texto plano con la firma reducida, más una parte de texto/html con la firma HTML original preservando imágenes de logotipos, colores y diseño. Establécelo en false si tu firma de Gmail tiene un logotipo o formato enriquecido que quieras conservar.
body.format"plain"Cómo se interpreta el campo body de las herramientas de enviar/responder/reenviar/borrador. "plain" (predeterminado): el cuerpo es texto plano, enviado como texto/plano (compatible con v0.3.5). "markdown" (v0.3.6+): el cuerpo es Markdown; la parte de texto plano conserva el Markdown en bruto, la parte HTML se renderiza: **bold**, *italic*, # H1, - lists, [links](url), `code` all render properly in email clients. "html": body is raw HTML; HTML part is passthrough, plain part is a stripped-to-text fallback. Enable markdown si quieres que el Markdown natural de Claude se renderice como formato enriquecido.
signature.send_as_emailnullQué identidad de sendAs usar para la firma. null = el correo principal.

Verificación del registro de auditoría

Ejecuta mcp-gmail-manager-verify-log para recorrer la cadena de hash y confirmar que ninguna entrada ha sido editada o eliminada:

mcp-gmail-manager-verify-log                       # verify the active log
mcp-gmail-manager-verify-log ~/.config/.../audit.jsonl.1   # verify a rotated backup

Códigos de salida: 0 OK, 1 registro no encontrado, 2 JSON malformado, 3 cadena rota.

Anulaciones de variables de entorno

VariablePredeterminado
GMAIL_MCP_CONFIG_DIR$XDG_CONFIG_HOME/mcp-gmail-manager o ~/.config/mcp-gmail-manager
GMAIL_MCP_CREDENTIALS<config_dir>/credentials.json
GMAIL_MCP_TOKEN<config_dir>/token.json

Notas de seguridad

  • Modelo de amenaza: este MCP está principalmente endurecido contra un LLM con mal comportamiento: inyección de prompts, destinatarios alucinados, escenarios de exfiltración engañosa. NO es un sustituto de la seguridad del host; un atacante con acceso local puede leer token.json y llamar a Gmail directamente, omitiendo todas las salvaguardas aquí.
  • Almacenamiento de tokens: token.json se escribe chmod 600. Trátalo como una contraseña.
  • Sin atestación remota: este servidor se ejecuta completamente en tu máquina. Sin telemetría, sin llamadas de terceros más allá de googleapis.com.
  • El alcance de OAuth es deliberadamente algo estrecho: gmail.modify cubre enviar/leer/etiquetar/papelera/borradores. NO solicita mail.google.com, por lo que la eliminación permanente no está disponible: las eliminaciones van a la Papelera y se pueden deshacer con untrash_*. Si solo necesitas enviar, haz un fork y reemplaza el alcance con gmail.send.
  • Las salvaguardas de destinatarios cubren el reenvío en filtros: create_filter con un action.forward dirigido a una dirección no permitida se rechaza. Los filtros eran una omisión común de las listas de permitidos solo de envío.
  • Las herramientas de lectura marcan el contenido como no confiable: los cuerpos y fragmentos están envueltos en <untrusted-email-content>...</untrusted-email-content>. Las descripciones de herramientas instruyen a los LLM posteriores a tratar el contenido envuelto como datos. Cualquier aparición de la etiqueta de cierre dentro del cuerpo de un mensaje se escapa para evitar la fuga.
  • Conjunto de denegación de adjuntos predeterminado (origen y destino) cubre rutas comunes de credenciales/secretos: ~/.ssh/, ~/.aws/, ~/.gnupg/, ~/.docker/config.json, ~/.kube/, .env, .env.*, credentials.json, token.json, id_rsa/id_ed25519/id_ecdsa/id_dsa, .git-credentials, .netrc, wallet.dat, .bash_history, .zsh_history, ~/.mozilla/*/logins.json, authorized_keys, known_hosts. Extiéndelo mediante attachments.deny_patterns o redúcelo más mediante attachments.allowed_paths.
  • El registro de auditoría es a prueba de manipulaciones, no a prueba de manipulaciones: cada entrada incluye prev_hash = sha256(previous line). La modificación parcial rompe la cadena y es detectable. Una reescritura completa del registro por un atacante con escritura de archivos NO se previene: combínalo con envío de registros fuera del host (hoja de ruta) para garantías más sólidas.
  • Lo que NO se mitiga: limitación de velocidad (un agente comprometido puede agotar la cuota de Gmail rápidamente), escaneo de patrones de contenido saliente (sin regex de secretos en cuerpos), phishing de firmas/vacaciones (la lista de permitidos no cubre su contenido), reescritura completa del registro por un atacante local. Consulta SECURITY.md para el modelo de amenaza actual y la hoja de ruta.

Limitaciones

  • La verificación "Producción" de OAuth para gmail.modify requiere una evaluación de seguridad paga de Google. Mantente en "Interno" (Workspace, sin expiración) o "Pruebas" (≤ 100 usuarios, rotación de token de actualización de 7 días — consulta Expiración de token) para evitar esto.
  • La composición del cuerpo de correo HTML no se expone como un campo de primera clase. Envía mediante create_draft + edición manual de HTML en la interfaz de Gmail, o extiende _build_mime en un fork.
  • Las notificaciones push (Pub/Sub watch/stop) no están implementadas: fuera de alcance.

Contribuciones

Se aceptan issues y PRs. Mantén los cambios enfocados, documenta cualquier nueva herramienta con un ejemplo de esquema y añade una entrada de registro de auditoría para cualquier cosa que mute el estado.

Licencia

MIT — consulta LICENSE.