Releases: Cloud-Temple/mcp-tools
Release list
v0.7.0
Cette version introduit le service mcp-cybersec, publiable et déployable
indépendamment du service historique mcp-tools.
Added
mcp-cybersec, second service MCP déployable séparément — image,
compose, WAF, port et réseaux propres. Le service historiquemcp-toolset
son catalogue ne sont pas modifiés.- Campagnes sous mandat — création en état
prepared, approbation
administrative avec snapshot immuable et hash, fenêtre temporelle,
capacités, limites de débit et arrêt d'urgence persistés dans S3. - Outillage cyber borné (13 outils) —
campaign,scope,network,
http,nmap,nuclei,evidence,shell,files,tokenet les trois
outils système. Les jobsnmapetnucleisont asynchrones, idempotents et
annulables. - Console
/adminet CLI Click cybersec — suivi des campagnes, mandats,
jobs, preuves et tokens, avec journal d'activité corrélé réutilisant le
socle observabilité déjà qualifié. - Recette laboratoire locale — overlay Compose isolé, cible privée sans
port exposé, manifestelaboratory=trueet templates Nuclei officiels
épinglés avec leur provenance.
Fixed
- Runners Docker exécutables — syntaxe des bind mounts corrigée, répertoire
runtime partagé avec le démon Docker, bridge scanner créé avant les jobs et
mode découverte Nmap limité à-snsans options incompatibles. - Verdict
tools/list— le probe SSE borné accepte désormais le catalogue
Cybersec de 11,6 Ko ; untools/listeffectivement remis à l'ASGI n'est plus
classé à tortresponse_missingdans/adminet la CLI. - Bornes de mandat exécutoires — les ports, chemins URL, classes de test,
débits Nmap et timeouts globaux sont maintenant refusés ou bornés avant le
trafic ; Nuclei exige une URL explicite pour conserver port et chemin. - Publication d'une version déjà préparée — le script de release tague le
commit courant quandVERSIONet les labels portent déjà la version cible,
sans tenter de fabriquer un commit vide. - Probe d'import CI — les vérifications Python remplacent explicitement
l'entrypoint serveur de l'image afin de terminer au lieu de laisser le job
GitHub Actions bloqué sur un serveur actif ; la recette MCP reçoit la même
clé éphémère que le serveur Docker au lieu du placeholder de développement. - Recette CI réellement hermétique — le smoke CLI vérifie health, catalogue,
parité/admin, activité et shell interactif sans cible Internet ni mutation
S3 ; la recette complète reste réservée à la qualification manuelle. - Scan d'images exécutable en CI — Trivy remplace Docker Scout, qui
s'arrêtait avant analyse faute d'éligibilité du compte GitHub Actions ; les
vulnérabilités HIGH/CRITICAL des images service et sandbox sont rapportées.
Security
- Isolation stricte — tenant obligatoire pour les tokens de mission,
préfixe S3 par tenant/campagne, accèsfileslimité au workspace de sa
campagne, aucun accès agent au bucket, aux secrets ou au socket Docker. - Contrôle de périmètre systématique — validation DNS/IP/URL, refus des
plages privées, loopback et metadata, puis revalidation avant les actions
réseau et les redirections HTTP. Nuclei reçoit les IP déjà validées (avec
Host/SNI contrôlé), ce qui ferme la fenêtre de DNS rebinding. L'exception
laboratoire exige les trois conditions explicites : mode local, CIDR local
et mandat approuvé. - Shell sans réseau — le shell de campagne est lancé avec
--network=none, racine en lecture seule et ressources bornées. Les accès
réseau passent uniquement par les outils à mandat (network,http,
nmap,nuclei). Les artefacts de sortie contenant un lien symbolique ou
sortant du workspace sont refusés avant toute écriture S3. - Secrets séparés — seules les variables
CYBERSEC_*, prévues pour une
injection Vault, sont acceptées. Les identifiants, bucket et tokens de
mcp-toolsne sont jamais repris, et le harnais E2E n'affiche plus aucun
fragment de bearer dans ses journaux.
v0.6.1
Ajouts
- Journal d'activité corrélé de la réception HTTP à la clôture, regroupé par
trace_id, avec corrélateurs sûrs (call_id, JSON-RPC, acteur et référence de session hachée). - Recherche ciblée dans
/admin/api/activityetsystem_activity, sans tronquer la chronologie conservée. - Journal HTTP corrélé aux appels MCP et Admin ; les lectures de journaux restent exclues pour éviter l'auto-bruit.
Correctifs
- Une réponse est marquée terminée seulement après acceptation par l'ASGI ; les échecs de remise, SSE vides et résultats distants incertains sont distingués.
- La CLI Click, le shell et
/adminprésentent la même vue corrélée lisible, avec JSON machine à la demande. - Les gros appels MCP non inspectables restent conservateurs et les annulations d'écritures HTTP/S3 signalent
remote_result_uncertain. - Le journal HTTP Admin reflète le statut réellement émis : erreur métier d'outil en
422, exception avant réponse en500.
Validation
- 11 tests de contrat de traçabilité.
- Recette Docker ciblée Admin + CLI : 64/64 réussis.
- Compatibilité client MCP 1.28.0 vérifiée via le WAF (
initializepuisdate).
v0.6.0 — MCP SDK v2 et traçabilité
Points clés
- Migration vers MCP SDK 2.1.1 :
MCPServer, API publiques et client Streamable HTTP v2. - Journal d’activité corrélé, sûr et exploitable dans
/adminet viasystem_activitypour les administrateurs. - Détection d’un flux SSE vide, nettoyage des sandboxes à l’annulation, et redaction des secrets dans les journaux.
- CLI Click et shell interactif alignés sur le catalogue de 13 outils ;
--jsonest désormais un flux JSON brut parseable.
Validation
- CLI Click et shell : 41/41 contrôles passés, dont la parité de catalogue avec
/admin(13/13). - Console
/admin: 24/24 contrôles passés. - Reproductibilité : 8/8 contrôles passés (
mcpetmcp-types2.1.1, imports image,pip check,pip-audit). - Smoke S3 final : écriture, lecture, listing, comparaison et nettoyage validés.
Note de recette
La suite S3 exhaustive a observé des Read timeout intermittents du endpoint ECS pendant une charge soutenue ; le smoke isolé final est passé. Aucun changement de timeout spéculatif n’est inclus dans cette release.
v0.5.2
Outillage de publication. Aucun changement fonctionnel ni de dépendance : src/ et requirements.lock sont inchangés.
Added
scripts/check_release_coherence.py— garde branché en CI (jobcoherence-version, déclenché aussi sur les tagsv*). Échoue simainporte unVERSIONcorrespondant à un tag pointant un autre commit, si un tagvX.Y.Zdésigne un commit dontVERSION≠ X.Y.Z, ou si un tag est publié sans entrée CHANGELOG. Le 2026-08-06, du travail avait été fusionné après la publication de v0.5.0 sans bump ni tag : la plateforme s'est vu annoncer une cible de déploiement qui a changé sous elle. Le garde reproduit ce cas et échoue dessusscripts/release.sh— rend la publication atomique : bumpVERSIONetLABEL, contrôles préalables (branchemain, arbre propre, synchroorigin, tag libre, CHANGELOG rédigé, aucun.envsuivi par git), gardes de cohérence et de reproductibilité, puis commit + tag + release.DRY_RUN=1contrôle tout sans publier
Fixed
- Bits exécutables absents des scripts —
core.fileMode=falsesur ce dépôt rendchmodinvisible à git :scripts/lock_requirements.shétait livré en100644, donc./scripts/lock_requirements.sh— la commande documentée dans le README et leDockerfile— échouait en « permission denied » depuis un clone neuf. Corrigé viagit update-index --chmod=+x
v0.5.1 — Durcissement de la recette E2E + garde secrets
Publie les correctifs de rigueur de la recette E2E, qui n'étaient portés par aucun tag. Aucun changement fonctionnel — 12 outils, signatures et API inchangés.
Différence d'artefact avec v0.5.0 : VERSION seul, remonté par /health et system_about. Dépendances, requirements.lock et les deux images de base sont strictement identiques. Les gains de sécurité de la v0.5.0 (sandbox Alpine 3.24, Docker CLI 29.7.2, pillow 12.3.0, setuptools 83.0.0) sont intégralement conservés.
Rigueur des tests
Trois défauts trouvés en auditant la suite, tous corrigés :
test_14_cline s'exécutait jamais — ses 52 assertions étaient enregistrées dansTEST_REGISTRYmais absentes de la séquence du run complet. La suite passe de 132 à 186 assertions- Deux assertions ne pouvaient pas échouer —
record(..., True)enfermé dans unif citations:: citations absentes ⇒ rien d'enregistré, l'anomalie passait inaperçue. Il en reste 0 dans le fichier - Les tests Perplexity confondaient panne externe et défaut de code — un
401 insufficient_quotaproduisait un rouge permanent. Discrimination sur des signatures d'indisponibilité explicitement listées ; toute autre erreur reste un échec
Sécurité
.gitignore ignorait .env mais pas .env~, qui porte exactement les mêmes secrets. Motifs *~, *.bak, *.orig, .env.* ajoutés, avec exception pour .env.example. Aucune fuite : le push avait été bloqué par la protection de secrets GitHub.
Automatisation
--test accepte désormais une liste, et la CI exécute une recette E2E hermétique de 132 assertions sur 9 outils sans aucun secret. token/admin (S3), les deux perplexity (clé facturée) et les cas SSH positifs restent manuels — documenté plutôt que masqué.
Vérifications
Build des deux images OK, conteneur healthy avec /health renvoyant "version": "0.5.1", 0 redémarrage, 186 PASS / 0 FAIL sur la suite complète.
v0.5.0 — Build reproductible + remédiation sécurité
Corrige l'issue #2 (BLOCKER) : la v0.4.1 n'était pas reconstructible depuis son tag. Aucun changement fonctionnel — 12 outils, signatures et API inchangés.
Reproductibilité
requirements.txt devient un contrat de compatibilité (bornes hautes obligatoires) ; requirements.lock — clôture transitive figée de 51 paquets, outillage pip/setuptools/wheel inclus — devient la source d'installation. Le lock se régénère dans l'image cible via scripts/lock_requirements.sh. Images de base épinglées par digest.
mcp[cli] est plafonné à <2.0 et figé à 1.29.0 : la 2.0.0 supprime mcp.server.fastmcp (serveur) et streamablehttp_client (client), ce second point étant absent de l'issue.
Sécurité
| Correction | Effet |
|---|---|
| Sandbox Alpine 3.20 → 3.24 | 47 CVE critiques/hautes → 3 hautes, 0 critique |
| Docker CLI 27.4.1 → 29.7.2 | Go stdlib 1.22.10 : 18 CVE dont 2 critiques |
pillow 12.2.0 → 12.3.0 |
10 CVE hautes |
setuptools 79.0.1 → 83.0.0 |
PYSEC-2026-3447 |
git retiré de l'image de service |
5 paquets perl, 2 CVE critiques « not fixed » |
Le retrait de git ne coûte aucune fonctionnalité : le tool shell délègue à mcp-tools-sandbox, où git reste présent.
Garde-fous
test_15_reproducibility (8 contrôles, exécutable sans serveur) et une CI GitHub Actions — le dépôt n'en avait aucune. Son passage hebdomadaire détecte la dérive amont avant qu'elle ne bloque un déploiement.
Vérifications
Build OCI frais des deux images, pip show mcp = 1.29.0 verrouillé, conteneur healthy avec /health HTTP 200, imports serveur et client OK, pip-audit sans vulnérabilité connue.
Risques résiduels
perl-base (Essential: yes, livré par l'image de base, « not fixed » Debian, jamais exécuté), msgpack et pkg_resources vendorés dans pip, jq et wget sans correctif Alpine. Détaillés dans le CHANGELOG et DESIGN/mcp-tools/ARCHITECTURE.md §8.
v0.4.1 — Fix OAuth well-known endpoints
Bugfix — Urgence déploiement
Problème
Les SDK MCP >= 2025-11-25 (spec 2025-11-25) implémentent le protocole "MCP Authorization". Après un 401 sur /mcp, ils sondent automatiquement les endpoints de découverte OAuth :
/.well-known/oauth-protected-resource/mcp/.well-known/oauth-protected-resource/.well-known/oauth-authorization-server/.well-known/openid-configurationPOST /register
Ces endpoints retournaient 401 (auth required), interprété comme "serveur cassé" → le client abandonnait définitivement avec "authentication failed".
Fix
AuthMiddleware retourne désormais 404 pour tous les chemins /.well-known/* et /register, signalant correctement l'absence d'OAuth (RFC 9728) — les clients comprennent qu'ils doivent utiliser un Bearer token statique.
# Ajouté dans AuthMiddleware
OAUTH_DENY_PREFIXES = ("/.well-known/",)
OAUTH_DENY_PATHS = {"/register"}Fichiers modifiés
src/mcp_tools/auth/middleware.py— fix principal (3 lignes + constantes)scripts/test_service.py— 5 nouveaux tests OAuth discovery danstest_02_auth
Déploiement
docker compose pull # ou build si image locale
docker compose up -d
python scripts/test_service.py --test auth --no-dockerRéférences
- RFC 9728 — OAuth 2.0 Protected Resource Metadata
- MCP Authorization spec 2025-11-25
v0.3.1 — Security Hardening
🔐 Security Hardening
Security
- §3.6 Timing attack bootstrap key — Remplacement de
==parhmac.compare_digest()pour la comparaison de la bootstrap key admin dansmiddleware.pyetadmin/api.py. Élimine le canal auxiliaire de timing permettant de deviner la clé caractère par caractère - §3.7 Bootstrap key par défaut — Ajout d'une vérification au démarrage (
server.py) : affichage d'un avertissement⚠️ CRITIQUE siADMIN_BOOTSTRAP_KEYn'a pas été modifiée depuis la valeur par défaut - §3.8 Token en query string supprimé — Le support
?token=a été retiré. Seul le headerAuthorization: Bearer <token>est désormais accepté - §3.9 Audit persisté sur stderr — Chaque entrée du journal d'audit est dupliquée sur
stderren JSON structuré pour collecte par Docker logs → Loki/ELK/CloudWatch
Added
_security_checks()— Vérification bootstrap key et sandbox au démarrage- Warning si
SANDBOX_ENABLED=false(exécution locale = RCE sur l'hôte) - Rapport d'audit enrichi (
SECURITY_AUDIT.md) avec §3.6-§3.9 et tableau historique
Fixed
- Tests WAF corrigés — ciblaient
/admin/api/health(sans WAF) au lieu de/health(avec Coraza)
Tests
- 138/138 PASS — 0 FAIL, 0 SKIP
v0.3.0 — Console Admin v2, Tests CLI, Journal d'audit
🎉 MCP Tools v0.3.0 — Console Admin v2, Tests CLI, Journal d'audit
✨ Nouveautés
Console Admin refonte complète (/admin)
- Token update (PUT) — Modification des permissions, tool_ids et email via modal d'édition
- Token purge — Suppression en masse des tokens expirés
- Journal d'audit — Ring buffer 500 entrées traçant QUI fait QUOI (acteur, action, cible, détails)
- Tool picker intelligent — 6 catégories avec descriptions, boutons Tout/Rien, masquage auto de l'outil
tokenpour les non-admin - Permissions access/admin — Sélecteur radio avec aide contextuelle, picker désactivé pour admin
- Info token formatée — Modal structuré (plus de dump JSON brut)
- Onglets Activité — Journal d'audit + Requêtes HTTP avec filtres et recherche
Tests CLI E2E
- 38 tests via subprocess couvrant les 13 commandes Click : health, about, run-shell, network, http, date, calc, token (cycle create→info→update→revoke), files, et 11 --help
- Lancement :
python3 scripts/test_service.py --test cli
Nouvelles API admin
PUT /admin/api/tokens/{name}— Modifier un tokenPOST /admin/api/tokens/purge— Purger les tokens expirésGET /admin/api/audit— Journal d'audit détaillé
🔧 Changements
- WAF Caddyfile : route
/admin*bypassée (auth par AdminMiddleware, Coraza bloquait les PUT) - Permissions corrigées dans l'interface (modèle
access/admin, plus de read/write) - Docstrings scripts enrichis (13 commandes, 15 catégories de tests)
🐛 Corrections
- "Réponse vide" sur PUT corrigé (WAF Coraza)
- Outil
tokenmasqué dans le picker pour les non-admin - Tool picker se désactive correctement quand admin est sélectionné
📊 Tests
- 138 tests MCP E2E + 38 tests CLI = 176 tests total
- 15 catégories de tests disponibles via
--test NOM
v0.2.0 — Sandbox enrichie + accès réseau optionnel
🔧 Sandbox shell enrichie
Nouveau paramètre network
network=false(défaut) : isolation totale (--network=none), inchangénetwork=true: accès réseau (--network=bridge+ DNS) pourpip install,curl,wget- Contraintes adaptées : tmpfs 256m, pids-limit 50, tmpfs
~/.localet~/.cachepour pip
14 packages Python pré-installés
numpy, pandas, requests, beautifulsoup4, lxml, pyyaml, scipy, matplotlib, pillow, boto3, tabulate, toml, chardet, dateutil — utilisables sans réseau.
Compatibilité
OPENBLAS_NUM_THREADS=1— fix threads numpy/scipy vs pids-limitPIP_BREAK_SYSTEM_PACKAGES=1— fix PEP 668 Alpine Pythonnoexecconservé sur tmpfs quandnetwork=false
Tests
- 6 nouveaux tests shell (packages pré-installés, curl, pip install, régression)
- Total : ~108 tests E2E (14 catégories)
- Documentation d'audit :
DESIGN/mcp-tools/TESTS_AUDIT.md
Inclut aussi (v0.1.9)
- Permissions simplifiées :
access/admin(remplaceread/write) - Migration automatique des tokens au démarrage
- 6 tests WAF Coraza (XSS, SQLi, Shellshock, path traversal)
65 paramètres MCP | 12 outils | ~108 tests E2E