Skip to main content
Glama

Servidor MCP de Outlook

Un servidor de Model Context Protocol que conecta Claude con Microsoft Outlook + Teams (correo electrónico, calendario, contactos, tareas, archivos, grabaciones y transcripciones de reuniones de Teams), desplegado en Cloudflare Workers.

Haz un fork de este repositorio, despliégalo en tu propia cuenta de Cloudflare, registra una aplicación de Microsoft Azure AD, apunta Claude.ai a tu worker, y Claude podrá leer y escribir tus datos de Microsoft 365 mediante lenguaje natural.

Construido sobre @bashco/mcp-toolkit — OAuth, tokens de portador por cliente, limitación de velocidad, registro estructurado y despacho de herramientas tipadas están manejados por la biblioteca compartida.

Lo que Claude obtiene — 39 herramientas en 7 dominios

  • Correo: listar correos, leer correo, buscar, responder, reenviar, eliminar, enviar, mover entre carpetas, crear borrador, actualizar borrador, enviar borrador, programar envío

  • Calendario: listar eventos, listar ocurrencias de eventos, crear, actualizar, eliminar, cancelar evento, responder a evento

  • Contactos: listar, crear contacto, actualizar contacto

  • Tareas: listar listas de tareas, listar tareas, crear tarea

  • Archivos: listar archivos, compartir archivo

  • Reuniones de Teams: listar grabaciones recientes (el punto de partida de descubrimiento — encuentra reuniones que tienen contenido en los últimos N días, sin necesidad de entradas), encontrar reunión en línea, listar grabaciones de reunión, listar transcripciones de reunión, obtener contenido de transcripción. Cada herramienta por reunión acepta cualquiera de meeting_id, calendar_event_id o join_url — por lo que las reuniones programadas (resueltas mediante evento), las llamadas ad-hoc / Meet-now (resueltas mediante la URL de unión pegada desde el chat de Teams) y las búsquedas directas por ID funcionan todas.

  • Conversación: obtener conversación (hilo completo)

  • Configuración: obtener configuración del buzón, establecer fuera de oficina

Catálogo completo en vivo en el endpoint MCP tools/list después del despliegue.

Related MCP server: MCP Outlook Server

Cómo funciona la autenticación

Dos capas:

  1. Claude.ai ↔ tu worker — flujo estándar de MCP OAuth 2.0 + PKCE. Cada cliente de Claude obtiene un token de portador único; tu MCP_APPROVAL_CODE es lo que pegas en /authorize una vez para acuñar ese portador.

  2. Tu worker ↔ Microsoft Graph — OAuth proxyado. Autorizas a Microsoft una vez visitando /oauth/start en tu worker desplegado; los tokens de actualización se almacenan cifrados en reposo en Cloudflare KV. La actualización ocurre automáticamente.

Configuración — despliega tu propia copia

Requisitos previos

1. Haz un fork y clona

git clone https://github.com/<your-username>/outlook-mcp
cd outlook-mcp
npm install

2. Crea el espacio de nombres KV

wrangler kv:namespace create OAUTH_KV

Wrangler imprime algo como:

🌀 Creating namespace with title "outlook-mcp-OAUTH_KV"
✨ Success! Add the following to your configuration file:
[[kv_namespaces]]
binding = "OAUTH_KV"
id = "abc123def456..."

Edita wrangler.jsonc y reemplaza el id existente bajo kv_namespaces con lo que wrangler acaba de imprimir.

wrangler.jsonc está confirmado por diseño — tanto Wrangler como el despliegue de CI lo necesitan, y no contiene secretos (solo tu ID de espacio de nombres KV, el ID público de cliente de Azure y la URL del worker). wrangler.jsonc.example lleva la misma estructura con marcadores de posición si prefieres empezar desde una copia limpia. Los secretos reales se gestionan mediante wrangler secret put y nunca aparecen en este archivo.

