Graph MCP

Un MCP para interactuar con Office 365: Teams, correo, calendario.

Documentación

Graph MCP

Graph MCP es un servidor MCP de Node.js que conecta Claude Code y Codex con Microsoft Teams, Outlook mail y calendario, reuniones en línea, OneDrive, usuarios y presencia a través de Microsoft Graph. Se ejecuta localmente sobre stdio y requiere Node.js 22 o superior.

Qué hace

Graph MCP expone exactamente 127 herramientas:

CategoríaHerramientas
AutenticaciónVerificar estado, iniciar sesión con navegador o código de dispositivo, cerrar sesión
Usuarios y organizaciónLeer tu perfil, buscar usuarios, consultar un gerente o informes directos
Personas y contactosBúsqueda de personas clasificada por relevancia, listar, crear, actualizar o eliminar contactos de Outlook, listar carpetas de contactos
BúsquedaBuscar mensajes de Teams, o buscar correo, calendario, archivos y Teams juntos en una consulta clasificada
ChatsListar, obtener o crear chats, leer, enviar, editar o eliminar mensajes, reaccionar a mensajes, renombrar chats, gestionar miembros, marcar como leído
Teams y canalesListar equipos, canales y miembros, obtener un equipo o su canal principal, crear canales, leer, enviar, responder, editar o eliminar mensajes de canal, acceder a la carpeta de SharePoint de un canal
CalendarioListar calendarios y eventos, obtener, crear, actualizar, cancelar o eliminar eventos, recurrencia, RSVP, disponibilidad, horarios sugeridos para reuniones, ocurrencias de series, salas reservables, calendarios compartidos
CorreoListar, leer, buscar o sincronizar delta de correo, enviar, responder o reenviar con borradores, CCO, importancia y adjuntos, mover y archivar, eliminar, marcar como leído, marcar, categorizar, gestionar carpetas y reglas de bandeja de entrada, sugerencias de correo, buzones compartidos
Configuración del buzónLeer configuración del buzón, configurar respuestas automáticas, configurar zona horaria y horario laboral
ReunionesResolver un ID de reunión desde un evento de calendario, URL de unión o chat de reunión, buscar una reunión por URL de unión o ID numérico de invitación, crear u obtener reuniones en línea con enlaces de unión, informes de asistencia, transcripciones y grabaciones
PresenciaLeer tu propia presencia, la de otro usuario o la de todo un equipo, configurar disponibilidad o un mensaje de estado, borrar presencia
TareasListar listas y tareas de To Do, crear, actualizar, completar o eliminar tareas, listar tareas asignadas de Planner
ArchivosExplorar, buscar o resolver enlaces a contenido de OneDrive y SharePoint, subir, descargar como texto o bytes base64, copiar, mover, eliminar, versionar y compartir archivos, gestionar permisos, leer elementos recientes y compartidos, leer y escribir rangos de Excel

Requisitos previos

  • Node.js 22 o superior.
  • Un registro de aplicación de Microsoft Entra ID configurado como cliente público en la plataforma Aplicaciones móviles y de escritorio.
  • URI de redirección http://localhost:3000/auth/callback.
  • Sin secreto de cliente. Graph MCP utiliza autenticación de usuario delegada.

Agrega estos permisos delegados exactos al registro de la aplicación:

  • offline_access
  • openid
  • profile
  • User.Read
  • User.ReadBasic.All
  • User.Read.All
  • Chat.Read
  • Chat.ReadWrite
  • ChatMember.ReadWrite
  • ChatMessage.Send
  • ChannelMessage.Read.All
  • ChannelMessage.Send
  • ChannelMessage.ReadWrite
  • Channel.Create
  • TeamMember.Read.All
  • Team.ReadBasic.All
  • Channel.ReadBasic.All
  • ChannelMember.Read.All
  • Calendars.ReadWrite
  • Calendars.Read.Shared
  • Calendars.ReadWrite.Shared
  • Place.Read.All
  • Mail.Read
  • Mail.ReadWrite
  • Mail.Send
  • MailboxSettings.ReadWrite
  • Mail.ReadWrite.Shared
  • Mail.Send.Shared
  • Presence.Read
  • Presence.Read.All
  • Presence.ReadWrite
  • OnlineMeetings.Read
  • OnlineMeetings.ReadWrite
  • OnlineMeetingArtifact.Read.All
  • OnlineMeetingTranscript.Read.All
  • OnlineMeetingRecording.Read.All
  • Files.ReadWrite.All
  • Sites.Read.All
  • People.Read
  • Contacts.ReadWrite
  • Tasks.ReadWrite

