Skip to main content
Glama
gunjanjp

Linux Bash MCP Server

by gunjanjp
test.js7.85 kB
#!/usr/bin/env node import { spawn } from "child_process"; import { promisify } from "util"; import { exec } from "child_process"; import fs from "fs/promises"; import path from "path"; import { fileURLToPath } from 'url'; const execAsync = promisify(exec); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); class MCPServerTester { constructor() { this.wslDistribution = null; this.tests = [ { name: "Load Configuration", method: this.testLoadConfig }, { name: "WSL Status Check", method: this.testWSLStatus }, { name: "Basic Command Execution", method: this.testBasicCommand }, { name: "Directory Listing", method: this.testDirectoryListing }, { name: "Script Creation", method: this.testScriptCreation }, { name: "Script Execution", method: this.testScriptExecution }, { name: "System Information", method: this.testSystemInfo }, ]; } async loadConfig() { try { // Try to get WSL distribution from environment variable first this.wslDistribution = process.env.WSL_DISTRIBUTION; if (!this.wslDistribution) { // Try to load from config file const configPath = path.join(__dirname, "..", "config.json"); const configContent = await fs.readFile(configPath, "utf8"); const config = JSON.parse(configContent); this.wslDistribution = config.wslDistribution; } if (!this.wslDistribution || this.wslDistribution === "auto-detect") { // Auto-detect WSL distribution this.wslDistribution = await this.detectDefaultWSLDistribution(); } console.log(` Using WSL distribution: ${this.wslDistribution}`); } catch (error) { throw new Error(`Failed to load configuration: ${error.message}`); } } async detectDefaultWSLDistribution() { try { const { stdout } = await execAsync("wsl -l"); const lines = stdout.split('\n').filter(line => line.trim()); for (const line of lines) { const cleanLine = line.replace(/[\x00-\x1f\x7f-\x9f]/g, '').trim(); if (cleanLine && !cleanLine.includes('Windows Subsystem for Linux') && !cleanLine.includes('----')) { const distName = cleanLine.replace(/^\*\s*/, '').split(/\s+/)[0]; if (distName && distName !== 'The' && distName !== 'following') { return distName; } } } throw new Error("No WSL distributions found"); } catch (error) { throw new Error(`Failed to detect WSL distribution: ${error.message}`); } } async runTests() { console.log("🧪 Starting Linux Bash MCP Server Tests...\n"); let passed = 0; let failed = 0; for (const test of this.tests) { try { console.log(`📋 Running: ${test.name}`); await test.method.call(this); console.log(`✅ PASSED: ${test.name}\n`); passed++; } catch (error) { console.log(`❌ FAILED: ${test.name}`); console.log(` Error: ${error.message}\n`); failed++; } } console.log(`\n📊 Test Results:`); console.log(` ✅ Passed: ${passed}`); console.log(` ❌ Failed: ${failed}`); console.log(` 📊 Total: ${this.tests.length}`); if (failed === 0) { console.log(`\n🎉 All tests passed! MCP Server is ready to use with ${this.wslDistribution}.`); } else { console.log(`\n⚠️ Some tests failed. Please check your WSL2 setup for ${this.wslDistribution}.`); } } async testLoadConfig() { await this.loadConfig(); if (!this.wslDistribution) { throw new Error("No WSL distribution configured or detected"); } console.log(` Configuration loaded successfully`); } async testWSLStatus() { // Check if WSL2 is available const { stdout } = await execAsync("wsl -l -v"); if (!stdout.includes(this.wslDistribution)) { throw new Error(`WSL distribution '${this.wslDistribution}' not found`); } // Test basic WSL command const { stdout: testOutput } = await execAsync(`wsl -d ${this.wslDistribution} -- echo 'test'`); if (!testOutput.includes("test")) { throw new Error(`WSL ${this.wslDistribution} not responding correctly`); } console.log(` WSL2 ${this.wslDistribution} is accessible`); } async testBasicCommand() { const command = `wsl -d ${this.wslDistribution} -- echo 'Hello from Linux'`; const { stdout } = await execAsync(command); if (!stdout.includes("Hello from Linux")) { throw new Error("Basic command execution failed"); } console.log(" Basic command execution works"); } async testDirectoryListing() { const command = `wsl -d ${this.wslDistribution} -- ls /`; const { stdout } = await execAsync(command); if (!stdout.includes("home") || !stdout.includes("usr")) { throw new Error("Directory listing failed - expected directories not found"); } console.log(" Directory listing works"); } async testScriptCreation() { const scriptContent = "#!/bin/bash\\necho 'Test script executed'\\ndate\\nuname -s"; const scriptPath = "/tmp/mcp_test_script.sh"; // Create script const createCommand = `wsl -d ${this.wslDistribution} -- bash -c "echo '${scriptContent}' > '${scriptPath}'"`; await execAsync(createCommand); // Make executable const chmodCommand = `wsl -d ${this.wslDistribution} -- chmod +x '${scriptPath}'`; await execAsync(chmodCommand); // Verify script exists const checkCommand = `wsl -d ${this.wslDistribution} -- test -f '${scriptPath}' && echo 'exists'`; const { stdout } = await execAsync(checkCommand); if (!stdout.includes("exists")) { throw new Error("Script creation failed"); } console.log(" Script creation works"); } async testScriptExecution() { const scriptPath = "/tmp/mcp_test_script.sh"; // Execute the script created in previous test const execCommand = `wsl -d ${this.wslDistribution} -- bash '${scriptPath}'`; const { stdout } = await execAsync(execCommand); if (!stdout.includes("Test script executed")) { throw new Error("Script execution failed"); } console.log(" Script execution works"); } async testSystemInfo() { const commands = ["uname -s", "whoami", "pwd"]; for (const cmd of commands) { const wslCommand = `wsl -d ${this.wslDistribution} -- ${cmd}`; const { stdout } = await execAsync(wslCommand); if (!stdout.trim()) { throw new Error(`System info command '${cmd}' returned empty result`); } } console.log(" System information commands work"); } async cleanup() { try { // Clean up test script await execAsync(`wsl -d ${this.wslDistribution} -- rm -f /tmp/mcp_test_script.sh`); console.log("🧹 Cleanup completed"); } catch (error) { console.log("⚠️ Cleanup warning:", error.message); } } async detectAllDistributions() { try { const { stdout } = await execAsync("wsl -l -v"); console.log("📋 Available WSL distributions:"); console.log(stdout); console.log(""); } catch (error) { console.log("⚠️ Could not list WSL distributions:", error.message); } } } // Run tests if this file is executed directly if (import.meta.url === `file://${process.argv[1]}`) { const tester = new MCPServerTester(); // Show available distributions first tester.detectAllDistributions() .then(() => tester.runTests()) .then(() => tester.cleanup()) .catch((error) => { console.error("❌ Test suite failed:", error); process.exit(1); }); } export default MCPServerTester;

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/gunjanjp/linuxshell-mcp'

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