3. Registra una aplicación de Microsoft Azure AD

  1. Ve a entra.microsoft.com → Identity → Applications → App registrations → New registration

  2. Nombre: cualquier cosa (por ejemplo, "Claude Outlook MCP")

  3. Tipos de cuenta admitidos:

    • "Solo cuentas en este directorio organizativo" si quieres restringir a un solo inquilino

    • "Cuentas en cualquier directorio organizativo y cuentas personales de Microsoft" para el soporte más amplio

  4. URI de redirección: déjalo en blanco por ahora — volverás después del Paso 6

  5. Haz clic en Registrar

  6. Desde la página de descripción general de la aplicación, anota:

    • ID de aplicación (cliente) → este es tu MICROSOFT_CLIENT_ID

    • ID de directorio (inquilino) → este es tu MICROSOFT_TENANT_ID (o usa la cadena common para soporte multiinquilino + cuentas personales)

  7. Permisos de API → Agrega los siguientes permisos delegados de Microsoft Graph:

    • Mail.ReadWrite, Mail.Send

    • Calendars.ReadWrite

    • Contacts.ReadWrite

    • Tasks.ReadWrite

    • Files.Read.All (o Files.ReadWrite.All si quieres herramientas de archivos con capacidad de escritura)

    • User.Read

    • offline_access (requerido para tokens de actualización)

    • MailboxSettings.ReadWrite

    • Sites.Read.All

    • OnlineMeetings.Read

    • OnlineMeetingRecording.Read.Allse requiere consentimiento de administrador

    • OnlineMeetingTranscript.Read.Allse requiere consentimiento de administrador

    Después de agregar los dos permisos .Read.All, haz clic en "Conceder consentimiento de administrador para [nombre del inquilino]" en la página de permisos de API. Sin el consentimiento de administrador, las herramientas de grabación / transcripción de reuniones devolverán 403.

  8. Certificados y secretos → Nuevo secreto de cliente → anota el valor (en 1Password). Este es tu MICROSOFT_CLIENT_SECRET. Solo puedes verlo una vez — cópialo inmediatamente.

4. Actualiza wrangler.jsonc

Edita wrangler.jsonc y reemplaza ambos:

  • vars.MICROSOFT_CLIENT_ID — con el ID de aplicación del Paso 3.6

  • vars.MICROSOFT_TENANT_ID — con el ID de directorio del Paso 3.6 (o common)

5. Establece los secretos

Genera un código de aprobación nuevo:

openssl rand -base64 32

Guárdalo en un gestor de contraseñas y luego envíalo a Cloudflare:

wrangler secret put MCP_APPROVAL_CODE          # paste the value from above
wrangler secret put MICROSOFT_CLIENT_SECRET    # from Step 3.8

Secreto

Propósito

MCP_APPROVAL_CODE

Código de un solo uso que pegas en /authorize para acuñar un portador de Claude. También se usa como secreto de cifrado para los tokens de Microsoft ascendentes en reposo — rotarlo invalida los tokens almacenados y fuerza una reautenticación limpia de Microsoft.

MICROSOFT_CLIENT_SECRET

El secreto de cliente de tu aplicación de Azure AD.

SIGNATURE_HTML

Opcional. Bloque de firma de correo electrónico añadido en el lado del servidor — consulta Firma de correo electrónico.

SIGNATURE_LOGO_URL

Opcional. URL HTTPS accesible públicamente del logotipo de la firma.

6. Primer despliegue (para conocer la URL del worker)

npm run deploy

Wrangler imprime la URL de tu worker — algo como https://outlook-mcp.<tu-cuenta>.workers.dev. Guárdala.

7. Actualiza WORKER_URL y el URI de redirección de Microsoft

Se necesitan dos actualizaciones:

a) Edita wrangler.jsonc — bajo vars, reemplaza WORKER_URL con la URL del Paso 6.

b) En la aplicación de Azure AD (entra.microsoft.com → tu aplicación → Authentication → Add a platform → Web), establece el URI de redirección a <tu-url-del-worker>/oauth/callback. Sin esto, Microsoft rechazará el flujo de OAuth.

Luego vuelve a desplegar:

npm run deploy

8. Conecta Microsoft (una vez)

En tu navegador, visita <tu-url-del-worker>/oauth/start. Pega tu MCP_APPROVAL_CODE. Serás redirigido a Microsoft para iniciar sesión y conceder los ámbitos del Paso 3.7. Después de dar tu consentimiento, tus tokens ascendentes cifrados se guardan en OAUTH_KV. La actualización ocurre automáticamente a partir de entonces.

