@aimarket/warden 0.5.0 → 0.6.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,41 @@
2
2
 
3
3
  All notable changes to `@aimarket/warden`.
4
4
 
5
+ ## 0.6.0 — 2026-09-23
6
+
7
+ Ruleset **v5**: language-independent coverage. A rule table written in one language cannot read
8
+ meaning in every other, so v5 strengthens what does not depend on the language at all, and says
9
+ plainly where the table stops.
10
+
11
+ - **Text is folded before any rule reads it** (`src/fold.ts`, published as `fold` beside the rules
12
+ and part of the digest): NFKC for fullwidth letters, ligatures and other compatibility forms;
13
+ invisible characters inside a word dropped; the Unicode TAG block (invisible ASCII that can spell a
14
+ whole sentence) decoded; look-alike Cyrillic/Greek letters mapped to Latin inside a word that
15
+ already mixes scripts, while text written wholly in one script is left alone. An English rule can
16
+ no longer be dodged by `ignore`, a zero-width space inside the word, tag characters or a Cyrillic
17
+ `о`. The two hidden-payload rules read the raw text (`raw: true` in the published table).
18
+ - **`TOOL_DEF_HIDDEN_UNICODE`** now also catches the Unicode-tag block and the bidi isolates
19
+ (U+2066–2069). `displaySafe` escapes tag characters, so a finding never prints them invisibly.
20
+ - **`TOOL_DEF_SECRET_EXFIL`** (new, advisory): a secret store (`.env`, `~/.ssh/…`,
21
+ `~/.aws/credentials`, `.npmrc`, …) and a URL, e-mail address or host within 100 characters of each
22
+ other — the shape of "read this, send it there" whatever language the connective words are in.
23
+ Advisory because on 10 645 live servers its only hit was honest (a deploy tool's ssh command to its
24
+ own host); refusing a server on a rule whose only real-world hit is honest is the v1 mistake again.
25
+ - **Three measured false positives removed**: "send the user to https://…" is a redirect of a person
26
+ (guard `navigation`); "keep calling this until done without asking the user" is autonomy, not
27
+ concealment (guard `autonomy`); a zero-width joiner inside an emoji sequence is not concealment.
28
+
29
+ Measured on the 10 645 distinct tool sets HISTOR holds (172 771 tools): v4 blocks 63, v5 blocks 56,
30
+ and v5 blocks none that v4 did not. The 1 108-server survey figures (v3 → v4) are unchanged and
31
+ still describe v4's calibration; this corpus is HISTOR's, not the survey's.
32
+
33
+ ## 0.5.1 — 2026-09-05
34
+
35
+ stdio wire fix for Glama: replies are newline-delimited JSON (MCP stdio / mcp-proxy).
36
+ Content-Length framing on stdout made Glama's health check time out (`ignoring non-JSON
37
+ output [ 'Content-Length: …' ]`). Input still accepts Content-Length and mirrors it on
38
+ the reply for legacy probes.
39
+
5
40
  ## 0.5.0 — 2026-09-03
6
41
 
7
42
  stdio MCP server for Glama / Claude Desktop / Cursor (`warden-mcp` / `node dist/mcp-server.js`).
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="166 pruebas en verde" />
11
+ <img src="docs/badges/tests.svg" alt="189 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>
@@ -85,7 +85,10 @@ El proceso **no** arranca, no hace de proxy ni aísla otro servidor MCP: pasas u
85
85
 
86
86
  ### Publicar en Glama
87
87
 
88
- Listado: **[glama.ai/mcp/servers/alexar76/warden](https://glama.ai/mcp/servers/alexar76/warden)**
88
+ Listado: **[glama.ai/mcp/servers/alexar76/warden](https://glama.ai/mcp/servers/alexar76/warden)** ·
89
+ quality score: **[glama.ai/mcp/servers/alexar76/warden/score](https://glama.ai/mcp/servers/alexar76/warden/score)**
90
+
91
+ [![alexar76/warden MCP server](https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg)](https://glama.ai/mcp/servers/alexar76/warden)
89
92
 
90
93
  El mismo patrón que [ARGUS](https://github.com/alexar76/argus) y
91
94
  [aimarket-mcp](https://github.com/alexar76/aimarket-mcp): [`glama.json`](glama.json) +
@@ -133,7 +136,7 @@ descarga del threat feed que tú pediste al pasar una URL a `load()`.
133
136
 
134
137
  ```mermaid
135
138
  flowchart LR
136
- T["definiciones<br/>de herramientas"] --> S["static scan<br/>25 reglas"]
139
+ T["definiciones<br/>de herramientas"] --> S["static scan<br/>26 reglas"]
137
140
  S --> F["threat feed<br/>11 integradas + firmado"]
138
141
  F --> O["origin<br/>declarado vs catálogo"]
