ftp-deploy-mcp 0.0.0-stage → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.fr.md +468 -0
- package/CHANGELOG.md +415 -0
- package/CONTRIBUTING.fr.md +120 -0
- package/CONTRIBUTING.md +111 -0
- package/LICENSE +21 -0
- package/LICENSE.fr.md +26 -0
- package/README.fr.md +518 -0
- package/README.md +501 -2
- package/SECURITY.fr.md +99 -0
- package/SECURITY.md +94 -0
- package/docs/AGENT-PERFORMANCE.fr.md +144 -0
- package/docs/AGENT-PERFORMANCE.md +133 -0
- package/docs/ERROR-CONTRACT.fr.md +141 -0
- package/docs/ERROR-CONTRACT.md +137 -0
- package/docs/LANGUAGES.fr.md +68 -0
- package/docs/LANGUAGES.md +62 -0
- package/docs/RELEASE.fr.md +462 -0
- package/docs/RELEASE.md +435 -0
- package/docs/RESOURCE-BOUNDS.fr.md +144 -0
- package/docs/RESOURCE-BOUNDS.md +132 -0
- package/docs/SCRIPTED-EVALUATIONS.fr.md +190 -0
- package/docs/SCRIPTED-EVALUATIONS.md +181 -0
- package/docs/SECURITY-MODEL.fr.md +262 -0
- package/docs/SECURITY-MODEL.md +236 -0
- package/docs/STATE-STORAGE.fr.md +236 -0
- package/docs/STATE-STORAGE.md +231 -0
- package/docs/TRANSFERS.fr.md +140 -0
- package/docs/TRANSFERS.md +123 -0
- package/docs/WORKFLOW-MODEL.fr.md +63 -0
- package/docs/WORKFLOW-MODEL.md +62 -0
- package/evaluations/README.fr.md +95 -0
- package/evaluations/README.md +92 -0
- package/evaluations/fixture/README.txt +3 -0
- package/evaluations/fixture/catalog/alpha.txt +4 -0
- package/evaluations/fixture/catalog/bravo.txt +4 -0
- package/evaluations/fixture/catalog/charlie.txt +4 -0
- package/evaluations/fixture/catalog/delta.txt +4 -0
- package/evaluations/fixture/catalog/echo.txt +4 -0
- package/evaluations/fixture/catalog/foxtrot.txt +4 -0
- package/evaluations/fixture/reports/checks.txt +4 -0
- package/evaluations/fixture/reports/release.txt +3 -0
- package/evaluations/read-only.fr.xml +42 -0
- package/evaluations/read-only.xml +42 -0
- package/ftp-servers.example.json +27 -0
- package/install.cmd +29 -0
- package/install.sh +18 -0
- package/package.json +88 -4
- package/server.json +35 -0
- package/src/adapters/ftp.js +392 -0
- package/src/adapters/sftp.js +647 -0
- package/src/admission.js +15 -0
- package/src/atomic-write.js +131 -0
- package/src/clients.js +212 -0
- package/src/config.js +629 -0
- package/src/durable/confirmation.js +88 -0
- package/src/durable/engine.js +696 -0
- package/src/durable/plan.js +238 -0
- package/src/durable/schemas.js +206 -0
- package/src/durable/state.js +317 -0
- package/src/durable/status.js +175 -0
- package/src/durable-tools.js +94 -0
- package/src/errors.js +88 -0
- package/src/filezilla.js +260 -0
- package/src/i18n.js +58 -0
- package/src/index.js +175 -0
- package/src/local-path.js +130 -0
- package/src/locales/en.js +152 -0
- package/src/locales/errors.en.js +22 -0
- package/src/locales/errors.fr.js +22 -0
- package/src/locales/fr.js +152 -0
- package/src/locales/runtime.en.js +259 -0
- package/src/locales/runtime.fr.js +259 -0
- package/src/operations.js +276 -0
- package/src/redact.js +105 -0
- package/src/remote-path.js +101 -0
- package/src/scanner.js +103 -0
- package/src/setup.js +888 -0
- package/src/state/codec.mjs +103 -0
- package/src/state/index.mjs +1 -0
- package/src/state/io.mjs +173 -0
- package/src/state/records.mjs +60 -0
- package/src/state/store.mjs +360 -0
- package/src/state/writer.mjs +250 -0
- package/src/tool-registry.js +464 -0
- package/src/tools.js +1226 -0
- package/src/transfers.js +425 -0
- package/src/workflow/budget.mjs +83 -0
- package/src/workflow/events.mjs +199 -0
- package/src/workflow/model.mjs +179 -0
package/CHANGELOG.fr.md
ADDED
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
# Journal des modifications
|
|
2
|
+
|
|
3
|
+
[English](./CHANGELOG.md) | **Français**
|
|
4
|
+
|
|
5
|
+
Toutes les modifications notables de ce projet sont consignées dans ce fichier.
|
|
6
|
+
|
|
7
|
+
Le format s'inspire de [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/),
|
|
8
|
+
et le projet suit le [versionnement sémantique](https://semver.org/lang/fr/spec/v2.0.0.html).
|
|
9
|
+
|
|
10
|
+
## [0.3.1] - 2026-10-17
|
|
11
|
+
|
|
12
|
+
Cette version corrective se limite à la qualification de release et à
|
|
13
|
+
l'actualisation du verrouillage de la chaîne d'approvisionnement. Elle préserve
|
|
14
|
+
le tag v0.3.0 immuable et sa release de sources GitHub. La publication sur npm
|
|
15
|
+
et le registre MCP officiel reste en attente.
|
|
16
|
+
|
|
17
|
+
### Corrigé
|
|
18
|
+
|
|
19
|
+
- La qualification de release verrouille désormais la dépendance transitive
|
|
20
|
+
optionnelle `nan` en 2.29.0, avec son URL de registre et son intégrité revues,
|
|
21
|
+
conformément à la version résolue par une installation neuve. Aucun
|
|
22
|
+
comportement d'exécution ni aucune API publique ne change.
|
|
23
|
+
|
|
24
|
+
### Modifié
|
|
25
|
+
|
|
26
|
+
- Les métadonnées du paquet, du verrouillage, du serveur MCP et de la release
|
|
27
|
+
bilingue ciblent maintenant v0.3.1 de façon cohérente. L'historique complet
|
|
28
|
+
de v0.3.0 est conservé ci-dessous.
|
|
29
|
+
|
|
30
|
+
## [0.3.0] - 2026-10-17
|
|
31
|
+
|
|
32
|
+
Cette version mineure utilise le canal distinct des releases de sources
|
|
33
|
+
GitHub ; le tag et la release v0.2.0 publiés restent inchangés.
|
|
34
|
+
La publication sur npm et le registre MCP officiel reste en attente. Installez
|
|
35
|
+
depuis les sources ; aucune disponibilité npm, `npx` ou registre n'est annoncée.
|
|
36
|
+
|
|
37
|
+
### Ajouts
|
|
38
|
+
|
|
39
|
+
- Déploiement durable facultatif avec `stateDir` : `ftp_plan_deploy`,
|
|
40
|
+
`ftp_apply_deploy`, `ftp_deploy_status` et `ftp_rollback_deploy`. Le workflow
|
|
41
|
+
utilise la confirmation MCP officielle `input_required`, des journaux scellés,
|
|
42
|
+
des sauvegardes vérifiées et bornées, une reprise explicite et une
|
|
43
|
+
réconciliation prudente. Sa garantie est `observable_state_reconciled`, pas
|
|
44
|
+
l'atomicité multi-fichiers ni l'exécution exactement une fois.
|
|
45
|
+
- Le format d'état v2 protège la vie privée : hash de racine locale salé par
|
|
46
|
+
domaine et chemins sources relatifs stricts, jamais la racine absolue. Apply
|
|
47
|
+
revalide l'identité locale avant connexion ; rollback reste utilisable après
|
|
48
|
+
dérive de racine. L'état v1 exige une réinitialisation hors ligne.
|
|
49
|
+
|
|
50
|
+
### Corrections
|
|
51
|
+
|
|
52
|
+
- La préparation interne est à usage unique, plafonnée à 10 secondes sans
|
|
53
|
+
prolonger l'échéance globale et conserve l'admission jusqu'à la fin réelle
|
|
54
|
+
du travail et du nettoyage. Les contextes préparés sont libérés une fois,
|
|
55
|
+
même après une fin tardive suivant une annulation. Une préparation annulée ou
|
|
56
|
+
expirée n'appelle jamais le handler ; son callback peut lui-même agir.
|
|
57
|
+
Aucun outil MCP public n'est ajouté.
|
|
58
|
+
- La qualification de publication compare le manifeste attendu complet, le
|
|
59
|
+
verrouillage source de référence et les octets de toutes les sources livrées. Les
|
|
60
|
+
modificateurs de dépendances et hooks d'installation non autorisés sont
|
|
61
|
+
refusés avant l'installation du consommateur.
|
|
62
|
+
- L'inspection lit et calcule l'empreinte des octets compressés une fois,
|
|
63
|
+
décompresse gzip strictement avec une borne globale de sortie de 32 MiB,
|
|
64
|
+
rejette les octets non nuls après la limite gzip consommée et fournit le
|
|
65
|
+
même TAR décodé à chaque invocation de tar. Le remplissage NUL terminal est
|
|
66
|
+
admis ; les frontières des membres gzip/TAR ne peuvent pas masquer de
|
|
67
|
+
fichiers supplémentaires à la validation.
|
|
68
|
+
- Les workflows npm et MCP séparent une qualification sans OIDC ni secret de
|
|
69
|
+
la publication dans une copie fraîche épinglée à `github.sha`. npm transfère
|
|
70
|
+
l'identifiant exact de l'artefact déposé et les valeurs d'inventaire/intégrité
|
|
71
|
+
d'origine ; le job de publication vérifie ces liens avant de créer sa preuve
|
|
72
|
+
locale. Installation de dépendances, tests, smoke checks et `--runtime`
|
|
73
|
+
s'exécutent uniquement hors des jobs privilégiés de publication.
|
|
74
|
+
- L'analyse des métadonnées accepte les formes JSON tableau/objet de npm pack
|
|
75
|
+
prises en charge de façon cohérente en CI. Les dates du journal doivent
|
|
76
|
+
correspondre à des dates calendaires valides.
|
|
77
|
+
|
|
78
|
+
### Changements
|
|
79
|
+
|
|
80
|
+
- Le runtime MCP utilise désormais le SDK TypeScript modulaire stable v2.3.1 :
|
|
81
|
+
`@modelcontextprotocol/server` est la dépendance de production épinglée, tandis
|
|
82
|
+
que le client et le paquet core de protocole brut, eux aussi épinglés, restent
|
|
83
|
+
réservés au développement. L'entrée stdio utilise la factory `serveStdio`,
|
|
84
|
+
négocie la révision `2026-07-28` et conserve le chemin des anciens clients,
|
|
85
|
+
y compris la révision `2024-11-05`.
|
|
86
|
+
- Les cinq dépendances directes de production sont épinglées exactement ; le seul
|
|
87
|
+
`package-lock.json` conserve 35 entrées non racine revues (22 de production
|
|
88
|
+
et 13 de développement). Aucun shrinkwrap n'est livré.
|
|
89
|
+
- Le builder produit une archive d'installation source de 90 fichiers avec le
|
|
90
|
+
verrouillage, distincte du paquet npm de 89 fichiers sans verrouillage. Les
|
|
91
|
+
preuves lient explicitement la distribution, les sources et l'intégrité.
|
|
92
|
+
- L'installation source utilise `npm ci --omit=dev --ignore-scripts` ; celle des
|
|
93
|
+
contributeurs utilise `npm ci --ignore-scripts`. Les octets des archives peuvent
|
|
94
|
+
varier entre systèmes. Le graphe réellement installé est comparé à la référence
|
|
95
|
+
originale, dépendances transitives et peers compris, avant publication.
|
|
96
|
+
- npm reste non qualifié après dix dérives observées lors d'une vraie installation.
|
|
97
|
+
Le job MCP qualifie l'archive réellement téléchargée du registre, puis le job
|
|
98
|
+
privilégié exige son intégrité originale avant authentification.
|
|
99
|
+
|
|
100
|
+
- La documentation anglais/français d'installation et de publication distingue
|
|
101
|
+
les releases de sources GitHub de la disponibilité sur npm et le registre
|
|
102
|
+
MCP officiel.
|
|
103
|
+
|
|
104
|
+
Les tests scriptés ne sont pas un benchmark de LLM et cette version mineure ne revendique
|
|
105
|
+
aucune certification pour un usage en entreprise.
|
|
106
|
+
|
|
107
|
+
## [0.2.0] - 2026-09-09
|
|
108
|
+
|
|
109
|
+
Le tag et la release GitHub sont créés depuis ce commit. La publication sur npm
|
|
110
|
+
et sur le registre MCP reste en attente : `npx -y ftp-deploy-mcp` et
|
|
111
|
+
l’installation depuis un registre ne fonctionnent donc pas encore ; installez
|
|
112
|
+
depuis les sources. Les métadonnées du paquet et du serveur sont alignées sur
|
|
113
|
+
0.2.0. Toutes les modifications ci-dessous sont relatives à 0.1.0, la seule
|
|
114
|
+
version jamais publiée.
|
|
115
|
+
|
|
116
|
+
### Ajouts
|
|
117
|
+
|
|
118
|
+
- Ligne de commande bilingue. `--lang en` et `--lang fr` (ainsi que
|
|
119
|
+
`--lang=fr`) choisissent la langue des aides générale et par sous-commande,
|
|
120
|
+
des questions et choix de `setup`, des libellés des tests de connexion, des
|
|
121
|
+
diagnostics `doctor`, des avertissements d’`import-filezilla` et des messages
|
|
122
|
+
de démarrage du serveur. La nouvelle variable d’environnement `FTP_MCP_LANG`
|
|
123
|
+
fixe le même défaut, et l’option prime sur elle, y compris sur une valeur
|
|
124
|
+
d’environnement invalide. L’option est lue avant l’analyse de la
|
|
125
|
+
sous-commande et peut figurer avant ou après celle-ci. Seules les valeurs `en`
|
|
126
|
+
et `fr` sont acceptées ; une option invalide ou incomplète provoque une sortie
|
|
127
|
+
en échec avant que `setup` ou `import-filezilla` n’écrive quoi que ce soit.
|
|
128
|
+
Les variables régionales du système, comme `LANG`, ne sont jamais consultées.
|
|
129
|
+
Voir les [langues](./docs/LANGUAGES.fr.md).
|
|
130
|
+
- Contrats MCP localisés. Les titres des outils, leurs descriptions, les
|
|
131
|
+
descriptions des champs d’entrée, les textes de succès métier et les messages
|
|
132
|
+
d’erreur suivent la langue choisie. Les dix noms d’outils, les noms des champs
|
|
133
|
+
des résultats structurés et les codes d’erreur publics sont stables et ne sont
|
|
134
|
+
pas traduits, et aucun argument d’outil ne choisit de langue.
|
|
135
|
+
- `setup` inscrit `FTP_MCP_LANG` dans les entrées de clients MCP qu’il génère,
|
|
136
|
+
y compris `en`, afin qu’un serveur configuré conserve après redémarrage la
|
|
137
|
+
langue choisie lors de son `setup`. Le bloc Trae prêt à coller porte le même
|
|
138
|
+
réglage.
|
|
139
|
+
- Enveloppe d’erreur structurée sur chaque erreur d’outil. À côté du texte
|
|
140
|
+
`isError`, les résultats portent désormais `structuredContent.error` avec
|
|
141
|
+
`schema_version`, `code`, `message`, `retryable`, un UUID `request_id` propre
|
|
142
|
+
à l’appel, `next_action` et `effects`. Les erreurs d’envoi, de téléchargement
|
|
143
|
+
et de déploiement peuvent ajouter un bloc `partial` strict
|
|
144
|
+
(`completed_files`, `completed_bytes`, `failed_files`, `total_files`
|
|
145
|
+
facultatif et `final`). `request_id` n’est pas un identifiant d’opération
|
|
146
|
+
durable ; il n’existe ni journal, ni retour arrière, ni commande de
|
|
147
|
+
récupération. Cette version renvoie `retryable: false` pour toute erreur et ne
|
|
148
|
+
réessaie jamais une mutation incertaine. Voir le
|
|
149
|
+
[contrat d’erreur](./docs/ERROR-CONTRACT.fr.md).
|
|
150
|
+
- Six clés de configuration par serveur, chacune avec un défaut et un maximum
|
|
151
|
+
imposés. Les arguments des outils ne peuvent pas les remplacer, et les valeurs
|
|
152
|
+
doivent être des entiers positifs représentables exactement :
|
|
153
|
+
`operationTimeoutMs` (défaut 120000 ms, plage acceptée 100–3600000),
|
|
154
|
+
`maxTransferBytes` (défaut 268435456, maximum 1099511627776),
|
|
155
|
+
`maxDeployFiles` (défaut 10000, maximum 100000),
|
|
156
|
+
`maxDeployBytes` (défaut 1073741824, maximum 1099511627776),
|
|
157
|
+
`maxScanEntries` (défaut 100000, maximum 1000000) et
|
|
158
|
+
`maxScanDepth` (défaut 64, maximum 256). Ces valeurs par défaut s’appliquent
|
|
159
|
+
aux serveurs qui ne les définissent pas : un déploiement qui réussissait en
|
|
160
|
+
0.1.0 peut désormais être refusé par `TRANSFER_LIMIT` ou `SCAN_LIMIT` avant
|
|
161
|
+
même l’ouverture d’une connexion.
|
|
162
|
+
**RUPTURE — `operationTimeoutMs` introduit aussi une échéance que 0.1.0
|
|
163
|
+
n’avait pas :** tout appel d’outil s’interrompt désormais avec `TIMEOUT` après
|
|
164
|
+
120000 ms par défaut et, contrairement aux autres limites, elle se déclenche
|
|
165
|
+
en cours d’exécution au lieu de refuser d’emblée ; un `ftp_deploy` volumineux
|
|
166
|
+
ou lent qui allait au bout en 0.1.0 peut donc s’arrêter en cours de route,
|
|
167
|
+
avec des fichiers déjà promus et aucun retour arrière. Augmentez
|
|
168
|
+
`operationTimeoutMs` (jusqu’à 3600000) pour les liaisons lentes. Voir les
|
|
169
|
+
[transferts vérifiés](./docs/TRANSFERS.fr.md) et les
|
|
170
|
+
[limites de ressources](./docs/RESOURCE-BOUNDS.fr.md).
|
|
171
|
+
- Contrôle d’admission à l’échelle du processus. Un isolate Node admet au plus
|
|
172
|
+
64 appels d’outil simultanés ; le 65e renvoie le nouveau `CAPACITY_LIMIT`
|
|
173
|
+
avec `effects:none`, `retryable:false` et `next_action:retry`. C’est un
|
|
174
|
+
plafond de simultanéité, pas un quota de durée de vie : une place est libérée
|
|
175
|
+
quand son worker et son nettoyage se terminent réellement, y compris après une
|
|
176
|
+
annulation ou un dépassement de délai, et il n’existe ni file d’attente ni
|
|
177
|
+
reprise automatique. L’admission suit la validation du schéma et précède la
|
|
178
|
+
préparation.
|
|
179
|
+
- Annulation MCP et échéances par appel. Une notification
|
|
180
|
+
`notifications/cancelled` d’un pair interrompt l’opération et le SDK supprime
|
|
181
|
+
sa réponse : les clients ne doivent donc pas attendre la livraison d’une
|
|
182
|
+
enveloppe `CANCELLED` ; l’échéance interne, distincte, renvoie `TIMEOUT`.
|
|
183
|
+
L’annulation et l’expiration arrêtent les étapes suivantes et ferment le
|
|
184
|
+
transport, mais n’annulent pas les effets déjà acceptés par le serveur. Un
|
|
185
|
+
décorateur du transport public corrige la lacune d’annulation du SDK installé
|
|
186
|
+
pour l’identifiant de corrélation numérique `0` et la chaîne vide `""` ; les
|
|
187
|
+
autres identifiants, dont la chaîne `"0"`, conservent le comportement natif du
|
|
188
|
+
SDK.
|
|
189
|
+
- Mutations sérialisées. Les outils d’écriture prennent un verrou FIFO sur le
|
|
190
|
+
point d’accès distant (protocole, hôte, port, utilisateur) et `ftp_download`
|
|
191
|
+
en prend un sur la destination locale canonique : deux appels ne peuvent donc
|
|
192
|
+
pas entrelacer leurs écritures sur la même cible. Les verrous sont conservés
|
|
193
|
+
jusqu’à la fin effective du worker sous-jacent, et non jusqu’à l’envoi de la
|
|
194
|
+
réponse, et ils ne coordonnent qu’au sein d’un même processus Node.js.
|
|
195
|
+
- Périmètre `localRoot` par serveur pour `ftp_upload`, `ftp_deploy` et
|
|
196
|
+
`ftp_download`. La racine doit être absolue (`~` est étendu) ; les traversées
|
|
197
|
+
et les sorties locales par symlink ou jonction sont refusées.
|
|
198
|
+
- Épinglage de clé d’hôte SFTP via `hostKeySha256`, qui accepte une empreinte
|
|
199
|
+
SHA-256 ou un tableau non vide pour les rotations de clé contrôlées.
|
|
200
|
+
- Dérogation explicite `allowUnknownHostKey` pour les opérateurs qui acceptent
|
|
201
|
+
temporairement une identité de serveur SFTP non vérifiée.
|
|
202
|
+
- Dérogation explicite `allowUnsafeRemoteRoot` pour les opérateurs FTP/FTPS qui
|
|
203
|
+
acceptent le risque de symlink non résolu d’une sous-racine côté client.
|
|
204
|
+
- Schémas de sortie MCP et réponses structurées en cas de succès pour tous les
|
|
205
|
+
outils sauf `ftp_read`, volontairement textuel, ainsi que des annotations pour
|
|
206
|
+
les dix outils.
|
|
207
|
+
- Ensemble documentaire bilingue, chaque page en anglais et en français :
|
|
208
|
+
[modèle de sécurité](./docs/SECURITY-MODEL.fr.md),
|
|
209
|
+
[processus de publication](./docs/RELEASE.fr.md),
|
|
210
|
+
[contrat d’erreur](./docs/ERROR-CONTRACT.fr.md),
|
|
211
|
+
[langues](./docs/LANGUAGES.fr.md),
|
|
212
|
+
[transferts vérifiés](./docs/TRANSFERS.fr.md),
|
|
213
|
+
[limites de ressources](./docs/RESOURCE-BOUNDS.fr.md),
|
|
214
|
+
[stockage d’état](./docs/STATE-STORAGE.fr.md),
|
|
215
|
+
[modèle de workflow](./docs/WORKFLOW-MODEL.fr.md) et
|
|
216
|
+
[conformité MCP scriptée](./docs/SCRIPTED-EVALUATIONS.fr.md). `CONTRIBUTING`,
|
|
217
|
+
`SECURITY`, `LICENSE` et ce journal reçoivent une contrepartie française, aux
|
|
218
|
+
côtés de la paire `README` déjà livrée en 0.1.0 ; les deux langues du `README`
|
|
219
|
+
ont été réécrites pour cette version.
|
|
220
|
+
- Guide HTML interactif bilingue sous `site/`, généré depuis
|
|
221
|
+
`site/project-data.json` et `site/i18n.json` et vérifié en CI par
|
|
222
|
+
`scripts/build-guide.mjs --check`. Il n’existe que dans le dépôt et il est
|
|
223
|
+
exclu du paquet npm.
|
|
224
|
+
- Jeu de données externe reproductible pour l’évaluation d’agents en lecture
|
|
225
|
+
seule et jeu d’évaluation MCP de 10 questions, désormais en anglais
|
|
226
|
+
(`evaluations/read-only.xml`) et en français (`evaluations/read-only.fr.xml`),
|
|
227
|
+
ainsi qu’un exécuteur distinct de conformité scriptée couvrant 43 scénarios,
|
|
228
|
+
exécutés dans les deux langues contre le vrai client du SDK MCP et un
|
|
229
|
+
transport en mémoire (`npm run eval:scripted`). Cet exécuteur est un outillage
|
|
230
|
+
du dépôt, n’est pas un benchmark de LLM et est exclu du paquet npm. Voir la
|
|
231
|
+
[conformité MCP scriptée](./docs/SCRIPTED-EVALUATIONS.fr.md).
|
|
232
|
+
- Bibliothèques internes inertes `src/state/` et `src/workflow/`. Elles sont
|
|
233
|
+
livrées dans le paquet parce qu’il publie `src`, mais elles n’exposent aucun
|
|
234
|
+
outil MCP, ne lisent aucune configuration, ne créent aucun répertoire d’état
|
|
235
|
+
et ne sont pas importées par le serveur en fonctionnement. Elles ne livrent
|
|
236
|
+
dans cette version ni workflow de déploiement, ni retour arrière, ni
|
|
237
|
+
récupération ; le [stockage d’état](./docs/STATE-STORAGE.fr.md) comme le
|
|
238
|
+
[modèle de workflow](./docs/WORKFLOW-MODEL.fr.md) l’indiquent explicitement.
|
|
239
|
+
- Scripts npm destinés aux contributeurs : `test:transports`, `test:contract`,
|
|
240
|
+
`test:bounds`, `test:state`, `test:workflow`, `test:eval-runner` et
|
|
241
|
+
`eval:scripted`. La CI exécute en plus `scripts/check-docs.mjs` pour la
|
|
242
|
+
documentation bilingue et `test/release-gates.js`.
|
|
243
|
+
- Métadonnées de registre MCP `server.json`, qui déclarent les variables
|
|
244
|
+
d’environnement `FTP_MCP_CONFIG` et `FTP_MCP_LANG` ainsi qu’un transport
|
|
245
|
+
stdio.
|
|
246
|
+
- `Dockerfile` et `.dockerignore` dans le dépôt, construisant une image
|
|
247
|
+
`node:24-alpine` dont le point d’entrée est le serveur stdio ; montez un
|
|
248
|
+
fichier de configuration et faites-y pointer `FTP_MCP_CONFIG`. Aucune image
|
|
249
|
+
n’est publiée, et aucun de ces deux fichiers n’est inclus dans le paquet npm.
|
|
250
|
+
|
|
251
|
+
### Changements
|
|
252
|
+
|
|
253
|
+
- **RUPTURE — Node.js 18, 19, 20 et 21 ne sont plus pris en charge.**
|
|
254
|
+
`engines.node` passe de `>=18` à `>=22`. La CI qualifie Node 22 et 24 sur
|
|
255
|
+
Linux, Windows et macOS.
|
|
256
|
+
- **RUPTURE — un sélecteur de configuration explicite échoue désormais de façon
|
|
257
|
+
fermée.** Lorsque `--config <chemin>` ou `FTP_MCP_CONFIG` est présent, ce
|
|
258
|
+
chemin unique fait autorité : il doit exister, être un fichier ordinaire et se
|
|
259
|
+
charger correctement, et aucun autre candidat n’est essayé. `--config` prime
|
|
260
|
+
sur `FTP_MCP_CONFIG`, et une valeur explicite vide est rejetée. Ce n’est qu’en
|
|
261
|
+
l’absence des deux que la découverte essaie encore `./ftp-servers.json` puis
|
|
262
|
+
`~/.ftp-mcp/servers.json`. En 0.1.0, ces deux sélecteurs n’étaient que les
|
|
263
|
+
premières entrées d’une liste de repli : un chemin explicite absent ou
|
|
264
|
+
illisible retombait silencieusement sur un autre fichier. Le serveur démarre
|
|
265
|
+
toujours ; chaque outil qui a besoin du fichier de configuration échoue
|
|
266
|
+
désormais avec `CONFIG_INVALID` au lieu de travailler sur une configuration
|
|
267
|
+
non voulue, et `ftp_list_servers` renvoie `status: "invalid"` accompagné du
|
|
268
|
+
diagnostic du chargeur.
|
|
269
|
+
- Une entrée de serveur rejetée ne désactive plus tout le fichier de
|
|
270
|
+
configuration. Les entrées sont validées individuellement : les serveurs
|
|
271
|
+
valides restent utilisables, et chaque entrée invalide est signalée par son
|
|
272
|
+
nom et son motif via `ftp_list_servers` (`status`, `valid_count`,
|
|
273
|
+
`invalid_count` et une liste `errors` bornée). Nommer une entrée rejetée
|
|
274
|
+
renvoie le `CONFIG_INVALID` de cette entrée, un nom inconnu renvoie
|
|
275
|
+
`SERVER_UNKNOWN`, et omettre `server` avec plusieurs candidats valides et sans
|
|
276
|
+
`defaultServer` renvoie `SERVER_REQUIRED`. En 0.1.0, la première entrée
|
|
277
|
+
invalide rendait tout le fichier inutilisable et chaque appel d’outil
|
|
278
|
+
échouait. Les problèmes d’enveloppe — objet `servers` absent ou vide,
|
|
279
|
+
`defaultServer` inconnu, `${ENV:VAR}` non défini — rejettent toujours tout le
|
|
280
|
+
fichier, tout comme un fichier dont chaque entrée est invalide.
|
|
281
|
+
- **RUPTURE — `localRoot` est désormais obligatoire** pour `ftp_upload`,
|
|
282
|
+
`ftp_deploy` et `ftp_download`, **et les chemins d’outil relatifs se résolvent
|
|
283
|
+
désormais par rapport à lui, et non par rapport au répertoire de travail du
|
|
284
|
+
processus serveur.** Une entrée de serveur sans `localRoot` absolu refuse ces
|
|
285
|
+
trois outils avec `CONFIG_INVALID`. En 0.1.0, `local_path` et `local_dir` se
|
|
286
|
+
résolvaient par rapport à `process.cwd()` : un appel inchangé comme
|
|
287
|
+
`ftp_deploy {"local_dir":"dist"}` lit désormais `<localRoot>/dist` au lieu de
|
|
288
|
+
`<cwd>/dist` — il peut silencieusement sélectionner un autre dossier, ou
|
|
289
|
+
échouer avec `NOT_FOUND` ou `PATH_REJECTED` lorsque l’ancienne cible se trouve
|
|
290
|
+
hors de la racine. Les chemins absolus conservent leur sens et doivent
|
|
291
|
+
toujours se résoudre à l’intérieur de `localRoot`. `ftp_list_servers` indique
|
|
292
|
+
l’état du `localRoot` de chaque serveur.
|
|
293
|
+
- Les erreurs d’outil ne sont plus seulement textuelles. Chaque résultat
|
|
294
|
+
d’erreur porte désormais l’enveloppe `{error}` structurée décrite plus haut,
|
|
295
|
+
et les neuf outils dotés d’un schéma de sortie publient un `oneOf` JSON Schema
|
|
296
|
+
draft-07 entre leur objet de succès et cette enveloppe. `ftp_read` conserve un
|
|
297
|
+
succès textuel sans schéma de sortie ; ses erreurs utilisent la même enveloppe
|
|
298
|
+
validée en interne. Les réponses textuelles existantes restent disponibles à
|
|
299
|
+
côté des réponses structurées en cas de succès, et `ftp_deploy` fournit
|
|
300
|
+
toujours des échantillons bornés plutôt que des listes exhaustives de
|
|
301
|
+
fichiers.
|
|
302
|
+
- `ftp_upload`, `ftp_deploy` et `ftp_download` vérifient désormais chaque
|
|
303
|
+
fichier avant de le promouvoir. Les envois calculent le SHA256 de la source
|
|
304
|
+
locale, écrivent dans un fichier voisin imprévisible nommé
|
|
305
|
+
`.ftp-mcp-<aléatoire>.tmp`, relisent ce temporaire, comparent le nombre
|
|
306
|
+
d’octets et l’empreinte, puis promeuvent par un unique renommage. En cas
|
|
307
|
+
d’échec, le serveur ne supprime jamais la destination finale pour faire
|
|
308
|
+
réussir la promotion et ne revient jamais à un écrasement direct ; il ne
|
|
309
|
+
supprime que son propre temporaire, et un échec du nettoyage ajoute un
|
|
310
|
+
avertissement borné indiquant qu’un temporaire peut subsister. Les
|
|
311
|
+
téléchargements lisent d’abord une attente SHA256 distante bornée, puis
|
|
312
|
+
promeuvent par lien physique dans le même dossier avec `overwrite:false`
|
|
313
|
+
(valeur par défaut) ou par renommage avec `overwrite:true`. Le motif de nom
|
|
314
|
+
`.ftp-mcp-*.tmp` est réservé et toujours exclu de `ftp_deploy`, même lorsqu’un
|
|
315
|
+
motif `include` explicite le sélectionne. Cela ajoute du trafic réseau et de
|
|
316
|
+
la latence, ne rend pas atomique un déploiement de plusieurs fichiers et ne
|
|
317
|
+
promet pas un remplacement atomique universel : le comportement du renommage
|
|
318
|
+
FTP et SFTP dépend du serveur et de son système de fichiers. En SFTP, le
|
|
319
|
+
serveur enregistre le mode attribué au temporaire, le restreint à 0600 pendant
|
|
320
|
+
l’écriture puis, avant la promotion, restaure les bits de permission de la
|
|
321
|
+
destination existante (masque 0777) ou ce mode de création enregistré pour un
|
|
322
|
+
fichier neuf ; un échec d’un `stat` ou d’un `chmod` requis empêche la
|
|
323
|
+
promotion. FTP/FTPS ne dispose ici d’aucun mécanisme portable de préservation
|
|
324
|
+
des permissions : remplacer un fichier distant existant peut donc
|
|
325
|
+
réinitialiser ses permissions aux valeurs de création du serveur. Localement,
|
|
326
|
+
`ftp_download` copie les bits 0777 d’une destination existante sur son
|
|
327
|
+
temporaire, mais un **nouveau** fichier local est désormais créé avec le mode
|
|
328
|
+
0600 au lieu du défaut issu de l’umask du processus en 0.1.0, et la promotion
|
|
329
|
+
avec `overwrite:false` par défaut exige la prise en charge des liens physiques
|
|
330
|
+
dans le dossier de destination et échoue de façon fermée sans elle. Voir les
|
|
331
|
+
[transferts vérifiés](./docs/TRANSFERS.fr.md).
|
|
332
|
+
- La sélection d’un déploiement est désormais bornée et asynchrone.
|
|
333
|
+
`maxScanEntries` et `maxScanDepth` plafonnent les entrées visitées et la
|
|
334
|
+
profondeur des dossiers ; dépasser l’une ou l’autre refuse toute la sélection
|
|
335
|
+
avec `SCAN_LIMIT` (`effects:none`, `retryable:false`, `next_action:fix_input`)
|
|
336
|
+
avant toute connexion distante, en simulation comme en déploiement réel. Voir
|
|
337
|
+
les [limites de ressources](./docs/RESOURCE-BOUNDS.fr.md).
|
|
338
|
+
- **La sélection d’un déploiement peut désormais inclure des fichiers qu’elle
|
|
339
|
+
omettait auparavant.** Seuls les noms de dossiers intégrés `node_modules`,
|
|
340
|
+
`.git` et `.ftp-mcp` élaguent le parcours. Les motifs `exclude` personnalisés
|
|
341
|
+
et les motifs `include` n’élaguent plus les dossiers ; ils conservent leurs
|
|
342
|
+
règles de correspondance existantes, fichier par fichier. Cela supprime un
|
|
343
|
+
ancien faux positif de test par sentinelle de dossier où, par exemple,
|
|
344
|
+
`exclude: ["**/__ftp_deploy_probe__"]` masquait aussi `docs/wanted.txt`.
|
|
345
|
+
Examinez une simulation après la mise à niveau si vous dépendez de motifs
|
|
346
|
+
d’exclusion.
|
|
347
|
+
- **RUPTURE — le FTP en clair, et le FTPS avec `insecureTLS: true`, sont
|
|
348
|
+
désormais refusés.** 0.1.0 n’avait aucun garde-fou de transport non sécurisé
|
|
349
|
+
et se connectait aux deux sans objection. 0.2.0 lève `TRANSPORT_POLICY` avant
|
|
350
|
+
toute entrée-sortie réseau, sauf si l’entrée de serveur définit
|
|
351
|
+
`allowInsecure: true` : chaque entrée `"protocol": "ftp"` de 0.1.0 — le
|
|
352
|
+
protocole par défaut, celui qui donne son nom à ce paquet — cesse donc de se
|
|
353
|
+
connecter tant que ce drapeau n’est pas ajouté.
|
|
354
|
+
- **RUPTURE — les connexions SFTP sans `hostKeySha256` sont refusées** avant
|
|
355
|
+
l’authentification, avec `HOST_KEY_REJECTED`, sauf configuration explicite de
|
|
356
|
+
`allowUnknownHostKey: true`. 0.1.0 n’effectuait aucune vérification de clé
|
|
357
|
+
d’hôte et ne possédait pas ce champ : chaque entrée de serveur SFTP existante
|
|
358
|
+
cesse donc de se connecter tant que l’une des deux clés n’est pas ajoutée.
|
|
359
|
+
- **RUPTURE — les connexions FTP/FTPS dont `root` n’est pas `/` sont refusées**
|
|
360
|
+
sauf configuration explicite de `allowUnsafeRemoteRoot: true` ;
|
|
361
|
+
`REMOTE_ROOT_REJECTED` est levé avant toute entrée-sortie réseau. 0.1.0
|
|
362
|
+
acceptait n’importe quel `root` et son propre README recommandait exactement
|
|
363
|
+
ce motif (`"root": "/var/www/site"`) : ces entrées cessent donc de se
|
|
364
|
+
connecter tant que le drapeau n’est pas ajouté. Le périmètre recommandé repose
|
|
365
|
+
désormais sur un compte dédié, chrooté côté serveur, avec `root: "/"`.
|
|
366
|
+
- `ftp_deploy` renvoie une erreur MCP dès qu’un transfert échoue et inclut un
|
|
367
|
+
résumé du déploiement partiel, désormais aussi sous forme de compteurs
|
|
368
|
+
`partial` structurés. Les transferts déjà réussis ne sont pas annulés.
|
|
369
|
+
- `ftp_list` ne renvoie plus toutes les entrées d’un dossier par défaut. Il
|
|
370
|
+
renvoie les 50 premières avec les métadonnées de pagination ; l’appelant peut
|
|
371
|
+
choisir un décalage et une taille de page comprise entre 1 et 200.
|
|
372
|
+
- Les résultats d’outil sont bornés à 25000 octets de `JSON.stringify` UTF-8,
|
|
373
|
+
couvrant le texte comme les données structurées après masquage. Un résultat
|
|
374
|
+
trop volumineux réduit d’abord ses échantillons bornés et reconstruit la
|
|
375
|
+
pagination, puis tronque le plus grand corps de texte avec un marqueur
|
|
376
|
+
`… [output truncated]`, et ne se rabat sur `OUTPUT_LIMIT` que si plus rien ne
|
|
377
|
+
peut être réduit — tout en préservant l’UUID de requête, les effets et les
|
|
378
|
+
compteurs partiels observés. Ce plafond est inférieur à la fenêtre `max_bytes`
|
|
379
|
+
inchangée de `ftp_read` (262144 par défaut, maximum absolu 1048576) : une
|
|
380
|
+
lecture qui renvoyait 256 Kio de contenu en 0.1.0 en renvoie désormais environ
|
|
381
|
+
25 Kio, marqués comme tronqués, dans un résultat réussi.
|
|
382
|
+
- Les indicateurs booléens de sécurité et les formats d’empreinte SFTP sont
|
|
383
|
+
validés pour chaque serveur.
|
|
384
|
+
- `setup` affiche les acceptations actives de transport non sécurisé ; `doctor`
|
|
385
|
+
affiche les acceptations actives de transport non sécurisé, de clé d’hôte
|
|
386
|
+
inconnue et de racine distante non sûre.
|
|
387
|
+
- La documentation distingue désormais l’installation fonctionnelle depuis les
|
|
388
|
+
sources des futures installations via `npx` et le registre MCP.
|
|
389
|
+
- Le paquet publié livre désormais aussi `docs/`, `evaluations/`, `server.json`,
|
|
390
|
+
`CONTRIBUTING.md`, `CONTRIBUTING.fr.md`, `SECURITY.md`, `SECURITY.fr.md`,
|
|
391
|
+
`CHANGELOG.fr.md` et `LICENSE.fr.md`. Les descriptions du paquet et de
|
|
392
|
+
`server.json` sont désormais bilingues et décrivent le confinement local et la
|
|
393
|
+
promotion vérifiée.
|
|
394
|
+
- Nouvelle dépendance d’exécution `zod-to-json-schema`, utilisée pour publier
|
|
395
|
+
les schémas JSON d’entrée et de sortie des outils.
|
|
396
|
+
- Le serveur FTP de test local utilise désormais la dépendance de développement
|
|
397
|
+
`@electerm/ftp-srv`.
|
|
398
|
+
|
|
399
|
+
### Retraits
|
|
400
|
+
|
|
401
|
+
- `assets/banner.svg`, `assets/banner.png`, `assets/demo.svg` et
|
|
402
|
+
`assets/diagram.svg`. Les bannières du README sont désormais
|
|
403
|
+
`assets/banner-en.png` et `assets/banner-fr.png`, avec leurs prompts de
|
|
404
|
+
génération et leur provenance consignés sous `assets/provenance/`.
|
|
405
|
+
- La dépendance de développement `ftp-srv`, remplacée comme indiqué ci-dessus.
|
|
406
|
+
|
|
407
|
+
### Corrections
|
|
408
|
+
|
|
409
|
+
- La saisie manuelle interactive d’un serveur dans `setup` n’écrit plus le
|
|
410
|
+
résultat de l’assistant via une propriété absente.
|
|
411
|
+
- Les variantes de casse des noms de protocole ne permettent plus de contourner
|
|
412
|
+
les contrôles de transport non sécurisé sur les chemins de `setup` et de
|
|
413
|
+
diagnostic.
|
|
414
|
+
- Les erreurs d’outil conservent les avertissements de sécurité applicables,
|
|
415
|
+
notamment lorsqu’une connexion non sécurisée a pu exposer les identifiants
|
|
416
|
+
avant l’échec.
|
|
417
|
+
|
|
418
|
+
### Sécurité
|
|
419
|
+
|
|
420
|
+
- Les transports non sécurisés sont refusés par défaut ; voir l’entrée
|
|
421
|
+
**RUPTURE** de la section *Changements* pour le nouveau garde-fou
|
|
422
|
+
`allowInsecure` et son impact à la mise à niveau. Des avertissements
|
|
423
|
+
accompagnent la découverte, les diagnostics, les succès et les échecs
|
|
424
|
+
impliquant un transport non sécurisé accepté.
|
|
425
|
+
- SFTP résout la racine distante configurée et utilise les contrôles
|
|
426
|
+
`realpath`/`lstat` pour refuser les composants symboliques et les chemins
|
|
427
|
+
résolus hors de cette racine. Un serveur malveillant peut encore créer une
|
|
428
|
+
course entre le contrôle et l’usage de cet état. Une connexion SFTP épingle
|
|
429
|
+
aussi sa racine canonique initiale ; un changement de racine constaté renvoie
|
|
430
|
+
`TARGET_CHANGED` et refuse de rebaser un temporaire lui appartenant.
|
|
431
|
+
- FTP/FTPS ne présentent plus la normalisation lexicale des chemins comme un
|
|
432
|
+
jail anti-symlink fiable ; l’isolation du compte côté serveur constitue la
|
|
433
|
+
véritable frontière.
|
|
434
|
+
- Les sources locales et les destinations de téléchargement sont confinées sous
|
|
435
|
+
`localRoot`.
|
|
436
|
+
- Un `setup` non interactif échoue de façon fermée : il signale les transports
|
|
437
|
+
non sécurisés mais n’accorde jamais automatiquement de dérogation
|
|
438
|
+
`allowInsecure`.
|
|
439
|
+
- La confidentialité des erreurs est imposée à la frontière des résultats. Les
|
|
440
|
+
objets d’erreur, leurs causes, les piles d’appels, les identifiants et les
|
|
441
|
+
arguments bruts ne sont jamais sérialisés ; les secrets sont masqués dans le
|
|
442
|
+
texte libre ; les identifiants de configuration sont collectés avant
|
|
443
|
+
validation, y compris les valeurs des entrées rejetées et les substitutions
|
|
444
|
+
`${ENV:VAR}` résolues, afin que les diagnostics du chargeur utilisent le même
|
|
445
|
+
masque. Un JSON de configuration mal formé produit un diagnostic de syntaxe
|
|
446
|
+
générique, sans extrait de l’analyseur, et les blocs FileZilla rejetés sont
|
|
447
|
+
identifiés par leur indice numérique, sans reprendre des noms ou des champs de
|
|
448
|
+
protocole non fiables. Des chaînes distantes comme `Page:` et
|
|
449
|
+
`SECURITY WARNING` ne peuvent pas usurper le rendu des avis de confiance.
|
|
450
|
+
- Le fichier de verrouillage versionné résout la dépendance transitive `hono` du
|
|
451
|
+
SDK MCP vers la version corrigée 4.13.5.
|
|
452
|
+
|
|
453
|
+
## [0.1.0] - 2026-07-20
|
|
454
|
+
|
|
455
|
+
### Ajouts
|
|
456
|
+
|
|
457
|
+
- Dix outils MCP : `ftp_list_servers`, `ftp_test`, `ftp_list`, `ftp_read`,
|
|
458
|
+
`ftp_upload`, `ftp_deploy`, `ftp_download`, `ftp_mkdir`, `ftp_rename` et
|
|
459
|
+
`ftp_delete`.
|
|
460
|
+
- Configuration de plusieurs serveurs FTP, FTPS et SFTP.
|
|
461
|
+
- Déploiement récursif de dossiers avec exclusions de type gitignore et simulation.
|
|
462
|
+
- Normalisation de la racine distante `root` et mode `readOnly` par serveur.
|
|
463
|
+
- Variables `${ENV:VAR}` pour les secrets de configuration.
|
|
464
|
+
- Import FileZilla, y compris les sites FTPS implicites.
|
|
465
|
+
- Assistant de configuration avec sauvegardes des configurations des clients MCP.
|
|
466
|
+
- Diagnostic `doctor` en lecture seule et scripts d'installation depuis les sources.
|
|
467
|
+
- Documentation en anglais et en français.
|
|
468
|
+
- Tests de bout en bout contre des serveurs FTP et SFTP locaux.
|