Puedes confirmar la conexión visitando <tu-url-del-worker>/oauth/status — debería decir connected: true.

9. Conecta Claude.ai

  1. En Claude.ai, ve a Settings → Integrations → Add MCP server

  2. URL del servidor: <tu-url-del-worker>/mcp

  3. Claude.ai te redirige a la página /authorize de tu worker

  4. Pega tu MCP_APPROVAL_CODE y confirma

  5. Estás conectado — Claude ahora tiene las 38 herramientas de Outlook + Teams disponibles

Firma de correo electrónico

Opcional. Cuando está configurada, el Worker añade tu firma en el momento del envío para que el agente que llama nunca tenga que reproducirla — no puede ser parafraseada, truncada u olvidada.

Pasa include_signature: true a cualquiera de send_email, schedule_send, reply_to_email, forward_email, create_draft, update_draft, create_reply_draft, create_reply_all_draft o create_forward_draft. El valor predeterminado es false, por lo que los llamadores existentes no se ven afectados.

Para borradores, la firma se inyecta en el momento de creación del borrador, no en el momento del envío — send_draft solo toma un ID y nunca toca el cuerpo. Esto significa que el cuerpo firmado es lo que revisas antes de enviar. En update_draft, la bandera solo se aplica cuando también pasas un nuevo body (de lo contrario no hay nada que firmar, y reemplazaría el borrador con un cuerpo solo de firma); ese caso se informa en las notes de la respuesta en lugar de borrar silenciosamente el borrador.

Invitaciones de calendario

create_calendar_event y update_calendar_event aceptan la misma bandera include_signature, añadiendo la firma a la descripción del evento. Reutiliza el mismo bloque SIGNATURE_HTML que el correo electrónico — incluidos sus botones de llamada a la acción de marketing — por lo que se adapta mejor a una invitación orientada al cliente que a una reunión interna; por eso es opcional por evento. update_calendar_event sigue la misma protección que update_draft: la bandera solo se aplica cuando también pasas una nueva description.

Configuración

cp signature-block.example.html signature-block.html   # then edit it
wrangler secret put SIGNATURE_HTML < signature-block.html
wrangler secret put SIGNATURE_LOGO_URL                 # paste your HTTPS logo URL

signature-block.html está en gitignore a propósito. La firma es configuración de despliegue, no código fuente: un fork que heredara una firma confirmada enviaría correos con el nombre, número de teléfono y enlaces de reserva de otra persona. Solo el marcador de posición signature-block.example.html está confirmado.

El token __LOGO_URL__ dentro de SIGNATURE_HTML se sustituye con SIGNATURE_LOGO_URL en tiempo de ejecución.

El logotipo debe ser accesible públicamente a través de HTTPS. Los clientes de correo lo obtienen desde la máquina del destinatario — no tiene acceso a tu red, a los enlaces de tu Worker ni a ninguna credencial que poseas. Una URL privada, autenticada o localhost se muestra como una imagen rota para todos. Si SIGNATURE_LOGO_URL no está configurado, la etiqueta <img> se elimina por completo en lugar de emitir un src roto.

Si SIGNATURE_HTML no está configurado, la bandera es una operación no-op silenciosa — el correo se envía sin firmar. Un despliegue no configurado nunca genera errores.

Comportamiento

  • Fuerza HTML. Una firma dentro de un cuerpo de texto plano se muestra como marcado visible sin procesar, por lo que body_type se sobrescribe a html siempre que la bandera está configurada. Cuando pasaste explícitamente body_type: "text", la sobrescritura se informa en las notes de la respuesta de la herramienta, nunca se aplica silenciosamente.

  • Los cuerpos de texto plano se escapan y luego los saltos de línea se convierten en <br>, para que tus saltos de línea sobrevivan al cambio forzado a HTML y los caracteres < sueltos no puedan convertirse en marcado.

  • Idempotente. Si el cuerpo ya lleva la firma — reconocida por el marcador propio del Worker o por el texto distintivo de la firma — no se añade dos veces.

  • Las respuestas y reenvíos colocan la firma por encima del original citado, no al final de todo el hilo.

  • Cuerpo vacío envía solo la firma, sin líneas en blanco iniciales.