Algunas organizaciones requieren consentimiento de administrador para uno o más permisos. Usa el principio de menor privilegio que tu implementación necesite y sigue el proceso de aprobación de tu organización.

Instalación

Plugin de Claude Code

Este repositorio es en sí mismo un mercado de plugins, por lo que Claude Code puede instalarlo directamente desde GitHub:

claude plugin marketplace add JustStas/Graph-MCP --scope user
claude plugin install graph-mcp@graph-mcp --scope user

Lo mismo funciona dentro de una sesión de Claude Code con /plugin marketplace add JustStas/Graph-MCP followed by /plugin install graph-mcp@graph-mcp.

Claude clona el repositorio en su caché de mercados, valida .claude-plugin/marketplace.json e instala el plugin autocontenido en la caché de plugins. El servidor MCP se inicia desde el paquete de plugin instalado, por lo que no se necesita una copia del código fuente. Para obtener una nueva versión, vuelve a ejecutar los dos comandos.

Para el desarrollo de plugins, se puede agregar una copia local de la misma manera usando una ruta en lugar de owner/repo:

claude plugin marketplace add /absolute/path/to/Graph-MCP --scope user
claude plugin install graph-mcp@graph-mcp --scope user

Plugin de Codex

Codex acepta la misma fuente de mercado de GitHub:

codex plugin marketplace add JustStas/Graph-MCP --json
codex plugin add graph-mcp@personal --json

codex plugin marketplace add acepta una ruta local, owner/repo[@ref] o una URL de Git HTTPS o SSH, y --ref fija una etiqueta o rama específica. El manifiesto de Codex inicia ./dist/graph-mcp.js relativo a la raíz del plugin instalado, por lo que no se necesita una copia del código fuente.

Para el desarrollo de plugins, apúntalo a una copia local en su lugar:

codex plugin marketplace add /absolute/path/to/Graph-MCP --json
codex plugin add graph-mcp@personal --json

npm

Instala el paquete público con ámbito globalmente:

npm install --global @juststas/graph-mcp
graph-mcp setup

El paquete npm tiene ámbito de JustStas, pero el ejecutable instalado sigue siendo graph-mcp. Invocar graph-mcp sin argumentos inicia el servidor MCP sobre stdio.

Copia del código fuente

npm ci
npm run build
node dist/cli.js setup

Luego registra el punto de entrada compilado con tu host:

claude mcp add graph-mcp -- node /absolute/path/to/Graph-MCP/dist/cli.js
codex mcp add graph-mcp -- node /absolute/path/to/Graph-MCP/dist/cli.js

Configuración inicial y autenticación

setup solicita el ID de cliente y el ID de inquilino de la aplicación Entra y los guarda en ~/.graph-mcp/config.json. El ID de cliente y el ID de inquilino son identificadores, no secretos. El comando de configuración no realiza el inicio de sesión.

Para un plugin instalado, usa la habilidad de configuración incluida y su comando específico del host:

  • Claude Code: node "${CLAUDE_PLUGIN_ROOT}/dist/graph-mcp.js" setup
  • Codex: resuelve la raíz del plugin instalado desde skills/setup/SKILL.md, cambia a ese directorio y luego ejecuta node "./dist/graph-mcp.js" setup

Después de la configuración, llama a graph_auth_login. El inicio de sesión PKCE del navegador es el predeterminado y abre una devolución de llamada de bucle local en la URI de redirección configurada. Si un navegador o una devolución de llamada de bucle local no está disponible, llama a graph_auth_login con method: "device_code" y sigue las instrucciones de verificación de Microsoft devueltas.

Nunca pegues un secreto de cliente, token de acceso, token de actualización, código de autorización, código MFA u otras credenciales en una conversación. Graph MCP no necesita un secreto de cliente.

