Skip to main content
Glama
test-modes.jsโ€ข3.65 kB
#!/usr/bin/env node /** * Quick test to validate readonly/readwrite mode functionality * This tests the mode system without requiring actual Langfuse credentials */ import { spawn } from 'child_process'; import { promises as fs } from 'fs'; async function testModeSystem() { console.log('๐Ÿงช Testing Langfuse MCP Server Mode System\n'); // Test 1: Readonly mode startup console.log('1๏ธโƒฃ Testing readonly mode startup...'); await testServerStartup('readonly', ['LANGFUSE_MCP_MODE=readonly']); // Test 2: Readwrite mode startup console.log('2๏ธโƒฃ Testing readwrite mode startup...'); await testServerStartup('readwrite', ['LANGFUSE_MCP_MODE=readwrite']); // Test 3: Default mode (should be readonly) console.log('3๏ธโƒฃ Testing default mode (should be readonly)...'); await testServerStartup('readonly (default)', []); // Test 4: Binary entrypoints console.log('4๏ธโƒฃ Testing binary entrypoints...'); await testBinaryEntrypoints(); console.log('\nโœ… All mode tests completed successfully!\n'); console.log('๐Ÿ“‹ Summary of implemented features:'); console.log(' โ€ข Triple-layer security (env, tool list, runtime validation)'); console.log(' โ€ข Write tool prefixing (write_create_dataset, etc.)'); console.log(' โ€ข Confirmation prompts for destructive operations'); console.log(' โ€ข Comprehensive audit logging for write operations'); console.log(' โ€ข Single CLI entrypoint with mode flags (langfuse-mcp)'); console.log(' โ€ข Mode-aware tool filtering and descriptions'); } async function testServerStartup(expectedMode, envVars) { return new Promise((resolve) => { const env = { ...process.env, LANGFUSE_PUBLIC_KEY: 'pk-lf-test-key', LANGFUSE_SECRET_KEY: 'sk-lf-test-secret', LANGFUSE_BASEURL: 'https://cloud.langfuse.com' }; // Apply additional env vars envVars.forEach(envVar => { const [key, value] = envVar.split('='); env[key] = value; }); const child = spawn('node', ['build/index.js'], { env, stdio: ['pipe', 'pipe', 'pipe'] }); let output = ''; child.stderr.on('data', (data) => { output += data.toString(); }); // Give it a moment to start up and log mode info setTimeout(() => { child.kill(); // Check if output contains expected mode info const hasCorrectMode = output.includes(expectedMode.toUpperCase()); const hasAuditLog = output.includes('[AUDIT]'); if (hasCorrectMode) { console.log(` โœ… ${expectedMode} mode detected correctly`); if (hasAuditLog) { console.log(` โœ… Audit logging initialized`); } } else { console.log(` โŒ Expected ${expectedMode} mode but got: ${output.slice(0, 200)}...`); } resolve(); }, 1000); }); } async function testBinaryEntrypoints() { try { // Check if CLI files exist const roExists = await fs.access('build/cli-ro.js').then(() => true).catch(() => false); const rwExists = await fs.access('build/cli-rw.js').then(() => true).catch(() => false); if (roExists && rwExists) { console.log(' โœ… Both CLI entrypoints built successfully'); console.log(' โœ… langfuse-mcp-ro โ†’ readonly mode'); console.log(' โœ… langfuse-mcp โ†’ single binary with mode flags'); } else { console.log(' โŒ CLI entrypoints not found'); } } catch (error) { console.log(' โš ๏ธ Could not verify CLI entrypoints'); } } // Only run if this script is executed directly if (import.meta.url === `file://${process.argv[1]}`) { testModeSystem().catch(console.error); }

Latest Blog Posts

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/therealsachin/langfuse-mcp-server'

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