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
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:
@@ -159,14 +159,23 @@ boucle (max N itérations):
|
||||
(les appels d'outils exigent la réponse complète avant exécution). Confirmations UI en deux temps
|
||||
(`confirmation` → `confirm`/`confirm_messages`).
|
||||
|
||||
### 3.4 Couche 4 — Serveur MCP
|
||||
### 3.4 Couche 4 — Serveur MCP (livré, phase E)
|
||||
|
||||
Nouveau `backend/mcp/server.py` basé sur le SDK MCP Python :
|
||||
`backend/mcp/server.py` s'appuie sur le SDK MCP Python (`mcp==1.9.4`) :
|
||||
|
||||
- **Tools** : enregistrés depuis le registry (mutations + recherche).
|
||||
- **Resources** : vaults/fichiers en lecture (`vault://name/path.md`).
|
||||
- **Prompts** : templates (résumer un dossier, générer une note…).
|
||||
- Transports : **stdio** (local) et **HTTP/SSE** (distant, auth JWT).
|
||||
- **Tools** : enregistrés depuis le registry (scope `mcp`). Les outils `read` sont exposés
|
||||
directement ; les outils `write`/`dangerous` le sont via la paire `propose_<tool>` /
|
||||
`apply_<tool>` (jeton signé, usage unique, TTL).
|
||||
- **Resources** : `vault://<name>` (vaults accessibles) et `vault://<name>/<path>` (fichiers,
|
||||
lecture seule, secrets redactés).
|
||||
- **Prompts** : `summarize-directory`, `generate-note`, `find-related`.
|
||||
- Transport : **Streamable HTTP** (`/mcp`, SDK `StreamableHTTPSessionManager` en
|
||||
`json_response=True`), auth `Authorization: Bearer <JWT>` → `get_current_user`. `stdio`
|
||||
optionnel plus tard.
|
||||
- Confirmations (E4) : `backend/mcp/confirmations.py` — jeton JWT (`type=mcp_confirmation`)
|
||||
contenant outil + arguments + utilisateur ; blacklist de JTI persistée pour l'anti-rejeu.
|
||||
- Le manager de session est démarré **paresseusement** à la première requête, pour fonctionner
|
||||
aussi bien sous uvicorn que sous le client de test (sans lifespan ASGI).
|
||||
|
||||
---
|
||||
|
||||
@@ -319,6 +328,8 @@ Voir `docs/ROADMAP.md` (item dédié) pour le détail des activités.
|
||||
- `backend/services/` — logique métier partagée (vaults, files, search, backups, graph, recent) consommée par les routes et les outils
|
||||
- `backend/ai_chat.py` — chat completion provider-agnostique avec tool calling et streaming (OpenAI-compat + Gemini)
|
||||
- `backend/agent/loop.py` — agent loop in-app (multi-étapes, LLM injectable)
|
||||
- `backend/mcp/server.py` — serveur MCP (Streamable HTTP `/mcp`, tools/resources/prompts)
|
||||
- `backend/mcp/confirmations.py` — jetons de confirmation signés (two-step, anti-rejeu)
|
||||
- `backend/bookslm.py`, `backend/bookslm_routes.py` — assistant contextuel (+ endpoint `/agent`)
|
||||
- `frontend/js/ai.js`, `frontend/js/bookslm.js` — UI IA
|
||||
- `backend/auth/middleware.py` — permissions
|
||||
|
||||
+3
-3
@@ -43,12 +43,12 @@
|
||||
### 79. Assistant IA — Outils (function calling) & serveur MCP
|
||||
|
||||
- **Effort :** 10-15 jours | **Impact :** 🟡
|
||||
- **Statut :** 🔵 Phase 0 + A2 + B1/B2/B3/B4/B5/B6/B7 + C + D + G livrés (2026-09-11). Détail complet : [features/ai-tools-mcp.md](./features/ai-tools-mcp.md)
|
||||
- **Statut :** 🔵 Phase 0 + A2 + B1/B2/B3/B4/B5/B6/B7 + C + D + E + G livrés (2026-09-11). Détail complet : [features/ai-tools-mcp.md](./features/ai-tools-mcp.md)
|
||||
- **Description :** Transformer l'assistant BooksLM en agent (lire, chercher, lister, ouvrir, modifier) via **function calling natif**, puis exposer ObsiGate à des **clients MCP externes** (Claude Desktop, Cursor…). Les deux fronts consomment une **couche d'outils partagée**.
|
||||
- **Reste à faire :**
|
||||
- [x] **C.** Catalogue lecture & recherche (vaults, read, backlinks, backups, search, tags)
|
||||
- [x] **D.** Catalogue mutations (create/edit/append/rename/move/delete) + confirmations two-step
|
||||
- [ ] **E.** Serveur MCP (Streamable HTTP `/mcp`, auth Bearer JWT, `propose`/`apply`, toggle par vault)
|
||||
- [x] **E.** Serveur MCP (Streamable HTTP `/mcp`, auth Bearer JWT, `propose`/`apply`, toggle par vault)
|
||||
- [ ] **F.** Durcissement (rate limiting, redaction secrets, OpenAPI + guide MCP, E2E)
|
||||
- **Documentation :** [AI_ARCHITECTURE_GUIDE.md](./AI_ARCHITECTURE_GUIDE.md) (architecture, catalogue d'outils, sécurité, phases).
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
|---|---|---|
|
||||
| ✅ Complété | #1 → #59, #61, #63–68, #71, #72, #74–76, #78 | ~82 jours réalisés |
|
||||
| 🔵 P2 restant | #77 Desktop : signature code (optionnel), wizard 1er lancement (optionnel), 6 tests E2E **manuels** | ~1-2 jours |
|
||||
| ⚪ P3 restant | #62 Collaboration Yjs (5-7j) · #79 Assistant IA outils + MCP (10-15j, Phase 0 + A2 + B + C + D + G livrés) · #80 Assistant IA UX (livré, en attente vérif) | ~15-22 jours |
|
||||
| ⚪ P3 restant | #62 Collaboration Yjs (5-7j) · #79 Assistant IA outils + MCP (10-15j, Phase 0 + A2 + B + C + D + E + G livrés) · #80 Assistant IA UX (livré, en attente vérif) | ~15-22 jours |
|
||||
| ⚪ P4 restant | #69 Mobile éditeur (2-3j) · #70 Sémantique (4-5j) · #73 Sync (6-8j) | 11-16 jours |
|
||||
| **Total restant** | **6 items + finitions** | **~27-39 jours** |
|
||||
|
||||
|
||||
@@ -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_*`)
|
||||
|
||||
Reference in New Issue
Block a user