overmind-mcp 2.8.21 β 2.8.23
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/dist/bridge/OverBridgeServer.d.ts +1 -0
- package/dist/bridge/OverBridgeServer.d.ts.map +1 -1
- package/dist/bridge/OverBridgeServer.js +35 -5
- package/dist/bridge/OverBridgeServer.js.map +1 -1
- package/dist/bridge/OverBridgeService.d.ts.map +1 -1
- package/dist/bridge/OverBridgeService.js +4 -0
- package/dist/bridge/OverBridgeService.js.map +1 -1
- package/docs/PLAN_REFACTORING_OVERMIND_V2.md +414 -0
- package/docs/PLAN_REFACTOR_OVERMIND_AGI.md +606 -0
- package/docs/doc_guide_agent_hermes_permanent.md +315 -0
- package/docs/doc_hermes_gateway.md +775 -0
- package/docs/guide_agent_hermes_overmind.md +403 -0
- package/docs/plan_securit/303/251.md +351 -0
- package/package.json +5 -1
- package/scripts/bridge-smoke-test.sh +238 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# π‘οΈ PLAN SΓCURITΓ OVERMIND β GuΓ©rison ComplΓ¨te
|
|
2
|
+
|
|
3
|
+
> **Date** : 28 Mai 2026
|
|
4
|
+
> **Auteur** : Sniper Analyste Financier (via audit Discord)
|
|
5
|
+
> **Relecteur** : sley_73350 (validation en cours)
|
|
6
|
+
> **Version** : 1.0 β Brouillon pour validation
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## π ΓTAT DES LIEUX β Diagnostic Critique
|
|
11
|
+
|
|
12
|
+
### Surface d'attaque actuelle
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
16
|
+
β TRANSPORT β PROTOCOLE β POINT D'ENTRΓE β AUTH? β PORT β
|
|
17
|
+
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
|
|
18
|
+
β STDIO β JSON-RPC 2.0 β stdin β stdout β β β N/A β
|
|
19
|
+
β HTTP Stream β JSON-RPC 2.0 β POST /mcp β β β 3099 β
|
|
20
|
+
β HTTP Stream β SSE β POST /mcp (stream) β β β 3099 β
|
|
21
|
+
β HTTP Stream β REST β GET /health β β β 3099 β
|
|
22
|
+
β HTTPS (SSL) β JSON-RPC 2.0 β POST /mcp β β β 3099 β
|
|
23
|
+
β HTTPS (SSL) β SSE β POST /mcp (stream) β β β 3099 β
|
|
24
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
25
|
+
|
|
26
|
+
π CONSTAT : TOUS les endpoints sont OUVERTS β 0 authentification cΓ΄tΓ© serveur
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 14 Outils MCP exposΓ©s sans protection
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
# β TOOL β RISQUE
|
|
33
|
+
ββββΌββββββββββββββββββββββββββΌββββββββββ
|
|
34
|
+
01 β run_agent β π΄ CRITIQUE
|
|
35
|
+
02 β run_agents_parallel β π΄ CRITIQUE
|
|
36
|
+
03 β create_agent β π ΓLEVΓ
|
|
37
|
+
04 β delete_agent β π ΓLEVΓ
|
|
38
|
+
05 β update_agent_config β π΄ CRITIQUE
|
|
39
|
+
06 β list_agents β π‘ MOYEN
|
|
40
|
+
07 β get_agent_configs β π΄ CRITIQUE (fuites clΓ©s API)
|
|
41
|
+
08 β create_prompt β π‘ MOYEN
|
|
42
|
+
09 β edit_prompt β π‘ MOYEN
|
|
43
|
+
10 β memory_search β π‘ MOYEN
|
|
44
|
+
11 β memory_store β π‘ MOYEN
|
|
45
|
+
12 β memory_runs β π’ FAIBLE
|
|
46
|
+
13 β config_example β π’ FAIBLE
|
|
47
|
+
14 β agent_control β π΄ CRITIQUE (kill process)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Modules bibliothΓ¨que β Couverture Bearer
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
MODULE β TYPE β ENVOIE BEARER β REΓOIT/VERIFY β STATUS
|
|
54
|
+
βββββββββββββββββββββββββΌββββββββββΌββββββββββββββββΌββββββββββββββββΌβββββββ
|
|
55
|
+
overmind-client.ts β Client β β
OUI β N/A β β
OK
|
|
56
|
+
cli.ts (serveur) β Serveur β N/A β β NON β π΄ GAP
|
|
57
|
+
server.ts (FastMCP) β Serveur β N/A β β NON β π΄ GAP
|
|
58
|
+
run_agent.ts β Tool β N/A β β NON β π΄ GAP
|
|
59
|
+
run_agents_parallel.ts β Tool β N/A β β NON β π΄ GAP
|
|
60
|
+
create_agent.ts β Tool β N/A β β NON β π΄ GAP
|
|
61
|
+
manage_agents.ts β Tool β N/A β β NON β π΄ GAP
|
|
62
|
+
memory_store.ts β Tool β N/A β β NON β π΄ GAP
|
|
63
|
+
memory_search.ts β Tool β N/A β β NON β π΄ GAP
|
|
64
|
+
agent_control.ts β Tool β N/A β β NON β π΄ GAP
|
|
65
|
+
config.ts β Config β N/A β β NON β π‘
|
|
66
|
+
processRegistry.ts β Runtime β N/A β β NON β π΄ GAP
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## ποΈ ARCHITECTURE CIBLE β AprΓ¨s GuΓ©rison
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
π MIDDLEWARE AUTH ACTIF π
|
|
75
|
+
ββββββββββββ Bearer ββββββββββββββββ ββββββββββββββ
|
|
76
|
+
β Client β βββββββββββΆ β FastMCP βββββΆβ 14 Tools β
|
|
77
|
+
β (TS/JS) β Header β β v4.0.1 β β MCP β
|
|
78
|
+
β β β β
CHECK β β β (protΓ©gΓ©s)β
|
|
79
|
+
ββββββββββββ ββββββββ¬ββββββββ ββββββββββββββ
|
|
80
|
+
β
|
|
81
|
+
ββββββββββββββ΄βββββββββββββ
|
|
82
|
+
β Transports sΓ©curisΓ©s β
|
|
83
|
+
βββββββββββββββββββββββββββ€
|
|
84
|
+
β stdio (pipe local) β
|
|
85
|
+
β httpStream (port 3099) β
|
|
86
|
+
β endpoint: /mcp β
|
|
87
|
+
β β
Bearer: REQUIRED β
|
|
88
|
+
β stateless: true β
|
|
89
|
+
β SSL: ACTIF β
|
|
90
|
+
βββββββββββββββββββββββββββ
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## π PLAN D'IMPLΓMENTATION β 5 Phases
|
|
96
|
+
|
|
97
|
+
### PHASE 1 β Middleware Serveur Bearer (PRIORITΓ MAX)
|
|
98
|
+
|
|
99
|
+
**Objectif** : Bloquer tout accès non authentifié sur HTTP/RPC
|
|
100
|
+
|
|
101
|
+
**Fichier cible** : `src/cli.ts` + `src/server.ts`
|
|
102
|
+
|
|
103
|
+
**TΓ’ches** :
|
|
104
|
+
- [ ] CrΓ©er `src/lib/bearerMiddleware.ts`
|
|
105
|
+
- Fonction `verifyBearer(request): boolean`
|
|
106
|
+
- Lecture `OVERMIND_AUTH` depuis `.env`
|
|
107
|
+
- Comparaison via `crypto.timingSafeEqual()` (anti timing attack)
|
|
108
|
+
- Retourner 401 + message JSON si token absent/invalide
|
|
109
|
+
- [ ] Injecter le middleware dans FastMCP httpStream
|
|
110
|
+
- Hook AVANT `server.start()`
|
|
111
|
+
- Exempter UNIQUEMENT `GET /health` (monitoring)
|
|
112
|
+
- Bloquer tout le reste si token absent
|
|
113
|
+
- [ ] Logger chaque accès (audit trail)
|
|
114
|
+
- IP source, timestamp, tool appelΓ©, rΓ©sultat auth
|
|
115
|
+
|
|
116
|
+
**Code de rΓ©fΓ©rence** :
|
|
117
|
+
```typescript
|
|
118
|
+
// src/lib/bearerMiddleware.ts
|
|
119
|
+
import crypto from 'crypto';
|
|
120
|
+
|
|
121
|
+
export function verifyBearer(authHeader: string | undefined): boolean {
|
|
122
|
+
const expected = process.env.OVERMIND_AUTH;
|
|
123
|
+
if (!expected) {
|
|
124
|
+
console.warn('[AUTH] β οΈ OVERMIND_AUTH non dΓ©fini β accΓ¨s refusΓ© par dΓ©faut');
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
if (!authHeader?.startsWith('Bearer ')) return false;
|
|
128
|
+
|
|
129
|
+
const token = authHeader.slice(7);
|
|
130
|
+
const expectedBuf = Buffer.from(expected);
|
|
131
|
+
const tokenBuf = Buffer.from(token);
|
|
132
|
+
|
|
133
|
+
if (tokenBuf.length !== expectedBuf.length) return false;
|
|
134
|
+
return crypto.timingSafeEqual(tokenBuf, expectedBuf);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Validation** :
|
|
139
|
+
- [ ] Tester sans token β 401
|
|
140
|
+
- [ ] Tester avec mauvais token β 401
|
|
141
|
+
- [ ] Tester avec bon token β 200
|
|
142
|
+
- [ ] GET /health sans token β 200 (exemptΓ©)
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### PHASE 2 β IntΓ©gration dans tous les modules de la bibliothΓ¨que
|
|
147
|
+
|
|
148
|
+
**Objectif** : Chaque module serveur vΓ©rifie le Bearer
|
|
149
|
+
|
|
150
|
+
**Fichiers cibles** :
|
|
151
|
+
- `src/cli.ts` (serveur principal)
|
|
152
|
+
- `src/server.ts` (FastMCP)
|
|
153
|
+
- Chaque tool MCP (run_agent, memory_store, etc.)
|
|
154
|
+
|
|
155
|
+
**TΓ’ches** :
|
|
156
|
+
- [ ] Importer `verifyBearer` dans chaque point d'entrΓ©e serveur
|
|
157
|
+
- [ ] Ajouter un wrapper `withAuth(toolHandler)` qui :
|
|
158
|
+
1. Extrait le header Authorization du contexte MCP
|
|
159
|
+
2. VΓ©rifie via `verifyBearer()`
|
|
160
|
+
3. Si Γ©chec β retourne erreur MCP avec code d'auth
|
|
161
|
+
4. Si succΓ¨s β exΓ©cute le tool normalement
|
|
162
|
+
- [ ] Valider que les 14 tools sont couverts
|
|
163
|
+
|
|
164
|
+
**Code de rΓ©fΓ©rence** :
|
|
165
|
+
```typescript
|
|
166
|
+
// src/lib/withAuth.ts
|
|
167
|
+
import { verifyBearer } from './bearerMiddleware';
|
|
168
|
+
|
|
169
|
+
export function withAuth(handler: Function) {
|
|
170
|
+
return async (args: any, context: any) => {
|
|
171
|
+
const authHeader = context?.request?.headers?.authorization;
|
|
172
|
+
if (!verifyBearer(authHeader)) {
|
|
173
|
+
throw new Error('[AUTH] β AccΓ¨s refusΓ© β Bearer token invalide');
|
|
174
|
+
}
|
|
175
|
+
return handler(args, context);
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### PHASE 3 β Propagation aux configs agents (.mcp.json)
|
|
183
|
+
|
|
184
|
+
**Objectif** : Chaque agent injecte le Bearer dans ses appels
|
|
185
|
+
|
|
186
|
+
**TΓ’ches** :
|
|
187
|
+
- [ ] VΓ©rifier que `overmind-client.ts` envoie bien le Bearer β
(dΓ©jΓ fait)
|
|
188
|
+
- [ ] Mettre Γ jour les templates `.mcp.json` des agents
|
|
189
|
+
- Ajouter `Authorization: Bearer ${OVERMIND_AUTH}` dans les headers
|
|
190
|
+
- [ ] Scripts externes β utiliser `OVERMIND_AUTH` depuis `.env`
|
|
191
|
+
- [ ] Documenter la variable dans le README Overmind
|
|
192
|
+
|
|
193
|
+
**Exemple .mcp.json** :
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"mcpServers": {
|
|
197
|
+
"overmind": {
|
|
198
|
+
"url": "http://localhost:3099/mcp",
|
|
199
|
+
"headers": {
|
|
200
|
+
"Authorization": "Bearer ${OVERMIND_AUTH}"
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### PHASE 4 β SSL/TLS + Durcissement RΓ©seau
|
|
210
|
+
|
|
211
|
+
**Objectif** : Chiffrer les communications + rΓ©duire la surface
|
|
212
|
+
|
|
213
|
+
**TΓ’ches** :
|
|
214
|
+
- [ ] Activer SSL sur le port 3099 (HTTPS)
|
|
215
|
+
- GΓ©nΓ©rer certificat auto-signΓ© ou Let's Encrypt
|
|
216
|
+
- Configurer dans FastMCP httpStream
|
|
217
|
+
- [ ] Restreindre le bind Γ `localhost` uniquement (sauf besoin externe)
|
|
218
|
+
- [ ] Ajouter rate-limiting sur les endpoints
|
|
219
|
+
- Max 100 req/min par IP
|
|
220
|
+
- Ban temporaire après 5 échecs d'auth consécutifs
|
|
221
|
+
- [ ] CORS restrictif (si besoin)
|
|
222
|
+
- [ ] Firewall : bloquer le port 3099 Γ l'extΓ©rieur sauf reverse proxy
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
### PHASE 5 β Audit Trail & Monitoring
|
|
227
|
+
|
|
228
|
+
**Objectif** : Traçabilité complète des accès
|
|
229
|
+
|
|
230
|
+
**TΓ’ches** :
|
|
231
|
+
- [ ] Logger chaque requΓͺte MCP :
|
|
232
|
+
- Timestamp ISO 8601
|
|
233
|
+
- IP source
|
|
234
|
+
- Tool appelΓ©
|
|
235
|
+
- RΓ©sultat auth (success/fail)
|
|
236
|
+
- Agent demandeur
|
|
237
|
+
- [ ] Stocker les logs dans PostgreSQL (table `audit_log`)
|
|
238
|
+
```sql
|
|
239
|
+
CREATE TABLE audit_log (
|
|
240
|
+
id SERIAL PRIMARY KEY,
|
|
241
|
+
timestamp TIMESTAMPTZ DEFAULT NOW(),
|
|
242
|
+
ip VARCHAR(45),
|
|
243
|
+
tool VARCHAR(100),
|
|
244
|
+
agent VARCHAR(100),
|
|
245
|
+
auth_result BOOLEAN,
|
|
246
|
+
details JSONB
|
|
247
|
+
);
|
|
248
|
+
```
|
|
249
|
+
- [ ] Alertes Discord automatiques :
|
|
250
|
+
- 3 Γ©checs d'auth consΓ©cutifs β alerte embed
|
|
251
|
+
- Tool critique appelΓ© β notification
|
|
252
|
+
- [ ] Dashboard simple (endpoint `/audit/stats`)
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## π§ͺ PLAN DE TEST β Validation par Phase
|
|
257
|
+
|
|
258
|
+
### Tests Phase 1 (Middleware)
|
|
259
|
+
```
|
|
260
|
+
TEST β DESCRIPTION β RΓSULTAT ATTENDU
|
|
261
|
+
ββββββΌβββββββββββββββββββββββββββββββββΌββββββββββββββββββ
|
|
262
|
+
T1.1 β curl POST /mcp sans header β 401 Unauthorized
|
|
263
|
+
T1.2 β curl POST /mcp mauvais token β 401 Unauthorized
|
|
264
|
+
T1.3 β curl POST /mcp bon token β 200 OK
|
|
265
|
+
T1.4 β curl GET /health sans token β 200 OK (exemptΓ©)
|
|
266
|
+
T1.5 β curl GET /health mauvais token β 200 OK (exemptΓ©)
|
|
267
|
+
T1.6 β Token vide β 401 Unauthorized
|
|
268
|
+
T1.7 β OVERMIND_AUTH non dΓ©fini β 500 / 403
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Tests Phase 2 (Couverture modules)
|
|
272
|
+
```
|
|
273
|
+
TEST β DESCRIPTION β RΓSULTAT ATTENDU
|
|
274
|
+
ββββββΌββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββ
|
|
275
|
+
T2.1 β Appeler run_agent sans Bearer β Erreur MCP auth
|
|
276
|
+
T2.2 β Appeler run_agent avec Bearer β ExΓ©cution normale
|
|
277
|
+
T2.3 β Appeler memory_search sans Bearer β Erreur MCP auth
|
|
278
|
+
T2.4 β Appeler agent_control sans Bearer β Erreur MCP auth
|
|
279
|
+
T2.5 β VΓ©rifier les 14 tools couverts β 14/14 β
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Tests Phase 3 (Propagation)
|
|
283
|
+
```
|
|
284
|
+
TEST β DESCRIPTION β RΓSULTAT ATTENDU
|
|
285
|
+
ββββββΌβββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββ
|
|
286
|
+
T3.1 β Agent Claude appelle overmind sans Bearer β Connexion refusΓ©e
|
|
287
|
+
T3.2 β Agent Kilo appelle overmind avec Bearer β Connexion OK
|
|
288
|
+
T3.3 β Script externe sans OVERMIND_AUTH β Γchec auth
|
|
289
|
+
T3.4 β Script externe avec OVERMIND_AUTH β SuccΓ¨s
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Tests Phase 4 (SSL + Durcissement)
|
|
293
|
+
```
|
|
294
|
+
TEST β DESCRIPTION β RΓSULTAT ATTENDU
|
|
295
|
+
ββββββΌβββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββ
|
|
296
|
+
T4.1 β AccΓ¨s HTTP (non SSL) β Connexion refusΓ©e
|
|
297
|
+
T4.2 β AccΓ¨s HTTPS avec cert valide β 200 OK
|
|
298
|
+
T4.3 β Rate limit : 100+ req/min β 429 Too Many
|
|
299
|
+
T4.4 β 5 Γ©checs auth consΓ©cutifs β Ban temporaire
|
|
300
|
+
T4.5 β Bind localhost uniquement β Pas d'accΓ¨s externe
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Tests Phase 5 (Audit)
|
|
304
|
+
```
|
|
305
|
+
TEST β DESCRIPTION β RΓSULTAT ATTENDU
|
|
306
|
+
ββββββΌβββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββ
|
|
307
|
+
T5.1 β Appel tool β vΓ©rifier log PostgreSQL β EntrΓ©e prΓ©sente
|
|
308
|
+
T5.2 β Γchec auth β vΓ©rifier log β EntrΓ©e avec auth_result=false
|
|
309
|
+
T5.3 β 3 Γ©checs consΓ©cutifs β alerte Discord β Embed envoyΓ©
|
|
310
|
+
T5.4 β GET /audit/stats β JSON statistiques
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## π PRIORISATION & EFFORT
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
PHASE β PRIORITΓ β EFFORT β IMPACT β DΓPENDANCE
|
|
319
|
+
βββββββΌββββββββββββββΌββββββββββββΌβββββββββββββΌββββββββββββ
|
|
320
|
+
1 β π΄ CRITIQUE β π‘ Moyen β π’ MAX β Aucune
|
|
321
|
+
2 β π ΓLEVΓ β π‘ Moyen β π’ ΓLEVΓ β Phase 1
|
|
322
|
+
3 β π‘ MOYEN β π’ Faible β π‘ MOYEN β Phase 1
|
|
323
|
+
4 β π‘ MOYEN β π΄ ΓLEVΓ β π’ ΓLEVΓ β Phase 1
|
|
324
|
+
5 β π’ FAIBLE β π‘ Moyen β π‘ MOYEN β Phase 1+2
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**Recommandation** : Phase 1 immΓ©diate β Phase 2 le mΓͺme jour β Phase 3 le lendemain β Phase 4-5 dans la semaine
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## π LIVRABLES
|
|
332
|
+
|
|
333
|
+
1. `src/lib/bearerMiddleware.ts` β Middleware de vΓ©rification Bearer
|
|
334
|
+
2. `src/lib/withAuth.ts` β Wrapper pour les handlers MCP
|
|
335
|
+
3. `.env` β Ajout de `OVERMIND_AUTH=<token_sΓ©curisΓ©>`
|
|
336
|
+
4. `audit_log` table PostgreSQL β TraΓ§abilitΓ©
|
|
337
|
+
5. Documentation mise Γ jour β README + SECURITY.md
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## β οΈ POINTS D'ATTENTION (Sley Γ vΓ©rifier)
|
|
342
|
+
|
|
343
|
+
- Le Bearer middleware doit-il Γͺtre dans `cli.ts` OU dans un hook FastMCP ?
|
|
344
|
+
- FastMCP v4.0.1 supporte-t-il un middleware natif ou faut-il un workaround Express ?
|
|
345
|
+
- STDIO doit-il aussi Γͺtre protΓ©gΓ© ou est-il trusted par design (local pipe) ?
|
|
346
|
+
- Le token doit-il Γͺtre rotatif ou statique ?
|
|
347
|
+
- Faut-il un système de scopes (admin vs lecture seule) ?
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
*π Document en attente de validation par sley_73350*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "overmind-mcp",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.23",
|
|
4
4
|
"description": "Orchestrateur universel agents IA multi-modeles via MCP. Inclut le protocole 'Custom-Nickname' pour identifier vos agents avec des surnoms originaux (The Chaos Prophet, Shadow Sniper, etc.), l'isolation mΓ©moire (Private Memory Context) et le support pour QwenCli et Nous Hermes. Installation automatique des dΓ©pendances Docker (PostgreSQL, pgvector) inclus.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"import": "./dist/index.js",
|
|
19
19
|
"types": "./dist/index.d.ts"
|
|
20
20
|
},
|
|
21
|
+
"./bridge": {
|
|
22
|
+
"import": "./dist/bridge/index.js",
|
|
23
|
+
"types": "./dist/bridge/index.d.ts"
|
|
24
|
+
},
|
|
21
25
|
"./package.json": "./package.json"
|
|
22
26
|
},
|
|
23
27
|
"files": [
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# Overmind Bridge - Smoke Test (post-install validation)
|
|
4
|
+
# ============================================================================
|
|
5
|
+
#
|
|
6
|
+
# Verifie en moins de 10s qu'un bridge nouvellement installe repond
|
|
7
|
+
# correctement. A lancer apres "systemctl start overmind-bridge".
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# ./scripts/bridge-smoke-test.sh
|
|
11
|
+
# ./scripts/bridge-smoke-test.sh --host 192.168.1.10 --port 3100
|
|
12
|
+
# ./scripts/bridge-smoke-test.sh --auth-token secret
|
|
13
|
+
#
|
|
14
|
+
# Exit codes:
|
|
15
|
+
# 0 = tous les tests OK
|
|
16
|
+
# 1 = au moins un test a echoue
|
|
17
|
+
#
|
|
18
|
+
# Dependances : bash 4+, curl, jq (optionnel)
|
|
19
|
+
# ============================================================================
|
|
20
|
+
|
|
21
|
+
set -uo pipefail
|
|
22
|
+
|
|
23
|
+
# === Defaults ===
|
|
24
|
+
HOST="127.0.0.1"
|
|
25
|
+
PORT="3100"
|
|
26
|
+
AUTH_TOKEN_VAL=""
|
|
27
|
+
ENV_FILE="/etc/overmind/bridge.env"
|
|
28
|
+
TIMEOUT=5
|
|
29
|
+
|
|
30
|
+
# === Couleurs, auto-desactivees si pas TTY ===
|
|
31
|
+
if [[ -t 1 ]]; then
|
|
32
|
+
C_RED=$'\033[0;31m'
|
|
33
|
+
C_GREEN=$'\033[0;32m'
|
|
34
|
+
C_YELLOW=$'\033[1;33m'
|
|
35
|
+
C_BLUE=$'\033[0;34m'
|
|
36
|
+
C_BOLD=$'\033[1m'
|
|
37
|
+
C_RESET=$'\033[0m'
|
|
38
|
+
else
|
|
39
|
+
C_RED=""
|
|
40
|
+
C_GREEN=""
|
|
41
|
+
C_YELLOW=""
|
|
42
|
+
C_BLUE=""
|
|
43
|
+
C_BOLD=""
|
|
44
|
+
C_RESET=""
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# === Args parsing ===
|
|
48
|
+
while [[ $# -gt 0 ]]; do
|
|
49
|
+
case "$1" in
|
|
50
|
+
--host) HOST="$2"; shift 2 ;;
|
|
51
|
+
--port) PORT="$2"; shift 2 ;;
|
|
52
|
+
--auth-token) AUTH_TOKEN_VAL="$2"; shift 2 ;;
|
|
53
|
+
--env-file) ENV_FILE="$2"; shift 2 ;;
|
|
54
|
+
--timeout) TIMEOUT="$2"; shift 2 ;;
|
|
55
|
+
-h|--help)
|
|
56
|
+
sed -n '2,20p' "$0" | sed 's/^# *//'
|
|
57
|
+
exit 0
|
|
58
|
+
;;
|
|
59
|
+
*)
|
|
60
|
+
echo "Unknown arg: $1" >&2
|
|
61
|
+
exit 2
|
|
62
|
+
;;
|
|
63
|
+
esac
|
|
64
|
+
done
|
|
65
|
+
|
|
66
|
+
# === Load token from env file si pas fourni ===
|
|
67
|
+
if [[ -z "${AUTH_TOKEN_VAL:-}" && -f "$ENV_FILE" ]]; then
|
|
68
|
+
AUTH_TOKEN_VAL="$(grep '^BRIDGE_AUTH_TOKEN=' "$ENV_FILE" | cut -d= -f2- | tr -d '"' | tr -d "'" || true)"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
BASE_URL="http://${HOST}:${PORT}"
|
|
72
|
+
PASS=0
|
|
73
|
+
FAIL=0
|
|
74
|
+
|
|
75
|
+
# === Helpers ===
|
|
76
|
+
have_jq() { command -v jq >/dev/null 2>&1; }
|
|
77
|
+
|
|
78
|
+
check() {
|
|
79
|
+
local name="$1"
|
|
80
|
+
local result="$2"
|
|
81
|
+
if [[ "$result" == "ok" ]]; then
|
|
82
|
+
echo -e " ${C_GREEN}OK${C_RESET} $name"
|
|
83
|
+
PASS=$((PASS + 1))
|
|
84
|
+
else
|
|
85
|
+
echo -e " ${C_RED}FAIL${C_RESET} $name"
|
|
86
|
+
FAIL=$((FAIL + 1))
|
|
87
|
+
fi
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
section() {
|
|
91
|
+
echo
|
|
92
|
+
echo -e "${C_BOLD}${C_BLUE}>> $1${C_RESET}"
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# === Banner ===
|
|
96
|
+
echo -e "${C_BOLD}=======================================================${C_RESET}"
|
|
97
|
+
echo -e "${C_BOLD} Overmind Bridge - Smoke Test${C_RESET}"
|
|
98
|
+
echo -e "${C_BOLD} Target: ${BASE_URL}${C_RESET}"
|
|
99
|
+
echo -e "${C_BOLD}=======================================================${C_RESET}"
|
|
100
|
+
|
|
101
|
+
# === Test 1 : service joignable ===
|
|
102
|
+
section "1. Reachability"
|
|
103
|
+
HTTP_CODE=$(curl -sS --max-time "$TIMEOUT" -o /dev/null -w "%{http_code}" \
|
|
104
|
+
"$BASE_URL/health" 2>/dev/null || echo "000")
|
|
105
|
+
if echo "$HTTP_CODE" | grep -qE '^(200|401|403)$'; then
|
|
106
|
+
check "HTTP /health repond [200/401/403]" ok
|
|
107
|
+
else
|
|
108
|
+
check "HTTP /health ne repond pas - bridge down" fail
|
|
109
|
+
echo
|
|
110
|
+
echo -e "${C_RED}Bridge inaccessible. Abandon.${C_RESET}"
|
|
111
|
+
echo -e " Verifier : ${C_YELLOW}systemctl status overmind-bridge${C_RESET}"
|
|
112
|
+
exit 1
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# === Test 2 : /health retourne un JSON valide ===
|
|
116
|
+
section "2. /health endpoint"
|
|
117
|
+
HEALTH_BODY=$(curl -sS --max-time "$TIMEOUT" "$BASE_URL/health" 2>/dev/null || true)
|
|
118
|
+
|
|
119
|
+
if have_jq; then
|
|
120
|
+
HEALTH_STATUS=$(echo "$HEALTH_BODY" | jq -r '.status // "missing"' 2>/dev/null)
|
|
121
|
+
else
|
|
122
|
+
HEALTH_STATUS=$(echo "$HEALTH_BODY" | grep -oE '"status"[[:space:]]*:[[:space:]]*"[^"]+"' | head -1 | cut -d'"' -f4)
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
if [[ -n "${HEALTH_STATUS:-}" && "$HEALTH_STATUS" != "missing" ]]; then
|
|
126
|
+
check "/health expose un status : $HEALTH_STATUS" ok
|
|
127
|
+
else
|
|
128
|
+
check "/health n expose pas de status - endpoint casse" fail
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# === Build AUTH_HEADER array for reuse ===
|
|
132
|
+
AUTH_HEADER=()
|
|
133
|
+
if [[ -n "${AUTH_TOKEN_VAL:-}" ]]; then
|
|
134
|
+
AUTH_HEADER=(-H "Authorization: Bearer ${AUTH_TOKEN_VAL}")
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# === Test 3 : auth requise si token configure ===
|
|
138
|
+
section "3. Authentication"
|
|
139
|
+
if [[ -n "${AUTH_TOKEN_VAL:-}" ]]; then
|
|
140
|
+
HTTP_NO_AUTH=$(curl -sS --max-time "$TIMEOUT" -o /dev/null -w "%{http_code}" \
|
|
141
|
+
-X POST "$BASE_URL/rpc" \
|
|
142
|
+
-H 'Content-Type: application/json' \
|
|
143
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"health.ping","params":{}}' 2>/dev/null || echo "000")
|
|
144
|
+
|
|
145
|
+
if [[ "$HTTP_NO_AUTH" == "401" ]]; then
|
|
146
|
+
check "Sans token -> 401, auth actif" ok
|
|
147
|
+
else
|
|
148
|
+
check "Sans token -> $HTTP_NO_AUTH [attendu: 401]" fail
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
HTTP_WITH_AUTH=$(curl -sS --max-time "$TIMEOUT" -o /dev/null -w "%{http_code}" \
|
|
152
|
+
-X POST "$BASE_URL/rpc" \
|
|
153
|
+
"${AUTH_HEADER[@]}" \
|
|
154
|
+
-H 'Content-Type: application/json' \
|
|
155
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"health.ping","params":{}}' 2>/dev/null || echo "000")
|
|
156
|
+
|
|
157
|
+
if [[ "$HTTP_WITH_AUTH" == "200" ]]; then
|
|
158
|
+
check "Avec token -> 200, auth OK" ok
|
|
159
|
+
else
|
|
160
|
+
check "Avec token -> $HTTP_WITH_AUTH [attendu: 200]" fail
|
|
161
|
+
fi
|
|
162
|
+
else
|
|
163
|
+
HTTP_OPEN=$(curl -sS --max-time "$TIMEOUT" -o /dev/null -w "%{http_code}" \
|
|
164
|
+
-X POST "$BASE_URL/rpc" \
|
|
165
|
+
-H 'Content-Type: application/json' \
|
|
166
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"health.ping","params":{}}' 2>/dev/null || echo "000")
|
|
167
|
+
|
|
168
|
+
if [[ "$HTTP_OPEN" == "200" ]]; then
|
|
169
|
+
check "/rpc ouvert, auth non configuree" ok
|
|
170
|
+
else
|
|
171
|
+
check "/rpc ouvert -> $HTTP_OPEN [attendu: 200]" fail
|
|
172
|
+
fi
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# === Test 4 : health.ping RPC ===
|
|
176
|
+
section "4. JSON-RPC methods"
|
|
177
|
+
PING_BODY=$(curl -sS --max-time "$TIMEOUT" \
|
|
178
|
+
"${AUTH_HEADER[@]}" \
|
|
179
|
+
-H 'Content-Type: application/json' \
|
|
180
|
+
-X POST "$BASE_URL/rpc" \
|
|
181
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"health.ping","params":{}}' 2>/dev/null || true)
|
|
182
|
+
|
|
183
|
+
if echo "$PING_BODY" | grep -q '"pong"[[:space:]]*:[[:space:]]*true'; then
|
|
184
|
+
check "RPC health.ping repond" ok
|
|
185
|
+
else
|
|
186
|
+
check "RPC health.ping echoue - body: ${PING_BODY:0:100}" fail
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
# === Test 5 : JSON-RPC validation (params invalides) ===
|
|
190
|
+
section "5. Error handling"
|
|
191
|
+
INVALID_BODY=$(curl -sS --max-time "$TIMEOUT" \
|
|
192
|
+
"${AUTH_HEADER[@]}" \
|
|
193
|
+
-H 'Content-Type: application/json' \
|
|
194
|
+
-X POST "$BASE_URL/rpc" \
|
|
195
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"agent.run","params":{}}' 2>/dev/null || true)
|
|
196
|
+
|
|
197
|
+
if echo "$INVALID_BODY" | grep -q '"code"[[:space:]]*:[[:space:]]*-32602'; then
|
|
198
|
+
check "Params invalides -> -32602 Invalid params" ok
|
|
199
|
+
else
|
|
200
|
+
check "Params invalides - code attendu: -32602, recu: $INVALID_BODY" fail
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
# === Test 6 : batch request ===
|
|
204
|
+
section "6. Batch RPC"
|
|
205
|
+
BATCH_BODY=$(curl -sS --max-time "$TIMEOUT" \
|
|
206
|
+
"${AUTH_HEADER[@]}" \
|
|
207
|
+
-H 'Content-Type: application/json' \
|
|
208
|
+
-X POST "$BASE_URL/rpc" \
|
|
209
|
+
-d '[\
|
|
210
|
+
{"jsonrpc":"2.0","id":1,"method":"health.ping","params":{}},\
|
|
211
|
+
{"jsonrpc":"2.0","id":2,"method":"health.ping","params":{}}\
|
|
212
|
+
]' 2>/dev/null || true)
|
|
213
|
+
|
|
214
|
+
BATCH_COUNT=$(echo "$BATCH_BODY" | grep -oE '"id"[[:space:]]*:[[:space:]]*[12]' | wc -l | tr -d ' ')
|
|
215
|
+
if [[ "$BATCH_COUNT" == "2" ]]; then
|
|
216
|
+
check "Batch RPC retourne 2 reponses" ok
|
|
217
|
+
else
|
|
218
|
+
check "Batch RPC - recu: $BATCH_COUNT reponses [attendu: 2]" fail
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
# === Resume ===
|
|
222
|
+
echo
|
|
223
|
+
echo -e "${C_BOLD}=======================================================${C_RESET}"
|
|
224
|
+
if [[ $FAIL -eq 0 ]]; then
|
|
225
|
+
echo -e "${C_GREEN}${C_BOLD} OK $PASS tests OK, 0 echec${C_RESET}"
|
|
226
|
+
echo -e "${C_GREEN} Bridge operationnel sur ${BASE_URL}${C_RESET}"
|
|
227
|
+
echo -e "${C_BOLD}=======================================================${C_RESET}"
|
|
228
|
+
exit 0
|
|
229
|
+
else
|
|
230
|
+
echo -e "${C_RED}${C_BOLD} FAIL $FAIL echec(s), $PASS tests OK${C_RESET}"
|
|
231
|
+
echo
|
|
232
|
+
echo -e " ${C_YELLOW}Diagnostic :${C_RESET}"
|
|
233
|
+
echo -e " 1. ${C_YELLOW}systemctl status overmind-bridge${C_RESET}"
|
|
234
|
+
echo -e " 2. ${C_YELLOW}journalctl -u overmind-bridge -n 100${C_RESET}"
|
|
235
|
+
echo -e " 3. ${C_YELLOW}curl -v $BASE_URL/health${C_RESET}"
|
|
236
|
+
echo -e "${C_BOLD}=======================================================${C_RESET}"
|
|
237
|
+
exit 1
|
|
238
|
+
fi
|