@aimarket/warden 0.21.0 → 0.22.0

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.
Files changed (126) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README-es.md +8 -7
  3. package/README-fr.md +8 -7
  4. package/README-ru.md +8 -7
  5. package/README-zh.md +8 -7
  6. package/README.md +8 -7
  7. package/dist/annotation-review.d.ts +10 -0
  8. package/dist/annotation-review.d.ts.map +1 -0
  9. package/dist/annotation-review.js +36 -0
  10. package/dist/annotation-review.js.map +1 -0
  11. package/dist/flow-guard-answer.d.ts +29 -0
  12. package/dist/flow-guard-answer.d.ts.map +1 -0
  13. package/dist/flow-guard-answer.js +201 -0
  14. package/dist/flow-guard-answer.js.map +1 -0
  15. package/dist/flow-guard-classify.d.ts +14 -0
  16. package/dist/flow-guard-classify.d.ts.map +1 -0
  17. package/dist/flow-guard-classify.js +224 -0
  18. package/dist/flow-guard-classify.js.map +1 -0
  19. package/dist/flow-guard-decode.d.ts +17 -0
  20. package/dist/flow-guard-decode.d.ts.map +1 -0
  21. package/dist/flow-guard-decode.js +149 -0
  22. package/dist/flow-guard-decode.js.map +1 -0
  23. package/dist/flow-guard-destinations.d.ts +23 -0
  24. package/dist/flow-guard-destinations.d.ts.map +1 -0
  25. package/dist/flow-guard-destinations.js +158 -0
  26. package/dist/flow-guard-destinations.js.map +1 -0
  27. package/dist/flow-guard-fingerprints.d.ts +27 -0
  28. package/dist/flow-guard-fingerprints.d.ts.map +1 -0
  29. package/dist/flow-guard-fingerprints.js +164 -0
  30. package/dist/flow-guard-fingerprints.js.map +1 -0
  31. package/dist/flow-guard-fragments.d.ts +17 -0
  32. package/dist/flow-guard-fragments.d.ts.map +1 -0
  33. package/dist/flow-guard-fragments.js +122 -0
  34. package/dist/flow-guard-fragments.js.map +1 -0
  35. package/dist/flow-guard-instructions.d.ts +12 -0
  36. package/dist/flow-guard-instructions.d.ts.map +1 -0
  37. package/dist/flow-guard-instructions.js +36 -0
  38. package/dist/flow-guard-instructions.js.map +1 -0
  39. package/dist/flow-guard-labels.d.ts +10 -0
  40. package/dist/flow-guard-labels.d.ts.map +1 -0
  41. package/dist/flow-guard-labels.js +55 -0
  42. package/dist/flow-guard-labels.js.map +1 -0
  43. package/dist/flow-guard-leak.d.ts +29 -0
  44. package/dist/flow-guard-leak.d.ts.map +1 -0
  45. package/dist/flow-guard-leak.js +135 -0
  46. package/dist/flow-guard-leak.js.map +1 -0
  47. package/dist/flow-guard-paths.d.ts +21 -0
  48. package/dist/flow-guard-paths.d.ts.map +1 -0
  49. package/dist/flow-guard-paths.js +72 -0
  50. package/dist/flow-guard-paths.js.map +1 -0
  51. package/dist/flow-guard-policy.d.ts +15 -0
  52. package/dist/flow-guard-policy.d.ts.map +1 -0
  53. package/dist/flow-guard-policy.js +179 -0
  54. package/dist/flow-guard-policy.js.map +1 -0
  55. package/dist/flow-guard-post.d.ts +6 -0
  56. package/dist/flow-guard-post.d.ts.map +1 -0
  57. package/dist/flow-guard-post.js +131 -0
  58. package/dist/flow-guard-post.js.map +1 -0
  59. package/dist/flow-guard-pre.d.ts +13 -0
  60. package/dist/flow-guard-pre.d.ts.map +1 -0
  61. package/dist/flow-guard-pre.js +335 -0
  62. package/dist/flow-guard-pre.js.map +1 -0
  63. package/dist/flow-guard-screen.d.ts +85 -0
  64. package/dist/flow-guard-screen.d.ts.map +1 -0
  65. package/dist/flow-guard-screen.js +558 -0
  66. package/dist/flow-guard-screen.js.map +1 -0
  67. package/dist/flow-guard-state.d.ts +12 -0
  68. package/dist/flow-guard-state.d.ts.map +1 -0
  69. package/dist/flow-guard-state.js +121 -0
  70. package/dist/flow-guard-state.js.map +1 -0
  71. package/dist/flow-guard-text.d.ts +9 -0
  72. package/dist/flow-guard-text.d.ts.map +1 -0
  73. package/dist/flow-guard-text.js +46 -0
  74. package/dist/flow-guard-text.js.map +1 -0
  75. package/dist/flow-guard-types.d.ts +154 -0
  76. package/dist/flow-guard-types.d.ts.map +1 -0
  77. package/dist/flow-guard-types.js +2 -0
  78. package/dist/flow-guard-types.js.map +1 -0
  79. package/dist/flow-guard.d.ts +20 -394
  80. package/dist/flow-guard.d.ts.map +1 -1
  81. package/dist/flow-guard.js +26 -2522
  82. package/dist/flow-guard.js.map +1 -1
  83. package/dist/mcp-client.d.ts +1 -2
  84. package/dist/mcp-client.d.ts.map +1 -1
  85. package/dist/mcp-client.js +2 -19
  86. package/dist/mcp-client.js.map +1 -1
  87. package/dist/public-address.d.ts +3 -0
  88. package/dist/public-address.d.ts.map +1 -0
  89. package/dist/public-address.js +58 -0
  90. package/dist/public-address.js.map +1 -0
  91. package/dist/review-diff.d.ts +3 -3
  92. package/dist/review-diff.d.ts.map +1 -1
  93. package/dist/review-diff.js +3 -5
  94. package/dist/review-diff.js.map +1 -1
  95. package/dist/wrap-cli.d.ts.map +1 -1
  96. package/dist/wrap-cli.js +2 -1
  97. package/dist/wrap-cli.js.map +1 -1
  98. package/dist/wrap-state.d.ts +3 -1
  99. package/dist/wrap-state.d.ts.map +1 -1
  100. package/dist/wrap-state.js +18 -3
  101. package/dist/wrap-state.js.map +1 -1
  102. package/dist/wrap.d.ts.map +1 -1
  103. package/dist/wrap.js +45 -7
  104. package/dist/wrap.js.map +1 -1
  105. package/docs/flow-guard-model-comparison-2026-10-25.es.md +82 -0
  106. package/docs/flow-guard-model-comparison-2026-10-25.fr.md +82 -0
  107. package/docs/flow-guard-model-comparison-2026-10-25.md +82 -0
  108. package/docs/flow-guard-model-comparison-2026-10-25.ru.md +82 -0
  109. package/docs/flow-guard-model-comparison-2026-10-25.zh.md +82 -0
  110. package/docs/flow-guard.es.md +34 -4
  111. package/docs/flow-guard.fr.md +34 -4
  112. package/docs/flow-guard.md +41 -4
  113. package/docs/flow-guard.ru.md +40 -4
  114. package/docs/flow-guard.zh.md +34 -4
  115. package/docs/scan-limits.es.md +39 -0
  116. package/docs/scan-limits.fr.md +39 -0
  117. package/docs/scan-limits.md +39 -0
  118. package/docs/scan-limits.ru.md +39 -0
  119. package/docs/scan-limits.zh.md +39 -0
  120. package/docs/scan.es.md +2 -0
  121. package/docs/scan.fr.md +2 -0
  122. package/docs/scan.md +2 -0
  123. package/docs/scan.ru.md +2 -0
  124. package/docs/scan.zh.md +2 -0
  125. package/native/macos/Sources/WardenDesktop/NativeSurface.swift +1 -1
  126. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.22.0 — 2026-10-25