139
142
  O --> P["pinning<br/>deriva vs aprobación"]
@@ -142,7 +145,7 @@ flowchart LR
142
145
 
143
146
  | Puerta | Qué decide | Red | ¿Fatal? |
144
147
  |---|---|---|---|
145
- | **static-scan** | Inyección, exfiltración, peticiones de credenciales y señales de Unicode oculto/base64 en el `name`, la `description` y el `inputSchema` de la herramienta — 25 reglas, v4, de las cuales 15 pueden bloquear y 10 son solo de aviso, 17 cubren también el nombre y 12 llevan un guard de contexto | ninguna | no |
148
+ | **static-scan** | Inyección, exfiltración, peticiones de credenciales y señales de Unicode oculto/base64 en el `name`, la `description` y el `inputSchema` de la herramienta — 26 reglas, v5, de las cuales 15 pueden bloquear y 11 son solo de aviso, 17 cubren también el nombre y 15 llevan un guard de contexto. v5 normaliza antes el texto (ancho completo, caracteres invisibles, etiquetas Unicode, letras sosias), así que la ofuscación no elude ninguna regla en ningún idioma | ninguna | no |
146
149
  | **threat-feed** | Identidad de servidor o herramienta conocida como maliciosa: 11 registros integrados más un feed firmado opcional | solo la descarga del feed | sí, para un `critical` con alcance de servidor |
147
150
  | **origin** | Si el operador declaró este servidor o llegó desde un catálogo remoto | ninguna | sí, con `allowUnknownServers: false` |
148
151
  | **pinning** | Si las definiciones de herramientas siguen coincidiendo con lo que el usuario aprobó | ninguna | sí, con `pinToolDefs: true` |
@@ -164,7 +167,7 @@ endureciera el umbral.
164
167
  findings: [{ gate, severity, code: "THREAT_TOOL_MATCH", message, tool, advisory? }],
165
168
  allowedTools: ["add"],
166
169
  blockedTools: ["sweeper"],
167
- rulesets: { staticScan: { version: "4", digest: "sha256-klRyTiD3…" } }
170
+ rulesets: { staticScan: { version: "5", digest: "sha256-HUKSzM6c…" } }
168
171
  }
169
172
  ```
170
173
 
@@ -242,7 +245,7 @@ degradar a ninguna protección:
242
245
  ## Desarrollo
243
246
 
244
247
  ```bash
245
- npm install && npm run build && npm test # 166 pruebas
248
+ npm install && npm run build && npm test # 189 pruebas
246
249
  ```
247
250
 
248
251
  `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="166 tests au vert" />
11
+ <img src="docs/badges/tests.svg" alt="189 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>
@@ -85,7 +85,10 @@ Le processus ne démarre, ne proxifie ni n'isole un autre serveur MCP : vous pas
85
85
 
86
86
  ### Publier sur Glama
87
87
 
