docs: section vue générale et workflow des interactions MCP
FlowDeck CI / test (push) Failing after 17s
FlowDeck CI / docker (push) Skipped

This commit is contained in:
2026-09-08 08:53:04 -04:00
parent bb12763a41
commit f84ff201ea
+106
View File
@@ -13,6 +13,9 @@
1. [Verdict : est-ce une bonne idée ?](#1-verdict) 1. [Verdict : est-ce une bonne idée ?](#1-verdict)
2. [Ce que FlowDeck a déjà (l'essentiel est fait)](#2-ce-que-flowdeck-a-déjà) 2. [Ce que FlowDeck a déjà (l'essentiel est fait)](#2-ce-que-flowdeck-a-déjà)
3. [Positionnement : deux rôles complémentaires](#3-positionnement) 3. [Positionnement : deux rôles complémentaires](#3-positionnement)
- [3.1 Vue générale des interactions](#31-vue-générale-des-interactions)
- [3.2 Workflow d'un échange avec un agent externe](#32-workflow-dun-échange-avec-un-agent-externe)
- [3.3 Les agents internes passent-ils par le MCP ?](#33-les-agents-internes-passent-ils-par-le-mcp-)
4. [Architecture cible](#4-architecture-cible) 4. [Architecture cible](#4-architecture-cible)
5. [Services offerts par le serveur MCP](#5-services-offerts) 5. [Services offerts par le serveur MCP](#5-services-offerts)
6. [Plan d'implémentation pas à pas](#6-plan-dimplémentation) 6. [Plan d'implémentation pas à pas](#6-plan-dimplémentation)
@@ -116,6 +119,109 @@ Deux surfaces agentiques, complémentaires — **ne pas confondre** :
Le serveur MCP **ne contient pas de LLM** : il exécute les outils demandés par le client. C'est le client Le serveur MCP **ne contient pas de LLM** : il exécute les outils demandés par le client. C'est le client
(claude, cursor, openclaw…) qui décide quoi appeler. Le code de raisonnement n'est pas dupliqué. (claude, cursor, openclaw…) qui décide quoi appeler. Le code de raisonnement n'est pas dupliqué.
### 3.1 Vue générale des interactions {#31-vue-générale-des-interactions}
Deux portes d'entrée distinctes, **un seul socle commun** :
```
CHEMIN A — AGENTS EXTERNES CHEMIN B — AGENT INTERNE
(serveur MCP, NOUVEAU) (UI existante, INCHANGÉE)
Claude Desktop ─┐ Utilisateur (navigateur)
Cursor ├─ MCP stdio ───┐ │
OpenClaw/Hermes ├─ MCP HTTP ────┼──┐ │ chat 🤖 + @mentions
npx mcp-remote ─┘ │ │ ▼
┌───────────▼──▼──────────────┐ ┌─────────────────────────┐
│ Serveur MCP │ │ AgentEngine (ReAct) │
│ app/mcp_server.py │ │ boucle raisonnement↔act │
│ auth token `fd_*` │ │ streaming SSE vers l'UI │
└───────────┬─────────────────┘ └────────────┬────────────┘
│ calls d'outils │ function calls
┌───────────▼──────────────────────────────────▼─────────────┐
│ ToolRegistry — 22 outils │
│ search · read · create · update · delete · gitea · … │
└───────────┬────────────────────────────────────────────────┘
│
┌───────────▼───────────────┐
│ PermissionManager │ ← mêmes ACL pour les deux chemins
│ agent_actions (audit+undo)│
└───────────┬───────────────┘
│
┌───────────▼───────────────┐
│ SQLite · API Gitea/GitHub │
└───────────────────────────┘
```
**À retenir :** les agents externes (chemin A) et l'agent interne (chemin B) ne se rencontrent
jamais « en vol » — ils **convergent** sur le même `ToolRegistry`, passent par les mêmes
`PermissionManager` et le même journal `agent_actions`. Une action faite par Claude Desktop arrive
au même endroit et avec les mêmes règles qu'une action faite par l'agent intégré au navigateur.
### 3.2 Workflow d'un échange avec un agent externe {#32-workflow-dun-échange-avec-un-agent-externe}
Exemple réel : un utilisateur demande à Claude Desktop *« crée une collection Sprint 27 avec les
issues ouvertes du dépôt bruno/flowdeck »*.
```
Claude Desktop Serveur MCP ToolRegistry / Perms / SQLite
│ │ │
│ 1. initialize (handshake) │ │
│─────────────────────────────▶│ │
│ 2. tools/list │ │
│─────────────────────────────▶│ │
│ ◀── 22 outils + schémas │ │
│ (JSON Schema exacts) │ │
│ │ │
│ 3. tools/call │ │
│ "sync_gitea" │ │
│ {owner:"bruno", │ │
│ repo:"flowdeck"} │ │
│─────────────────────────────▶│ 4. résolution user_id │
│ │ (Bearer fd_* → users.id) │
│ │ 5. PermissionManager │
│ │ assert_can(...) │
│ │ 6. execute() → GET issues │
│ │ Gitea + INSERT collection│
│ │ 7. journal agent_actions │
│ │ (payload + undo snapshot)│
│ ◀── résultat JSON │ │
│ {status:"success", │ │
│ data:{collection_id, │ │
│ issues:N}} │ │
│ │ │
│ 8. tools/call "create_page" │ (même séquence 4→7 : │
│ … contenu du CR… │ perms → execute → audit) │
```
Le client MCP orchestre : il décide seul d'enchaîner `sync_gitea` puis `create_page` (ou
`create_document`, `create_gitea_issue`…). Le serveur ne fait que **vérifier, exécuter, auditer** —
l'équivalent de ce que fait `AgentEngine` côté interne, mais sans LLM et sans streaming UI.
### 3.3 Les agents internes passent-ils par le MCP ? {#33-les-agents-internes-passent-ils-par-le-mcp-}
**Non. L'agent interne continue d'appeler directement le `ToolRegistry`** — et c'est une décision
d'architecture, pas un oubli. Le serveur MCP est la porte d'entrée des agents **externes uniquement**.
| Critère | Agent interne → ToolRegistry (direct) | Agent interne → serveur MCP (contournement) |
|---|---|---|
| Streaming SSE (raisonnement + actions live) | événements natifs | **perdu** — le MCP est atomique requête/réponse |
| Contexte (user, workspace, @mentions, page ouverte) | déjà en mémoire dans `AgentEngine` | à re-transmettre à chaque appel |
| Mode approval interactif (`confirm`) | fonctionne (dialogue dans l'UI) | impossible — pas d'humain pour confirmer |
| Surcharge | aucune | sérialisation JSON-RPC + re-auth à chaque outil |
| Bénéfice | — | **aucun** : mêmes outils, mêmes permissions, même base |
Un mauvais aiguillage (agent interne → MCP → ToolRegistry) créerait une boucle hermétique :
l'agent interne n'est pas un « agent externe », il vit **dans** FlowDeck et possède déjà tout ce
dont le MCP aurait besoin d'être re-sécurisé. Réutiliser le serveur MCP en interne reviendrait à
faire transiter des appels locaux par un protocole réseau sans protection supplémentaire.
**Ce que ça ne change pas :** les deux chemins respectent exactement les mêmes règles
(permissions, audit, rollback), donc un agent externe ne peut ni voir ni modifier plus de choses
que l'agent interne ou l'utilisateur lui-même. Et si un jour l'agent interne doit *consommer*
des serveurs MCP externes (rôle client, façon « External Agents » de Notion), c'est une
fonctionnalité séparée — documentée dans `Guide_Complet_Notion_AI.md` — qui n'entre pas en conflit
avec le serveur décrit ici.
--- ---
## 4. Architecture cible {#4-architecture-cible} ## 4. Architecture cible {#4-architecture-cible}