4
+
5
+ Ships the local source recorded below. npm `0.21.0` did not include it. The entries below describe changes since 0.21.0.
6
+
7
+ - Add opt-in `annotationReview: "first-use"` for unverified MCP tool annotations. Server hints remain untrusted and never authorize effects or payments; the default remains off.
8
+ - Distinguish a requested package version from the version reported by a server when reviewing launch changes.
9
+ - Include the credential-window and flow-guard module changes recorded below.
10
+ - Add a repository-only selection evaluator with admissible choice sets, matched baseline comparisons and separate selection/mention metrics. The tie experiment does not establish reliable added guard benefit; no new runtime selection-blocking behavior is claimed. The evaluator is outside the npm package file list.
11
+ - Expand bounded source instruction signals for role/authority spoofing and add source-warning and Stop-trigger diagnostics. Keep semantic compliance unassessed and the existing overlap/continuation contract; saved-answer hook replay cannot establish changed model behavior. Local candidate only, not published by this change.
12
+ - Keep Post/Stop warnings free of raw tool/source metadata and detected-text quotes. Use stable opaque source IDs for correlation only; add hostile identifier/URL regressions and update source-identification tests. This is warning-channel custody, not semantic prevention.
13
+ - Record a fresh 720-answer, five-profile model comparison on Linux: injected target choices 48/48 unguarded, 44/48 and 46/48 published, 27/48 in both local candidate profiles; keep different clean baselines and six-cluster intervals visible. Twelve actual Stop continuations change no selected IDs. All 30 genuine-user controls pass; admissible IDs do not prove factual explanations. No independent holdout, native-client or broad security claim; no npm publication. Evidence: `docs/evidence/launchgate-live-comparison-2026-10-25/` in the monorepo.
14
+
15
+ ## Local source — credential-window measurement and prefix indexing, 2026-10-25
16
+
17
+ - Retain non-hex/hex strong windows at 8/10 after Linux hook comparisons at 6/7/8. Recognized normalized provider prefixes no longer cause alphabetic payload before the first digit to be skipped. Preserve generic/DER starts, every previous fingerprint and the existing storage format; existing sessions need a credential reread to gain new windows.
18
+ - Add a reproducible threshold sweep with two synthetic seeds, corpus manifests, whole-call decisions and deliberately selected collision controls. At unchanged 8/10, 717 of 14,400 attack fixtures change from ask to deny; all attacks already required ask or deny. Decisions on 7,680 benign requests per profile remain unchanged. A broader generic-prefix candidate was rejected for a false hard denial. These are fixture results, not a production false-positive estimate. [Study and evidence](../docs/growth/warden-thresholds-2026-10-25.ru.md). Local only, unreleased.
19
+
20
+ ## Local source — flow guard split into modules, 2026-10-24
21
+
22
+ - `src/flow-guard.ts` (2,286 lines) is now the public API and the hook entry point. The code moved unchanged into `src/flow-guard-*.ts`: types, paths, policy, text, classify, screen, destinations, fingerprints, decode, fragments, leak, state, pre, post, answer and labels. Exports and behaviour are the same: the existing tests pass unchanged, and the code-aware red team writes the same report as before (0 of 28 delivered).
23
+ - The Claude Code plugin carries `scripts/flow-guard.mjs` and its `flow-guard-*.mjs` parts. `npm run build` writes them; a test checks every copy against its compiled file and refuses any import other than node: built-ins and the guard's own parts. The parts sit in `dist/` beside the other modules, so the MOMUS release gate's build digest (`dist/*.js`) still covers the whole guard. Replaying another build with `WARDEN_FLOW_GUARD` needs the parts in the same folder.
24
+
3
25
  ## 0.21.0 — 2026-10-24
4
26
 
5
27
  Ships the local source recorded below. npm `0.20.0` did not include it.
package/README-es.md CHANGED
@@ -8,7 +8,7 @@
8
8
  <a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
9
9
  <a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="npm version" /></a>
10
10
  <img src="docs/badges/deps.svg" alt="Cero dependencias de ejecución" />
11
- <img src="docs/badges/tests.svg" alt="1148 pruebas en verde" />
11
+ <img src="docs/badges/tests.svg" alt="1256 pruebas en verde" />
12
12
  <img src="docs/badges/node.svg" alt="Node >= 20" />
13
13
  <a href="LICENSE"><img src="docs/badges/license.svg" alt="Licencia: MIT" /></a>
14
14
  </p>
@@ -29,7 +29,7 @@
29
29
  **Revisa todos los servidores MCP de tu máquina.** Sin cuenta, sin clave de API, sin modelo. El único tráfico de red va a los servidores de tu configuración.
30
30
 
31
31
  ```bash
32
- npx -y @aimarket/warden@0.21.0 scan
32
+ npx -y @aimarket/warden@0.22.0 scan
33
33
  ```
34
34
 
35
35
  ```text
@@ -104,14 +104,14 @@ Operaciones limitadas explícitas: `node dist/mcp-server.js task`. [Adaptador, p
104
104
  "mcpServers": {
105
105
  "filesystem": {
106
106
  "command": "npx",
107
- "args": ["-y", "@aimarket/warden@0.21.0", "wrap", "--id", "filesystem", "--",
107
+ "args": ["-y", "@aimarket/warden@0.22.0", "wrap", "--id", "filesystem", "--",
108
108
  "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
109
109
  }
110
110
  }
111
111
  }
112
112
  ```
113
113
 
114
- Especifique siempre `--id`: sin él, cambiar los argumentos crea otra identidad y otro primer contacto. Con un ID estable, cambiar el comando o una ruta produce `SERVER_IDENTITY_DRIFT`. El hijo hereda el entorno, excluido de la identidad. `npm install -g @aimarket/warden@0.21.0` y el comando `warden-mcp` evitan arranques fríos repetidos de `npx`.
114
+ Especifique siempre `--id`: sin él, cambiar los argumentos crea otra identidad y otro primer contacto. Con un ID estable, cambiar el comando o una ruta produce `SERVER_IDENTITY_DRIFT`. El hijo hereda el entorno, excluido de la identidad. `npm install -g @aimarket/warden@0.22.0` y el comando `warden-mcp` evitan arranques fríos repetidos de `npx`.
115
115
 
116
116
  **Herramientas sensibles.** `sensitiveToolPatterns` en un archivo de política (`--policy policy.json` con `{"sensitiveToolPatterns": ["*delete*", "*transfer*"]}`, comodines `*` sin distinguir mayúsculas) hace que cada llamada a una herramienta que coincida espere a una persona: `wrap` pregunta mediante el propio formulario del cliente (elicitation de MCP) con la herramienta, el servidor y los argumentos, y solo una respuesta aceptada con la casilla marcada deja pasar esa llamada. La casilla empieza desmarcada, así que un cliente que acepta formularios con sus valores por defecto no aprueba nada. Un cliente sin formulario de elicitation recibe un rechazo y el servidor nunca recibe la llamada; `--ask refuse` rechaza sin preguntar. Si el cliente cancela la llamada mientras la persona decide, o las definiciones cambian entretanto, no se envía. Antes de 0.20.0 `wrap` aceptaba estos patrones sin aplicarlos. Con `--flow`, un envío por el que la guardia de flujo preguntaría se pregunta igual.
