Skip to main content
Glama
mcp-outlook

mcp-outlook

by ItayElizur

mcp-outlook

Un servidor MCP autoalojable para Microsoft Exchange local a través de EWS (Exchange Web Services). Diseñado para entornos aislados / sin nube: se comunica directamente con tu servidor Exchange interno y nunca toca Microsoft Graph, Azure AD ni un cliente de escritorio de Outlook.

  • Backend: exchangelib (cliente EWS)

  • Framework: FastMCP

  • Transporte: streamable-http (un servidor HTTP independiente al que se conectan otros hosts internos)

  • Autenticación con Exchange: básica o NTLM (seleccionable mediante configuración)

Dos modos

Modo

A quién sirve

Cómo autentica

static (predeterminado)

un buzón

se conecta como esa cuenta (tus propias credenciales) — ideal para pruebas beta locales

jwt

muchos usuarios

valida el JWT de usuario de cada llamante y luego actúa sobre el buzón de ese usuario mediante una cuenta de servicio + suplantación de EWS (EWS Impersonation)

Cómo el modo jwt tiende un puente entre identidades. Exchange no puede consumir los JWT de tu empresa (Outlook se basa en PKINIT/Kerberos). Por eso el MCP realiza dos autenticaciones separadas que nunca se mezclan:

User --(JWT)--> MCP validates the token, reads the user's email
                MCP --(service account, NTLM)--> Exchange
                MCP --(impersonation header = user's email)--> acts on the user's mailbox

El JWT del usuario nunca se envía a Exchange, y ninguna contraseña/tarjeta inteligente de usuario toca jamás el MCP: solo lo hace la única credencial de servicio. Consulta TODO.md para saber qué deben configurar los administradores para el modo jwt.

Related MCP server: OWA Exchange MCP Server

Herramientas

Herramienta

Propósito

list_emails(folder="inbox", limit=20)

Mensajes recientes, primero los más nuevos

search_emails(query, folder, start_date, end_date, sender, recipient, limit)

Búsqueda por texto + rango de fechas + remitente/destinatario

get_email(message_id, folder="inbox")

Mensaje completo: cuerpo, destinatarios, nombres de los archivos adjuntos

draft_email(to, subject, body)

Abre el widget interactivo de redacción (MCP Apps); el usuario edita y envía

reply_email(message_id, folder, reply_all, body)

Abre el widget de redacción prerrellenado como respuesta

forward_email(message_id, folder, to, body)

Abre el widget de redacción prerrellenado como reenvío

send_email(to, subject, body, cc, bcc, html, attachments)

Enviar: se puede llamar solo desde el widget (visibilidad solo para la app)

search_contacts(query, limit)

Buscar contactos: se puede llamar solo desde el widget (solo para la app)

mark_email_read(message_id, folder) / mark_email_unread(...)

Cambia el estado de leído/no leído

delete_email(message_id, folder, permanent=False)

Mover a Elementos eliminados, o eliminar permanentemente

flag_email_important(message_id, folder, important=True)

Establece la importancia Alta/Normal de Outlook

move_email(message_id, destination, folder)

Mueve un mensaje a otra carpeta

list_folders()

Nombres de carpetas de correo disponibles, incluidas subcarpetas

list_events(start_date, end_date, limit)

Eventos de calendario en un rango de fechas

get_event(event_id)

Evento completo: cuerpo, asistentes, ubicación

find_meeting_slots(attendees, duration_minutes, ...)

Asistente de programación: ordena las franjas por disponibilidad de los asistentes

draft_event(subject, start, end, location, body, required_attendees, optional_attendees)

Abre el widget interactivo de borrador de evento

create_event(subject, start, end, required_attendees, ...)

Crear el evento: se puede llamar solo desde el widget (solo para la app)

accept_meeting(event_id) / decline_meeting(event_id)

Responde a una invitación de reunión

list_emails y search_emails también aceptan unread_only=true para devolver solo mensajes no leídos.

Instalación

Requiere Python 3.11+ y uv.

uv sync                 # create venv + install deps
cp .env.example .env    # then edit .env with your Exchange details
uv run python -m mcp_outlook

El servidor se vincula a MCP_HOST:MCP_PORT (por defecto 127.0.0.1:8000) y sirve el endpoint MCP streamable-http en /mcp.

Pruebas beta locales (sin configuración de administrador)

Ejecuta contra tu propio buzón con tu propio nombre de usuario/contraseña: sin JWT, sin suplantación, sin cuenta de servicio, sin tarjeta inteligente:

# in .env:
OUTLOOK_AUTH_MODE=static          # the default
OUTLOOK_EWS_ENDPOINT=https://mail.corp.local/EWS/Exchange.asmx
OUTLOOK_USERNAME=CORP\you
OUTLOOK_PASSWORD=...
uv run python -m mcp_outlook

Configuración

Todos los ajustes provienen de variables de entorno (o de un archivo .env). Consulta .env.example para ver la lista completa. Lo esencial:

Variable

Notas

OUTLOOK_AUTH_MODE

static (predeterminado, un buzón) o jwt (túnel multiusuario)

OUTLOOK_EWS_ENDPOINT

URL asmx completa, p. ej. https://mail.corp.local/EWS/Exchange.asmx. Recomendada.

OUTLOOK_SERVER

Alternativa solo con host (se asume el endpoint en /EWS/Exchange.asmx)

OUTLOOK_USERNAME

La cuenta que se conecta: la tuya propia (static) o la cuenta de servicio (jwt). DOMAIN\user para NTLM, o correo electrónico para basic. No se usa con sspi

OUTLOOK_EMAIL

Buzón que se abre (modo static). Opcional: por defecto usa OUTLOOK_USERNAME cuando es un correo electrónico; se ignora en modo jwt; obligatorio con sspi (no hay nombre de usuario del que tomar el valor predeterminado)

OUTLOOK_PASSWORD

Contraseña de la cuenta. No se usa con sspi

OUTLOOK_AUTH_TYPE

ntlm (predeterminado), basic o sspi (autenticación integrada de Windows: se autentica como la identidad de AD del propio proceso, sin usuario/contraseña; solo Windows, requiere uv sync --extra sspi)

OUTLOOK_JWT_ISSUER / _AUDIENCE

Requeridos en modo jwt: emisor y audiencia del token que se deben exigir

OUTLOOK_JWT_JWKS_URI / _PUBLIC_KEY

modo jwt: claves de firma (URI JWKS, o un PEM estático para entornos aislados)

OUTLOOK_JWT_EMAIL_CLAIM

modo jwt: claim que contiene la dirección SMTP del usuario (por defecto email)

OUTLOOK_CA_BUNDLE

Ruta al .pem de la CA interna (para certificados autofirmados / CA interna)

OUTLOOK_VERIFY_SSL

true (predeterminado); false desactiva la verificación TLS (solo desarrollo)

MCP_HOST / MCP_PORT

Enlace HTTP (por defecto 127.0.0.1:8000)

Cómo encontrar tu endpoint de EWS

La URL de EWS no es la URL de OWA (webmail). En el servidor Exchange:

Get-WebServicesVirtualDirectory | fl Name,InternalUrl,ExternalUrl

En una instalación aislada casi siempre querrás la InternalUrl.

Pruebas

Las pruebas unitarias no necesitan servidor Exchange (solo análisis de configuración + serialización):

uv run pytest

Prueba de humo en vivo (con un .env real): inicia el servidor, conecta un cliente MCP o el MCP Inspector, y luego llama a list_folders → list_emails → send_email (a ti mismo) y confirma la recepción. Cambia OUTLOOK_AUTH_TYPE entre ntlm y basic para confirmar cuál tiene habilitado tu administrador de Exchange.

Interfaz de redacción (MCP Apps)

draft_email abre un widget interactivo de MCP Apps: un editor de React integrado en un único archivo HTML autocontenido (src/mcp_outlook/widgets/compose.html). Cualquier host compatible con MCP Apps lo renderiza en línea dentro del hilo de chat.

Funcionalidades del widget:

  • Campo Para con búsqueda de contactos integrada: escribe después de la última coma para buscar contactos; selecciona un resultado para sustituir la consulta por un chip; las direcciones válidas se muestran como chips etiquetados.

  • Enviar / Descartar: Enviar dispara send_email directamente desde el widget (solo para la app: el modelo no puede llamarlo); Descartar colapsa la tarjeta.

  • Sustitución: abrir un nuevo borrador atenúa (pone en gris) cualquier widget de borrador anterior abierto.

  • Firma: cada borrador se precarga con "Written with Airchat" (editable).

Garantía de aislamiento: el HTML generado (React + JS de puente incrustado) se distribuye con el paquete de Python. No se realizan solicitudes de recursos externos en tiempo de ejecución; Node.js solo se necesita para reconstruir el widget.

Reconstruir el widget (solo desarrollo)

cd frontend
npm ci
npm run build     # tsc + vite build + artifact copy → src/mcp_outlook/widgets/compose.html

El script de compilación verifica que no haya URLs externas en el HTML antes de copiarlo.

Pruébalo visualmente (vista previa de desarrollo independiente)

cd frontend && npm run dev
# Opens http://localhost:5173 with a mock host — no Exchange needed.
# Type in To, see chips form, contact results appear, Send/Discard collapse the card.

Advertencias

  • La autenticación básica suele estar deshabilitada en Exchange moderno: NTLM es la opción predeterminada más segura.

  • Los certificados internos/autofirmados requieren OUTLOOK_CA_BUNDLE; de lo contrario, la conexión falla en la verificación TLS.

  • El modo multiusuario (jwt) necesita un permiso de Exchange: la cuenta de servicio debe tener el rol RBAC ApplicationImpersonation. Consulta TODO.md. El modo static no necesita ese permiso.

  • .env contiene una contraseña en texto plano. Está ignorado por git; además, restringe los permisos del archivo (chmod 600 .env) en el host.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    MCP server for any Microsoft Exchange / OWA deployment. Gives LLM agents access to email, calendar, directory search, folders, availability, and meeting analytics via 30 tools.
    30
    43 PyPI
    12
    MIT
  • -
    license
    Not graded
    quality
    D
    maintenance
    Secure MCP server for Microsoft Exchange. It enables authorized users to list, search, read, download attachments, send, and reply to email via EWS with strict access control and audit.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables an MCP client to read, draft, organize, send, and delete email across multiple Gmail and Exchange Online/Outlook.com accounts, with per-account capability policies, recipient allowlists, confirmations, minimum OAuth scopes, and local audit logging.
    MIT