
Un mcp léger pour prévenir l'empoisonnement de CVE (CVE-2025-54136), le détournement de Claude Code/Copilot/Gemini par des chercheurs via l'injection de prompt, et des centaines de serveurs MCP exposés sans aucune authentification, ce mcp protège l'ordinateur portable du développeur individuel, là où la plupart des serveurs MCP s'exécutent réellement.
La passerelle de sécurité pour les serveurs MCP — chaque appel d'outil est vérifié à l'entrée.
CI npm License: Apache-2.0 PRs welcome
mcp-doorman est un proxy prêt à l'emploi qui se place entre votre agent IA (Claude Desktop, Claude Code, Cursor, VS Code, n'importe quel client MCP) et les serveurs MCP qu'il utilise. Une commande, zéro infrastructure, et chaque tools/list et tools/call passe par un pipeline de garde :
Tout le monde est à un npx some-random-mcp-server de confier ses clés API à un processus non vérifié et une ligne directe dans la fenêtre de contexte de son modèle. Les classes d'attaques documentées sont réelles, pas hypothétiques :
| Attaque | Comment ça marche |
|---|---|
| Empoisonnement d'outil | Instructions malveillantes cachées dans la description d'un outil, invisibles dans la plupart des interfaces client |
| Rug pull | Le serveur présente des outils innocents le premier jour, puis échange les définitions après que vous les ayez approuvées |
| Injection indirecte de prompt | Une page web / issue / email récupérée par un outil légitime contient des instructions destinées au modèle |
| Exfiltration de secrets | Un identifiant divulgué dans un résultat d'outil + une instruction injectée = votre clé sur le serveur de quelqu'un d'autre |
| Boucles incontrôlées | Un agent confus ou détourné supprime en masse, envoie en masse, scrape en masse |
Les passerelles MCP d'entreprise existent pour les équipes de plateforme avec des clusters Kubernetes. Rien de léger ne protège l'ordinateur portable du développeur individuel — l'endroit où 99 % des serveurs MCP s'exécutent réellement. C'est le vide que ce projet comble.
# 1. Créez une configuration
npx -y mcp-doorman init
# 2. Modifiez doorman.config.json — mettez-y vos vrais serveurs
# 3. Épinglez les définitions d'outils actuelles (confiance à la première utilisation)
npx -y mcp-doorman pin --config doorman.config.json
Puis pointez votre client vers la passerelle au lieu de vos serveurs. Claude Desktop / Claude Code / Cursor :
// AVANT — chaque serveur parle directement au modèle
{
"mcpServers": {
"github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"] },
"filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/repos"] }
}
}
// APRÈS — un seul doorman les garde tous
{
"mcpServers": {
"doorman": {
"command": "npx",
"args": ["-y", "mcp-doorman", "run", "--config", "/absolute/path/to/doorman.config.json"]
}
}
}
Les outils apparaissent avec un espace de noms comme github__create_issue, filesystem__read_file, etc., plus deux outils intégrés : doorman__status et doorman__recent_events (demandez à votre agent "qu'est-ce que doorman a bloqué récemment ?").
Remarque Windows : si une entrée de serveur utilise
npxdirectement, lancez-la via cmd :"command": "cmd", "args": ["/c", "npx", "-y", "..."].
git clone https://github.com/Sushank05/mcp-doorman && cd mcp-doorman
npm install
npm run demo
La démo connecte la passerelle à un serveur volontairement malveillant (examples/demo-server.mjs) qui fuit de faux identifiants, sert une charge utile d'injection de prompt et offre un outil destructeur — et montre chaque garde l'arrêter.
flowchart LR
A["MCP client\n(Claude Desktop, Cursor, ...)"] -- stdio --> D
subgraph D [mcp-doorman]
direction TB
P[policy] --> R[rate limit] --> AP[approval] --> RD[redaction] --> I[injection scan] --> AU[(audit log)]
end
D -- stdio --> S1[github server]
D -- stdio --> S2[filesystem server]
D -- streamable HTTP --> S3[remote server]La passerelle est un serveur MCP vers votre client et un client MCP vers chaque amont (processus enfants stdio ou endpoints HTTP streamables), les agrège derrière une seule connexion. Elle est construite sur le SDK TypeScript officiel.
Tout se trouve dans un seul fichier JSON. Exemple complet avec toutes les options :
{
"servers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" } // ${VAR} = lire depuis l'environnement de la passerelle
},
"remote": { "url": "https://mcp.example.com/mcp", "headers": { "Authorization": "Bearer ${MCP_TOKEN}" } }
},
"policy": {
"defaultAction": "allow", // "allow" | "deny" | "approve"
"rules": [ // la première correspondance gagne, évaluée de haut en bas
{ "match": "*__delete*", "action": "deny", "reason": "pas d'outils destructeurs" },
{ "match": ["github__create_*", "*__send_*"], "action": "approve" },
{ "match": "filesystem__*", "action": "allow" }
]
},
"redaction": {
"enabled": true,
"disable": [], // noms des règles intégrées à désactiver
"enableOptIn": ["email"], // opt-ins : "email", "us-ssn", "ipv4"
"custom": [{ "name": "acme-id", "pattern": "ACME-[0-9]{6}" }],
"redactArguments": false // également nettoyer les arguments fournis par le modèle
},
"injection": {
"action": "flag", // "flag" (avertir le modèle) | "block" | "off"
"scanToolDescriptions": true, // vérification d'empoisonnement d'outil sur tools/list
"custom": []
},
"pinning": {
"enabled": true,
"onNewTool": "pin", // "pin" (TOFU) | "block" (jusqu'à `mcp-doorman pin`)
"onChangedTool": "block" // "block" | "warn"
},
"rateLimit": { "perMinute": 120, "perTool": { "*__send_*": 5 } },
"approval": { "fallback": "deny", "timeoutMs": 120000 }, // fallback quand le client manque d'élicitation
"audit": { "enabled": true, "includeArguments": true, "includeResults": false },
"logLevel": "info"
}
L'état d'épinglage et le journal d'audit sont par défaut <config-name>.pins.json / <config-name>.audit.jsonl à côté du fichier de configuration.
| Commande | Ce qu'il fait |
|---|---|
mcp-doorman run --config <path> | Démarrer la passerelle sur stdio (commande par défaut) |
mcp-doorman pin --config <path> | Se connecter à tous les amonts et épingler (faire confiance) à leurs définitions d'outils actuelles |
mcp-doorman init | Écrire une configuration de démarrage avec des valeurs par défaut sensibles |
Les outils de sécurité qui promettent trop sont pires que rien. Lisez cette partie.
deny/approve comme barrière dure ; le filtrage est une défense en profondeur.approval.fallback (refus par défaut).resources/* et prompts/* (actuellement outils uniquement)doorman-rules-finance, doorman-rules-healthcare…)mcp-doorman audit : affichage et interrogation du journal JSONLAttrapez n'importe quoi ci-dessus, ou commencez par une [good first issue](https://github.com/YOUR_GITHUB_USERNAME/mcp-doorman/labels/good%20first%20issue). Les nouvelles règles de détection sont la contribution la plus simple : une regex + deux tests. Voir CONTRIBUTING.md et docs/detection-rules.md.
npm install
npm test # 69 tests : unitaires + e2e stdio complet
npm run build
npm run demo # regardez les gardes s'activer en direct
Apache-2.0 — libre pour toute utilisation, avec une licence de brevet explicite.