117
117
 
@@ -139,12 +139,12 @@ Claude Desktop en macOS: `~/Library/Logs/Claude/mcp-server-<nombre>.log`. En Cur
139
139
  ## Analiza todos los servidores que inician tus clientes
140
140
 
141
141
  ```bash
142
- npx -y @aimarket/warden@0.21.0 scan
142
+ npx -y @aimarket/warden@0.22.0 scan
143
143
  ```
144
144
 
145
145
  Lee las configuraciones MCP de Claude Code, Claude Desktop, Cursor, VS Code y Windsurf, se conecta a cada servidor que inician y revisa las definiciones de herramientas antes de que un modelo las vea. Imprime una tabla, JSON, SARIF o Markdown, y sale con 1 cuando bloquea un servidor; `--no-launch` no inicia nada. En un repositorio, `warden.lock.json` convierte un cambio en las definiciones en un diff revisable, y la CI falla ante un servidor nuevo o modificado. También como GitHub Action (`uses: alexar76/warden@v0.21.0`), hooks de pre-commit y plugin de Claude Code (`/plugin marketplace add alexar76/warden`). `--histor` pregunta al registro público HISTOR si un servidor te sirve lo mismo que a todos; para un servidor remoto envía el endpoint y un digest; para un servidor stdio que arranca desde npm o PyPI, el nombre del paquete (`npm:<nombre>`, `pypi:<nombre>`, que HISTOR ejecuta en un sandbox gVisor) y un digest; nunca el texto de las herramientas. Un clasificador opcional (`--classifier-url`, `--classifier-model`) añade la lectura de un modelo que tú eliges, local o alojado, para lo que ninguna regla nombra. Consulta la [guía de scan](docs/scan.es.md). Cómo se compara con otros dos escáneres sobre los mismos servidores: [comparación de escáneres](docs/scanner-comparison.es.md).
146
146
 
147
- **Para el editor de un servidor.** Si tu servidor lista otras herramientas donde está instalado algo que el sandbox de HISTOR no tiene —el runner de un lanzador, uno por sistema operativo—, `npx -y @aimarket/warden@0.21.0 declare --out mcp-tool-sets.json -- <tu servidor>` escribe esos conjuntos en un archivo que publicas en tu propio dominio, y quienes los reciben ven la declaración del editor en lugar de un conjunto desconocido. Consulta la [guía de scan](docs/scan.es.md).
147
+ **Para el editor de un servidor.** Si tu servidor lista otras herramientas donde está instalado algo que el sandbox de HISTOR no tiene —el runner de un lanzador, uno por sistema operativo—, `npx -y @aimarket/warden@0.22.0 declare --out mcp-tool-sets.json -- <tu servidor>` escribe esos conjuntos en un archivo que publicas en tu propio dominio, y quienes los reciben ven la declaración del editor en lugar de un conjunto desconocido. Consulta la [guía de scan](docs/scan.es.md).
148
148
 
149
149
  ## Lo que WARDEN no hace
150
150
 
