ruv-swarm
Version:
High-performance neural network swarm orchestration in WebAssembly
1,238 lines (1,074 loc) ⢠68.6 kB
JavaScript
#!/usr/bin/env node
/**
* Production-ready ruv-swarm MCP server with ZERO timeout mechanisms
* ALL timeout/connection/interval code completely removed for bulletproof operation
* Maintains security and stability without ANY timeout-related disconnections
*/
import { spawn } from 'child_process';
import { setupClaudeIntegration, invokeClaudeWithSwarm as _invokeClaudeWithSwarm } from '../src/claude-integration/index.js';
import { RuvSwarm } from '../src/index-enhanced.js';
import { EnhancedMCPTools } from '../src/mcp-tools-enhanced.js';
import { daaMcpTools } from '../src/mcp-daa-tools.js';
import mcpToolsEnhanced from '../src/mcp-tools-enhanced.js';
import { Logger } from '../src/logger.js';
import { CommandSanitizer, SecurityError } from '../src/security.js';
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
// Get version from package.json
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
async function getVersion() {
try {
const packagePath = join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(readFileSync(packagePath, 'utf8'));
return packageJson.version;
} catch (error) {
return 'unknown';
}
}
// Stability configuration - NO TIMEOUT MECHANISMS
const MAX_RESTARTS = 10;
const RESTART_DELAY = 1000; // 1 second
const RESTART_RESET_TIME = 300000; // 5 minutes
let restartCount = 0;
let lastRestartTime = 0;
let isStabilityMode = false;
let childProcess = null;
// Input validation constants and functions
const VALID_TOPOLOGIES = ['mesh', 'hierarchical', 'ring', 'star'];
const VALID_AGENT_TYPES = ['researcher', 'coder', 'analyst', 'optimizer', 'coordinator', 'architect', 'tester'];
const MAX_AGENTS_LIMIT = 100;
const MIN_AGENTS_LIMIT = 1;
class ValidationError extends Error {
constructor(message, parameter = null) {
super(message);
this.name = 'ValidationError';
this.parameter = parameter;
}
}
function validateTopology(topology) {
if (!topology || typeof topology !== 'string') {
throw new ValidationError('Topology must be a non-empty string', 'topology');
}
if (!VALID_TOPOLOGIES.includes(topology.toLowerCase())) {
throw new ValidationError(
`Invalid topology '${topology}'. Valid topologies are: ${VALID_TOPOLOGIES.join(', ')}`,
'topology'
);
}
return topology.toLowerCase();
}
function validateMaxAgents(maxAgents) {
// Handle string input
if (typeof maxAgents === 'string') {
const parsed = parseInt(maxAgents, 10);
if (isNaN(parsed)) {
throw new ValidationError(
`Invalid maxAgents '${maxAgents}'. Must be a number between ${MIN_AGENTS_LIMIT} and ${MAX_AGENTS_LIMIT}`,
'maxAgents'
);
}
maxAgents = parsed;
}
if (!Number.isInteger(maxAgents) || maxAgents < MIN_AGENTS_LIMIT || maxAgents > MAX_AGENTS_LIMIT) {
throw new ValidationError(
`Invalid maxAgents '${maxAgents}'. Must be an integer between ${MIN_AGENTS_LIMIT} and ${MAX_AGENTS_LIMIT}`,
'maxAgents'
);
}
return maxAgents;
}
function validateAgentType(type) {
if (!type || typeof type !== 'string') {
throw new ValidationError('Agent type must be a non-empty string', 'type');
}
if (!VALID_AGENT_TYPES.includes(type.toLowerCase())) {
throw new ValidationError(
`Invalid agent type '${type}'. Valid types are: ${VALID_AGENT_TYPES.join(', ')}`,
'type'
);
}
return type.toLowerCase();
}
function validateAgentName(name) {
if (name !== null && name !== undefined) {
if (typeof name !== 'string') {
throw new ValidationError('Agent name must be a string', 'name');
}
if (name.length === 0) {
throw new ValidationError('Agent name cannot be empty', 'name');
}
if (name.length > 100) {
throw new ValidationError('Agent name cannot exceed 100 characters', 'name');
}
// Check for invalid characters
if (!/^[a-zA-Z0-9\s\-_\.]+$/.test(name)) {
throw new ValidationError(
'Agent name can only contain letters, numbers, spaces, hyphens, underscores, and periods',
'name'
);
}
}
return name;
}
function validateTaskDescription(task) {
if (!task || typeof task !== 'string') {
throw new ValidationError('Task description must be a non-empty string', 'task');
}
if (task.trim().length === 0) {
throw new ValidationError('Task description cannot be empty or only whitespace', 'task');
}
if (task.length > 1000) {
throw new ValidationError('Task description cannot exceed 1000 characters', 'task');
}
return task.trim();
}
function logValidationError(error, command) {
console.log(`ā Validation Error in '${command}' command:`);
console.log(` ${error.message}`);
if (error.parameter) {
console.log(` Parameter: ${error.parameter}`);
}
console.log(`\nš” For help with valid parameters, run: ruv-swarm help`);
}
function stabilityLog(message) {
const timestamp = new Date().toISOString();
console.error(`[${timestamp}] [STABILITY] ${message}`);
}
let globalRuvSwarm = null;
let globalMCPTools = null;
let globalLogger = null;
// Initialize logger based on environment
async function initializeLogger() {
if (!globalLogger) {
globalLogger = new Logger({
name: 'ruv-swarm-mcp-no-timeout',
level: process.env.LOG_LEVEL || (process.argv.includes('--debug') ? 'DEBUG' : 'INFO'),
enableStderr: true, // Always use stderr in MCP mode
enableFile: process.env.LOG_TO_FILE === 'true',
formatJson: process.env.LOG_FORMAT === 'json',
logDir: process.env.LOG_DIR || './logs',
metadata: {
pid: process.pid,
version: await getVersion(),
mode: 'mcp-stdio-no-timeout'
}
});
// Set up global error handlers with stability - NO TIMEOUT MECHANISMS
process.on('uncaughtException', (error) => {
globalLogger.fatal('Uncaught exception', { error });
if (isStabilityMode) {
stabilityLog(`Uncaught exception: ${error.message}`);
stabilityLog('Attempting graceful recovery...');
// NO TIMEOUT - immediate exit
process.exit(1);
} else {
process.exit(1);
}
});
process.on('unhandledRejection', (reason, promise) => {
globalLogger.fatal('Unhandled rejection', { reason, promise });
if (isStabilityMode) {
stabilityLog(`Unhandled rejection: ${reason}`);
stabilityLog('Attempting graceful recovery...');
} else {
process.exit(1);
}
});
}
return globalLogger;
}
async function initializeSystem() {
if (!globalRuvSwarm) {
// RuvSwarm.initialize already prints initialization messages
globalRuvSwarm = await RuvSwarm.initialize({
loadingStrategy: 'progressive',
enablePersistence: true,
enableNeuralNetworks: true,
enableForecasting: true,
useSIMD: RuvSwarm.detectSIMDSupport(),
debug: process.argv.includes('--debug')
});
}
if (!globalMCPTools) {
// Pass the already initialized RuvSwarm instance to avoid duplicate initialization
globalMCPTools = new EnhancedMCPTools(globalRuvSwarm);
await globalMCPTools.initialize(globalRuvSwarm);
// Initialize DAA MCP tools with the same instance
daaMcpTools.mcpTools = globalMCPTools;
await daaMcpTools.ensureInitialized();
// Add DAA tool methods to the MCP tools object
const daaToolNames = [
'daa_init', 'daa_agent_create', 'daa_agent_adapt', 'daa_workflow_create',
'daa_workflow_execute', 'daa_knowledge_share', 'daa_learning_status',
'daa_cognitive_pattern', 'daa_meta_learning', 'daa_performance_metrics'
];
for (const toolName of daaToolNames) {
if (typeof daaMcpTools[toolName] === 'function') {
globalMCPTools[toolName] = daaMcpTools[toolName].bind(daaMcpTools);
}
}
}
return { ruvSwarm: globalRuvSwarm, mcpTools: globalMCPTools };
}
async function handleInit(args) {
try {
const { mcpTools } = await initializeSystem();
// Filter out flags to get positional arguments
const positionalArgs = args.filter(arg => !arg.startsWith('--'));
const rawTopology = positionalArgs[0] || 'mesh';
const rawMaxAgents = positionalArgs[1] || '5';
const setupClaude = args.includes('--claude') || args.includes('--setup-claude');
const forceSetup = args.includes('--force');
const mergeSetup = args.includes('--merge');
const noInteractive = args.includes('--no-interactive');
const noBackup = args.includes('--no-backup');
// Validate inputs
const topology = validateTopology(rawTopology);
const maxAgents = validateMaxAgents(rawMaxAgents);
console.log('š Initializing ruv-swarm (NO TIMEOUT VERSION)...');
const result = await mcpTools.swarm_init({
topology,
maxAgents,
strategy: 'balanced',
enableCognitiveDiversity: true,
enableNeuralAgents: true,
enableForecasting: args.includes('--forecasting')
});
console.log('š Swarm initialized:');
console.log(' ID: ' + result.id);
console.log(' Topology: ' + result.topology);
console.log(' Max Agents: ' + result.maxAgents);
console.log(' Features: ' + Object.entries(result.features).filter(([k,v]) => v).map(([k,v]) => k).join(', '));
console.log(' Performance: ' + result.performance.initialization_time_ms.toFixed(1) + 'ms');
console.log(' š„ TIMEOUT MECHANISMS: COMPLETELY REMOVED');
// Setup Claude integration using modular approach
if (setupClaude || forceSetup || mergeSetup) {
console.log('\nš Setting up modular Claude Code integration...');
try {
await setupClaudeIntegration({
autoSetup: setupClaude,
forceSetup: forceSetup,
mergeSetup: mergeSetup,
noBackup: noBackup,
interactive: !noInteractive,
workingDir: process.cwd(),
packageName: 'ruv-swarm'
});
} catch (error) {
console.log('ā ļø Claude integration setup had issues:', error.message);
console.log('š” Manual setup: claude mcp add ruv-swarm npx ruv-swarm mcp start');
}
}
console.log('\nā
Initialization complete!');
console.log('\nš Next steps:');
console.log(' 1. Test with MCP tools: mcp__ruv-swarm__agent_spawn');
console.log(' 2. Use wrapper scripts for remote execution');
console.log(' 3. Check .claude/commands/ for detailed guides');
console.log(' 4. š„ ENJOY INFINITE RUNTIME - NO TIMEOUTS!');
if (forceSetup) {
console.log('\nš Files regenerated with --force flag');
} else if (mergeSetup) {
console.log('\nš Configuration merged with existing files');
}
} catch (error) {
if (error instanceof ValidationError) {
logValidationError(error, 'init');
return;
}
throw error;
}
}
async function handleSpawn(args) {
try {
const { mcpTools } = await initializeSystem();
const rawType = args[0] || 'researcher';
const rawName = args[1] || null;
// Validate inputs
const type = validateAgentType(rawType);
const name = validateAgentName(rawName);
const result = await mcpTools.agent_spawn({
type,
name,
enableNeuralNetwork: !args.includes('--no-neural')
});
console.log('š¤ Agent spawned:');
console.log(' ID: ' + result.agent.id);
console.log(' Name: ' + result.agent.name);
console.log(' Type: ' + result.agent.type);
console.log(' Cognitive Pattern: ' + result.agent.cognitive_pattern);
if (result.agent.neural_network_id) {
console.log(' Neural Network: ' + result.agent.neural_network_id);
}
console.log(' Swarm Capacity: ' + result.swarm_info.capacity);
console.log(' š„ TIMEOUT PROTECTION: DISABLED');
} catch (error) {
if (error instanceof ValidationError) {
logValidationError(error, 'spawn');
return;
}
throw error;
}
}
async function handleOrchestrate(args) {
try {
const { mcpTools } = await initializeSystem();
const rawTask = args.join(' ');
if (!rawTask) {
console.log('ā No task provided');
console.log('Usage: ruv-swarm orchestrate "task description"');
return;
}
// Validate task description
const task = validateTaskDescription(rawTask);
const result = await mcpTools.task_orchestrate({
task: task,
strategy: 'adaptive'
});
console.log('š Task orchestrated:');
console.log(' ID: ' + result.taskId);
console.log(' Description: ' + result.description);
console.log(' Assigned Agents: ' + result.assigned_agents.length);
console.log(' Status: ' + result.status);
console.log(' Estimated Completion: ' + result.performance.estimated_completion_ms + 'ms');
console.log(' š„ EXECUTION MODE: INFINITE RUNTIME');
} catch (error) {
if (error instanceof ValidationError) {
logValidationError(error, 'orchestrate');
return;
}
throw error;
}
}
async function handleClaudeInvoke(args) {
const prompt = args.join(' ');
if (!prompt.trim()) {
console.log('ā No prompt provided');
console.log('Usage: ruv-swarm claude-invoke "your swarm prompt"');
console.log('Note: Use --dangerously-skip-permissions explicitly if needed');
return;
}
// Security: validate prompt for dangerous patterns
try {
CommandSanitizer.validateArgument(prompt.trim());
} catch (error) {
if (error instanceof SecurityError) {
console.error('ā Security validation failed:', error.message);
return;
}
throw error;
}
console.log('š Invoking Claude Code with ruv-swarm integration...');
console.log('Prompt: ' + prompt.trim());
try {
// Create orchestrator with secure mode
const { ClaudeIntegrationOrchestrator } = await import('../src/claude-integration/index.js');
const orchestrator = new ClaudeIntegrationOrchestrator({
workingDir: process.cwd()
});
// Use secure mode (no automatic permissions)
await orchestrator.core.invokeClaudeWithPrompt(prompt, { secure: true });
} catch (error) {
console.error('ā Claude invocation failed:', error.message);
console.error('Make sure Claude Code CLI is installed and in your PATH');
process.exit(1);
}
}
async function handleStatus(args) {
const { mcpTools } = await initializeSystem();
const verbose = args.includes('--verbose') || args.includes('-v');
const swarmId = args.find(arg => !arg.startsWith('-'));
const result = await mcpTools.swarm_status({ verbose });
if (swarmId) {
console.log(`š Swarm Status (${swarmId}) - NO TIMEOUT VERSION:`);
console.log(` Agents: ${result.agents.total} (${result.agents.active} active, ${result.agents.idle} idle)`);
console.log(` Tasks: ${result.tasks.total} (${result.tasks.pending} pending, ${result.tasks.in_progress} in progress)`);
console.log(` š„ TIMEOUT PROTECTION: COMPLETELY DISABLED`);
} else {
console.log('š Global Status (NO TIMEOUT VERSION):');
console.log(` Active Swarms: ${result.active_swarms}`);
console.log(` Total Agents: ${result.global_metrics.totalAgents}`);
console.log(` Total Tasks: ${result.global_metrics.totalTasks}`);
console.log(` Memory Usage: ${result.global_metrics.memoryUsage / (1024 * 1024)}MB`);
console.log(` š„ RUNTIME: INFINITE (NO TIMEOUTS)`);
if (verbose) {
console.log('\nš WASM Modules:');
Object.entries(result.runtime_info.wasm_modules).forEach(([name, status]) => {
console.log(` ${name}: ${status.loaded ? 'ā
Loaded' : 'ā³ Not loaded'} (${(status.size / 1024).toFixed(0)}KB)`);
});
}
}
}
async function handleMonitor(args) {
const { mcpTools } = await initializeSystem();
const duration = parseInt(args.find(arg => arg.match(/^\d+$/)), 10) || 10000;
console.log(`š Monitoring for ${duration}ms... (NO TIMEOUT VERSION)`);
console.log('Press Ctrl+C to stop\n');
// REMOVED: All connection intervals and timeout mechanisms
// Instead, use a simple loop with await delay
let elapsed = 0;
const interval = 1000; // 1 second
while (elapsed < duration) {
const status = await mcpTools.swarm_status({ verbose: false });
process.stdout.write('\r');
process.stdout.write(`Swarms: ${status.active_swarms} | Agents: ${status.global_metrics.totalAgents} | Tasks: ${status.global_metrics.totalTasks} | Memory: ${(status.global_metrics.memoryUsage / (1024 * 1024)).toFixed(1)}MB | Runtime: INFINITE`);
// Simple delay without setTimeout
await new Promise(resolve => {
const start = Date.now();
while (Date.now() - start < interval) {
// Busy wait - no timeout mechanisms
}
resolve();
});
elapsed += interval;
}
console.log('\n\nā
Monitoring complete (NO TIMEOUT MECHANISMS USED)');
}
async function handleMcp(args) {
const subcommand = args[0] || 'help';
switch (subcommand) {
case 'start':
await startMcpServer(args.slice(1));
break;
case 'status':
await getMcpStatus();
break;
case 'stop':
await stopMcpServer();
break;
case 'tools':
await listMcpTools();
break;
case 'config':
await configureMcp(args.slice(1));
break;
case 'help':
default:
showMcpHelp();
}
}
async function startMcpServer(args) {
const protocol = args.find(arg => arg.startsWith('--protocol='))?.split('=')[1] || 'stdio';
const enableStability = args.includes('--stability') || process.env.MCP_STABILITY === 'true';
if (enableStability) {
isStabilityMode = true;
stabilityLog('Starting MCP server with stability mode enabled (NO TIMEOUT VERSION)');
return startStableMcpServer(args);
}
// Initialize logger first
const logger = await initializeLogger();
const sessionId = logger.setCorrelationId();
try {
if (protocol === 'stdio') {
// In stdio mode, only JSON-RPC messages should go to stdout
logger.info('ruv-swarm MCP server starting in stdio mode (NO TIMEOUT VERSION)', {
protocol,
sessionId,
nodeVersion: process.version,
platform: process.platform,
arch: process.arch
});
// Log connection establishment
logger.logConnection('established', sessionId, {
protocol: 'stdio',
transport: 'stdin/stdout',
timestamp: new Date().toISOString()
});
// Initialize WASM if needed
const initOpId = logger.startOperation('initialize-system');
const { ruvSwarm, mcpTools } = await initializeSystem();
logger.endOperation(initOpId, true, { modulesLoaded: true });
// Start stdio MCP server loop
process.stdin.setEncoding('utf8');
// Signal server readiness for testing
if (process.env.MCP_TEST_MODE === 'true') {
console.error('MCP server ready (NO TIMEOUT VERSION)'); // Use stderr so it doesn't interfere with JSON-RPC
}
let buffer = '';
let messageCount = 0;
// Infinite runtime - no activity tracking needed
process.stdin.on('data', (chunk) => {
logger.trace('Received stdin data', { bytes: chunk.length });
// Infinite runtime - no activity tracking needed
buffer += chunk;
// Process complete JSON messages
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (line.trim()) {
messageCount++;
const messageId = `msg-${sessionId}-${messageCount}`;
try {
const request = JSON.parse(line);
logger.logMcp('in', request.method || 'unknown', {
method: request.method,
id: request.id,
params: request.params,
messageId
});
const opId = logger.startOperation(`mcp-${request.method}`, {
requestId: request.id,
messageId
});
handleMcpRequest(request, mcpTools, logger).then(response => {
logger.endOperation(opId, !response.error, {
hasError: !!response.error
});
logger.logMcp('out', request.method || 'response', {
method: request.method,
id: response.id,
result: response.result,
error: response.error,
messageId
});
try {
process.stdout.write(JSON.stringify(response) + '\n');
} catch (writeError) {
logger.error('Failed to write response to stdout', { writeError, response });
process.exit(1);
}
}).catch(error => {
logger.endOperation(opId, false, { error });
logger.error('Request handler error', { error, request });
const errorResponse = {
jsonrpc: '2.0',
error: {
code: -32603,
message: 'Internal error',
data: error.message
},
id: request.id
};
process.stdout.write(JSON.stringify(errorResponse) + '\n');
});
} catch (error) {
logger.error('JSON parse error', {
error,
line: line.substring(0, 100),
messageId
});
const errorResponse = {
jsonrpc: '2.0',
error: {
code: -32700,
message: 'Parse error',
data: error.message
},
id: null
};
process.stdout.write(JSON.stringify(errorResponse) + '\n');
}
}
}
});
// Infinite runtime - no monitoring intervals needed
// The server now runs indefinitely without any timeout checks
// Handle stdin close
process.stdin.on('end', () => {
logger.logConnection('closed', sessionId, {
messagesProcessed: messageCount,
uptime: process.uptime()
});
logger.info('MCP: stdin closed, shutting down...');
// REMOVED: clearInterval calls (no intervals to clear)
process.exit(0);
});
process.stdin.on('error', (error) => {
logger.logConnection('failed', sessionId, { error });
logger.error('MCP: stdin error, shutting down...', { error });
// REMOVED: clearInterval calls (no intervals to clear)
process.exit(1);
});
// Handle process termination signals
process.on('SIGTERM', () => {
logger.info('MCP: Received SIGTERM, shutting down gracefully...');
// REMOVED: clearInterval calls (no intervals to clear)
process.exit(0);
});
process.on('SIGINT', () => {
logger.info('MCP: Received SIGINT, shutting down gracefully...');
// REMOVED: clearInterval calls (no intervals to clear)
process.exit(0);
});
// Send initialization message
const version = await getVersion();
const initMessage = {
jsonrpc: '2.0',
method: 'server.initialized',
params: {
serverInfo: {
name: 'ruv-swarm-no-timeout',
version: version,
capabilities: {
tools: true,
prompts: false,
resources: true
}
}
}
};
process.stdout.write(JSON.stringify(initMessage) + '\n');
// COMPLETELY REMOVED: ALL CONNECTION AND TIMEOUT MECHANISMS
// The server now runs indefinitely without any timeout checks
logger.info('MCP server running with NO TIMEOUT MECHANISMS', {
connectionStatus: 'INFINITE_RUNTIME',
timeoutStatus: 'DISABLED',
connectionMode: 'INFINITE'
});
} else {
logger.error('WebSocket protocol not yet implemented', { protocol });
console.log('ā WebSocket protocol not yet implemented in production version');
console.log('Use stdio mode for Claude Code integration');
}
} catch (error) {
logger.fatal('Failed to start MCP server', { error, protocol });
console.error('ā Failed to start MCP server:', error.message);
process.exit(1);
}
}
async function startStableMcpServer(args) {
const now = Date.now();
// Reset restart count if it's been more than 5 minutes
if (now - lastRestartTime > RESTART_RESET_TIME) {
restartCount = 0;
}
if (restartCount >= MAX_RESTARTS) {
stabilityLog(`Maximum restarts (${MAX_RESTARTS}) reached. Server may have persistent issues.`);
stabilityLog('Please check logs and restart manually if needed.');
return;
}
restartCount++;
lastRestartTime = now;
stabilityLog(`Starting MCP server (attempt ${restartCount}/${MAX_RESTARTS}) - NO TIMEOUT VERSION`);
// Create new process args without --stability flag
const processArgs = ['mcp', 'start', ...args.filter(arg => arg !== '--stability')];
childProcess = spawn('node', [__filename, ...processArgs], {
stdio: ['inherit', 'inherit', 'inherit'],
env: { ...process.env, MCP_STABILITY: 'false' }
});
childProcess.on('exit', (code, signal) => {
if (code === 0) {
stabilityLog('MCP server exited normally');
return;
}
stabilityLog(`MCP server crashed with code ${code} and signal ${signal}`);
stabilityLog(`Restarting in ${RESTART_DELAY}ms...`);
// Using async delay instead of timeout mechanisms
(async () => {
const delayStart = Date.now();
const delayEnd = delayStart + RESTART_DELAY;
while (Date.now() < delayEnd) {
await new Promise(resolve => {
const waitTime = Math.min(100, delayEnd - Date.now());
const start = Date.now();
while (Date.now() - start < waitTime) {
// Busy wait - no intervals
}
resolve();
});
}
startStableMcpServer(args);
})();
});
childProcess.on('error', (error) => {
stabilityLog(`Failed to start MCP server: ${error.message}`);
stabilityLog(`Restarting in ${RESTART_DELAY}ms...`);
// Using async delay instead of timeout mechanisms
(async () => {
const delayStart = Date.now();
const delayEnd = delayStart + RESTART_DELAY;
while (Date.now() < delayEnd) {
await new Promise(resolve => {
const waitTime = Math.min(100, delayEnd - Date.now());
const start = Date.now();
while (Date.now() - start < waitTime) {
// Busy wait - no intervals
}
resolve();
});
}
startStableMcpServer(args);
})();
});
// Handle process termination signals
process.on('SIGTERM', () => {
stabilityLog('Received SIGTERM, shutting down...');
if (childProcess) {
childProcess.kill('SIGTERM');
}
process.exit(0);
});
process.on('SIGINT', () => {
stabilityLog('Received SIGINT, shutting down...');
if (childProcess) {
childProcess.kill('SIGINT');
}
process.exit(0);
});
}
async function getMcpStatus() {
console.log('š MCP Server Status (NO TIMEOUT VERSION):');
console.log(' Protocol: stdio (for Claude Code integration)');
console.log(' Status: Ready to start');
console.log(' Usage: npx ruv-swarm mcp start [--stability]');
console.log(' Stability: Auto-restart on crashes (use --stability flag)');
console.log(' š„ TIMEOUT MECHANISMS: COMPLETELY DISABLED');
console.log(' š„ RUNTIME: INFINITE');
}
async function stopMcpServer() {
if (childProcess) {
stabilityLog('Stopping MCP server...');
childProcess.kill('SIGTERM');
childProcess = null;
}
console.log('ā
MCP server stopped');
}
async function listMcpTools() {
console.log('š ļø Available MCP Tools (NO TIMEOUT VERSION):');
console.log('\nš Core Swarm Tools:');
console.log(' mcp__ruv-swarm__swarm_init - Initialize a new swarm');
console.log(' mcp__ruv-swarm__agent_spawn - Spawn new agents');
console.log(' mcp__ruv-swarm__task_orchestrate - Orchestrate tasks');
console.log(' mcp__ruv-swarm__swarm_status - Get swarm status');
console.log(' ... and 11 more core tools');
console.log('\nš¤ DAA (Decentralized Autonomous Agents) Tools:');
console.log(' mcp__ruv-swarm__daa_init - Initialize DAA service');
console.log(' mcp__ruv-swarm__daa_agent_create - Create autonomous agents');
console.log(' mcp__ruv-swarm__daa_workflow_create - Create DAA workflows');
console.log(' mcp__ruv-swarm__daa_learning_status - Get learning progress');
console.log(' ... and 6 more DAA tools');
console.log('\nš„ SPECIAL FEATURE: NO TIMEOUT MECHANISMS');
console.log(' ⢠Infinite runtime capability');
console.log(' ⢠No connection interruptions');
console.log(' ⢠No connection timeouts');
console.log(' ⢠Bulletproof stability');
console.log('\nFor full documentation, run: ruv-swarm init --claude');
}
function showMcpHelp() {
console.log(`
š MCP (Model Context Protocol) Commands - NO TIMEOUT VERSION
Usage: ruv-swarm mcp <subcommand> [options]
Subcommands:
start [--protocol=stdio] [--stability] Start MCP server
status Show MCP server status
stop Stop MCP server
tools List available MCP tools
help Show this help message
Options:
--stability Enable auto-restart on crashes
--protocol=stdio Use stdio protocol (default)
š„ TIMEOUT MECHANISMS: COMPLETELY REMOVED
⢠No connection intervals
⢠No connection timeouts
⢠No activity monitoring
⢠Infinite runtime capability
Environment Variables:
LOG_LEVEL Log level (DEBUG, INFO, WARN, ERROR)
šØ REMOVED VARIABLES (NO LONGER NEEDED):
MCP_CONNECTION_INTERVAL ā REMOVED
MCP_CONNECTION_TIMEOUT ā REMOVED
Examples:
ruv-swarm mcp start # Start stdio MCP server (no timeouts)
ruv-swarm mcp start --stability # Start with crash protection (no timeouts)
ruv-swarm mcp tools # List available tools
For Claude Code integration:
claude mcp add ruv-swarm npx ruv-swarm mcp start --stability
š„ SPECIAL FEATURES:
⢠Bulletproof infinite runtime
⢠No disconnection mechanisms
⢠Maximum stability without timeouts
⢠Secure operation maintained
`);
}
async function configureMcp(args) {
console.log('š§ MCP configuration is managed through Claude Code');
console.log('Run: ruv-swarm init --claude');
console.log('š„ NO TIMEOUT CONFIGURATION NEEDED - RUNS FOREVER!');
}
async function getResourceContent(uri) {
const resources = {
'swarm://docs/getting-started': {
contents: [{
uri,
mimeType: 'text/markdown',
text: `# Getting Started with ruv-swarm (NO TIMEOUT VERSION)
## Introduction
ruv-swarm is a powerful WASM-powered neural swarm orchestration system that enhances Claude Code's capabilities through intelligent agent coordination.
š„ **SPECIAL FEATURE: NO TIMEOUT MECHANISMS**
This version has ALL timeout and connection monitoring mechanisms completely removed for bulletproof infinite runtime.
## Quick Start
1. **Initialize a swarm:**
\`\`\`bash
mcp__ruv-swarm__swarm_init { topology: "mesh", maxAgents: 5 }
\`\`\`
2. **Spawn agents:**
\`\`\`bash
mcp__ruv-swarm__agent_spawn { type: "researcher", name: "Doc Analyzer" }
mcp__ruv-swarm__agent_spawn { type: "coder", name: "Implementation Expert" }
\`\`\`
3. **Orchestrate tasks:**
\`\`\`bash
mcp__ruv-swarm__task_orchestrate { task: "Build a REST API", strategy: "adaptive" }
\`\`\`
## Key Concepts
- **Agents**: Cognitive patterns that guide Claude Code's approach
- **Topologies**: Organizational structures for agent coordination
- **Memory**: Persistent state across sessions
- **Neural Training**: Continuous improvement through learning
- **š„ INFINITE RUNTIME**: No timeout mechanisms whatsoever
## Best Practices
1. Always batch operations in a single message
2. Use memory for cross-agent coordination
3. Monitor progress with status tools
4. Train neural patterns for better results
5. š„ ENJOY INFINITE RUNTIME - NO TIMEOUTS!
## Removed Features (For Bulletproof Operation)
- ā Connection monitoring mechanisms
- ā Connection timeouts
- ā Activity monitoring
- ā Automatic disconnections
- ā
Infinite runtime capability`
}]
},
'swarm://docs/stability': {
contents: [{
uri,
mimeType: 'text/markdown',
text: `# Stability Features (NO TIMEOUT VERSION)
## Auto-Restart Protection
The production version includes built-in crash protection:
- **Maximum restarts**: 10 attempts
- **Restart delay**: 1 second between attempts
- **Reset window**: 5 minutes (restart count resets)
- **Graceful shutdown**: SIGTERM/SIGINT handling
## š„ TIMEOUT REMOVAL FEATURES
### What Was Removed:
- ā **Connection intervals**: No periodic connection checks
- ā **Connection timeouts**: No automatic disconnections
- ā **Activity monitoring**: No idle timeout tracking
- ā **Timeout environment variables**: MCP_CONNECTION_* vars removed
### What Was Preserved:
- ā
**Security validation**: All security features intact
- ā
**Error handling**: Proper error management
- ā
**Process signals**: SIGTERM/SIGINT handling
- ā
**Stability mode**: Auto-restart on crashes
- ā
**Logging**: Full logging capability
## Usage
\`\`\`bash
# Enable stability mode (no timeouts)
ruv-swarm mcp start --stability
# For Claude Code integration (no timeouts)
claude mcp add ruv-swarm npx ruv-swarm mcp start --stability
\`\`\`
## Features
- Automatic process restart on crashes
- Proper signal handling
- Detailed logging of restart attempts
- Circuit breaker pattern to prevent infinite loops
- š„ **INFINITE RUNTIME**: Never disconnects due to timeout
- š„ **BULLETPROOF STABILITY**: No timeout-related failures
## Security Notes
- All security features from Issue #107 are preserved
- Input validation and sanitization maintained
- Command injection prevention intact
- WASM integrity verification preserved
- š„ **TIMEOUT VULNERABILITIES**: Eliminated by removing all timeout code`
}]
}
};
const resource = resources[uri];
if (!resource) {
throw new Error(`Resource not found: ${uri}`);
}
return resource;
}
async function handleMcpRequest(request, mcpTools, logger = null) {
const response = {
jsonrpc: '2.0',
id: request.id
};
// Use default logger if not provided
if (!logger) {
logger = await initializeLogger();
}
try {
logger.debug('Processing MCP request (NO TIMEOUT VERSION)', {
method: request.method,
hasParams: !!request.params,
requestId: request.id
});
switch (request.method) {
case 'initialize':
const version = await getVersion();
response.result = {
protocolVersion: '2024-11-05',
capabilities: {
tools: {},
resources: {
list: true,
read: true
}
},
serverInfo: {
name: 'ruv-swarm-no-timeout',
version: version
}
};
break;
case 'tools/list':
response.result = {
tools: [
{
name: 'swarm_init',
description: 'Initialize a new swarm with specified topology (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
topology: { type: 'string', enum: ['mesh', 'hierarchical', 'ring', 'star'], description: 'Swarm topology type' },
maxAgents: { type: 'number', minimum: 1, maximum: 100, default: 5, description: 'Maximum number of agents' },
strategy: { type: 'string', enum: ['balanced', 'specialized', 'adaptive'], default: 'balanced', description: 'Distribution strategy' }
},
required: ['topology']
}
},
{
name: 'swarm_status',
description: 'Get current swarm status and agent information (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
verbose: { type: 'boolean', default: false, description: 'Include detailed agent information' }
}
}
},
{
name: 'swarm_monitor',
description: 'Monitor swarm activity in real-time (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
duration: { type: 'number', default: 10, description: 'Monitoring duration in seconds' },
interval: { type: 'number', default: 1, description: 'Update interval in seconds' }
}
}
},
{
name: 'agent_spawn',
description: 'Spawn a new agent in the swarm (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
type: { type: 'string', enum: ['researcher', 'coder', 'analyst', 'optimizer', 'coordinator'], description: 'Agent type' },
name: { type: 'string', description: 'Custom agent name' },
capabilities: { type: 'array', items: { type: 'string' }, description: 'Agent capabilities' }
},
required: ['type']
}
},
{
name: 'agent_list',
description: 'List all active agents in the swarm (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
filter: { type: 'string', enum: ['all', 'active', 'idle', 'busy'], default: 'all', description: 'Filter agents by status' }
}
}
},
{
name: 'agent_metrics',
description: 'Get performance metrics for agents (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Specific agent ID (optional)' },
metric: { type: 'string', enum: ['all', 'cpu', 'memory', 'tasks', 'performance'], default: 'all' }
}
}
},
{
name: 'task_orchestrate',
description: 'Orchestrate a task across the swarm (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
task: { type: 'string', description: 'Task description or instructions' },
strategy: { type: 'string', enum: ['parallel', 'sequential', 'adaptive'], default: 'adaptive', description: 'Execution strategy' },
priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], default: 'medium', description: 'Task priority' },
maxAgents: { type: 'number', minimum: 1, maximum: 10, description: 'Maximum agents to use' }
},
required: ['task']
}
},
{
name: 'task_status',
description: 'Check progress of running tasks (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
taskId: { type: 'string', description: 'Specific task ID (optional)' },
detailed: { type: 'boolean', default: false, description: 'Include detailed progress' }
}
}
},
{
name: 'task_results',
description: 'Retrieve results from completed tasks (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
taskId: { type: 'string', description: 'Task ID to retrieve results for' },
format: { type: 'string', enum: ['summary', 'detailed', 'raw'], default: 'summary', description: 'Result format' }
},
required: ['taskId']
}
},
{
name: 'benchmark_run',
description: 'Execute performance benchmarks (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
type: { type: 'string', enum: ['all', 'wasm', 'swarm', 'agent', 'task'], default: 'all', description: 'Benchmark type' },
iterations: { type: 'number', minimum: 1, maximum: 100, default: 10, description: 'Number of iterations' }
}
}
},
{
name: 'features_detect',
description: 'Detect runtime features and capabilities (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
category: { type: 'string', enum: ['all', 'wasm', 'simd', 'memory', 'platform'], default: 'all', description: 'Feature category' }
}
}
},
{
name: 'memory_usage',
description: 'Get current memory usage statistics (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
detail: { type: 'string', enum: ['summary', 'detailed', 'by-agent'], default: 'summary', description: 'Detail level' }
}
}
},
{
name: 'neural_status',
description: 'Get neural agent status and performance metrics (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Specific agent ID (optional)' }
}
}
},
{
name: 'neural_train',
description: 'Train neural agents with sample tasks (NO TIMEOUT VERSION)',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', descripti