feat(ai): serveur MCP Streamable HTTP + confirmations two-step (#79 phase E)
CI / lint (push) Successful in 1m3s
CI / security (push) Successful in 41s
CI / test (push) Successful in 1m20s
CI / build (push) Successful in 1m19s
CI / e2e (push) Successful in 10m56s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s

This commit is contained in:
2026-09-11 21:28:05 -04:00
parent 83c412b33d
commit 88eecd7671
9 changed files with 984 additions and 17 deletions
+12 -8
View File
@@ -1,6 +1,6 @@
# #79 — Assistant IA — Outils (function calling) & serveur MCP
> **Statut :** 🔵 En cours — Phase 0 + A2 + B1/B2/B3/B4/B5/B6/B7 + C + D + G livrés (2026-09-11)
> **Statut :** 🔵 En cours — Phase 0 + A2 + B1/B2/B3/B4/B5/B6/B7 + C + D + E + G livrés (2026-09-11)
> **Effort :** 10-15 jours | **Impact :** 🟡
> **Références :** [Roadmap](../ROADMAP.md) · [Guide d'architecture IA](../AI_ARCHITECTURE_GUIDE.md)
@@ -41,13 +41,17 @@
Toggle par vault `aiDestructiveTools` (défaut activé) pour désactiver les outils `DANGEROUS`.
Tests : `tests/test_tools_mutations.py` (40 tests).
## E. Serveur MCP (2-3 jours)
- [ ] **E1.** `backend/mcp/server.py` (SDK MCP Python) enregistrant les outils depuis le registry
- [ ] **E2.** Mapping des primitives : Tools (mutations + recherche), Resources (vaults/fichiers en lecture `vault://`), Prompts (templates)
- [ ] **E3.** Transport **Streamable HTTP** : endpoint `/mcp` dans FastAPI, auth `Authorization: Bearer <JWT>` → `get_current_user` (décision 2026-09-11). `stdio` optionnel plus tard
- [ ] **E4.** Confirmations : **two-step `propose_*`/`apply_*`** avec token signé (usage unique, TTL) ; élicitation optionnelle si le client l'annonce (décision 2026-09-11)
- [ ] **E5.** Toggle par vault pour désactiver les outils destructifs (défaut : activés)
- [ ] **E6.** Tests : handshake MCP, permissions par vault, mapping des ressources, anti-rejeu du token
## E. Serveur MCP (2-3 jours) — ✅ livré (2026-09-11)
- [x] **E1.** `backend/mcp/server.py` (SDK MCP Python `mcp==1.9.4`) enregistrant les outils depuis le registry
- [x] **E2.** Mapping des primitives : Tools (lecture + `propose_*`/`apply_*`), Resources (`vault://<name>`, `vault://<name>/<path>`), Prompts (`summarize-directory`, `generate-note`, `find-related`)
- [x] **E3.** Transport **Streamable HTTP** : route `/mcp` (matching exact + sous-chemins), auth `Authorization: Bearer <JWT>` → `get_current_user`. `stdio` optionnel plus tard
- [x] **E4.** Confirmations **two-step `propose_*`/`apply_*`** avec token JWT signé (usage unique, TTL `OBSIGATE_MCP_CONFIRMATION_TTL`, défaut 300 s) + blacklist de JTI persistée (`data/mcp_used_tokens.json`, anti-rejeu)
- [x] **E5.** Toggle par vault `aiDestructiveTools` appliqué à la proposition et à l'application
- [x] **E6.** Tests : `tests/test_mcp.py` (13 tests) — handshake `initialize`, `tools/list`/`tools/call`, resources, prompts, permissions par vault, anti-rejeu du token
- **Détail :** `backend/mcp/confirmations.py` (jetons signés + anti-rejeu) ; `backend/mcp/server.py`
(`Server` lowlevel + `StreamableHTTPSessionManager` en `json_response=True`, `McpMount` pour
matcher `/mcp` exact, démarrage paresseux du manager pour les tests). Dépendances ajoutées :
`mcp==1.9.4`, `sse-starlette==2.1.3` (compatibles avec FastAPI 0.110 / starlette 0.37).
## F. Durcissement & documentation (1 jour)
- [ ] **F1.** Rate limiting par token/outil + quotas (`BOOKSLM_MAX_*`)