Skip to main content
Glama
ItayElizur

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_folderslist_emailssend_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.

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    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
    7
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables reading, sending, and managing Microsoft 365/Outlook emails through MCP tools with OAuth 2.1 authentication.
    114
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ItayElizur/mcp-outlook'

If you have feedback or need assistance with the MCP directory API, please join our Discord server