Skip to main content
Glama
ovh-exchange-mcp

ovh-exchange-mcp

by elmehdimrh

ovh-exchange-mcp

Serveur MCP (Model Context Protocol) distant et multi-utilisateurs qui expose des boîtes Exchange (EWS, authentification NTLM) à Claude (web, desktop, mobile) — recherche, lecture, envoi, réponse, transfert d'emails, gestion des dossiers et pièces jointes.

Fonctionnement

Le serveur est un MCP distant (Streamable HTTP + OAuth 2.1). Il s'utilise comme connecteur personnalisé dans Claude sur le web, desktop, iOS et Android, et il est multi-utilisateurs. Chaque personne se connecte avec sa propre adresse Exchange :

  1. Dans Claude, la personne ajoute le connecteur https://<domaine>/mcp, puis clique sur « Se connecter ».

  2. Une page de connexion hébergée par ce serveur demande l'adresse email et le mot de passe Exchange.

  3. Le serveur vérifie ces identifiants auprès d'EWS. Seuls les domaines listés dans ALLOWED_DOMAINS sont acceptés.

  4. Le mot de passe est stocké chiffré (AES-256-GCM) dans data/mcp.sqlite, et Claude reçoit un token d'accès.

  5. Chaque appel de tool utilise la boîte mail de la personne liée au token.

Les tokens d'accès expirent après 1 h. Les refresh tokens durent 30 jours et changent à chaque utilisation. Seuls des hashes des tokens sont stockés. Pour enregistrer un client OAuth, son URL de callback doit figurer dans ALLOWED_REDIRECT_URIS (par défaut, Claude uniquement). Cela empêche un tiers d'utiliser la page de connexion pour du phishing.

Related MCP server: mcp-imap

Déploiement sur Coolify (Traefik)

Coolify et son proxy Traefik gèrent le certificat HTTPS et le routage. Le serveur écoute sur le port 3000 dans le conteneur.

  1. Créer un enregistrement DNS A (ex. mcp.exemple.fr) qui pointe vers le VPS.

  2. Dans Coolify : New Resource → dépôt Git → build pack Dockerfile. Le build pack Docker Compose fonctionne aussi avec le docker-compose.yml fourni.

  3. Domains : https://mcp.exemple.fr. Avec le build pack Compose, ajouter le port du conteneur : https://mcp.exemple.fr:3000.

  4. Ports Exposes : 3000. Ne publier aucun port sur l'hôte : Traefik s'en charge.

  5. Persistent Storage : un volume monté sur /app/data, qui contient la base SQLite. Sans ce volume, tout est perdu à chaque redéploiement.

  6. Environment Variables : voir le tableau ci-dessous. Générer ENCRYPTION_KEY avec openssl rand -base64 32.

  7. Déployer, puis vérifier :

curl https://mcp.exemple.fr/health
curl https://mcp.exemple.fr/.well-known/oauth-authorization-server

Variables d'environnement :

Variable

Rôle

PUBLIC_URL

URL publique du serveur, ex. https://mcp.exemple.fr (identique au domaine configuré dans Coolify)

EWS_URL

Endpoint EWS, ex. https://ex2.mail.ovh.net/EWS/Exchange.asmx

EWS_DOMAIN

Domaine Windows NTLM, en général vide

ALLOWED_DOMAINS

Domaines email autorisés, séparés par des virgules

ENCRYPTION_KEY

32 octets en base64. Ne pas changer après la mise en service, sinon tous les utilisateurs devront se reconnecter

ALLOWED_REDIRECT_URIS

Optionnel. Callbacks OAuth autorisés (par défaut ceux de claude.ai et claude.com)

Le serveur fait confiance à un seul proxy devant lui (Traefik) pour connaître l'IP du client, ce qui sert à la limitation des tentatives de connexion. Si Cloudflare (mode proxy) est ajouté devant Traefik, passer trust proxy à 2 dans index.js.

Ajouter le connecteur dans Claude

  • Compte individuel (Pro/Max) : Settings → Connectors → Add custom connector, URL https://mcp.exemple.fr/mcp. Le connecteur est ensuite disponible automatiquement dans l'app mobile.

  • Team / Enterprise : un administrateur ajoute le connecteur une seule fois dans les paramètres de l'organisation. Chaque membre clique ensuite sur « Connect » et se connecte avec sa propre boîte mail.

Développement local

npm install
PUBLIC_URL=http://localhost:3000 ALLOWED_REDIRECT_URIS=http://localhost:6274/oauth/callback npm start
npx @modelcontextprotocol/inspector   # se connecter à http://localhost:3000/mcp