Configuración

Para el ID de cliente y el ID de inquilino, las variables de entorno tienen prioridad sobre ~/.graph-mcp/config.json, que tiene prioridad sobre los valores predeterminados integrados. El comando de configuración solo persiste esos dos identificadores. Las otras opciones son anulaciones solo de entorno de los valores predeterminados integrados.

VariableRequeridaPredeterminadoDescripción
AZURE_CLIENT_IDSíguardado azureClientId, luego vacíoID de aplicación de cliente público de Entra
AZURE_TENANT_IDNoguardado azureTenantId, luego commonID de inquilino o common
GRAPH_REDIRECT_URINohttp://localhost:3000/auth/callbackDebe coincidir exactamente con el registro de la aplicación
GRAPH_TOKEN_ENCRYPTION_KEYNoclave local generadaMaterial de clave de cifrado de token explícito
GRAPH_TOKEN_REFRESH_BUFFERNo300Renovar los tokens de acceso esta cantidad de segundos antes de la expiración
GRAPH_RATE_LIMIT_MAX_REQUESTSNo10000Límite de solicitudes de ventana deslizante
GRAPH_RATE_LIMIT_WINDOWNo600Duración de la ventana deslizante en segundos
GRAPH_DEBUGNofalseHabilitar registro de diagnóstico en stderr

Las opciones de enteros positivos rechazan cero, negativos, decimales y valores mal formados. Los valores booleanos aceptan true, false, 1, 0, yes, no, on o off.

Almacenamiento de tokens y migración desde Python

El servidor Node cifra los tokens con AES-256-GCM y los almacena en ~/.graph-mcp:

  • tokens-v2.enc — datos de token cifrados
  • .key-v2 — clave de cifrado local generada cuando no se proporciona una clave de entorno

El runtime anterior de Python usaba tokens.enc y .key. La versión 0.6.0 deliberadamente no lee, sobrescribe ni elimina esos archivos heredados porque los formatos de texto cifrado difieren. Después de actualizar desde la versión de Python, autentícate una vez con graph_auth_login; el servidor Node entonces crea sus archivos de token versionados separados. Los archivos de token de Python existentes permanecen sin tocar y pueden eliminarse más tarde según tu política de seguridad local.

Los tokens de acceso se renuevan automáticamente antes de la expiración. graph_auth_logout borra el estado de token de Node; no modifica los archivos heredados de Python.

Formato de mensajes y correos electrónicos

Las herramientas de mensajes de Teams (graph_send_chat_message, graph_send_channel_message y graph_reply_to_channel_message) y las herramientas de correo saliente (graph_send_mail y graph_reply_mail) usan el modo HTML de forma predeterminada. Cuando is_html=true, pasa HTML explícito; Markdown no se convierte automáticamente.

<p><strong>Status update</strong></p>
<ul>
  <li>Use <code>&lt;strong&gt;</code> for bold text.</li>
  <li>Use <code>&lt;pre&gt;&lt;code&gt;</code> for multi-line code blocks.</li>
</ul>

Usa is_html=false para texto plano exacto. Las menciones pueden usar datos Graph sin procesar o esta forma simplificada, emparejada con la etiqueta <at id="0">Jane Smith</at> correspondiente en el cuerpo HTML:

[
  {
    "name": "Jane Smith",
    "user_id": "ef1c916a-3135-4417-ba27-8eb7bd084193"
  }
]

Desarrollo y verificación

Instala las dependencias bloqueadas y ejecuta el pipeline completo de verificación de Node:

npm ci
npm run verify

Comandos individuales útiles:

npm run format:check
npm run lint
npm run typecheck
npm test
npm run build
npm run validate:versions
npm run validate:package
npx vitest run tests/plugin-install-smoke.test.ts

Validación de plugins y versiones:

claude plugin validate --strict plugins/graph-mcp
claude plugin validate --strict .
python3 "${CODEX_HOME:-$HOME/.codex}/skills/.system/plugin-creator/scripts/validate_plugin.py" plugins/graph-mcp
node scripts/test-plugin-install.mjs
npm pack --json --dry-run

