zimbra-mcp
zimbra-mcp
Servidor MCP en Python que expone tu casilla Zimbra (IMAP + SMTP + LDAP/GAL) como herramientas para Claude / Cowork.
🚀 Start Rápido
¿Primera vez? → Seguí QUICKSTART.md (5 minutos)
¿Querés ejemplos detallados? → Ver INTEGRATION_EXAMPLES.md
Incluye:
📘 Claude Desktop (Windows, macOS, Linux)
🟢 ChatGPT con Bridge API
☁️ Deployment en AWS, DigitalOcean, Fly.io
🔐 Seguridad en producción
Probado contra mcp SDK v2.0.0 (API MCPServer, no la vieja FastMCP). Si
en tu máquina pip install mcp te trae una versión distinta y algo no
importa, fijate el changelog del SDK — la clase clave hoy es
mcp.server.MCPServer.
📚 Documentación
Documento | Para qué |
🎯 Instalar en Claude Desktop (método actual con | |
⚡ Setup alternativo (Docker, venv local) | |
📖 Ejemplos para ChatGPT, AWS, DigitalOcean, Fly.io | |
📋 Tabla de herramientas, variables, configuración | |
📘 Overview general (este archivo) |
Herramientas expuestas
Tool | Qué hace |
| Lista las carpetas IMAP |
| Busca por remitente, asunto, texto, no-leídos, rango de fechas |
| Trae el contenido completo (texto/html/adjuntos) de un mensaje |
| Pone/saca flags: seen, flagged, answered, deleted |
| Mueve/archiva un mensaje a otra carpeta |
| Por defecto mueve a Trash (recuperable); |
| Descarga un adjunto al volumen |
| Envía correo por SMTP (texto/html, cc/bcc, adjuntos, threading) |
| Busca en la Libreta Global (GAL) por LDAP |
| Trae el detalle de un contacto GAL por su DN |
| (auth) Genera un JWT access token a partir de una API key |
⚠️ Sobre LDAP/GAL — leé esto antes de asumir que va a andar
El LDAP interno de Zimbra (OpenLDAP embebido) generalmente solo escucha en
localhost del propio servidor de correo y no está expuesto hacia afuera por
defecto. Si tu Zimbra no tiene el puerto LDAP (389/636) abierto para vos desde
donde corra este contenedor, search_contacts/get_contact van a fallar con
un error explicando por qué — no es un bug del código. Antes de invertir
tiempo en esto:
Preguntale a tu admin de Zimbra si el LDAP de GAL está expuesto externamente y con qué host/puerto/base DN.
Si no lo está, la alternativa típica es CardDAV (no implementado acá todavía) o la API SOAP/REST de Zimbra — avisame si querés que lo agregue.
Setup rápido (sin Docker, para probar)
cd zimbra-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # completá ZIMBRA_USERNAME, ZIMBRA_PASSWORD, ZIMBRA_IMAP_HOST, ZIMBRA_SMTP_HOST
# 1) Primero verificá que las credenciales/host andan, SIN pasar por MCP:
python scripts/check_connection.py
# 2) Si eso dio OK, probá el server MCP en modo stdio:
ZIMBRA_MCP_TRANSPORT=stdio python -m zimbra_mcp.serverDatos que necesitás para el .env
ZIMBRA_IMAP_HOST/ puerto: normalmentemail.tudominio.compuerto993con SSL. Podés confirmarlo mirando la config de tu cliente actual (Thunderbird/Outlook: cuenta → configuración del servidor).ZIMBRA_SMTP_HOST: casi siempre el mismo host, puerto587con STARTTLS (o465con SSL directo — ajustáZIMBRA_SMTP_SSL/ZIMBRA_SMTP_STARTTLS).ZIMBRA_USERNAME/ZIMBRA_PASSWORD: tu login normal. Si tu Zimbra soporta contraseñas de aplicación, mejor usar una en vez de tu password principal.
Correr con Docker
cp .env.example .env # completar antes de levantar
docker compose up --buildEsto deja el server escuchando http://localhost:8000/mcp (streamable-http).
El Dockerfile no pude probarlo en este sandbox porque no tenía acceso al
demonio de Docker, pero es un build estándar (python:3.11-slim + pip install -e .) — corré docker compose up --build vos y avisame si algo
rompe.
Nota de red: el contenedor tiene que poder llegar al host de Zimbra por IMAP(S)/SMTP(S)/LDAP. Si Zimbra solo es alcanzable dentro de tu VPN/red interna, corré el contenedor en una máquina que ya tenga esa conectividad (tu PC, o un VPS que ya esté en la VPN) — no en un entorno cloud aislado.
Integración con Claude Desktop / Cowork / ChatGPT
🔵 Claude Desktop — Opción A: Local sin Docker (recomendado para probar)
Paso 1: Ubicá el archivo de configuración de Claude Desktop según tu SO:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Si el archivo no existe, crealo en esa ubicación.
Paso 2: Editá el archivo y agregá la configuración del servidor Zimbra:
{
"mcpServers": {
"zimbra": {
"command": "/ruta/absoluta/al/.venv/bin/python",
"args": ["-m", "zimbra_mcp.server"],
"env": {
"ZIMBRA_MCP_TRANSPORT": "stdio",
"ZIMBRA_USERNAME": "tu@email.com",
"ZIMBRA_PASSWORD": "tu-contraseña",
"ZIMBRA_IMAP_HOST": "mail.tudominio.com",
"ZIMBRA_IMAP_PORT": "993",
"ZIMBRA_SMTP_HOST": "mail.tudominio.com",
"ZIMBRA_SMTP_PORT": "465",
"ZIMBRA_AUTO_MARK_READ": "false",
"ZIMBRA_AUTH_ENABLED": "false"
},
"cwd": "/ruta/absoluta/a/zimbra-mcp"
}
}
}Ejemplo en Windows:
{
"mcpServers": {
"zimbra": {
"command": "C:\\Users\\tuusuario\\Projects\\zimbra-mcp\\.venv\\Scripts\\python.exe",
"args": ["-m", "zimbra_mcp.server"],
"env": {
"ZIMBRA_MCP_TRANSPORT": "stdio",
"ZIMBRA_USERNAME": "dani@empresa.com",
"ZIMBRA_PASSWORD": "MiPassword123",
"ZIMBRA_IMAP_HOST": "mail.empresa.com",
"ZIMBRA_IMAP_PORT": "993",
"ZIMBRA_SMTP_HOST": "mail.empresa.com",
"ZIMBRA_SMTP_PORT": "465"
},
"cwd": "C:\\Users\\tuusuario\\Projects\\zimbra-mcp"
}
}
}Paso 3: Reiniciá Claude Desktop para cargar la configuración.
Paso 4: Abrí una conversación en Claude y escribí algo como:
Listá los correos en mi INBOX de ZimbraClaude debería poder acceder a tus herramientas de Zimbra automáticamente.
🔵 Claude Desktop — Opción B: Docker con conexión remota
Paso 1: Asegurate que Docker está corriendo:
docker compose up -dEl servidor estará disponible en http://localhost:8000/mcp.
Paso 2: En Claude Desktop, usa la opción "Agregar conector remoto" (Remote Connector) o "Custom MCP Server":
URL del servidor:
http://localhost:8000/mcpTipo de transporte:
streamable-http(seleccionar automáticamente)
Paso 3: Si tu servidor tiene autenticación (ZIMBRA_AUTH_ENABLED=true):
Antes de usar cualquier herramienta, ejecutá primero:
get_access_token(api_key="tu-api-key-aqui")Esto te dará un token JWT que será válido por 1 hora. Guardalo para referencia.
🟢 ChatGPT + OpenAI
⚠️ Nota importante: ChatGPT usa su propio sistema de "Custom GPT" y no soporta directamente MCP (Model Context Protocol). Sin embargo, tenés estas opciones:
Opción 1: Usar OpenAI API + MCP Server Bridge (avanzado)
Si querés que un Custom GPT acceda a Zimbra, necesitás crear un "bridge" que exponga el MCP como una API REST. Eso requiere:
Un servidor FastAPI/Flask que envuelva las herramientas MCP
Configurar una "Action" en tu Custom GPT apuntando a ese servidor
Ejemplo mínimo:
# bridge_server.py
from fastapi import FastAPI, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthCredentials
import sys
sys.path.insert(0, 'src')
from zimbra_mcp.server import create_server
from zimbra_mcp.config import load_settings
app = FastAPI()
security = HTTPBearer()
settings = load_settings()
mcp_server = create_server(settings)
@app.post("/api/search_messages")
async def search_emails(
credentials: HTTPAuthCredentials,
folder: str = "INBOX",
query: str = None,
limit: int = 10
):
# Validar token si auth está habilitada
if settings.auth_enabled:
# Verificar token aquí
pass
# Llamar herramienta MCP
results = mcp_server.search_messages(folder=folder, query=query, limit=limit)
return {"emails": results}
# Más endpoints para get_message, send_email, etc.Luego:
Deployá este bridge en un servidor (Heroku, Replit, tu VPS, etc.)
En Custom GPT → "Configure" → "Actions" → agrega tu servidor
Define un OpenAPI schema para que el GPT sepa qué parámetros usar
Opción 2: Usar Cowork (recomendado para ChatGPT users)
Si querés usar Zimbra desde algo como ChatGPT, considerá Cowork (plataforma agnóstica de MCP):
Instalar Cowork: https://cowork.anthropic.com
Agregar el servidor Zimbra usando la misma config de Claude Desktop
Usar Cowork con ChatGPT u otros modelos
Cuando lo llevés a la nube
Paso 1: Deployá el Docker en tu servidor (AWS, DigitalOcean, tu VPS, etc.):
# En tu servidor
git clone <repo>
cd zimbra-mcp
cp .env.example .env
# Completá el .env con tus credenciales
docker compose up -dPaso 2: Exponé el servidor de forma segura:
Con HTTPS + Nginx reverse proxy (recomendado):
server { listen 443 ssl; server_name zimbra-mcp.tudominio.com; location / { proxy_pass http://localhost:8000; } }Con Cloudflare Tunnel (sin exponer IP pública):
cloudflared tunnel run zimbra-mcp
Paso 3: En Claude Desktop, usá la URL remota:
{
"mcpServers": {
"zimbra": {
"command": "python",
"args": ["-m", "mcp.client.http", "https://zimbra-mcp.tudominio.com/mcp"],
"env": {
"ZIMBRA_AUTH_ENABLED": "true",
"ZIMBRA_AUTH_API_KEY": "tu-api-key"
}
}
}
}Point importante: El servidor que corre en la nube necesita conectividad a tu Zimbra (IMAP/SMTP/LDAP). Si tu Zimbra está en una VPN privada:
Deployá el servidor en una máquina que ya tenga acceso (tu router, una Raspberry Pi en tu oficina)
O expone Zimbra con seguridad (firewall + certificados SSL)
📚 Ejemplos Detallados de Integración
Para instrucciones paso a paso con ejemplos específicos según tu SO y caso de uso, consultá:
Incluye:
✅ Claude Desktop (Windows, macOS, Linux)
✅ ChatGPT (con Bridge FastAPI)
✅ Cowork (agnóstico a LLM)
✅ AWS EC2, DigitalOcean, Fly.io
✅ Troubleshooting común
Seguridad
.envnunca se commitea (está en.gitignore) ni se hornea en la imagen.Las conexiones IMAP/SMTP son por TLS (SSL directo o STARTTLS según config).
delete_messagepor defecto NO borra permanente — mueve a Trash. Solo pasa a expunge real si vos (o el modelo, con tu confirmación explícita) pasáspermanent=True.Considerá usar una contraseña de aplicación en vez de tu password principal de Zimbra, si tu instalación lo soporta.
Autenticación (opcional)
Para proteger el servidor MCP con API keys y access tokens JWT:
Generá una API key y JWT secret:
python scripts/generate_auth_keys.pyCompletá tu
.env:ZIMBRA_AUTH_ENABLED=true ZIMBRA_AUTH_API_KEYS=<tu-api-key> ZIMBRA_AUTH_JWT_SECRET=<tu-jwt-secret> ZIMBRA_AUTH_TOKEN_TTL=3600Antes de usar otras herramientas, obtené un access token:
get_access_token(api_key="<tu-api-key>")El servidor devuelve un JWT válido por el tiempo especificado en
ZIMBRA_AUTH_TOKEN_TTL.
Nota: En versiones futuras se agregará validación de tokens en cada request HTTP.
Estado / qué falta
✅ IMAP: listar carpetas, buscar, leer, flags, mover, borrar, adjuntos
✅ SMTP: enviar (texto/html, cc/bcc, adjuntos, threading headers)
✅ LDAP: búsqueda GAL (sujeto a que tu Zimbra la exponga — ver aviso arriba)
✅ Dockerfile + docker-compose
⬜ CardDAV como alternativa a LDAP si el GAL no es alcanzable
⬜ Paginación real en
search_messages(hoy es unlimitsimple)⬜ Tests automatizados (por ahora:
scripts/check_connection.pya mano)