# Guide Complet MCP (Model Context Protocol) ## 📘 Table des MatiĂšres 1. [Introduction au MCP](#introduction) 2. [Architecture du Serveur](#architecture) 3. [Configuration et Installation](#configuration) 4. [Utilisation avec N8N](#utilisation-n8n) 5. [API Endpoints](#api-endpoints) 6. [Exemples de RequĂȘtes](#exemples) 7. [Outils Disponibles](#outils) 8. [Troubleshooting](#troubleshooting) --- ## 1. Introduction au MCP {#introduction} Le **Model Context Protocol (MCP)** est un protocole standardisĂ© permettant aux modĂšles de langage (LLMs) d'interagir avec des applications externes via des outils structurĂ©s. ### Qu'est-ce que MCP ? - **Protocol Version**: 2025-06-18 - **Transport**: Streamable HTTP (remplace l'ancien HTTP+SSE) - **Format**: JSON-RPC 2.0 - **Architecture**: Client-Serveur avec session management ### Pourquoi utiliser MCP ? - ✅ Communication standardisĂ©e entre LLMs et applications - ✅ Outils typĂ©s avec validation de schĂ©ma - ✅ Support des sessions et de la reconnexion - ✅ Compatible avec N8N, Claude Desktop, et autres clients MCP --- ## 2. Architecture du Serveur {#architecture} ### Structure du Projet ``` Keep/ ├── mcp-server/ │ ├── index-sse.js # Serveur MCP principal │ ├── package.json # DĂ©pendances MCP SDK │ └── start-sse.ps1 # Script de dĂ©marrage ├── keep-notes/ │ ├── prisma/ │ │ └── dev.db # Base de donnĂ©es SQLite │ └── ... # Application Next.js └── MCP-GUIDE.md # Ce guide ``` ### Composants ClĂ©s #### 1. **Serveur MCP** (`index-sse.js`) - Port: **3001** - Endpoint principal: `/sse` - Base de donnĂ©es: Prisma + SQLite partagĂ©e avec keep-notes - Transport: `StreamableHTTPServerTransport` #### 2. **Serveur Next.js** (`keep-notes`) - Port: **3000** - Interface utilisateur web - Partage la mĂȘme base de donnĂ©es que MCP #### 3. **Base de donnĂ©es Prisma** ```prisma model Note { id String @id @default(uuid()) title String? content String type String @default("text") color String @default("default") checkItems String? // JSON labels String? // JSON images String? // JSON isPinned Boolean @default(false) isArchived Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } ``` --- ## 3. Configuration et Installation {#configuration} ### PrĂ©requis - Node.js 18+ - npm ou pnpm - AccĂšs rĂ©seau sur ports 3000 et 3001 ### Installation ```bash # 1. Installer les dĂ©pendances MCP cd mcp-server npm install # 2. VĂ©rifier Prisma Client cd ../keep-notes npx prisma generate ``` ### DĂ©marrage #### Serveur MCP ```powershell # Option 1: Script PowerShell cd mcp-server .\start-sse.ps1 # Option 2: Commande directe node index-sse.js ``` #### Serveur Next.js ```bash cd keep-notes npm run dev ``` ### VĂ©rification ```powershell # Tester le serveur MCP Invoke-RestMethod -Uri "http://localhost:3001/" | ConvertTo-Json # RĂ©sultat attendu: { "name": "Memento MCP SSE Server", "version": "1.0.0", "status": "running", "endpoints": { "sse": "/sse", "message": "/message" } } ``` --- ## 4. Utilisation avec N8N {#utilisation-n8n} ### Configuration du NƓud MCP Client #### Étape 1: Ajouter le nƓud 1. Glisser-dĂ©poser **"MCP Client"** dans le workflow 2. SĂ©lectionner **"HTTP Streamable"** comme transport 3. Configurer l'endpoint #### Étape 2: Configuration de base ```yaml Server Transport: HTTP Streamable MCP Endpoint URL: http://192.168.1.10:3001/sse Authentication: None ``` ⚠ **Important**: Utiliser l'IP locale correcte, pas `192.168.110` ou `127.0.0.1` #### Étape 3: DĂ©tecter l'IP locale ```powershell # Windows ipconfig # Chercher "Adresse IPv4" pour votre adaptateur rĂ©seau # Exemple: 192.168.1.10, 172.26.64.1, etc. ``` #### Étape 4: SĂ©lectionner un outil Une fois connectĂ©, N8N charge automatiquement la liste des 9 outils disponibles: - `create_note` - `get_notes` - `get_note` - `update_note` - `delete_note` - `search_notes` - `get_labels` - `toggle_pin` - `toggle_archive` --- ## 5. API Endpoints {#api-endpoints} ### Health Check **GET** `/` VĂ©rifier l'Ă©tat du serveur. ```bash curl http://localhost:3001/ ``` **RĂ©ponse:** ```json { "name": "Memento MCP SSE Server", "version": "1.0.0", "status": "running", "endpoints": { "sse": "/sse", "message": "/message" } } ``` ### MCP Endpoint **GET/POST** `/sse` Endpoint principal pour toutes les communications MCP. #### Initialisation (POST) ```bash curl -X POST http://localhost:3001/sse \ -H "Content-Type: application/json" \ -H "Accept: text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": { "name": "n8n-mcp-client", "version": "1.0.0" } } }' ``` **RĂ©ponse SSE Stream:** ``` event: message data: {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{}},"serverInfo":{"name":"memento-mcp-server","version":"1.0.0"}}} event: message data: {"jsonrpc":"2.0","method":"initialized"} ``` #### Stream SSE (GET) ```bash curl -H "Accept: text/event-stream" \ -H "Mcp-Session-Id: YOUR_SESSION_ID" \ http://localhost:3001/sse ``` --- ## 6. Exemples de RequĂȘtes {#exemples} ### Liste des Outils ```json POST /sse Content-Type: application/json Mcp-Session-Id: abc123... { "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} } ``` **RĂ©ponse:** ```json { "jsonrpc": "2.0", "id": 2, "result": { "tools": [ { "name": "create_note", "description": "Create a new note in Memento", "inputSchema": { "type": "object", "properties": { "title": { "type": "string" }, "content": { "type": "string" }, "color": { "type": "string", "default": "default" } }, "required": ["content"] } } // ... 8 autres outils ] } } ``` ### CrĂ©er une Note ```json POST /sse Content-Type: application/json Mcp-Session-Id: abc123... { "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "create_note", "arguments": { "title": "Ma premiĂšre note via MCP", "content": "Contenu de ma note créée depuis N8N", "color": "blue", "labels": ["mcp", "test"] } } } ``` **RĂ©ponse:** ```json { "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "{\"id\":\"uuid-123\",\"title\":\"Ma premiĂšre note via MCP\",\"content\":\"Contenu...\",\"color\":\"blue\",\"labels\":[\"mcp\",\"test\"],\"createdAt\":\"2026-01-04T...\"}" } ] } } ``` ### RĂ©cupĂ©rer Toutes les Notes ```json POST /sse Content-Type: application/json Mcp-Session-Id: abc123... { "jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": { "name": "get_notes", "arguments": {} } } ``` ### Rechercher des Notes ```json POST /sse { "jsonrpc": "2.0", "id": 5, "method": "tools/call", "params": { "name": "search_notes", "arguments": { "query": "rĂ©union" } } } ``` ### Épingler/DĂ©sĂ©pingler une Note ```json POST /sse { "jsonrpc": "2.0", "id": 6, "method": "tools/call", "params": { "name": "toggle_pin", "arguments": { "id": "uuid-123" } } } ``` --- ## 7. Outils Disponibles {#outils} ### 1. `create_note` CrĂ©er une nouvelle note. **ParamĂštres:** - `title` (string, optionnel) - Titre de la note - `content` (string, **requis**) - Contenu de la note - `color` (string) - Couleur parmi: default, red, orange, yellow, green, teal, blue, purple, pink, gray - `type` (string) - Type: "text" ou "checklist" - `checkItems` (array) - Items de checklist (si type=checklist) - `labels` (array[string]) - Tags/labels - `isPinned` (boolean) - Épingler la note - `isArchived` (boolean) - Archiver la note - `images` (array[string]) - Images base64 **Exemple:** ```json { "title": "Liste de courses", "content": "", "type": "checklist", "checkItems": [ {"id": "1", "text": "Lait", "checked": false}, {"id": "2", "text": "Pain", "checked": false} ], "color": "yellow", "labels": ["shopping"] } ``` ### 2. `get_notes` RĂ©cupĂ©rer toutes les notes non archivĂ©es. **ParamĂštres:** Aucun **Retour:** Array de notes ### 3. `get_note` RĂ©cupĂ©rer une note spĂ©cifique par ID. **ParamĂštres:** - `id` (string, **requis**) - UUID de la note ### 4. `update_note` Mettre Ă  jour une note existante. **ParamĂštres:** - `id` (string, **requis**) - UUID de la note - `title` (string, optionnel) - Nouveau titre - `content` (string, optionnel) - Nouveau contenu - `color` (string, optionnel) - Nouvelle couleur - `checkItems` (array, optionnel) - Nouveaux items - `labels` (array, optionnel) - Nouveaux labels - `images` (array, optionnel) - Nouvelles images ### 5. `delete_note` Supprimer dĂ©finitivement une note. **ParamĂštres:** - `id` (string, **requis**) - UUID de la note ⚠ **Attention:** Suppression irrĂ©versible ### 6. `search_notes` Rechercher des notes par mots-clĂ©s. **ParamĂštres:** - `query` (string, **requis**) - Texte Ă  rechercher **Recherche dans:** - Titres - Contenus - Labels - Items de checklist **Exemple:** ```json { "query": "rĂ©union 2026" } ``` ### 7. `get_labels` RĂ©cupĂ©rer tous les labels uniques utilisĂ©s. **ParamĂštres:** Aucun **Retour:** ```json { "content": [ { "type": "text", "text": "[\"work\",\"personal\",\"urgent\",\"mcp\"]" } ] } ``` ### 8. `toggle_pin` Épingler/dĂ©sĂ©pingler une note. **ParamĂštres:** - `id` (string, **requis**) - UUID de la note **Comportement:** Si Ă©pinglĂ©e → dĂ©sĂ©pingle, si non Ă©pinglĂ©e → Ă©pingle ### 9. `toggle_archive` Archiver/dĂ©sarchiver une note. **ParamĂštres:** - `id` (string, **requis**) - UUID de la note **Comportement:** Si archivĂ©e → dĂ©sarchive, si non archivĂ©e → archive --- ## 8. Troubleshooting {#troubleshooting} ### ❌ "Could not connect to your MCP server" **Causes possibles:** 1. Serveur MCP non dĂ©marrĂ© 2. IP incorrecte dans N8N 3. Firewall bloque le port 3001 **Solutions:** ```powershell # 1. VĂ©rifier si le serveur tourne Get-Process -Name node | Where-Object { (Get-NetTCPConnection -OwningProcess $_.Id -ErrorAction SilentlyContinue).LocalPort -eq 3001 } # 2. DĂ©tecter votre IP ipconfig | Select-String "IPv4" # 3. Tester la connexion Invoke-RestMethod -Uri "http://localhost:3001/" # 4. Tester depuis l'IP rĂ©seau Invoke-RestMethod -Uri "http://192.168.1.10:3001/" ``` ### ❌ "Could not load list" **Cause:** Serveur MCP ne rĂ©pond pas correctement au protocole Streamable HTTP **Solution:** 1. VĂ©rifier la version du SDK: ```bash cd mcp-server npm list @modelcontextprotocol/sdk # Doit ĂȘtre >= 1.0.4 ``` 2. RedĂ©marrer le serveur: ```powershell # Tuer tous les processus node Get-Process -Name node | Stop-Process -Force # Relancer cd mcp-server node index-sse.js ``` ### ❌ Port 3001 dĂ©jĂ  utilisĂ© ```powershell # Trouver le processus Get-Process -Name node | Where-Object { (Get-NetTCPConnection -OwningProcess $_.Id).LocalPort -eq 3001 } | Stop-Process -Force ``` ### ❌ Base de donnĂ©es verrouillĂ©e **Erreur:** `SQLITE_BUSY: database is locked` **Solution:** ```powershell # ArrĂȘter tous les serveurs Get-Process -Name node | Stop-Process -Force # VĂ©rifier qu'aucun processus n'accĂšde Ă  la DB lsof keep-notes/prisma/dev.db # Linux/Mac handle dev.db # Windows # RedĂ©marrer les serveurs ``` ### ❌ "Invalid session ID" **Cause:** Session expirĂ©e ou non initialisĂ©e **Solution:** Relancer la connexion depuis N8N (bouton "Execute Node") ### 🔍 Logs de DĂ©bogage Le serveur MCP affiche des logs dĂ©taillĂ©s: ``` New SSE connection from: 192.168.1.10 Session initialized: abc-123-def Received message: {"jsonrpc":"2.0","id":1,"method":"tools/call",...} Transport closed for session abc-123-def ``` **Activer plus de logs:** ```javascript // Dans index-sse.js, ajouter: console.log('Request body:', JSON.stringify(req.body, null, 2)); console.log('Response:', JSON.stringify(result, null, 2)); ``` --- ## 9. Workflow N8N Exemple ### Exemple: CrĂ©er une note Ă  partir d'un email ``` [Email Trigger] ↓ [MCP Client] → create_note ‱ title: {{ $json.subject }} ‱ content: {{ $json.body }} ‱ labels: ["email", "auto"] ‱ color: "blue" ↓ [Send Notification] ``` ### Exemple: Recherche et mise Ă  jour ``` [HTTP Request] (webhook) ↓ [MCP Client] → search_notes ‱ query: {{ $json.keyword }} ↓ [Code Node] (filtrer rĂ©sultats) ↓ [MCP Client] → update_note ‱ id: {{ $json.noteId }} ‱ labels: [...$json.existingLabels, "processed"] ``` ### Exemple: Backup quotidien ``` [Schedule Trigger] (daily 2am) ↓ [MCP Client] → get_notes ↓ [Convert to File] (JSON) ↓ [Save to Dropbox/Drive] ``` --- ## 10. AvancĂ© ### Sessions et Reconnexion Le serveur gĂšre automatiquement les sessions: - GĂ©nĂšre un UUID unique par session - Retourne `Mcp-Session-Id` dans le header de rĂ©ponse - Accepte la reconnexion avec le mĂȘme session ID - Nettoie automatiquement les sessions fermĂ©es ### Streaming SSE Le serveur peut envoyer des notifications au client via SSE: ```javascript // CĂŽtĂ© serveur (exemple futur) transport.send({ jsonrpc: '2.0', method: 'notifications/resources/updated', params: { uri: 'notes://123' } }); ``` ### SĂ©curitĂ© ⚠ **Important pour la production:** 1. **Bind Ă  localhost uniquement:** ```javascript app.listen(PORT, '127.0.0.1'); // Pas 0.0.0.0 ``` 2. **Ajouter authentication:** ```javascript app.use((req, res, next) => { const token = req.headers.authorization; if (token !== 'Bearer SECRET_TOKEN') { return res.status(401).send('Unauthorized'); } next(); }); ``` 3. **Validation Origin:** ```javascript const allowedOrigins = ['http://localhost:3000']; if (!allowedOrigins.includes(req.headers.origin)) { return res.status(403).send('Forbidden'); } ``` --- ## 11. Ressources ### Documentation Officielle - MCP Spec: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports - TypeScript SDK: https://github.com/modelcontextprotocol/typescript-sdk ### Exemples de Code - MCP Examples: https://github.com/modelcontextprotocol/typescript-sdk/tree/main/examples/server ### Support - GitHub Issues: https://github.com/modelcontextprotocol/typescript-sdk/issues - Discord: https://discord.gg/modelcontextprotocol --- ## 12. Changelog ### Version 1.0.0 (2026-01-04) - ✅ ImplĂ©mentation Streamable HTTP transport - ✅ 9 outils de gestion de notes - ✅ Support des sessions - ✅ IntĂ©gration Prisma - ✅ Compatible N8N ### AmĂ©liorations Futures - [ ] Authentication OAuth - [ ] WebSocket transport - [ ] Notifications temps rĂ©el - [ ] Backup/restore automatique - [ ] Rate limiting --- **Auteur:** MCP Memento Server **Version:** 1.0.0 **Date:** 2026-01-04 **Licence:** MIT