Skip to main content
Glama

Shortcut MCP Server

by currentspace
find-memory-leak.mjs4.97 kB
import v8 from 'v8'; import fs from 'fs'; import path from 'path'; import { spawn } from 'child_process'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Create directory for snapshots const snapshotDir = path.join(__dirname, 'heap-snapshots-leak'); if (!fs.existsSync(snapshotDir)) { fs.mkdirSync(snapshotDir, { recursive: true }); } // Clean old snapshots fs.readdirSync(snapshotDir).forEach(file => { if (file.endsWith('.heapsnapshot') || file.endsWith('.txt')) { fs.unlinkSync(path.join(snapshotDir, file)); } }); console.log('Starting memory leak detection test...'); console.log('Will run for 45 seconds and take periodic snapshots\n'); // Start the test process const testProcess = spawn('pnpm', [ 'test', 'tests/unit/languageServer.test.ts', '--', '--run', '--reporter=verbose' ], { env: { ...process.env, NODE_OPTIONS: '--expose-gc --max-old-space-size=16384' } }); let outputBuffer = ''; const memoryLog = []; // Capture output testProcess.stdout.on('data', (data) => { outputBuffer += data.toString(); process.stdout.write(data); }); testProcess.stderr.on('data', (data) => { outputBuffer += data.toString(); process.stderr.write(data); }); // Monitor process memory const startTime = Date.now(); let snapshotCount = 0; async function getProcessMemory() { return new Promise((resolve) => { const memProcess = spawn('ps', ['-o', 'rss,vsz', '-p', testProcess.pid]); let output = ''; memProcess.stdout.on('data', (data) => { output += data.toString(); }); memProcess.on('close', () => { const lines = output.trim().split('\n'); if (lines.length > 1) { const [rss, vsz] = lines[1].trim().split(/\s+/).map(Number); resolve({ rss: rss * 1024, vsz: vsz * 1024 }); // Convert KB to bytes } else { resolve({ rss: 0, vsz: 0 }); } }); }); } // Take snapshots periodically const snapshotInterval = setInterval(async () => { const elapsed = Math.floor((Date.now() - startTime) / 1000); const processMemory = await getProcessMemory(); const memInfo = { elapsed, timestamp: new Date().toISOString(), process: { rss: (processMemory.rss / 1024 / 1024).toFixed(2) + ' MB', vsz: (processMemory.vsz / 1024 / 1024).toFixed(2) + ' MB' } }; memoryLog.push(memInfo); console.log(`\n[${elapsed}s] Process Memory - RSS: ${memInfo.process.rss}, VSZ: ${memInfo.process.vsz}`); // Take heap snapshot every 10 seconds if (elapsed % 10 === 0 && elapsed > 0) { // Use debug protocol to request heap snapshot from the test process const snapshotFile = path.join(snapshotDir, `heap-${elapsed}s.txt`); fs.writeFileSync(snapshotFile, `Snapshot at ${elapsed}s - RSS: ${memInfo.process.rss}`); console.log(` → Marked snapshot point at ${elapsed}s`); } }, 1000); // Kill process after 45 seconds setTimeout(() => { console.log('\n\nStopping test after 45 seconds...'); clearInterval(snapshotInterval); testProcess.kill('SIGTERM'); // Give it time to clean up setTimeout(() => { if (!testProcess.killed) { testProcess.kill('SIGKILL'); } }, 5000); }, 45000); testProcess.on('close', async (code) => { clearInterval(snapshotInterval); console.log('\n=== Memory Growth Analysis ===\n'); // Save memory log const logFile = path.join(snapshotDir, 'memory-log.json'); fs.writeFileSync(logFile, JSON.stringify(memoryLog, null, 2)); // Analyze growth if (memoryLog.length > 0) { const first = memoryLog[0]; const last = memoryLog[memoryLog.length - 1]; console.log('Memory growth over time:'); console.log(` Start: ${first.process.rss}`); console.log(` End: ${last.process.rss}`); console.log(` Duration: ${last.elapsed}s`); // Show growth chart console.log('\nMemory usage over time:'); const maxRss = Math.max(...memoryLog.map(m => parseFloat(m.process.rss))); const scale = 50 / maxRss; memoryLog.forEach((m, i) => { if (i % 5 === 0) { // Show every 5 seconds const rss = parseFloat(m.process.rss); const bar = '█'.repeat(Math.floor(rss * scale)); console.log(`${m.elapsed.toString().padStart(3)}s: ${bar} ${m.process.rss}`); } }); } // Save output const outputFile = path.join(snapshotDir, 'test-output.log'); fs.writeFileSync(outputFile, outputBuffer); console.log(`\nTest output saved to: ${outputFile}`); console.log(`Memory log saved to: ${logFile}`); process.exit(code || 0); });

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/currentspace/shortcut_mcp'

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