Nota de seguridad

La firma se concatena después de que el cuerpo del llamador haya sido saneado. Esto es deliberado y crucial: sanitizeOutboundHtml elimina cada atributo style= (un sumidero XSS solo de atributos), y la firma está construida enteramente con estilos en línea, por lo que pasarla por el saneador eliminaría el tamaño del logotipo, el divisor y los botones de CTA.

Las dos cadenas tienen diferentes niveles de confianza. El cuerpo es proporcionado por el agente y no es confiable, por lo que aún se sanea por completo. La firma es configuración de despliegue proporcionada por el operador mediante wrangler secret put — cualquiera que pueda establecer ese secreto ya puede cambiar el Worker por completo. Consulta src/signature.ts.

Desarrollo local

cp .dev.vars.example .dev.vars   # fill in MCP_APPROVAL_CODE + MICROSOFT_CLIENT_SECRET; .dev.vars is gitignored
npm test                          # 171 tests via vitest with workers pool
npm run typecheck                 # tsc --noEmit
npm run dev                       # wrangler dev — local at http://localhost:8787

Endpoints

  • GET /.well-known/oauth-authorization-server — Metadatos OAuth (público)

  • GET /.well-known/oauth-protected-resource — Metadatos de recurso (público)

  • GET /authorize — Página de pegado de código de aprobación (público)

  • POST /approve — Envío de código de aprobación (con límite de tasa)

  • POST /token — Intercambio de tokens OAuth (con límite de tasa)

  • POST /register — Registro dinámico de clientes según RFC 7591 (con límite de tasa)

  • GET /oauth/start — Iniciar flujo OAuth de Microsoft (restringido por MCP_APPROVAL_CODE)

  • GET /oauth/callback — Destino de redirección OAuth de Microsoft

  • GET /oauth/status — Comprobar estado de conexión (restringido por MCP_APPROVAL_CODE)

  • POST /mcp — Despacho de herramientas JSON-RPC (protegido por bearer, con límite de tasa)

Stack

  • Cloudflare Workers (compatibility_date 2025-04-28, nodejs_compat)

  • TypeScript (estricto)

  • Hono v4

  • Zod v4

  • Vitest con @cloudflare/vitest-pool-workers (171 pruebas)

  • @bashco/mcp-toolkit — infraestructura compartida de OAuth/cripto/límite de tasa/despacho

Aspectos destacados de la arquitectura de seguridad

  • Saneador HTML de dos pasadas con normalización de entidades en las vistas previas de correo saliente

  • Protección SSRF con normalización de IP de 32 bits en HTTP saliente

  • Análisis de envoltura de errores odata de Microsoft Graph para devoluciones de errores estructurados

  • Archivos de herramientas por dominio en src/tools/ (correo, calendario, contactos, tareas, archivos, reuniones, configuración) para auditabilidad

Despliegue continuo

.github/workflows/deploy.yml ejecuta vitest run en cada push a main y luego despliega en Cloudflare. Para habilitarlo en tu fork, establece dos secretos de repositorio:

  • CLOUDFLARE_API_TOKEN — crea en dash.cloudflare.com/profile/api-tokens (usa la plantilla "Edit Cloudflare Workers")

  • CLOUDFLARE_ACCOUNT_ID — encuéntralo en la parte inferior derecha de tu panel de Cloudflare

Contribuciones

Se aceptan issues y PRs en github.com/doublebash/outlook-mcp.

Para cambios en el código subyacente de OAuth/cripto/límite de tasa, el toolkit está en github.com/doublebash/mcp-toolkit — reporta issues allí.

Seguridad

¿Encontraste una vulnerabilidad? Por favor no abras un issue público. Abre un aviso de seguridad privado en GitHub.

Licencia

MIT — Copyright (c) 2026 Bashar Basheer.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.

  • Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.

  • Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.

View all MCP Connectors

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/Sidd-doshi/outlook-mcp'

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