Keep/MCP-GUIDE.md
sepehr 355ffb59bb feat: Add robust Undo/Redo system and improve note input
- Implement useUndoRedo hook with proper state management (max 50 history)
- Add Undo/Redo buttons with keyboard shortcuts (Ctrl+Z/Ctrl+Y)
- Fix image upload with proper sizing (max-w-full max-h-96 object-contain)
- Add image validation (type and 5MB size limit)
- Implement reminder system with date validation
- Add comprehensive input validation with user-friendly error messages
- Improve error handling with try-catch blocks
- Add MCP-GUIDE.md with complete MCP documentation and examples

Breaking changes: None
Production ready: Yes
2026-01-04 14:22:36 +01:00

15 KiB

Guide Complet MCP (Model Context Protocol)

📘 Table des Matières

  1. Introduction au MCP
  2. Architecture du Serveur
  3. Configuration et Installation
  4. Utilisation avec N8N
  5. API Endpoints
  6. Exemples de Requêtes
  7. Outils Disponibles
  8. Troubleshooting

1. Introduction au MCP

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

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

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

Prérequis

  • Node.js 18+
  • npm ou pnpm
  • Accès réseau sur ports 3000 et 3001

Installation

# 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

# Option 1: Script PowerShell
cd mcp-server
.\start-sse.ps1

# Option 2: Commande directe
node index-sse.js

Serveur Next.js

cd keep-notes
npm run dev

Vérification

# 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

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

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

# 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

Health Check

GET /

Vérifier l'état du serveur.

curl http://localhost:3001/

Réponse:

{
  "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)

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)

curl -H "Accept: text/event-stream" \
     -H "Mcp-Session-Id: YOUR_SESSION_ID" \
     http://localhost:3001/sse

6. Exemples de Requêtes

Liste des Outils

POST /sse
Content-Type: application/json
Mcp-Session-Id: abc123...

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list",
  "params": {}
}

Réponse:

{
  "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

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:

{
  "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

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

POST /sse

{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "search_notes",
    "arguments": {
      "query": "réunion"
    }
  }
}

Épingler/Désépingler une Note

POST /sse

{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "tools/call",
  "params": {
    "name": "toggle_pin",
    "arguments": {
      "id": "uuid-123"
    }
  }
}

7. Outils Disponibles

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:

{
  "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:

{
  "query": "réunion 2026"
}

7. get_labels

Récupérer tous les labels uniques utilisés.

Paramètres: Aucun

Retour:

{
  "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

"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:

# 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:
cd mcp-server
npm list @modelcontextprotocol/sdk
# Doit être >= 1.0.4
  1. Redémarrer le serveur:
# 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é

# 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:

# 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:

// 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:

// 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:
app.listen(PORT, '127.0.0.1');  // Pas 0.0.0.0
  1. Ajouter authentication:
app.use((req, res, next) => {
  const token = req.headers.authorization;
  if (token !== 'Bearer SECRET_TOKEN') {
    return res.status(401).send('Unauthorized');
  }
  next();
});
  1. Validation Origin:
const allowedOrigins = ['http://localhost:3000'];
if (!allowedOrigins.includes(req.headers.origin)) {
  return res.status(403).send('Forbidden');
}

11. Ressources

Documentation Officielle

Exemples de Code

Support


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