@@ -340,6 +340,7 @@ comprobarlas: [Identidades ERC-8004](https://github.com/alexar76/aicom/blob/main
340
340
  | [Estudio de campo: 1 108 servidores MCP públicos](docs/mcp-survey.es.md) | Qué decidió WARDEN sobre definiciones de herramienta reales de terceros — 50 servidores bloqueados, 4 sustentados, y las seis formas en que el resto se equivocó |
341
341
  | [Comparación de escáneres](docs/scanner-comparison.es.md) | WARDEN, mcp-audit, mcp-shield, truecopy y mcpsentry sobre los mismos servidores, sobre 14 933 paquetes de npm y PyPI y sobre el benchmark MCPTox, con cada juicio, el manifiesto y el banco de pruebas |
342
342
  | [Guardián de flujos](docs/flow-guard.es.md) | La protección en ejecución del plugin de Claude Code: texto ajeno, datos privados, llamadas salientes; la medición en AgentDojo y sus límites |
343
+ | [Nueva comparación del modelo](docs/flow-guard-model-comparison-2026-10-25.es.md) | 720 respuestas: mejora en casos conocidos, incertidumbre, canal de avisos y ninguna corrección de ID observada por Stop |
343
344
  | [Glama / Docker](docs/GLAMA.md) | MCP stdio, health check, Build steps / CMD |
344
345
  | [Security](SECURITY.md) | Cómo informar de un bypass del cortafuegos |
345
346
  | [Contributing](CONTRIBUTING.md) | Regla de cero dependencias, PRs de la tabla de reglas |
@@ -363,7 +364,7 @@ comprobarlas: [Identidades ERC-8004](https://github.com/alexar76/aicom/blob/main
363
364
  ## Desarrollo
364
365
 
365
366
  ```bash
366
- npm install && npm run build && npm test # 1148 pruebas
367
+ npm install && npm run build && npm test # 1256 pruebas
367
368
  ```
368
369
 
369
370
  `test/packaging.test.ts` es lo que mantiene honesto el titular: falla si aparece una dependencia de
package/README-fr.md CHANGED
@@ -8,7 +8,7 @@
8
8
  <a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
9
9
  <a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="version npm" /></a>
10
10
  <img src="docs/badges/deps.svg" alt="Zéro dépendance d'exécution" />
11
- <img src="docs/badges/tests.svg" alt="1148 tests au vert" />
11
+ <img src="docs/badges/tests.svg" alt="1256 tests au vert" />
12
12
  <img src="docs/badges/node.svg" alt="Node >= 20" />
13
13
  <a href="LICENSE"><img src="docs/badges/license.svg" alt="Licence : MIT" /></a>
14
14
  </p>
@@ -29,7 +29,7 @@
29
29
  **Vérifiez tous les serveurs MCP de votre machine.** Pas de compte, pas de clé d’API, pas de modèle. Le seul trafic réseau va vers les serveurs de votre configuration.
30
30
 
31
31
  ```bash
32
- npx -y @aimarket/warden@0.21.0 scan
32
+ npx -y @aimarket/warden@0.22.0 scan
33
33
  ```
34
34
 
35
35
  ```text
@@ -104,14 +104,14 @@ Opérations limitées sur activation explicite : `node dist/mcp-server.js task`.
104
104
  "mcpServers": {
105
105
  "filesystem": {
106
106
  "command": "npx",
107
- "args": ["-y", "@aimarket/warden@0.21.0", "wrap", "--id", "filesystem", "--",
107
+ "args": ["-y", "@aimarket/warden@0.22.0", "wrap", "--id", "filesystem", "--",
108
108
  "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
109
109
  }
110
110
  }
111
111
  }
112
112
  ```
113
113
 
114
- Spécifiez toujours `--id` : sans cet identifiant, modifier les arguments crée une nouvelle identité et un premier contact. Un ID stable transforme un changement de commande ou de chemin en `SERVER_IDENTITY_DRIFT`. Le processus enfant hérite de l’environnement, exclu de l’identité. `npm install -g @aimarket/warden@0.21.0` puis `warden-mcp` évitent les démarrages à froid répétés de `npx`.
114
+ Spécifiez toujours `--id` : sans cet identifiant, modifier les arguments crée une nouvelle identité et un premier contact. Un ID stable transforme un changement de commande ou de chemin en `SERVER_IDENTITY_DRIFT`. Le processus enfant hérite de l’environnement, exclu de l’identité. `npm install -g @aimarket/warden@0.22.0` puis `warden-mcp` évitent les démarrages à froid répétés de `npx`.
115
115
 
116
116
  **Outils sensibles.** `sensitiveToolPatterns` dans un fichier de politique (`--policy policy.json` avec `{"sensitiveToolPatterns": ["*delete*", "*transfer*"]}`, motifs `*` insensibles à la casse) fait attendre une personne à chaque appel d’un outil correspondant : `wrap` demande par le formulaire du client lui-même (elicitation MCP), avec l’outil, le serveur et les arguments, et seule une réponse acceptée, case cochée, laisse passer cet appel-là. La case est décochée au départ : un client qui accepte les formulaires avec leurs valeurs par défaut n’approuve rien. Un client sans formulaire d’elicitation reçoit un refus et le serveur ne reçoit jamais l’appel ; `--ask refuse` refuse sans demander. Si le client annule l’appel pendant que la personne décide, ou si les définitions changent entre-temps, il n’est pas envoyé. Avant 0.20.0, `wrap` acceptait ces motifs sans les appliquer. Avec `--flow`, un envoi pour lequel la garde de flux demanderait est demandé de la même façon.
117
117
 
@@ -139,12 +139,12 @@ Claude Desktop sur macOS : `~/Library/Logs/Claude/mcp-server-<nom>.log`. Cursor
139
139
  ## Analyser tous les serveurs que démarrent vos clients
140
140
 
141
141
  ```bash
142
- npx -y @aimarket/warden@0.21.0 scan
142
+ npx -y @aimarket/warden@0.22.0 scan
143
143
  ```
144
144
 
145
145
  Lit les configurations MCP de Claude Code, Claude Desktop, Cursor, VS Code et Windsurf, se connecte à chaque serveur qu’elles démarrent et vérifie les définitions d’outils avant qu’un modèle ne les voie. Affiche un tableau, du JSON, du SARIF ou du Markdown, et sort avec 1 quand un serveur est bloqué ; `--no-launch` ne démarre rien. Dans un dépôt, `warden.lock.json` transforme un changement de définitions en diff relisible, et la CI échoue sur un serveur nouveau ou modifié. Existe aussi en GitHub Action (`uses: alexar76/warden@v0.21.0`), en hooks pre-commit et en plugin Claude Code (`/plugin marketplace add alexar76/warden`). `--histor` demande au journal public HISTOR si un serveur vous sert ce qu’il sert à tout le monde ; pour un serveur distant il envoie l’endpoint et un condensé, pour un serveur stdio lancé depuis npm ou PyPI le nom du paquet (`npm:<nom>`, `pypi:<nom>`, qu’HISTOR exécute dans un bac à sable gVisor) et un condensé — jamais le texte des outils. Un classificateur optionnel (`--classifier-url`, `--classifier-model`) ajoute la lecture d'un modèle que vous choisissez, local ou hébergé, pour ce qu'aucune règle ne nomme. Voir le [guide de scan](docs/scan.fr.md). Comment il se compare à deux autres scanners sur les mêmes serveurs : [comparaison de scanners](docs/scanner-comparison.fr.md).
146
146
 
147
- **Pour l’éditeur d’un serveur.** Si votre serveur liste d’autres outils là où est installé ce que le bac à sable d’HISTOR n’a pas — le runner d’un lanceur, un par système —, `npx -y @aimarket/warden@0.21.0 declare --out mcp-tool-sets.json -- <votre serveur>` écrit ces ensembles dans un fichier que vous publiez sur votre propre domaine, et ceux qui les reçoivent voient la déclaration de l’éditeur au lieu d’un ensemble inconnu. Voir le [guide de scan](docs/scan.fr.md).
147
+ **Pour l’éditeur d’un serveur.** Si votre serveur liste d’autres outils là où est installé ce que le bac à sable d’HISTOR n’a pas — le runner d’un lanceur, un par système —, `npx -y @aimarket/warden@0.22.0 declare --out mcp-tool-sets.json -- <votre serveur>` écrit ces ensembles dans un fichier que vous publiez sur votre propre domaine, et ceux qui les reçoivent voient la déclaration de l’éditeur au lieu d’un ensemble inconnu. Voir le [guide de scan](docs/scan.fr.md).
148
148
 
149
149
  ## Ce que WARDEN ne fait pas
150
150
 
@@ -341,6 +341,7 @@ transactions et la façon de les vérifier :
341
341
  | [Étude de terrain : 1 108 serveurs MCP publics](docs/mcp-survey.fr.md) | Ce que WARDEN a décidé sur de vraies définitions d'outil tierces — 50 serveurs bloqués, 4 étayés, et les six façons dont le reste était faux |
342
342
  | [Comparaison de scanners](docs/scanner-comparison.fr.md) | WARDEN, mcp-audit, mcp-shield, truecopy et mcpsentry sur les mêmes serveurs, sur 14 933 paquets npm et PyPI et sur le benchmark MCPTox, avec chaque jugement, le manifeste et le banc d’essai |
343
343
  | [Garde de flux](docs/flow-guard.fr.md) | La protection à l’exécution du plugin Claude Code : texte extérieur, données privées, appels sortants ; la mesure sur AgentDojo et ses limites |
344
+ | [Nouvelle comparaison du modèle](docs/flow-guard-model-comparison-2026-10-25.fr.md) | 720 réponses : amélioration sur des cas connus, incertitude, canal d’avertissement et aucune correction d’ID observée par Stop |
344
345
  | [Glama / Docker](docs/GLAMA.md) | MCP stdio, health check, Build steps / CMD |
345
346
  | [Security](SECURITY.md) | Signaler un contournement du pare-feu |
346
347
  | [Contributing](CONTRIBUTING.md) | Règle zéro dépendance, PRs de table de règles |
@@ -364,7 +365,7 @@ transactions et la façon de les vérifier :
364
365
  ## Développement
365
366
 
366
367
  ```bash
367
- npm install && npm run build && npm test # 1148 tests
368
+ npm install && npm run build && npm test # 1256 tests
368
369
  ```
369
370
 
370
371
  `test/packaging.test.ts` est ce qui tient l'accroche honnête : il échoue si une dépendance d'exécution
package/README-ru.md CHANGED
@@ -8,7 +8,7 @@
8
8
  <a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
9
9
  <a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="npm version" /></a>
10
10
  <img src="docs/badges/deps.svg" alt="Zero runtime dependencies" />
11
- <img src="docs/badges/tests.svg" alt="1148 tests passing" />
11
+ <img src="docs/badges/tests.svg" alt="1256 tests passing" />
12
12
  <img src="docs/badges/node.svg" alt="Node >= 20" />
13
13
  <a href="LICENSE"><img src="docs/badges/license.svg" alt="License: MIT" /></a>
14
14
  </p>
@@ -29,7 +29,7 @@
29
29
  **Проверьте все MCP-серверы на своей машине.** Без аккаунта, без API-ключа, без модели. Сетевой трафик идёт только к серверам из вашего конфига.
30
30
 
31
31
  ```bash
32
- npx -y @aimarket/warden@0.21.0 scan
32
+ npx -y @aimarket/warden@0.22.0 scan
33
33
  ```
34
34
 
35
35
  ```text
@@ -104,7 +104,7 @@ MCP-сервер добавляет другие `node:` builtins (`fs`, `path`,
104
104
  "mcpServers": {
105
105
  "filesystem": {
106
106
  "command": "npx",
107
- "args": ["-y", "@aimarket/warden@0.21.0", "wrap", "--id", "filesystem", "--",
107
+ "args": ["-y", "@aimarket/warden@0.22.0", "wrap", "--id", "filesystem", "--",
108
108
  "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
109
109
  }
110
110
  }
@@ -113,7 +113,7 @@ MCP-сервер добавляет другие `node:` builtins (`fs`, `path`,
113
113
 
114
114
  Для обязательного утверждения первого контакта добавьте к `wrap` флаг `--require-approval`. Определения не попадут модели до `warden-mcp pins approve --id filesystem` в терминале оператора. Любое изменение полей или идентичности запуска требует нового утверждения; автоматические и старые pins не подходят. Подробнее: [граница допуска, не зависящая от языка](docs/security-hardening-language-boundary.md).
115
115
 
116
- Всегда задавайте `--id`: без него изменение аргументов создаёт новую идентичность и новый первый контакт. Со стабильным ID смена команды или пути даёт `SERVER_IDENTITY_DRIFT`. Дочерний процесс наследует окружение; оно не входит в идентичность. Чтобы избежать холодного старта `npx`, установите глобально: `npm install -g @aimarket/warden@0.21.0`, затем команда `warden-mcp`.
116
+ Всегда задавайте `--id`: без него изменение аргументов создаёт новую идентичность и новый первый контакт. Со стабильным ID смена команды или пути даёт `SERVER_IDENTITY_DRIFT`. Дочерний процесс наследует окружение; оно не входит в идентичность. Чтобы избежать холодного старта `npx`, установите глобально: `npm install -g @aimarket/warden@0.22.0`, затем команда `warden-mcp`.
117
117
 
118
118
  **Чувствительные инструменты.** `sensitiveToolPatterns` в файле политики (`--policy policy.json` с `{"sensitiveToolPatterns": ["*delete*", "*transfer*"]}`, шаблоны `*` без учёта регистра) заставляет каждый вызов подходящего инструмента ждать человека: `wrap` спрашивает через собственную форму клиента (MCP elicitation), показывая инструмент, сервер и аргументы, и пропускает этот один вызов только при отмеченной галочке и принятой форме. Галочка по умолчанию снята, поэтому клиент, принимающий формы со значениями по умолчанию, ничего не одобрит. Клиенту без формы elicitation вызов отклоняется, и сервер его не получает; `--ask refuse` отклоняет, не спрашивая. Если клиент отменил вызов, пока человек решает, или за это время изменились определения, вызов не отправляется. До 0.20.0 `wrap` принимал эти шаблоны, но не применял их. С `--flow` отправка, о которой страж потоков спросил бы, спрашивается так же.
119
119
 
@@ -141,12 +141,12 @@ warden-mcp pins revoke --id filesystem
141
141
  ## Проверить все серверы, которые запускают ваши клиенты
142
142
 
143
143
  ```bash
144
- npx -y @aimarket/warden@0.21.0 scan
144
+ npx -y @aimarket/warden@0.22.0 scan
145
145
  ```
146
146
 
147
147
  Читает MCP-конфиги Claude Code, Claude Desktop, Cursor, VS Code и Windsurf, подключается к каждому серверу из них и проверяет определения инструментов до того, как их увидит модель. Выводит таблицу, JSON, SARIF или Markdown и завершается с кодом 1, если сервер заблокирован; `--no-launch` ничего не запускает. В репозитории `warden.lock.json` превращает изменение определений инструментов в дифф для ревью, а CI падает на новом или изменённом сервере. Есть GitHub Action (`uses: alexar76/warden@v0.21.0`), хуки pre-commit и плагин Claude Code (`/plugin marketplace add alexar76/warden`). `--histor` спрашивает публичный журнал HISTOR, отдаёт ли сервер вам то же, что всем; для удалённого сервера уходят адрес и дайджест, для stdio-сервера из npm или PyPI — имя пакета (`npm:<имя>`, `pypi:<имя>`; HISTOR запускает такие пакеты в песочнице gVisor) и дайджест, текст инструментов — никогда. Опциональный классификатор (`--classifier-url`, `--classifier-model`) добавляет прочтение модели, которую выбираете вы, локальной или облачной, — для того, что не называет ни одно правило. Подробно — в [руководстве по scan](docs/scan.ru.md). Как он выглядит рядом с двумя другими сканерами на одних и тех же серверах: [сравнение сканеров](docs/scanner-comparison.ru.md).
148
148
 
149
- **Для издателя сервера.** Если ваш сервер отдаёт другие инструменты там, где установлено то, чего нет в песочнице HISTOR, — раннер запускателя, по одному на ОС, — `npx -y @aimarket/warden@0.21.0 declare --out mcp-tool-sets.json -- <ваш сервер>` записывает эти наборы в файл, который вы публикуете на своём домене, и те, кто их получает, видят заявление издателя, а не незнакомый набор. Подробно — в [руководстве по scan](docs/scan.ru.md).
149
+ **Для издателя сервера.** Если ваш сервер отдаёт другие инструменты там, где установлено то, чего нет в песочнице HISTOR, — раннер запускателя, по одному на ОС, — `npx -y @aimarket/warden@0.22.0 declare --out mcp-tool-sets.json -- <ваш сервер>` записывает эти наборы в файл, который вы публикуете на своём домене, и те, кто их получает, видят заявление издателя, а не незнакомый набор. Подробно — в [руководстве по scan](docs/scan.ru.md).
150
150
 
151
151
  ## Чего WARDEN не делает
152
152
 
@@ -342,6 +342,7 @@ WARDEN — агент ERC-8004 [`96684` в сети Base](https://8004scan.io/ag
342
342
  | [Полевой обзор: 1 108 публичных MCP-серверов](docs/mcp-survey.ru.md) | Что WARDEN решил на настоящих чужих определениях инструментов — 50 серверов заблокировано, 4 подтверждено, и шесть способов, которыми остальные оказались ошибкой |
343
343
  | [Сравнение сканеров](docs/scanner-comparison.ru.md) | WARDEN, mcp-audit, mcp-shield, truecopy и mcpsentry на одних и тех же серверах, на 14 933 пакетах npm и PyPI и на бенчмарке MCPTox, со всеми разметками, манифестом и стендом |
344
344
  | [Страж потоков](docs/flow-guard.ru.md) | Защита плагина Claude Code во время работы: чужой текст, приватные данные, исходящие вызовы; измерение на AgentDojo и его границы |
345
+ | [Свежий прогон модели](docs/flow-guard-model-comparison-2026-10-25.ru.md) | 720 ответов: улучшение на известных сценариях, неопределённость, канал предупреждений и отсутствие исправленных ID через Stop |
345
346
  | [Glama / Docker](docs/GLAMA.md) | stdio MCP, health check, Build steps / CMD |
346
347
  | [Security](SECURITY.md) | Как сообщать об обходе файрвола |
347
348
  | [Contributing](CONTRIBUTING.md) | Правило нулевых зависимостей, PR на таблицу правил |
@@ -365,7 +366,7 @@ WARDEN — агент ERC-8004 [`96684` в сети Base](https://8004scan.io/ag
365
366
  ## Разработка
366
367
 
367
368
  ```bash
368
- npm install && npm run build && npm test # 1148 тестов
369
+ npm install && npm run build && npm test # 1256 тестов
369
370
  ```
370
371
 
371
372
  `test/packaging.test.ts` — то, что удерживает заголовок честным: он падает, если появляется
package/README-zh.md CHANGED
@@ -8,7 +8,7 @@
8
8
  <a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
9
9
  <a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="npm 版本" /></a>
10
10
  <img src="docs/badges/deps.svg" alt="零运行时依赖" />
11
- <img src="docs/badges/tests.svg" alt="1148 项测试通过" />
11
+ <img src="docs/badges/tests.svg" alt="1256 项测试通过" />
12
12
  <img src="docs/badges/node.svg" alt="Node >= 20" />
13
13
  <a href="LICENSE"><img src="docs/badges/license.svg" alt="许可证:MIT" /></a>
14
14
  </p>
@@ -29,7 +29,7 @@
29
29
  **检查你机器上的所有 MCP 服务器。** 无需账号、无需 API 密钥、不调用模型。唯一的网络流量是发往你配置中的服务器。
30
30
 
31
31
  ```bash
32
- npx -y @aimarket/warden@0.21.0 scan
32
+ npx -y @aimarket/warden@0.22.0 scan
33
33
  ```
34
34
 
35
35
  ```text
@@ -100,14 +100,14 @@ Auten 后续:`taskAdapter.mode: "review"` / `task_run` 按固定结果确认
100
100
  "mcpServers": {
101
101
  "filesystem": {
102
102
  "command": "npx",
103
- "args": ["-y", "@aimarket/warden@0.21.0", "wrap", "--id", "filesystem", "--",
103
+ "args": ["-y", "@aimarket/warden@0.22.0", "wrap", "--id", "filesystem", "--",
104
104
  "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
105
105
  }
106
106
  }
107
107
  }
108
108
  ```
109
109
 
110
- 始终指定 `--id`:否则修改命令参数会创建新身份并重新执行首次信任。稳定 ID 会把命令或路径变更识别为 `SERVER_IDENTITY_DRIFT`。子进程继承环境变量,身份哈希不包含环境。可运行 `npm install -g @aimarket/warden@0.21.0`,使用 `warden-mcp` 避免反复进行 `npx` 冷启动。
110
+ 始终指定 `--id`:否则修改命令参数会创建新身份并重新执行首次信任。稳定 ID 会把命令或路径变更识别为 `SERVER_IDENTITY_DRIFT`。子进程继承环境变量,身份哈希不包含环境。可运行 `npm install -g @aimarket/warden@0.22.0`,使用 `warden-mcp` 避免反复进行 `npx` 冷启动。
111
111
 
112
112
  **敏感工具。** 策略文件中的 `sensitiveToolPatterns`(`--policy policy.json`,内容如 `{"sensitiveToolPatterns": ["*delete*", "*transfer*"]}`,`*` 通配、不区分大小写)让每次调用匹配的工具都要等人确认:`wrap` 通过客户端自己的表单(MCP elicitation)询问,列出工具、服务器和参数,只有勾选并接受的回答才放行这一次调用。复选框默认不勾选,所以按默认值自动接受表单的客户端什么也批准不了。不提供 elicitation 表单的客户端会收到拒绝,服务器永远收不到这次调用;`--ask refuse` 不询问直接拒绝。若客户端在等人决定时取消调用,或其间定义发生变化,调用不会发出。0.20.0 之前 `wrap` 接受这些模式却不执行。配合 `--flow`,流守卫会询问的发送也以同样方式询问。
113
113
 
@@ -135,12 +135,12 @@ macOS 上 Claude Desktop 日志:`~/Library/Logs/Claude/mcp-server-<名称>.log
135
135
  ## 扫描客户端启动的所有服务器
136
136
 
137
137
  ```bash
138
- npx -y @aimarket/warden@0.21.0 scan
138
+ npx -y @aimarket/warden@0.22.0 scan
139
139
  ```
140
140
 
141
141
  读取 Claude Code、Claude Desktop、Cursor、VS Code 和 Windsurf 的 MCP 配置,连接其中启动的每个服务器,并在模型看到工具定义之前对其进行审查。输出表格、JSON、SARIF 或 Markdown,有服务器被阻止时以 1 退出;`--no-launch` 不启动任何程序。在仓库中,`warden.lock.json` 把工具定义的改动变成可审查的 diff,CI 会在出现新的或改动过的服务器时失败。也提供 GitHub Action(`uses: alexar76/warden@v0.21.0`)、pre-commit 钩子和 Claude Code 插件(`/plugin marketplace add alexar76/warden`)。`--histor` 询问公开的 HISTOR 日志:服务器给你的是否与给所有人的相同;对远程服务器发送端点和摘要,对从 npm 或 PyPI 启动的 stdio 服务器发送软件包名(`npm:<名称>`、`pypi:<名称>`,HISTOR 会在 gVisor 沙箱中运行它)和摘要,从不发送工具文本。可选的分类器(`--classifier-url`、`--classifier-model`)会加入你所选模型(本地或托管)的判断,用于覆盖任何规则都没有提到的内容。详见 [scan 指南](docs/scan.zh.md)。与另外两款扫描器在同一批服务器上的对比,见[扫描器对比](docs/scanner-comparison.zh.md)。
142
142
 
143
- **面向服务器发布者。** 如果在安装了 HISTOR 沙箱所没有的东西(启动器的运行器、每个操作系统各一个)的地方,你的服务器列出的是别的工具,`npx -y @aimarket/warden@0.21.0 declare --out mcp-tool-sets.json -- <你的服务器>` 会把这些工具集写进一个文件,由你发布在自己的域名上;拿到这些工具集的人看到的将是发布者的声明,而不是陌生的工具集。参见 [scan 指南](docs/scan.zh.md)。
143
+ **面向服务器发布者。** 如果在安装了 HISTOR 沙箱所没有的东西(启动器的运行器、每个操作系统各一个)的地方,你的服务器列出的是别的工具,`npx -y @aimarket/warden@0.22.0 declare --out mcp-tool-sets.json -- <你的服务器>` 会把这些工具集写进一个文件,由你发布在自己的域名上;拿到这些工具集的人看到的将是发布者的声明,而不是陌生的工具集。参见 [scan 指南](docs/scan.zh.md)。
144
144
 
145
145
  ## WARDEN 不做什么
146
146
 
@@ -322,6 +322,7 @@ WARDEN 是 [Base 上的 `96684` 号](https://8004scan.io/agents/base/96684) ERC-
322
322
  | [实地普查:1 108 个公开 MCP 服务器](docs/mcp-survey.zh.md) | WARDEN 在真实的第三方工具定义上判了什么——拦截 50 个服务器,4 项成立,其余判错的六种方式 |
323
323
  | [扫描器对比](docs/scanner-comparison.zh.md) | WARDEN、mcp-audit、mcp-shield、truecopy 与 mcpsentry 在同一批服务器、14,933 个 npm 和 PyPI 包以及 MCPTox 基准上的结果,附全部判定、清单和测试工具 |
324
324
  | [流向守卫](docs/flow-guard.zh.md) | Claude Code 插件的运行时守卫:外部文本、私有数据、外发调用;AgentDojo 测量及其局限 |
325
+ | [新的模型对比](docs/flow-guard-model-comparison-2026-10-25.zh.md) | 720 个答案:已知案例上的改善、不确定性、警告内容边界,以及未观察到 Stop 纠正 ID |
325
326
  | [Glama / Docker](docs/GLAMA.md) | stdio MCP、健康检查、Build steps / CMD |
326
327
  | [Security](SECURITY.md) | 如何报告防火墙绕过 |
327
328
  | [Contributing](CONTRIBUTING.md) | 零依赖规则、规则表 PR |
@@ -341,7 +342,7 @@ WARDEN 是 [Base 上的 `96684` 号](https://8004scan.io/agents/base/96684) ERC-
341
342
  ## 开发
342
343
 
343
344
  ```bash
344
- npm install && npm run build && npm test # 1148 项测试
345
+ npm install && npm run build && npm test # 1256 项测试
345
346
  ```
346
347
 
347
348
  `test/packaging.test.ts` 正是让标题保持诚实的东西:一旦出现运行时依赖、任何源文件从包外 import、或者入口点不
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  <a href="https://glama.ai/mcp/servers/alexar76/warden"><img src="https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg" alt="warden MCP server" /></a>
9
9
  <a href="https://warden.modelmarket.dev/"><img src="https://img.shields.io/npm/v/@aimarket/warden?color=cb3837&label=npm" alt="npm version" /></a>
10
10
  <img src="docs/badges/deps.svg" alt="Zero runtime dependencies" />
11
- <img src="docs/badges/tests.svg" alt="1148 tests passing" />
11
+ <img src="docs/badges/tests.svg" alt="1256 tests passing" />
12
12
  <img src="docs/badges/node.svg" alt="Node >= 20" />
13
13
  <a href="LICENSE"><img src="docs/badges/license.svg" alt="License: MIT" /></a>
14
14
  </p>
@@ -29,7 +29,7 @@
29
29
  **Check every MCP server on your machine.** No account, no API key, no model. The only network traffic is to the servers in your config.
30
30
 
31
31
  ```bash
32
- npx -y @aimarket/warden@0.21.0 scan
32
+ npx -y @aimarket/warden@0.22.0 scan
33
33
  ```
34
34
 
35
35
  ```text
@@ -103,7 +103,7 @@ Opt-in constrained operations: `node dist/mcp-server.js task`. See the [task ada
103
103
  "mcpServers": {
104
104
  "filesystem": {
105
105
  "command": "npx",
106
- "args": ["-y", "@aimarket/warden@0.21.0", "wrap", "--id", "filesystem", "--",
106
+ "args": ["-y", "@aimarket/warden@0.22.0", "wrap", "--id", "filesystem", "--",
107
107
  "npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/docs"]
108
108
  }
109
109
  }
@@ -112,7 +112,7 @@ Opt-in constrained operations: `node dist/mcp-server.js task`. See the [task ada
112
112
 
113
113
  For explicit first-contact review, add `--require-approval` to `wrap`. It withholds new definitions until `warden-mcp pins approve --id filesystem` in an operator terminal, then rejects any changed field or launch identity. Automatic/legacy pins need reapproval. See the [language-independent admission boundary](docs/security-hardening-language-boundary.md).
114
114
 
115
- Always specify `--id`: without it, changing command arguments creates a new identity and a new first contact. A stable ID turns a command or path change into `SERVER_IDENTITY_DRIFT`. Environment variables are inherited by the child and excluded from identity. To avoid repeated cold `npx` starts, install globally with `npm install -g @aimarket/warden@0.21.0`, then use `warden-mcp`.
115
+ Always specify `--id`: without it, changing command arguments creates a new identity and a new first contact. A stable ID turns a command or path change into `SERVER_IDENTITY_DRIFT`. Environment variables are inherited by the child and excluded from identity. To avoid repeated cold `npx` starts, install globally with `npm install -g @aimarket/warden@0.22.0`, then use `warden-mcp`.
116
116
 
117
117
  **Sensitive tools.** A policy file's `sensitiveToolPatterns` (`--policy policy.json` with `{"sensitiveToolPatterns": ["*delete*", "*transfer*"]}`, case-insensitive `*` globs) makes every call to a matching tool wait for a person: `wrap` asks through the client's own form (MCP elicitation) with the tool, the server and the arguments, and only a ticked, accepted answer lets that one call through. The box starts unticked, so a client that accepts forms with their defaults approves nothing. A client that offers no elicitation form gets a refusal and the server never receives the call; `--ask refuse` refuses without asking. If the client cancels the call while the person decides, or the definitions change meanwhile, it is not sent. Before 0.20.0 `wrap` accepted these patterns and did not enforce them. With `--flow`, a send the flow guard would ask about is asked the same way.
118
118
 
@@ -140,12 +140,12 @@ Claude Desktop on macOS writes stderr to `~/Library/Logs/Claude/mcp-server-<name
140
140
  ## Scan every server your clients start
141
141
 
142
142
  ```bash
143
- npx -y @aimarket/warden@0.21.0 scan
143
+ npx -y @aimarket/warden@0.22.0 scan
144
144
  ```
145
145
 
146
146
  Reads the MCP configs of Claude Code, Claude Desktop, Cursor, VS Code and Windsurf, connects to every server they start, and vets the tool definitions before a model sees them. It prints a table, JSON, SARIF or Markdown, and exits 1 when a server is blocked; `--no-launch` starts nothing. In a repository, `warden.lock.json` turns a change in tool definitions into a reviewable diff, and CI fails on a new or changed server. Also as a GitHub Action (`uses: alexar76/warden@v0.21.0`), pre-commit hooks and a Claude Code plugin (`/plugin marketplace add alexar76/warden`). `--histor` asks the public HISTOR log whether a server serves you what it serves everyone; for a remote server it sends the endpoint and a digest, for a stdio server started from npm or PyPI the package name (`npm:<name>`, `pypi:<name>`, which HISTOR runs in a gVisor sandbox) and a digest — never tool text. An opt-in classifier (`--classifier-url`, `--classifier-model`) adds the reading of a model you choose, local or hosted, for what no rule names. See the [scan guide](docs/scan.md). How it compares with two other scanners, on the same servers: [scanner comparison](docs/scanner-comparison.md).
147
147
 
148
- **For a server's publisher.** If your server lists different tools where something HISTOR's sandbox lacks is installed — a launcher's runner, one per operating system — `npx -y @aimarket/warden@0.21.0 declare --out mcp-tool-sets.json -- <your server>` writes those sets to a file you publish on your own domain, and the people who get them see the publisher's declaration instead of an unseen tool set. See [declare your server's tool sets](docs/scan.md#for-publishers-declare-your-servers-tool-sets).
148
+ **For a server's publisher.** If your server lists different tools where something HISTOR's sandbox lacks is installed — a launcher's runner, one per operating system — `npx -y @aimarket/warden@0.22.0 declare --out mcp-tool-sets.json -- <your server>` writes those sets to a file you publish on your own domain, and the people who get them see the publisher's declaration instead of an unseen tool set. See [declare your server's tool sets](docs/scan.md#for-publishers-declare-your-servers-tool-sets).
149
149
 
150
150
  ## What WARDEN does not do
151
151
 
@@ -342,6 +342,7 @@ check them: [ERC-8004 identities](https://github.com/alexar76/aicom/blob/main/do
342
342
  | [Field survey: 1 108 public MCP servers](docs/mcp-survey.md) | What WARDEN decided on real third-party tool definitions — 50 servers blocked, 4 substantiated, and the six ways the rest were wrong |
343
343
  | [Scanner comparison](docs/scanner-comparison.md) | WARDEN, mcp-audit, mcp-shield, truecopy and mcpsentry on the same servers, on 14,933 npm and PyPI packages and on the MCPTox benchmark, with every judgment, the manifest and the harness |
344
344
  | [Flow guard](docs/flow-guard.md) | The Claude Code plugin's runtime guard: outside text, private data, outbound calls; the AgentDojo measurement and its limits |
345
+ | [Fresh model comparison](docs/flow-guard-model-comparison-2026-10-25.md) | 720 answers; known-case improvement, uncertainty, warning custody and no observed Stop choice correction |
345
346
  | [Glama / Docker](docs/GLAMA.md) | stdio MCP server, health check, admin Build steps / CMD |
346
347
  | [MCP registries](docs/REGISTRIES.md) | Official Registry, mcp.so / Pulse |
347
348
  | [Security](SECURITY.md) | How to report a firewall bypass |
@@ -365,7 +366,7 @@ check them: [ERC-8004 identities](https://github.com/alexar76/aicom/blob/main/do
365
366
  ## Development
366
367
 
367
368
  ```bash
368
- npm install && npm run build && npm test # 1148 tests
369
+ npm install && npm run build && npm test # 1256 tests
369
370
  ```
370
371
 
371
372
  `test/packaging.test.ts` is what keeps the headline honest: it fails if an npm runtime dependency
@@ -0,0 +1,10 @@
1
+ import type { FlowPolicy } from './flow-guard-types.js';
2
+ import type { CapabilityBinding, McpServerRef, ToolDef } from './types.js';
3
+ export interface AnnotationReview {
4
+ /** Acknowledgement is valid only inside this wrapper for this exact identity/tool set. */
5
+ key: string;
6
+ reason: string;
7
+ }
8
+ /** Deliberately independent of tool arguments, destination allowlists and server titles. */
9
+ export declare function annotationReview(server: McpServerRef, tools: ToolDef[], toolName: string, flowName: string, policy: FlowPolicy, bindings?: readonly CapabilityBinding[]): AnnotationReview | undefined;
10
+ //# sourceMappingURL=annotation-review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotation-review.d.ts","sourceRoot":"","sources":["../src/annotation-review.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI3E,MAAM,WAAW,gBAAgB;IAC/B,0FAA0F;IAC1F,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAC1E,MAAM,EAAE,UAAU,EAAE,QAAQ,GAAE,SAAS,iBAAiB,EAAO,GAC9D,gBAAgB,GAAG,SAAS,CAsB9B"}
@@ -0,0 +1,36 @@
1
+ /** Server-authored MCP annotations can request caution, never establish authority. */
2
+ import { globMatch } from './flow-guard-policy.js';
3
+ import { pinToolsHash, serverIdentityHash } from './pinning.js';
4
+ import { boundCapabilities } from './toxic-flow.js';
5
+ const HINTS = ['readOnlyHint', 'destructiveHint', 'openWorldHint'];
6
+ /** Deliberately independent of tool arguments, destination allowlists and server titles. */
7
+ export function annotationReview(server, tools, toolName, flowName, policy, bindings = []) {
8
+ if (!flowName || policy.annotationReview !== 'first-use' || policy.mode === 'off')
9
+ return undefined;
10
+ const qualified = `mcp__${flowName}__${toolName}`;
11
+ if (Object.keys(policy.labels).some(glob => globMatch(glob, qualified)))
12
+ return undefined;
13
+ if (boundCapabilities(server, tools, bindings))
14
+ return undefined;
15
+ const tool = tools.find(t => t.name === toolName);
16
+ if (!tool || tool.annotations === undefined)
17
+ return undefined;
18
+ const annotations = tool.annotations;
19
+ let claims;
20
+ if (!annotations || typeof annotations !== 'object' || Array.isArray(annotations))
21
+ claims = ['invalid annotation object'];
22
+ else {
23
+ const fields = annotations;
24
+ claims = HINTS.filter(hint => Object.hasOwn(fields, hint))
25
+ .map(hint => `${hint}=${typeof fields[hint] === 'boolean' ? String(fields[hint]) : 'invalid'}`);
26
+ if (!claims.length)
27
+ return undefined;
28
+ }
29
+ return {
30
+ key: JSON.stringify([server.id, serverIdentityHash(server), pinToolsHash(tools), toolName]),
31
+ reason: `The server supplied unverified MCP annotations (${claims.join(', ')}), and the operator has not labelled this tool. ` +
32
+ 'Review them before first use. Even readOnlyHint=true does not prove a call is read-only or free. ' +
33
+ 'Acceptance records this annotation review only for this exact server and tool set in this running wrapper; later calls still face every other guard.',
34
+ };
35
+ }
36
+ //# sourceMappingURL=annotation-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotation-review.js","sourceRoot":"","sources":["../src/annotation-review.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGpD,MAAM,KAAK,GAAG,CAAC,cAAc,EAAE,iBAAiB,EAAE,eAAe,CAAU,CAAC;AAQ5E,4FAA4F;AAC5F,MAAM,UAAU,gBAAgB,CAC9B,MAAoB,EAAE,KAAgB,EAAE,QAAgB,EAAE,QAAgB,EAC1E,MAAkB,EAAE,WAAyC,EAAE;IAE/D,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,gBAAgB,KAAK,WAAW,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IACpG,MAAM,SAAS,GAAG,QAAQ,QAAQ,KAAK,QAAQ,EAAE,CAAC;IAClD,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1F,IAAI,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IACjE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAClD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC9D,MAAM,WAAW,GAAY,IAAI,CAAC,WAAW,CAAC;IAC9C,IAAI,MAAgB,CAAC;IACrB,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;QAAE,MAAM,GAAG,CAAC,2BAA2B,CAAC,CAAC;SACrH,CAAC;QACJ,MAAM,MAAM,GAAG,WAAsC,CAAC;QACtD,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;aACvD,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QAClG,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;IACvC,CAAC;IACD,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC3F,MAAM,EAAE,mDAAmD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,kDAAkD;YAC5H,mGAAmG;YACnG,sJAAsJ;KACzJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ /** UserPromptSubmit: remember what the user asked for, so destinations they named are theirs. */
2
+ /**
3
+ * The user's own words in a prompt: what is left after text they pasted or quoted. An address that appears only in
4
+ * a pasted block, a quoted line or the headers of a forwarded message was written by someone else, and naming it
5
+ * is what an attacker who mails the user would want. Asking once before writing to it is the price when the user
6
+ * meant it ("reply to the sender of this").
7
+ */
8
+ export declare function ownWords(prompt: string): string;
9
+ export declare function flowPrompt(input: Record<string, unknown>, env?: NodeJS.ProcessEnv): void;
10
+ /** The sentence in which outside text addresses the model, from the instruction to the sentence's end. Not the
11
+ * sentences around it: in a list of reviews they are ordinary reviews, which an honest answer repeats. */
12
+ export declare function instructionText(text: string): string;
13
+ export declare function hintWindows(text: string): string[];
14
+ /** The text of the last assistant message: given directly, or read from the end of the Claude Code transcript. */
15
+ export declare function lastAnswer(input: Record<string, unknown>): string;
16
+ export interface FlowStopOutput {
17
+ systemMessage?: string;
18
+ decision?: 'block';
19
+ reason?: string;
20
+ }
21
+ /**
22
+ * Stop: an injection that only changes the answer ("recommend this hotel") makes no call to refuse. Two levers are
23
+ * left. Under any answer whose turn read outside text, one line tells the user which sources it drew on. And when
24
+ * the answer repeats words from text that addressed the model with instructions, the answer goes back to the model
25
+ * once to be checked against the user's request (`decision: block` makes Claude Code continue); the user loses
26
+ * nothing but the time of that check.
27
+ */
28
+ export declare function flowStop(input: Record<string, unknown>, env?: NodeJS.ProcessEnv): FlowStopOutput | undefined;
29
+ //# sourceMappingURL=flow-guard-answer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-guard-answer.d.ts","sourceRoot":"","sources":["../src/flow-guard-answer.ts"],"names":[],"mappings":"AAiBA,iGAAiG;AACjG;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAU/C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,IAAI,CAqBrG;AAED;0GAC0G;AAC1G,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqBpD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKlD;AAED,kHAAkH;AAClH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAwBjE;AAED,MAAM,WAAW,cAAc;IAAG,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;AAE/F;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,cAAc,GAAG,SAAS,CA2CzH"}