La menace cachée des serveurs MCP : il faut une couche DLP dédiée
Le Model Context Protocol est le nouveau format de fil entre agents et outils. Le DLP navigateur ne le voit pas. Voici à quoi ressemble une couche DLP consciente de MCP.
Dix-huit mois pour passer d'une spécification à une crise de shadow IT
Anthropic a publié la première spécification du Model Context Protocol en novembre 2024. Dix-huit mois plus tard, MCP est la tuyauterie par défaut entre les agents et les outils dans Claude Desktop, Cursor, Claude Code, Continue, Zed, Windsurf, le panneau agent de Copilot, et une liste croissante de plugins IDE d'entreprise. La place de marché communautaire mcp.so recense plus de deux mille serveurs couvrant Notion, Linear, GitHub, Postgres, Snowflake, Stripe, Jira, S3, Kubernetes, des wikis internes et des API éditeurs sur mesure. Chacun de ces serveurs peut lire des données pour le compte d'un modèle.
Presque aucun ne se trouve derrière un sas DLP.
Les extensions navigateur attrapent l'onglet ChatGPT. Les agents de bureau attrapent l'application Claude. Ni l'un ni l'autre ne voit ce qui circule sur un tube stdio entre Claude Desktop et le serveur MCP Postgres que vous avez installé la semaine dernière. C'est de cet angle mort que parle ce billet.
Le primer MCP en trente secondes
MCP est un protocole JSON-RPC 2.0 avec deux transports : stdio (l'hôte modèle lance le serveur comme sous-processus et dialogue via l'entrée/sortie standard) et SSE (Server-Sent Events sur HTTPS, pour les serveurs distants). Claude Desktop, Cursor et la plupart des intégrations IDE locales privilégient stdio par défaut. Les déploiements en entreprise commencent à utiliser SSE derrière une passerelle interne.
Le vocabulaire est réduit. Après le handshake initialize, vous voyez surtout quatre méthodes.
tools/list— le serveur publie les outils qu'il propose et le schéma JSON de chaque argument.tools/call— le modèle invoque un outil avec des arguments et le serveur renvoie un résultat structuré.resources/listetresources/read— le serveur expose des contenus adressables (un fichier, une ligne de base, une page Confluence) que le modèle peut tirer dans son contexte.resources/subscribe— le modèle demande à être notifié lorsqu'une ressource change ; chaque mise à jour entre dans le tour suivant.
C'est à peu près tout le fil. Simple, bien spécifié, facile à parser — c'est précisément pour cela qu'une couche DLP dédiée est faisable.
Quatre endroits où les données sensibles fuient dans un échange MCP
Tous les vecteurs de fuite que vous redoutez déjà dans un chat navigateur existent dans MCP, plus deux nouveaux que l'hôte génère sans qu'aucune touche soit pressée.
1. Les entrées d'outils
Lorsqu'un utilisateur demande « résume le dernier deal HubSpot d'Acme », l'agent construit un tools/call avec le nom littéral de la société, l'identifiant du deal et souvent l'email ou le jeton de session de l'utilisateur comme arguments. Ces arguments sont du contenu fourni par l'utilisateur, à tous égards sauf l'apparence. Un prompt de jailbreak qui glisse le NIR d'un client dans l'argument query d'un outil Postgres équivaut fonctionnellement à coller ce NIR dans ChatGPT.
2. Les sorties d'outils
C'est la surface nouvelle, et c'est celle que la plupart des équipes sous-estiment. Un resources/read sur une page Confluence renvoie tout ce qui s'y trouve — y compris l'api_key que quelqu'un a collée dans un runbook il y a trois ans. Un outil SQL retourne des lignes contenant des emails, des IBAN, des NIR, des scans de passeports encodés en data URI. Le modèle reprend cette sortie, la résume, et le résumé traverse le réseau vers Anthropic, OpenAI, Google ou Mistral. L'utilisateur n'a rien tapé de tout cela.
3. Les abonnements de ressources
Un agent IDE abonné à file:///home/dev/secrets.env pour du hot-reload pendant une session de débogage va streamer chaque événement de sauvegarde dans le contexte du modèle. Les abonnements de longue durée sont particulièrement dangereux parce qu'ils découplent le mouvement des données de l'attention de l'utilisateur — personne ne regarde la conversation à 02h14 quand le fichier de secrets tourne.
4. Le contexte d'hôte accumulé
L'hôte (Claude Desktop, Cursor) est responsable d'assembler le prompt envoyé au modèle. Il replie dedans les sorties d'outils précédentes, les snapshots de ressources et l'historique de conversation. Sur une longue session, cette fenêtre de contexte accumule discrètement une tranche de chaque système touché par l'utilisateur. La plupart des hôtes renvoient ce contexte entier à chaque tour. Si vous n'inspectez que le prompt tapé par l'utilisateur, vous ratez 90 % de ce qui traverse réellement le fil.
Pourquoi le DLP générique passe à côté de tout cela
Trois raisons, toutes structurelles.
Pas de point d'interception HTTP. Le DLP navigateur s'appuie sur le hook de fetch dans le contexte de la page. Un serveur MCP stdio n'a ni page, ni navigateur, ni fetch. Les octets passent par un tube anonyme entre deux processus que l'OS traite comme frères. DLP proxy web, CASB, SWG — aucun ne voit la conversation.
Le trafic SSE ne ressemble pas à du chat. Même quand MCP s'exécute sur HTTPS, l'enveloppe est text/event-stream avec des charges JSON-RPC, pas les formes de chat-completion pour lesquelles les éditeurs DLP ont construit des bibliothèques de signatures. L'inspection de contenu générique traite le flux comme de la télémétrie opaque.
La charge sensible arrive du serveur. Le DLP classique est sortant : il regarde ce que l'utilisateur envoie. MCP inverse la menace. Le contenu à haut risque est la réponse de l'outil, qui atterrit dans le contexte du modèle puis quitte la machine lors du prochain appel LLM. Au moment de franchir la frontière réseau, elle a déjà été blanchie par un résumé du modèle et ne correspond plus à aucun motif littéral.
Inspectez la réponse, pas seulement la requête. Un DLP MCP qui ne scanne que les arguments de tools/call n'attrape que la moitié du problème. L'autre moitié est dans le champ result au retour.
Ce que fait réellement une couche DLP consciente de MCP
Le composant est petit. Il se place entre le processus hôte et le serveur MCP et fait quatre choses.
- Parser les enveloppes JSON-RPC. Reconnaître les requêtes
tools/call, les réponsestools/call, les réponsesresources/readet les notifications d'abonnement. Tout le reste passe avec un surcoût négligeable. - Appliquer la même détection de types de fund que partout ailleurs. Les détecteurs pour
api_key,password,jwt,private_key,credit_card,IBAN,email,phone,NIR,passport,connection_stringet code source sont les mêmes que ceux utilisés par l'extension navigateur. Pas de seconde taxonomie à maintenir. - Agir par type de détection. Monitor, Anonymize avec rédaction préservant le format, ou Block — la matrice de politique est identique à celles du navigateur et du poste. Un analyste SOC qui connaît déjà l'Operator Console comprend les incidents MCP sans formation supplémentaire.
- Émettre la même enveloppe d'incident. Chaque détection devient un incident avec la même forme, le même modèle de sévérité, le même payload webhook vers Slack, Splunk HEC ou Microsoft Sentinel. L'investigateur reste dans un seul outil.
Un wrapper Python de 40 lignes qui scanne les deux sens
Concrètement, voici à quoi ressemble un wrapper stdio. Il lance le vrai serveur MCP en sous-processus et fait passer chaque message par un scanner de contenu avant de le relayer.
import asyncio, json, sys
from zeuslock_mcp import Scanner, Policy
scanner = Scanner(policy=Policy.from_file("policy.yaml"))
async def pipe(reader, writer, direction):
while True:
line = await reader.readline()
if not line:
break
try:
msg = json.loads(line)
except json.JSONDecodeError:
writer.write(line); await writer.drain(); continue
verdict = scanner.inspect(msg, direction=direction)
if verdict.action == "block":
err = {"jsonrpc": "2.0", "id": msg.get("id"),
"error": {"code": -32001, "message": verdict.reason}}
writer.write((json.dumps(err) + "\n").encode())
await writer.drain(); continue
writer.write((json.dumps(verdict.payload) + "\n").encode())
await writer.drain()
async def main(cmd):
proc = await asyncio.create_subprocess_exec(
*cmd, stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE)
loop = asyncio.get_event_loop()
stdin_reader = asyncio.StreamReader()
await loop.connect_read_pipe(
lambda: asyncio.StreamReaderProtocol(stdin_reader), sys.stdin)
stdout_writer = sys.stdout.buffer
await asyncio.gather(
pipe(stdin_reader, proc.stdin, direction="to_server"),
pipe(proc.stdout, stdout_writer, direction="to_host"))
asyncio.run(main(sys.argv[1:]))
L'utilisateur pointe Claude Desktop sur zeuslock-mcp postgres-mcp-server --dsn ... au lieu de postgres-mcp-server --dsn .... Même expérience, visibilité totale, décisions de rédaction ou de blocage prises avant que les octets ne quittent la machine.
Le problème de chaîne d'approvisionnement dont personne ne parle encore
La place de marché MCP communautaire a les mêmes caractéristiques que npm en 2015 et la marketplace VS Code en 2019 : peu de friction à la publication, pas de signature obligatoire, pas de provenance, des instructions d'installation qui collent le binaire d'un inconnu dans le répertoire utilisateur. Un serveur MCP malveillant peut faire tout ce que fait un serveur normal — lire des fichiers, exécuter des requêtes, taper des API — plus exfiltrer discrètement la fenêtre de contexte du modèle via un appel d'outil parallèle.
La CNIL, le BSI et l'ENISA n'ont pas encore publié de guidance spécifique à MCP. Ils le feront. En attendant, traitez tout serveur MCP tiers comme une extension navigateur non signée ou un plugin VS Code anonyme : un bout de code qui s'exécute avec vos privilèges et voit tout ce que votre agent voit.
Liste de contrôle défensive pour les 90 prochains jours
- Inventaire. Demandez à chaque ingénieur quels serveurs MCP sont configurés dans son Claude Desktop, Cursor et Claude Code. La liste vous surprendra.
- Audit. Pour chaque serveur, identifiez l'éditeur, lisez la source si elle est disponible et épinglez la version. Bloquez par défaut l'installation des serveurs non signés depuis la place de marché.
- Wrap. Placez un scanner DLP MCP entre l'hôte et chaque serveur. Scannez dans les deux sens. Démarrez en mode Monitor pendant deux semaines pour apprendre la base.
- Allowlist des appels d'outils par rôle. Les développeurs peuvent avoir besoin de
filesystem/write; la finance non. Le nom d'outil est exactement la primitive de politique recherchée. - Inspectez les sorties de ressources. Un scan qui ne regarde que les arguments de
tools/callet ignore les réponsesresources/readrate la plus grande catégorie de fuites. - Journalisez chaque
tools/callà des fins d'audit. Nom d'outil, empreinte des arguments, taille du résultat, types détectés, action prise. Envoyez vers votre SIEM avec des webhooks signés HMAC. - Couvrez aussi les serveurs SSE distants. Si vous laissez un serveur MCP distant se connecter en HTTPS, terminez le flux SSE sur une passerelle que vous contrôlez et exécutez-y le même scanner.
- Mappez les contrôles sur vos référentiels. Le scan MCP s'insère dans la gestion des risques NIS2, le risque tiers TIC du DORA et les obligations de journalisation de l'article 15 de l'AI Act. Documentez le mapping maintenant pour que l'audit ne vous prenne pas au dépourvu.
Pourquoi cela compte en 2026, pas en 2028
MCP est la prochaine surface de menace « pièce jointe d'email » pour les agents IA. Les pièces jointes ont mis une décennie et plusieurs incidents à la une — ILOVEYOU, le ver Slammer, Locky — avant que les entreprises ne mettent une vraie inspection devant. Cette fois, nous n'avons pas une décennie. Les IDE agentiques touchent déjà des bases de production pour le compte de chaque développeur ayant installé le mauvais serveur depuis une fiche de marketplace.
Les organisations qui gagneront les dix-huit prochains mois sont celles qui ont traité MCP comme une surface DLP de premier rang avant que la première grosse fuite ne fasse la une. Wrappez vos serveurs. Scannez dans les deux sens. Journalisez tout. Le motif est bien compris ; la seule question est de savoir si vous le déployez avant ou après le post-mortem.
Si vous voulez la version production du wrapper ci-dessus, l'intégration MCP de Zeuslock est documentée sur zeuslock.ai/docs, et vous pouvez demander une démo depuis le même site.
Protect your data from AI leaks
Try Zeuslock free — DLP for ChatGPT, Claude, Gemini and more.
Book a demo →