(PUBLIC_URL en http n'est accepté que pour localhost.)

Test manuel du client EWS

Renseigner EWS_USERNAME et EWS_PASSWORD dans .env (utilisés uniquement par ce script) :

node test-manual.js verify
node test-manual.js search
node test-manual.js get <itemId>
node test-manual.js folders
node test-manual.js update <itemId>
node test-manual.js attachments <itemId> [attachmentId]
node test-manual.js reply <itemId>
node test-manual.js forward <itemId> <destinataire>
node test-manual.js send <destinataire>

Ajouter DEBUG_EWS=1 devant la commande pour afficher la requête SOAP envoyée.

Tools disponibles

search_emails(folder, query?, maxResults?)

Liste les emails d'un dossier.

{ "folder": "inbox", "query": "subject:facture", "maxResults": 10 }

get_email(itemId)

Récupère le contenu complet d'un email (corps HTML, destinataires, pièces jointes).

{ "itemId": "AQMkAD..." }

send_email(to, subject, body, cc?)

Action irréversible — envoie réellement un email.

{ "to": "quelqu'un@exemple.fr", "subject": "Bonjour", "body": "<p>Contenu</p>" }

list_folders()

Énumère tous les dossiers de la boîte mail avec leur nombre d'emails non lus.

{}

update_email(itemId, markAsRead?, moveToFolder?)

Marque comme lu/non lu et/ou déplace vers un autre dossier (par nom d'affichage ou nom standard).

{ "itemId": "AQMkAD...", "markAsRead": true, "moveToFolder": "Archive" }

get_attachments(itemId, attachmentId?)

Sans attachmentId : liste les pièces jointes. Avec : télécharge le contenu en base64.

{ "itemId": "AQMkAD..." }
{ "itemId": "AQMkAD...", "attachmentId": "AAMkAD..." }

reply_to_email(itemId, body, replyAll?)

Action irréversible — envoie réellement une réponse.

{ "itemId": "AQMkAD...", "body": "<p>Merci, c'est noté.</p>", "replyAll": false }

forward_email(itemId, to, comment?)

Action irréversible — transfère réellement l'email.

{ "itemId": "AQMkAD...", "to": "collegue@exemple.fr", "comment": "Pour info" }

Notes

  • Les tools send_email, reply_to_email et forward_email sont marqués comme irréversibles dans leur description : un agent IA bien élevé doit demander confirmation du destinataire et du contenu avant de les appeler.

  • La vulnérabilité npm underscore (dépendance transitive de httpntlm) est corrigée via le champ overrides du package.json, sans changer de version de httpntlm.

Available Tools

8 tools
forward_emailTransférer un emailA

ACTION IRRÉVERSIBLE: transfère réellement un email existant à un nouveau destinataire. L'agent DOIT toujours demander confirmation explicite du destinataire et du commentaire à l'utilisateur avant d'appeler cet outil.

Inputs: to (required), itemId (required), comment.

get_attachmentsLister ou télécharger les pièces jointesA

Sans attachmentId: liste les pièces jointes d'un email (nom, type, taille, id). Avec attachmentId: télécharge le contenu de la pièce jointe encodé en base64.

Inputs: itemId (required), attachmentId.

get_emailRécupérer un emailA

Récupère le contenu complet d'un email (corps HTML, destinataires, pièces jointes) à partir de son identifiant.

Inputs: itemId (required).

list_foldersLister les dossiersA

Énumère tous les dossiers de la boîte mail (Inbox, Éléments envoyés, Brouillons, dossiers personnalisés...) avec leur nombre d'emails non lus.

Inputs: no named parameters.

reply_to_emailRépondre à un emailA

ACTION IRRÉVERSIBLE: envoie réellement une réponse à un email existant. L'agent DOIT toujours demander confirmation explicite du contenu (et du choix répondre/répondre à tous) à l'utilisateur avant d'appeler cet outil.

Inputs: body (required), itemId (required), replyAll.

search_emailsRechercher des emailsA

Liste les emails d'un dossier Exchange (inbox, sent, drafts, ou un nom de dossier personnalisé), avec un filtre de recherche optionnel (AQS).

Inputs: folder (required), query, maxResults.

send_emailEnvoyer un emailA

ACTION IRRÉVERSIBLE: envoie réellement un nouvel email. L'agent DOIT toujours demander confirmation explicite du destinataire, du sujet et du contenu à l'utilisateur avant d'appeler cet outil.

Inputs: to (required), body (required), subject (required), cc.

update_emailMettre à jour un emailA

Marque un email comme lu/non lu et/ou le déplace vers un autre dossier.

Inputs: itemId (required), markAsRead, moveToFolder.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 8 tools

    Disambiguation5/5

    Each tool targets a distinct email operation: folder listing, search, reading, sending, updating, attachment retrieval, replying, and forwarding. There is no meaningful overlap that would confuse an agent.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern (list_folders, search_emails, get_email, send_email, update_email, get_attachments, reply_to_email, forward_email). Naming is uniform and predictable throughout.

    Tool Count5/5

    8 tools cover the core email workflow without bloat. Each tool earns its place, and the count fits the server's scope well.

    Completeness4/5

    The core lifecycle (read, search, send, reply, forward, update, attachments) is covered, but obvious missing operations include deleting emails and creating/managing folders. These are minor gaps an agent can work around.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to manage Microsoft Outlook emails through the Microsoft Graph API, supporting operations like listing, reading, sending, and moving emails.
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to interact with email accounts via IMAP and SMTP, supporting mailbox listing, email search, retrieval, sending, and management.
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI agents to read, search, draft, send, reply to, forward, and organize Microsoft Outlook mail via Microsoft Graph, with safe-by-default read-only operation and browser-based sign-in.
      15
      72 npm
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Lets AI agents send email over SMTP and read, search, and manage email over IMAP or POP3 using app passwords or authorization codes, with attachment handling and support for common providers.
      7
      49 npm
      MIT