El validador de Codex es una herramienta de publicación proporcionada por la habilidad plugin-creator de Codex; Python no es necesario para compilar, probar o ejecutar Graph MCP en sí. Antes de publicar, verifica que el paquete, el manifiesto de Claude y el manifiesto de Codex coincidan con la versión objetivo de la publicación, que el paquete de plugin confirmado esté actualizado, que ambos plugins instalados expongan exactamente 127 herramientas y que el árbol de trabajo esté limpio.

Procedimiento de publicación

Las publicaciones de Graph MCP usan el paquete npm público @juststas/graph-mcp; no hay un paso de publicación Python/PyPI. La versión 0.6.0 completó la migración a Node pero no se publicó en npm porque npm rechazó el nombre graph-mcp@0.6.0 sin ámbito por ser demasiado similar al paquete graphmcp existente. La versión 0.6.1 es la primera publicación npm con ámbito.

Publicaciones normales

  1. Actualiza package.json, package-lock.json, ambos manifiestos de plugin, metadatos de runtime, CHANGELOG.md y el paquete de plugin confirmado a una versión.
  2. Ejecuta npm ci, npm run verify, node scripts/test-plugin-install.mjs y npm pack --json --dry-run desde un árbol de trabajo limpio.
  3. Fusiona la solicitud de extracción revisada en main. Un administrador del repositorio crea entonces la etiqueta v<version> anotada en la confirmación fusionada a través del conjunto de reglas obligatorio de autoridad de etiquetas de publicación; el conjunto de reglas de inmutabilidad separado sin omisión bloquea actualizaciones o eliminaciones posteriores.
  4. Publica la versión de GitHub correspondiente. El desencadenador del flujo de trabajo es release: types: [published].
  5. El trabajo de paquete instala dependencias bloqueadas, ejecuta npm run verify y prepara el tarball exacto sin permiso OIDC.
  6. El trabajo de publicación se ejecuta en el entorno de GitHub npm y es el único trabajo que recibe permiso OIDC. Descarga un artefacto solo de datos que contiene el tarball y los metadatos, verifica su asistente de confianza en github.workflow_sha, vincula la etiqueta esperada directamente al evento de publicación, valida el manifiesto JSON en seco de npm para la instantánea privada exacta y usa Publicación de confianza de npm. No tiene NODE_AUTH_TOKEN ni secreto npm.
  7. Verifica el flujo de trabajo, la versión npm, dist.integrity, la versión CLI instalada y el inventario MCP de 127 herramientas.

Las repeticiones del flujo de trabajo son idempotentes. Si la versión ya existe, el flujo de trabajo tiene éxito solo cuando dist.integrity de npm es igual al tarball preparado. Una integridad diferente falla y requiere una nueva versión de parche.

Primer arranque de paquete con ámbito

npm requiere que un paquete exista antes de que se pueda configurar la Publicación de confianza. Arranca la primera publicación con ámbito en este orden:

  1. Verifica la fusión de main, luego activa el conjunto de reglas de autoridad de administrador v*.
  2. Audita el inventario histórico exacto de etiquetas y su ascendencia, exige el blob exacto del flujo de trabajo histórico de PyPI en la lista blanca donde se espera, y exige que el nuevo asistente de lanzamiento esté ausente en todas partes.
  3. Activa el conjunto de reglas de inmutabilidad separado sin omisiones.
  4. Crea la etiqueta anotada v0.6.1 solo después de que esas compuertas pasen.
  5. Ejecuta publish.yml desde main con prepare_only habilitado e inspecciona su artefacto preparado.
  6. Valida el nombre de archivo exacto, el estado de archivo regular, los resúmenes SHA-512 y SHA-1, y el manifiesto JSON de ejecución en seco de npm. Publica esa misma instantánea privada una vez con la 2FA interactiva del mantenedor, el registro explícito de npmjs, la etiqueta latest, los scripts de ciclo de vida deshabilitados y acceso público; luego verifica su versión e integridad en el registro.
  7. Vuelve a verificar ambos conjuntos de reglas de etiquetas de lanzamiento.
  8. Crea el entorno de GitHub npm.
  9. Agrega políticas de entorno tipadas separadas para la rama main y la etiqueta v*.
  10. Verifica ambos conjuntos de reglas y ambas políticas de entorno tipadas.
  11. Configura la publicación de confianza de npm:
npx --yes npm@11.15.0 trust github @juststas/graph-mcp \
  --file publish.yml \
  --repo JustStas/Graph-MCP \
  --env npm \
  --allow-publish

Verifica el repositorio guardado, el nombre del archivo de flujo de trabajo, el entorno y el permiso de publicación, luego establece el acceso de publicación de npm para requerir 2FA y deshabilitar los tokens tradicionales.

El arranque manual 0.6.1 no utiliza OIDC ni procedencia, y su flujo de trabajo de lanzamiento con integridad coincidente es una operación nula que no prueba el intercambio OIDC. La versión 0.6.2 es la primera publicación real de OIDC y verificación de procedencia.

Recuperación

Usa workflow_dispatch desde main con una etiqueta protegida existente para volver a ejecutar la publicación. Usa prepare_only cuando solo se necesite el tarball verificado. Los conjuntos de reglas de etiquetas de lanzamiento prohíben mover o eliminar etiquetas v* publicadas. Nunca sobrescribas una versión de npm; recupérate de una mala publicación con una nueva versión de parche.

Arquitectura y comportamiento en tiempo de ejecución

Claude Code or Codex  --stdio-->  Graph MCP  --HTTPS-->  Microsoft Graph API
                                      |
                                ~/.graph-mcp/
                                  config.json
                                  tokens-v2.enc
                                  .key-v2
  • La autenticación utiliza OAuth 2.0 Authorization Code con PKCE o código de dispositivo.
  • La renovación del token de acceso se serializa para que las llamadas concurrentes de Graph compartan una sola renovación.
  • Las solicitudes de Graph utilizan tiempos de espera limitados, limitación de velocidad con ventana deslizante y comportamiento de reintento exponencial que respeta Retry-After en respuestas limitadas.
  • La salida del protocolo MCP se escribe en stdout; los diagnósticos se escriben en stderr.

Solución de problemas

Aprobación requerida durante el inicio de sesión

Confirma que los permisos delegados exactos anteriores estén presentes y que se haya otorgado el consentimiento de administrador requerido.

403 Prohibido para una herramienta

El punto final puede necesitar un permiso delegado o consentimiento de administrador no disponible para el usuario con sesión iniciada. Verifica el permiso de la herramienta y tu política organizacional.

La devolución de llamada del navegador no está disponible

Llama a graph_auth_login con method: "device_code" y completa el inicio de sesión en la URL de verificación de Microsoft.

La configuración cambió pero el host aún usa valores antiguos

Reinicia el servidor MCP o el host para que el proceso recargue config.json y su entorno. Las variables de entorno anulan los valores guardados de ID de cliente e ID de inquilino.

Actualizado desde la versión de Python y parece que has cerrado sesión

Esto es esperado una vez. Ejecuta graph_auth_login; el runtime de Node crea tokens-v2.enc y .key-v2 sin cambiar los archivos antiguos tokens.enc y .key.

Descargo de responsabilidad

Este proyecto es un esfuerzo independiente de código abierto y no está afiliado, respaldado o patrocinado por Microsoft Corporation. Microsoft, Microsoft Teams, Outlook, Microsoft 365, Microsoft Graph y Azure son marcas comerciales del grupo de empresas de Microsoft.

Este software se proporciona "tal cual", sin garantía de ningún tipo. Úsalo bajo tu propio riesgo. Los autores no aceptan responsabilidad por daños, pérdida de datos o problemas de seguridad que surjan de su uso. Eres responsable de cumplir con las políticas de tu organización y los Términos de uso de la API de Microsoft.

Este software accede a los servicios de Microsoft en tu nombre utilizando tus propias credenciales y registro de aplicación. Los datos recuperados de Microsoft Graph (incluidos correos, mensajes, eventos de calendario, reuniones y archivos) se pasan al modelo que invocó la herramienta. Sigue las BP y los requisitos de manejo de datos, retención y uso aceptable de tu organización al usar modelos de IA alojados en la nube.

Licencia

MIT — ver LICENCIA.