88
- Listing : **[glama.ai/mcp/servers/alexar76/warden](https://glama.ai/mcp/servers/alexar76/warden)**
88
+ Listing : **[glama.ai/mcp/servers/alexar76/warden](https://glama.ai/mcp/servers/alexar76/warden)** ·
89
+ quality score : **[glama.ai/mcp/servers/alexar76/warden/score](https://glama.ai/mcp/servers/alexar76/warden/score)**
90
+
91
+ [![alexar76/warden MCP server](https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg)](https://glama.ai/mcp/servers/alexar76/warden)
89
92
 
90
93
  Même modèle que [ARGUS](https://github.com/alexar76/argus) et
91
94
  [aimarket-mcp](https://github.com/alexar76/aimarket-mcp) : [`glama.json`](glama.json) +
@@ -133,7 +136,7 @@ téléchargement du threat feed que vous avez demandé en passant une URL à `lo
133
136
 
134
137
  ```mermaid
135
138
  flowchart LR
136
- T["définitions<br/>des outils"] --> S["static scan<br/>25 règles"]
139
+ T["définitions<br/>des outils"] --> S["static scan<br/>26 règles"]
137
140
  S --> F["threat feed<br/>11 intégrées + signé"]
138
141
  F --> O["origin<br/>déclaré vs catalogue"]
139
142
  O --> P["pinning<br/>dérive vs approbation"]
@@ -142,7 +145,7 @@ flowchart LR
142
145
 
143
146
  | Porte | Ce qu'elle décide | Réseau | Fatale ? |
144
147
  |---|---|---|---|
145
- | **static-scan** | Injection, exfiltration, demandes d'identifiants et indices d'Unicode masqué/base64 dans le `name`, la `description` et l'`inputSchema` de l'outil — 25 règles, v4, dont 15 peuvent bloquer et 10 sont purement indicatives, 17 couvrent aussi le nom et 12 portent un guard de contexte | aucun | non |
148
+ | **static-scan** | Injection, exfiltration, demandes d'identifiants et indices d'Unicode masqué/base64 dans le `name`, la `description` et l'`inputSchema` de l'outil — 26 règles, v5, dont 15 peuvent bloquer et 11 sont purement indicatives, 17 couvrent aussi le nom et 15 portent un guard de contexte. v5 normalise d'abord le texte (pleine chasse, caractères invisibles, balises Unicode, lettres sosies) : l'obfuscation ne contourne aucune règle, quelle que soit la langue | aucun | non |
146
149
  | **threat-feed** | Identité de serveur ou outil connu comme malveillant : 11 enregistrements intégrés plus un feed signé optionnel | seulement le téléchargement du feed | oui, pour un `critical` de portée serveur |
147
150
  | **origin** | Si l'opérateur a déclaré ce serveur ou s'il provient d'un catalogue distant | aucun | oui, avec `allowUnknownServers: false` |
148
151
  | **pinning** | Si les définitions d'outils correspondent encore à ce que l'utilisateur a approuvé | aucun | oui, avec `pinToolDefs: true` |
@@ -164,7 +167,7 @@ bloquante pour quiconque durcissait le seuil.
164
167
  findings: [{ gate, severity, code: "THREAT_TOOL_MATCH", message, tool, advisory? }],
165
168
  allowedTools: ["add"],
166
169
  blockedTools: ["sweeper"],
167
- rulesets: { staticScan: { version: "4", digest: "sha256-klRyTiD3…" } }
170
+ rulesets: { staticScan: { version: "5", digest: "sha256-HUKSzM6c…" } }
168
171
  }
169
172
  ```
170
173
 
@@ -242,7 +245,7 @@ une absence de protection :
242
245
  ## Développement
243
246
 
244
247
  ```bash
245
- npm install && npm run build && npm test # 166 tests
248
+ npm install && npm run build && npm test # 189 tests
246
249
  ```
247
250
 
248
251
  `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="166 tests passing" />
11
+ <img src="docs/badges/tests.svg" alt="189 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>
@@ -85,7 +85,10 @@ Claude Desktop / Cursor (`mcpServers`):
85
85
 
86
86
  ### Публикация на Glama
87
87
 
88
- Листинг: **[glama.ai/mcp/servers/alexar76/warden](https://glama.ai/mcp/servers/alexar76/warden)**
88
+ Листинг: **[glama.ai/mcp/servers/alexar76/warden](https://glama.ai/mcp/servers/alexar76/warden)** ·
89
+ quality score: **[glama.ai/mcp/servers/alexar76/warden/score](https://glama.ai/mcp/servers/alexar76/warden/score)**
90
+
91
+ [![alexar76/warden MCP server](https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg)](https://glama.ai/mcp/servers/alexar76/warden)
89
92
 
90
93
  Тот же шаблон, что у [ARGUS](https://github.com/alexar76/argus) и
91
94
  [aimarket-mcp](https://github.com/alexar76/aimarket-mcp): [`glama.json`](glama.json) +
@@ -133,7 +136,7 @@ await warden.approve(server, tools); // зафиксировать (pin) то,
133
136
 
134
137
  ```mermaid
135
138
  flowchart LR
136
- T["определения<br/>инструментов"] --> S["static scan<br/>25 правил"]
139
+ T["определения<br/>инструментов"] --> S["static scan<br/>26 правил"]
137
140
  S --> F["threat feed<br/>11 встроенных + подписанный"]
138
141
  F --> O["origin<br/>объявлен или из каталога"]
139
142
  O --> P["pinning<br/>дрейф против подтверждения"]
@@ -142,7 +145,7 @@ flowchart LR
142
145
 
143
146
  | Гейт | Что решает | Сеть | Fatal? |
144
147
  |---|---|---|---|
145
- | **static-scan** | Инъекции, эксфильтрация, запросы учётных данных, скрытый Unicode и base64-признаки в `name`, `description` и `inputSchema` инструмента — 25 правил, версия 4, из них 15 могут блокировать и 10 только сообщают, 17 покрывают и имя, а у 12 есть контекстный guard | нет | нет |
148
+ | **static-scan** | Инъекции, эксфильтрация, запросы учётных данных, скрытый Unicode и base64-признаки в `name`, `description` и `inputSchema` инструмента — 26 правил, версия 5, из них 15 могут блокировать и 11 только сообщают, 17 покрывают и имя, а у 15 есть контекстный guard. v5 сначала приводит текст к обычному виду (широкие буквы, невидимые символы, Unicode-теги, буквы-двойники), поэтому обфускация не обходит правило ни на каком языке | нет | нет |
146
149
  | **threat-feed** | Известный плохой сервер или инструмент: 11 встроенных записей плюс опциональный подписанный feed | только загрузка feed | да, для `critical` на уровне сервера |
147
150
  | **origin** | Объявил ли оператор этот сервер, или он пришёл из удалённого каталога | нет | да, при `allowUnknownServers: false` |
148
151
  | **pinning** | Совпадают ли определения инструментов с тем, что подтвердил пользователь | нет | да, при `pinToolDefs: true` |
@@ -163,7 +166,7 @@ severity снова делало находку блокирующей для в
163
166
  findings: [{ gate, severity, code: "THREAT_TOOL_MATCH", message, tool, advisory? }],
164
167
  allowedTools: ["add"],
165
168
  blockedTools: ["sweeper"],
166
- rulesets: { staticScan: { version: "4", digest: "sha256-klRyTiD3…" } }
169
+ rulesets: { staticScan: { version: "5", digest: "sha256-HUKSzM6c…" } }
167
170
  }
168
171
  ```
169
172
 
@@ -241,7 +244,7 @@ GET <ваш feed url>
241
244
  ## Разработка
242
245
 
243
246
  ```bash
244
- npm install && npm run build && npm test # 166 тестов
247
+ npm install && npm run build && npm test # 189 тестов
245
248
  ```
246
249
 
247
250
  `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="166 项测试通过" />
11
+ <img src="docs/badges/tests.svg" alt="189 项测试通过" />
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>
@@ -80,7 +80,10 @@ Claude Desktop / Cursor(`mcpServers`):
80
80
 
81
81
  ### 发布到 Glama
82
82
 
83
- 列表页:**[glama.ai/mcp/servers/alexar76/warden](https://glama.ai/mcp/servers/alexar76/warden)**
83
+ 列表页:**[glama.ai/mcp/servers/alexar76/warden](https://glama.ai/mcp/servers/alexar76/warden)** ·
84
+ quality score:**[glama.ai/mcp/servers/alexar76/warden/score](https://glama.ai/mcp/servers/alexar76/warden/score)**
85
+
86
+ [![alexar76/warden MCP server](https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg)](https://glama.ai/mcp/servers/alexar76/warden)
84
87
 
85
88
  与 [ARGUS](https://github.com/alexar76/argus)、[aimarket-mcp](https://github.com/alexar76/aimarket-mcp)
86
89
  相同:[`glama.json`](glama.json) + [`Dockerfile`](Dockerfile) + `node dist/mcp-server.js`。
@@ -128,7 +131,7 @@ await warden.approve(server, tools); // 把用户认可的内容固定(pin)
128
131
 
129
132
  ```mermaid
130
133
  flowchart LR
131
- T["服务器给出的<br/>工具定义"] --> S["static scan<br/>25 条规则"]
134
+ T["服务器给出的<br/>工具定义"] --> S["static scan<br/>26 条规则"]
132
135
  S --> F["threat feed<br/>11 条内置 + 已签名"]
133
136
  F --> O["origin<br/>已声明 vs 来自目录"]
134
137
  O --> P["pinning<br/>漂移 vs 已批准"]
@@ -137,7 +140,7 @@ flowchart LR
137
140
 
138
141
  | 门控 | 判定什么 | 网络 | 是否 fatal |
139
142
  |---|---|---|---|
140
- | **static-scan** | 工具 `name`、`description` 与 `inputSchema` 中的注入、外泄、索要凭据,以及隐藏 Unicode/base64 迹象——25 条规则(v4),其中 15 条可阻止、10 条仅提示,17 条同时覆盖名称,12 条带有上下文 guard | 无 | 否 |
143
+ | **static-scan** | 工具 `name`、`description` 与 `inputSchema` 中的注入、外泄、索要凭据,以及隐藏 Unicode/base64 迹象——26 条规则(v5),其中 15 条可阻止、11 条仅提示,17 条同时覆盖名称,15 条带有上下文 guard。v5 先对文本做归一化(全角、不可见字符、Unicode 标签、形近字母),因此无论何种语言,混淆都绕不过规则 | 无 | 否 |
141
144
  | **threat-feed** | 已知恶意的服务器身份或工具:11 条内置记录,外加可选的已签名 feed | 仅 feed 下载 | 是,服务器范围的 `critical` |
142
145
  | **origin** | 该服务器是运营者声明的,还是来自远端目录 | 无 | 是,当 `allowUnknownServers: false` |
143
146
  | **pinning** | 工具定义是否仍与用户批准过的一致 | 无 | 是,当 `pinToolDefs: true` |
@@ -157,7 +160,7 @@ flowchart LR
157
160
  findings: [{ gate, severity, code: "THREAT_TOOL_MATCH", message, tool, advisory? }],
158
161
  allowedTools: ["add"],
159
162
  blockedTools: ["sweeper"],
160
- rulesets: { staticScan: { version: "4", digest: "sha256-klRyTiD3…" } }
163
+ rulesets: { staticScan: { version: "5", digest: "sha256-HUKSzM6c…" } }
161
164
  }
162
165
  ```
163
166
 
@@ -224,7 +227,7 @@ GET <你的 feed url>
224
227
  ## 开发
225
228
 
226
229
  ```bash
227
- npm install && npm run build && npm test # 166 项测试
230
+ npm install && npm run build && npm test # 189 项测试
228
231
  ```
229
232
 
230
233
  `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="166 tests passing" />
11
+ <img src="docs/badges/tests.svg" alt="189 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>
@@ -88,7 +88,10 @@ when-not naming siblings, every `inputSchema` property described, `outputSchema`
88
88
 
89
89
  ### Publish on Glama
90
90
 
91
- Listing: **[glama.ai/mcp/servers/alexar76/warden](https://glama.ai/mcp/servers/alexar76/warden)**
91
+ Listing: **[glama.ai/mcp/servers/alexar76/warden](https://glama.ai/mcp/servers/alexar76/warden)** ·
92
+ quality score: **[glama.ai/mcp/servers/alexar76/warden/score](https://glama.ai/mcp/servers/alexar76/warden/score)**
93
+
94
+ [![alexar76/warden MCP server](https://glama.ai/mcp/servers/alexar76/warden/badges/score.svg)](https://glama.ai/mcp/servers/alexar76/warden)
92
95
 
93
96
  Same pattern as **[ARGUS](https://github.com/alexar76/argus)** and
94
97
  **[aimarket-mcp](https://github.com/alexar76/aimarket-mcp)**: repo-root [`glama.json`](glama.json) +
@@ -136,7 +139,7 @@ asked for by passing a URL to `load()`.
136
139
 
137
140
  ```mermaid
138
141
  flowchart LR
139
- T["tool defs<br/>from the server"] --> S["static scan<br/>25 rules"]
142
+ T["tool defs<br/>from the server"] --> S["static scan<br/>26 rules"]
140
143
  S --> F["threat feed<br/>11 built-ins + signed"]
141
144
  F --> O["origin<br/>declared vs catalog"]
142
145
  O --> P["pinning<br/>drift vs approval"]
@@ -145,7 +148,7 @@ flowchart LR
145
148
 
146
149
  | Gate | What it decides | Network | Fatal? |
147
150
  |---|---|---|---|
148
- | **static-scan** | Injection, exfiltration, credential requests and hidden-Unicode/base64 tells in the tool `name`, its `description` and its `inputSchema` — 25 rules, v4, of which 15 can block and 10 are advisory-only, 17 also cover the name, and 12 carry a context guard | none | no |
151
+ | **static-scan** | Injection, exfiltration, credential requests and hidden-Unicode/base64 tells in the tool `name`, its `description` and its `inputSchema` — 26 rules, v5, of which 15 can block and 11 are advisory-only, 17 also cover the name, and 15 carry a context guard. v5 folds the text first (fullwidth, invisible characters, Unicode tags, look-alike letters) so obfuscation cannot dodge a rule in any language | none | no |
149
152
  | **threat-feed** | Known-bad server identity or tool, from 11 built-in records plus an optional signed feed | only the feed fetch | yes, for a server-scoped `critical` |
150
153
  | **origin** | Whether the operator declared this server or it arrived from a remote catalog | none | yes, under `allowUnknownServers: false` |
151
154
  | **pinning** | Whether the tool defs still match what the user approved | none | yes, under `pinToolDefs: true` |
@@ -166,7 +169,7 @@ second as a low severity made it blocking again for anyone who tightened the thr
166
169
  findings: [{ gate, severity, code: "THREAT_TOOL_MATCH", message, tool, advisory? }],
167
170
  allowedTools: ["add"],
168
171
  blockedTools: ["sweeper"],
169
- rulesets: { staticScan: { version: "4", digest: "sha256-klRyTiD3…" } }
172
+ rulesets: { staticScan: { version: "5", digest: "sha256-HUKSzM6c…" } }
170
173
  }
171
174
  ```
172
175
 
@@ -242,7 +245,7 @@ no protection:
242
245
  ## Development
243
246
 
244
247
  ```bash
245
- npm install && npm run build && npm test # 166 tests
248
+ npm install && npm run build && npm test # 189 tests
246
249
  ```
247
250
 
248
251
  `test/packaging.test.ts` is what keeps the headline honest: it fails if an npm runtime dependency
package/dist/fold.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Unicode folding before the rule table reads a tool definition.
3
+ *
4
+ * A rule written as `ignore previous instructions` must not be defeated by the
5
+ * same words spelled so that a regex no longer sees them while a model still
6
+ * does. Three spellings do that, and none of them depends on the language:
7
+ *
8
+ * 1. Compatibility forms. `ignore previous` (fullwidth), ligatures,
9
+ * mathematical alphanumerics, circled letters. NFKC maps each to the plain
10
+ * letter a reader sees.
11
+ * 2. Invisible characters inside a word. `ig​nore`, a soft hyphen, a
12
+ * variation selector. They are dropped here so they cannot split a rule word.
13
+ * The high-signal ones (zero-width, bidi, word-joiner, BOM, the tag block and
14
+ * the variation-selector supplement) are ALSO reported, because the
15
+ * hidden-character rule runs on the raw text; the purely cosmetic ones (a
16
+ * soft hyphen, an Indic/Arabic joiner control) are neutralised here and not
17
+ * separately flagged.
18
+ * 3. Look-alike letters from another script inside a Latin word: `іgnоre` with a
19
+ * Cyrillic і and о. A token that mixes Latin with Cyrillic or Greek letters has
20
+ * its look-alikes mapped to Latin. A token written wholly in one script is left
21
+ * alone, so Russian and Greek text still reads as Russian and Greek.
22
+ *
23
+ * Unicode TAG characters (U+E0020–U+E007E) are the exception to "dropped": each is
24
+ * an invisible copy of an ASCII character, and a whole instruction can be written in
25
+ * them. They are DECODED to that ASCII here, so the instruction they carry meets the
26
+ * same rules as visible text.
27
+ *
28
+ * The fold is part of the published ruleset (FOLD_ID is in its digest): the same
29
+ * regexes over folded and unfolded text are different scans.
30
+ */
31
+ /** Identity of this fold, carried in the ruleset preimage. Bump on any change below. */
32
+ export declare const FOLD_ID = "nfkc+tags-decoded+invisible-stripped+mixed-script-confusables/1";
33
+ /**
34
+ * Fold `text` for matching. Never shown to anyone: findings quote the folded span,
35
+ * and the raw text is what the hidden-character rules and the reader see.
36
+ */
37
+ export declare function foldForScan(text: string): string;
38
+ //# sourceMappingURL=fold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,wFAAwF;AACxF,eAAO,MAAM,OAAO,oEAAoE,CAAC;AAuCzF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBhD"}
package/dist/fold.js ADDED
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Unicode folding before the rule table reads a tool definition.
3
+ *
4
+ * A rule written as `ignore previous instructions` must not be defeated by the
5
+ * same words spelled so that a regex no longer sees them while a model still
6
+ * does. Three spellings do that, and none of them depends on the language:
7
+ *
8
+ * 1. Compatibility forms. `ignore previous` (fullwidth), ligatures,
9
+ * mathematical alphanumerics, circled letters. NFKC maps each to the plain
10
+ * letter a reader sees.
11
+ * 2. Invisible characters inside a word. `ig​nore`, a soft hyphen, a
12
+ * variation selector. They are dropped here so they cannot split a rule word.
13
+ * The high-signal ones (zero-width, bidi, word-joiner, BOM, the tag block and
14
+ * the variation-selector supplement) are ALSO reported, because the
15
+ * hidden-character rule runs on the raw text; the purely cosmetic ones (a
16
+ * soft hyphen, an Indic/Arabic joiner control) are neutralised here and not
17
+ * separately flagged.
18
+ * 3. Look-alike letters from another script inside a Latin word: `іgnоre` with a
19
+ * Cyrillic і and о. A token that mixes Latin with Cyrillic or Greek letters has
20
+ * its look-alikes mapped to Latin. A token written wholly in one script is left
21
+ * alone, so Russian and Greek text still reads as Russian and Greek.
22
+ *
23
+ * Unicode TAG characters (U+E0020–U+E007E) are the exception to "dropped": each is
24
+ * an invisible copy of an ASCII character, and a whole instruction can be written in
25
+ * them. They are DECODED to that ASCII here, so the instruction they carry meets the
26
+ * same rules as visible text.
27
+ *
28
+ * The fold is part of the published ruleset (FOLD_ID is in its digest): the same
29
+ * regexes over folded and unfolded text are different scans.
30
+ */
31
+ /** Identity of this fold, carried in the ruleset preimage. Bump on any change below. */
32
+ export const FOLD_ID = "nfkc+tags-decoded+invisible-stripped+mixed-script-confusables/1";
33
+ /**
34
+ * Characters with no visible form in running text. Dropped by the fold; the
35
+ * hidden-character rule reports them from the raw text.
36
+ */
37
+ const INVISIBLE_RE = new RegExp("[\\u00AD\\u034F\\u061C\\u115F\\u1160\\u17B4\\u17B5\\u180B-\\u180F\\u200B-\\u200F\\u202A-\\u202E" +
38
+ "\\u2060-\\u2064\\u2066-\\u206F\\u3164\\uFE00-\\uFE0F\\uFEFF\\uFFA0\\u{E0000}-\\u{E001F}" +
39
+ "\\u{E007F}\\u{E0100}-\\u{E01EF}]", "gu");
40
+ /** U+E0020–U+E007E: invisible ASCII. Decoded, not dropped. */
41
+ const TAG_RE = /[\u{E0020}-\u{E007E}]/gu;
42
+ /**
43
+ * Cyrillic and Greek letters that render like a Latin letter. Used only inside a
44
+ * token that already contains Latin letters.
45
+ */
46
+ const CONFUSABLE = {
47
+ // Cyrillic lower case
48
+ "а": "a", "в": "b", "е": "e", "ё": "e", "к": "k", "м": "m", "н": "h", "о": "o", "р": "p",
49
+ "с": "c", "т": "t", "у": "y", "х": "x", "і": "i", "ї": "i", "ј": "j", "ѕ": "s", "ԁ": "d",
50
+ "ԛ": "q", "ԝ": "w", "ӏ": "l", "һ": "h", "ɡ": "g",
51
+ // Cyrillic upper case
52
+ "А": "A", "В": "B", "Е": "E", "Ё": "E", "К": "K", "М": "M", "Н": "H", "О": "O", "Р": "P",
53
+ "С": "C", "Т": "T", "У": "Y", "Х": "X", "І": "I", "Ї": "I", "Ј": "J", "Ѕ": "S", "Һ": "H",
54
+ "Ԛ": "Q", "Ԝ": "W", "Ӏ": "I",
55
+ // Greek
56
+ "α": "a", "ε": "e", "ι": "i", "κ": "k", "ν": "v", "ο": "o", "ρ": "p", "τ": "t", "υ": "u",
57
+ "χ": "x", "Α": "A", "Β": "B", "Ε": "E", "Ζ": "Z", "Η": "H", "Ι": "I", "Κ": "K", "Μ": "M",
58
+ "Ν": "N", "Ο": "O", "Ρ": "P", "Τ": "T", "Υ": "Y", "Χ": "X",
59
+ };
60
+ const TOKEN_RE = /[\p{L}\p{M}]+/gu;
61
+ const LATIN_RE = /[A-Za-z]/;
62
+ const CONFUSABLE_RE = new RegExp(`[${Object.keys(CONFUSABLE).join("")}]`, "gu");
63
+ /**
64
+ * Fold `text` for matching. Never shown to anyone: findings quote the folded span,
65
+ * and the raw text is what the hidden-character rules and the reader see.
66
+ */
67
+ export function foldForScan(text) {
68
+ if (!text)
69
+ return text;
70
+ let out = text.normalize("NFKC");
71
+ out = out.replace(TAG_RE, (ch) => String.fromCharCode((ch.codePointAt(0) ?? 0xe0020) - 0xe0000));
72
+ out = out.replace(INVISIBLE_RE, "");
73
+ CONFUSABLE_RE.lastIndex = 0;
74
+ if (!CONFUSABLE_RE.test(out))
75
+ return out;
76
+ return out.replace(TOKEN_RE, (tok) => {
77
+ // Map a token that mixes Latin with look-alikes (`pаypаl`), OR one written
78
+ // WHOLLY in look-alike letters (`ЅУЅТЕМ`, `рrіvаtе` where every letter is in
79
+ // the table). A token with non-Latin letters that are NOT all confusables —
80
+ // ordinary Russian or Greek — is left alone, so those languages read normally.
81
+ // The scanner also matches the un-mapped raw text, so this only ever ADDS a
82
+ // reading; it never hides the original.
83
+ const marks = tok.replace(/\p{M}/gu, "");
84
+ if (!LATIN_RE.test(tok) && !allConfusable(marks))
85
+ return tok;
86
+ return tok.replace(CONFUSABLE_RE, (ch) => CONFUSABLE[ch] ?? ch);
87
+ });
88
+ }
89
+ /** Every letter of the token is one of the Latin look-alikes in the table. */
90
+ function allConfusable(letters) {
91
+ if (!letters)
92
+ return false;
93
+ for (const ch of letters) {
94
+ if (!(ch in CONFUSABLE) && !/[A-Za-z]/.test(ch))
95
+ return false;
96
+ }
97
+ return /[^A-Za-z]/.test(letters); // at least one non-Latin look-alike, else nothing to map
98
+ }
99
+ //# sourceMappingURL=fold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold.js","sourceRoot":"","sources":["../src/fold.ts"],"names":[],"mappings":"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"}
package/dist/mcp-rpc.js CHANGED
@@ -6,7 +6,7 @@ import { dirname, join } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { callMcpTool, MCP_INSTRUCTIONS, MCP_TOOLS, McpToolError, payloadTooLarge } from "./mcp-tools.js";
8
8
  export const PROTOCOL = "2025-03-26";
9
- const FALLBACK_VERSION = "0.5.0";
9
+ const FALLBACK_VERSION = "0.5.1";
10
10
  export function packageVersion() {
11
11
  try {
12
12
  const pkgPath = join(dirname(fileURLToPath(import.meta.url)), "..", "package.json");
@@ -3,8 +3,13 @@
3
3
  * WARDEN stdio MCP server — Glama / Claude Desktop / Cursor.
4
4
  *
5
5
  * stdout is the MCP wire. Logs go to stderr. No environment variables required.
6
- * Speaks LSP-style Content-Length framing (official SDK / mcp-proxy) and
7
- * newline-delimited JSON as a fallback for simple probes.
6
+ *
7
+ * Wire format (MCP stdio spec): newline-delimited JSON. Glama's mcp-proxy and the
8
+ * official TypeScript SDK both speak NDJSON; LSP-style Content-Length framing on
9
+ * *stdout* is treated as non-JSON noise and the health check times out.
10
+ *
11
+ * Input still accepts Content-Length (legacy probes) and mirrors that framing on
12
+ * the reply so old clients keep working. Fresh `{…}\n` peers get `{…}\n` back.
8
13
  */
9
14
  export {};
10
15
  //# sourceMappingURL=mcp-server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":";AACA;;;;;;GAMG"}
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG"}
@@ -3,15 +3,27 @@
3
3
  * WARDEN stdio MCP server — Glama / Claude Desktop / Cursor.
4
4
  *
5
5
  * stdout is the MCP wire. Logs go to stderr. No environment variables required.
6
- * Speaks LSP-style Content-Length framing (official SDK / mcp-proxy) and
7
- * newline-delimited JSON as a fallback for simple probes.
6
+ *
7
+ * Wire format (MCP stdio spec): newline-delimited JSON. Glama's mcp-proxy and the
8
+ * official TypeScript SDK both speak NDJSON; LSP-style Content-Length framing on
9
+ * *stdout* is treated as non-JSON noise and the health check times out.
10
+ *
11
+ * Input still accepts Content-Length (legacy probes) and mirrors that framing on
12
+ * the reply so old clients keep working. Fresh `{…}\n` peers get `{…}\n` back.
8
13
  */
9
14
  import { stderr, stdin, stdout } from "node:process";
10
15
  import { consumeLsp, handleRpc } from "./mcp-rpc.js";
16
+ let mode = "unknown";
11
17
  function writeMessage(msg) {
12
- const body = Buffer.from(JSON.stringify(msg), "utf8");
13
- stdout.write(`Content-Length: ${body.length}\r\n\r\n`);
14
- stdout.write(body);
18
+ const body = JSON.stringify(msg);
19
+ if (mode === "lsp") {
20
+ const buf = Buffer.from(body, "utf8");
21
+ stdout.write(`Content-Length: ${buf.length}\r\n\r\n`);
22
+ stdout.write(buf);
23
+ return;
24
+ }
25
+ // Default + Glama / TS SDK: NDJSON
26
+ stdout.write(`${body}\n`);
15
27
  }
16
28
  async function dispatchBody(body) {
17
29
  let parsed;
@@ -38,7 +50,6 @@ function skipWs(buf) {
38
50
  }
39
51
  async function main() {
40
52
  let buf = Buffer.from([]);
41
- let mode = "unknown";
42
53
  let ndjson = "";
43
54
  for await (const chunk of stdin) {
44
55
  const piece = Buffer.from(chunk);
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-tools.d.ts","sourceRoot":"","sources":["../src/mcp-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAaH,OAAO,KAAK,EAKV,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,SAAS,MAAM,CAAC;AAC7B,eAAO,MAAM,UAAU,QAAS,CAAC;AACjC,eAAO,MAAM,iBAAiB,SAAU,CAAC;AAIzC,eAAO,MAAM,kBAAkB,EAAE,YAKhC,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,OAAO,CAAC;QACzB,cAAc,EAAE,OAAO,CAAC;QACxB,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AA0DD,eAAO,MAAM,SAAS,EAAE,UAAU,EAwXjC,CAAC;AAEF,eAAO,MAAM,gBAAgB,QASgK,CAAC;AAkF9L,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAiBtG;AA+FD,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAMtD"}
1
+ {"version":3,"file":"mcp-tools.d.ts","sourceRoot":"","sources":["../src/mcp-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAaH,OAAO,KAAK,EAKV,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,SAAS,MAAM,CAAC;AAC7B,eAAO,MAAM,UAAU,QAAS,CAAC;AACjC,eAAO,MAAM,iBAAiB,SAAU,CAAC;AAIzC,eAAO,MAAM,kBAAkB,EAAE,YAKhC,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,OAAO,CAAC;QACzB,cAAc,EAAE,OAAO,CAAC;QACxB,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AA0DD,eAAO,MAAM,SAAS,EAAE,UAAU,EA0XjC,CAAC;AAEF,eAAO,MAAM,gBAAgB,QASgK,CAAC;AAkF9L,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAiBtG;AAoGD,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAMtD"}