Skip to main content
Glama

Self-Improving Memory MCP

by SuperPiTT
test-vector-system.js8.52 kB
#!/usr/bin/env node /** * Test completo del sistema de vector search * Verifica que todo funciona end-to-end */ import { spawn } from 'child_process'; import { setTimeout as sleep } from 'timers/promises'; const colors = { reset: '\x1b[0m', green: '\x1b[32m', red: '\x1b[31m', cyan: '\x1b[36m', yellow: '\x1b[33m', }; function log(color, ...args) { console.log(colors[color], ...args, colors.reset); } let mcpProcess = null; async function startMCPServer() { log('cyan', '\n🚀 Starting MCP Server...\n'); mcpProcess = spawn('node', ['index.js'], { stdio: ['pipe', 'pipe', 'pipe'], }); let serverReady = false; mcpProcess.stderr.on('data', (data) => { const output = data.toString(); if (output.includes('MCP server running')) { serverReady = true; } process.stderr.write(data); }); // Esperar a que el servidor esté listo let waited = 0; while (!serverReady && waited < 30000) { await sleep(500); waited += 500; } if (!serverReady) { throw new Error('Server did not start in time'); } log('green', '✓ MCP Server started\n'); return mcpProcess; } async function sendMCPRequest(method, params = {}) { return new Promise((resolve, reject) => { const request = { jsonrpc: '2.0', id: Date.now(), method, params, }; let response = ''; const timeout = setTimeout(() => { reject(new Error('Request timeout')); }, 10000); mcpProcess.stdout.once('data', (data) => { clearTimeout(timeout); response = data.toString(); try { const parsed = JSON.parse(response); resolve(parsed); } catch (error) { reject(new Error(`Failed to parse response: ${response}`)); } }); mcpProcess.stdin.write(JSON.stringify(request) + '\n'); }); } async function testAddEntry() { log('cyan', '📝 Test 1: Agregar entrada con vector embedding...'); try { const response = await sendMCPRequest('tools/call', { name: 'save_knowledge', arguments: { type: 'insight', content: 'Vector search usa embeddings semánticos para búsqueda inteligente', context: 'LanceDB + Transformers.js implementado correctamente', confidence: 0.95, verified: true, tags: ['vector-search', 'embeddings', 'lancedb'], }, }); if (response.result && response.result.content) { const text = response.result.content[0].text; log('green', `✓ Entrada guardada: ${text}`); return text.match(/ID: ([a-f0-9-]+)/)?.[1]; } else { throw new Error('Unexpected response format'); } } catch (error) { log('red', `✗ Error: ${error.message}`); throw error; } } async function testSemanticSearch() { log('cyan', '\n🔍 Test 2: Búsqueda semántica (debe encontrar conceptos relacionados)...'); try { // Buscar "neural embeddings" debería encontrar "vector search" y "embeddings" const response = await sendMCPRequest('tools/call', { name: 'search_knowledge', arguments: { query: 'neural embeddings semantic similarity', }, }); if (response.result && response.result.content) { const results = JSON.parse(response.result.content[0].text); log('yellow', ` Encontrados: ${results.length} resultados`); if (results.length > 0) { results.slice(0, 3).forEach((r, i) => { log('reset', ` ${i + 1}. [${r.type}] ${r.content.slice(0, 60)}...`); }); log('green', '✓ Búsqueda semántica funciona'); return results.length; } else { log('red', '✗ No se encontraron resultados'); return 0; } } } catch (error) { log('red', `✗ Error: ${error.message}`); throw error; } } async function testStats() { log('cyan', '\n📊 Test 3: Estadísticas con vectores...'); try { const response = await sendMCPRequest('tools/call', { name: 'get_stats', arguments: {}, }); if (response.result && response.result.content) { const stats = JSON.parse(response.result.content[0].text); log('yellow', ` Total entradas JSON: ${stats.totalEntries}`); log('yellow', ` Total vectores: ${stats.vectorEntries}`); log('yellow', ` Estado sync: ${stats.syncStatus}`); if (stats.syncStatus === 'synced' && stats.totalEntries === stats.vectorEntries) { log('green', '✓ JSON y VectorDB sincronizados correctamente'); return true; } else { log('red', `✗ Bases de datos NO sincronizadas`); return false; } } } catch (error) { log('red', `✗ Error: ${error.message}`); throw error; } } async function testExactMatch() { log('cyan', '\n🎯 Test 4: Búsqueda exacta por tags...'); try { const response = await sendMCPRequest('tools/call', { name: 'search_knowledge', arguments: { query: 'lancedb', }, }); if (response.result && response.result.content) { const results = JSON.parse(response.result.content[0].text); if (results.length > 0) { const hasLanceDB = results.some(r => r.tags?.includes('lancedb') || r.content.toLowerCase().includes('lancedb') ); if (hasLanceDB) { log('green', `✓ Encontró entradas con 'lancedb' (${results.length} resultados)`); return true; } } log('red', '✗ No encontró entradas con lancedb'); return false; } } catch (error) { log('red', `✗ Error: ${error.message}`); throw error; } } async function testTypeFilter() { log('cyan', '\n🔖 Test 5: Filtro por tipo...'); try { const response = await sendMCPRequest('tools/call', { name: 'search_knowledge', arguments: { query: 'error npm package', type: 'error', }, }); if (response.result && response.result.content) { const results = JSON.parse(response.result.content[0].text); const allErrors = results.every(r => r.type === 'error'); if (results.length > 0 && allErrors) { log('green', `✓ Filtro por tipo funciona (${results.length} errores encontrados)`); return true; } else if (results.length === 0) { log('yellow', '⚠ No se encontraron errores (puede ser normal)'); return true; } else { log('red', '✗ Resultados contienen tipos incorrectos'); return false; } } } catch (error) { log('red', `✗ Error: ${error.message}`); throw error; } } async function runTests() { let passed = 0; let failed = 0; try { await startMCPServer(); await sleep(2000); // Esperar warm-up log('cyan', '\n' + '='.repeat(60)); log('cyan', ' VECTOR SEARCH SYSTEM - INTEGRATION TESTS'); log('cyan', '='.repeat(60) + '\n'); // Test 1: Agregar entrada try { await testAddEntry(); passed++; } catch (error) { failed++; } await sleep(1000); // Test 2: Búsqueda semántica try { const results = await testSemanticSearch(); if (results > 0) passed++; else failed++; } catch (error) { failed++; } await sleep(500); // Test 3: Estadísticas try { const synced = await testStats(); if (synced) passed++; else failed++; } catch (error) { failed++; } await sleep(500); // Test 4: Búsqueda exacta try { const found = await testExactMatch(); if (found) passed++; else failed++; } catch (error) { failed++; } await sleep(500); // Test 5: Filtro por tipo try { const works = await testTypeFilter(); if (works) passed++; else failed++; } catch (error) { failed++; } // Resumen log('cyan', '\n' + '='.repeat(60)); log('cyan', ' RESUMEN'); log('cyan', '='.repeat(60) + '\n'); log('green', `✓ Passed: ${passed}/5`); if (failed > 0) { log('red', `✗ Failed: ${failed}/5`); } log('cyan', '\n' + '='.repeat(60) + '\n'); if (passed === 5) { log('green', '🎉 TODOS LOS TESTS PASARON - Sistema 100% funcional\n'); process.exit(0); } else { log('red', '❌ ALGUNOS TESTS FALLARON\n'); process.exit(1); } } catch (error) { log('red', `\n❌ Test suite failed: ${error.message}\n`); process.exit(1); } finally { if (mcpProcess) { mcpProcess.kill(); } } } runTests();

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SuperPiTT/self-improving-memory-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server