docs: section vue générale et workflow des interactions MCP
This commit is contained in:
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user