- Add debounced state updates for title and content (500ms delay) - Immediate UI updates with delayed history saving - Prevent one-letter-per-undo issue - Add cleanup for debounce timers on unmount
7.6 KiB
7.6 KiB
MCP et SSE (Server-Sent Events) - Analyse
Question
Peut-on utiliser le MCP en SSE?
Réponse: OUI ✅ (avec nuances)
Le SDK MCP (@modelcontextprotocol/sdk) supporte plusieurs transports, dont certains utilisent SSE.
Transports MCP Disponibles
1. stdio (Actuellement utilisé) ✅
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
Avantages:
- Simple, direct, pas de réseau
- Idéal pour processus locaux
- Utilisé par Claude Desktop, Cline, etc.
Inconvénients:
- ❌ Nécessite accès fichier local
- ❌ Pas adapté pour N8N sur machine distante
- ❌ N8N doit avoir accès à
D:/dev_new_pc/Keep/mcp-server/index.js
2. SSE via HTTP ✅ (RECOMMANDÉ pour N8N distant!)
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
Avantages:
- ✅ Fonctionne sur le réseau (parfait pour N8N distant!)
- ✅ Connexion persistante unidirectionnelle
- ✅ Standard HTTP/HTTPS
- ✅ Pas de WebSocket nécessaire
- ✅ Compatible avec la plupart des firewalls
Comment ça marche:
- Client (N8N) se connecte à
http://your-ip:3001/sse - Serveur maintient la connexion ouverte
- Envoie des événements SSE au format
data: {...}\n\n - Client peut envoyer des requêtes via POST sur
/message
3. HTTP avec WebSockets (Alternative)
// Pas officiellement documenté dans SDK 1.0.4
// Mais possible avec implémentation custom
Configuration SSE pour Memento MCP Server
Option A: Créer un serveur SSE séparé
Fichier: mcp-server/index-sse.js
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import express from 'express';
import { PrismaClient } from '@prisma/client';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const app = express();
const PORT = 3001;
// Initialize Prisma
const prisma = new PrismaClient({
datasources: {
db: {
url: `file:${join(__dirname, '../keep-notes/prisma/dev.db')}`
}
}
});
// Helper function
function parseNote(dbNote) {
return {
...dbNote,
checkItems: dbNote.checkItems ? JSON.parse(dbNote.checkItems) : null,
labels: dbNote.labels ? JSON.parse(dbNote.labels) : null,
images: dbNote.images ? JSON.parse(dbNote.images) : null,
};
}
// Initialize MCP Server
const server = new Server(
{
name: 'memento-mcp-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
// Register all tools (same as stdio version)
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
// ... tous les tools comme create_note, get_notes, etc.
],
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
// ... même logique que stdio version
});
// SSE Endpoint
app.get('/sse', async (req, res) => {
const transport = new SSEServerTransport('/message', res);
await server.connect(transport);
});
// Message Endpoint
app.post('/message', express.json(), async (req, res) => {
// Handled by SSEServerTransport
});
app.listen(PORT, () => {
console.log(`MCP SSE Server running on http://localhost:${PORT}`);
console.log(`SSE endpoint: http://localhost:${PORT}/sse`);
});
Dépendances à ajouter:
cd mcp-server
npm install express
Démarrage:
node mcp-server/index-sse.js
Option B: Utiliser Next.js API Route avec SSE
Fichier: keep-notes/app/api/mcp/route.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import { prisma } from '@/lib/prisma';
import { NextRequest } from 'next/server';
const mcpServer = new Server(
{
name: 'memento-mcp-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
// Register tools...
export async function GET(req: NextRequest) {
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
const transport = new SSEServerTransport('/api/mcp/message', {
write: (data) => controller.enqueue(encoder.encode(data)),
});
await mcpServer.connect(transport);
},
});
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
},
});
}
export async function POST(req: NextRequest) {
// Handle messages
const body = await req.json();
// Process via mcpServer
return Response.json({ success: true });
}
Avantage: Même serveur Next.js, pas de port séparé!
Configuration N8N avec SSE
Méthode 1: MCP Client Community Node (si supporte SSE)
Configuration:
{
"name": "memento-sse",
"transport": "sse",
"url": "http://YOUR_IP:3001/sse"
}
Méthode 2: HTTP Request Nodes (Fallback)
Si le MCP Client ne supporte pas SSE, utiliser les nodes HTTP Request standards de N8N avec l'API REST existante (comme actuellement).
Comparaison: stdio vs SSE
| Feature | stdio | SSE |
|---|---|---|
| Connexion | Process local | HTTP réseau |
| N8N distant | ❌ Non | ✅ Oui |
| Latence | Très faible | Faible |
| Setup | Simple | Moyen |
| Firewall | N/A | Standard HTTP |
| Scaling | 1 instance | Multiple clients |
| Debugging | Console logs | Network logs + curl |
Recommandation pour ton cas
Contexte
- N8N déployé sur une machine séparée
- Besoin d'accès distant au MCP server
- MCP Client Community Node installé
Solution: SSE via Express ✅
Pourquoi:
- stdio nécessite accès fichier local (impossible si N8N sur autre machine)
- SSE fonctionne sur HTTP standard (réseau)
- Facile à tester avec curl
- Compatible avec la plupart des clients MCP
Étapes:
- Créer
mcp-server/index-sse.jsavec Express + SSE - Ajouter
expressaux dépendances - Démarrer sur port 3001 (ou autre)
- Trouver l'IP de ta machine Windows:
ipconfig - Configurer N8N MCP Client avec
http://YOUR_IP:3001/sse - Tester avec N8N workflows
Test SSE sans N8N
Avec curl:
# Test connexion SSE
curl -N http://localhost:3001/sse
# Test appel d'un tool
curl -X POST http://localhost:3001/message \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_notes",
"arguments": {}
},
"id": 1
}'
Avec JavaScript (test rapide):
const eventSource = new EventSource('http://localhost:3001/sse');
eventSource.onmessage = (event) => {
console.log('Received:', event.data);
};
eventSource.onerror = (error) => {
console.error('SSE Error:', error);
};
Prochaines étapes
- ✅ Je peux créer le serveur SSE si tu veux
- ✅ Tester localement avec curl
- ✅ Configurer N8N pour pointer vers SSE endpoint
- ✅ Vérifier que MCP Client Community Node supporte SSE
Tu veux que je crée le serveur SSE maintenant?
Ressources
Conclusion: Oui, MCP peut utiliser SSE! C'est même recommandé pour ton cas avec N8N sur une machine distante. Le transport stdio actuel ne fonctionne que pour processus locaux.