UNPKG

@paradiselabs/mco-protocol

Version:

MCO (Model Configuration Orchestration) MCP Server & Configuration Tool

256 lines (218 loc) โ€ข 8.62 kB
#!/usr/bin/env node /** * MCO CLI * * Command-line interface for the MCO MCP Server and Configuration Tool */ const { program } = require('commander'); const fs = require('fs-extra'); const path = require('path'); const { spawn } = require('child_process'); const { SNLPParser } = require('../lib/snlp-parser'); // Set up CLI program .name('mco') .description('MCO (Model Configuration Orchestration) MCP Server & Configuration Tool') .version('0.1.0'); // Init command - Create new MCO project with config tool program .command('init') .description('Create a new MCO project with the configuration tool') .argument('[project-name]', 'Name of the project directory', 'mco-project') .action(async (projectName) => { try { // Create project directory const projectDir = path.resolve(process.cwd(), projectName); await fs.ensureDir(projectDir); console.log(`Creating new MCO project in ${projectDir}...`); // Create empty SNLP files await fs.writeFile(path.join(projectDir, 'mco.core'), '// MCO Core Configuration\n\n@workflow "New Workflow"\n\n@data\n\n@agents\n'); await fs.writeFile(path.join(projectDir, 'mco.sc'), '// MCO Success Criteria\n\n@goal\n\n@success_criteria\n'); await fs.writeFile(path.join(projectDir, 'mco.features'), '// MCO Features\n\n@features\n'); await fs.writeFile(path.join(projectDir, 'mco.styles'), '// MCO Styles\n\n@styles\n'); console.log('Created empty SNLP files.'); // Open configuration tool console.log('Opening configuration tool...'); const configToolPath = path.resolve(__dirname, '../web/config-tool/index.html'); const open = (await import('open')).default; await open(configToolPath); console.log(` MCO project initialized successfully! ๐Ÿ”ง For MCP Inspector, use: npx @modelcontextprotocol/inspector node "${path.resolve(__dirname, 'mco-server.js')}" ๐Ÿ“‹ Or run the MCP server directly: mco serve ${projectName} ๐Ÿงช To validate your SNLP files: mco validate ${projectName} `); } catch (error) { console.error('Error initializing MCO project:', error); process.exit(1); } }); // Validate command - Validate SNLP files program .command('validate') .description('Validate SNLP files') .argument('[config-dir]', 'Directory containing SNLP files', '.') .action(async (configDir) => { try { const parser = new SNLPParser(); const resolvedDir = path.resolve(process.cwd(), configDir); console.log(`Validating SNLP files in ${resolvedDir}...`); // Check if directory exists if (!await fs.pathExists(resolvedDir)) { console.error(`Directory ${resolvedDir} does not exist.`); process.exit(1); } // Check for required files const requiredFiles = ['mco.core', 'mco.sc']; const optionalFiles = ['mco.features', 'mco.styles']; const missingFiles = []; for (const file of requiredFiles) { if (!await fs.pathExists(path.join(resolvedDir, file))) { missingFiles.push(file); } } if (missingFiles.length > 0) { console.error(`Missing required files: ${missingFiles.join(', ')}`); process.exit(1); } // Parse and validate files try { const workflow = await parser.parseDirectory(resolvedDir); console.log('โœ… SNLP files are valid!'); // Print workflow summary const persistentContext = workflow.getPersistentContext(); console.log('\nWorkflow Summary:'); console.log(`- Name: ${persistentContext.workflow_name || 'Unnamed workflow'}`); console.log(`- Goal: ${persistentContext.goal || 'No goal specified'}`); if (persistentContext.criteria && persistentContext.criteria.length > 0) { console.log(`- Success Criteria: ${persistentContext.criteria.length} criteria defined`); } else { console.log('- Success Criteria: None defined'); } // Check for optional files for (const file of optionalFiles) { if (await fs.pathExists(path.join(resolvedDir, file))) { console.log(`- ${file}: Present`); } else { console.log(`- ${file}: Missing (optional)`); } } } catch (error) { console.error('โŒ SNLP validation failed:', error.message); process.exit(1); } } catch (error) { console.error('Error validating SNLP files:', error); process.exit(1); } }); // Serve command - Start MCP server program .command('serve') .description('Start MCP server') .argument('[config-dir]', 'Directory containing SNLP files', '.') .option('-p, --port <port>', 'Port to listen on', '3000') .option('-h, --host <host>', 'Host to bind to', 'localhost') .action(async (configDir, options) => { try { const resolvedDir = path.resolve(process.cwd(), configDir); console.log(`Starting MCO MCP Server with configuration from ${resolvedDir}...`); console.log(''); console.log('๐Ÿ”ง For MCP Inspector, use this command instead:'); console.log(`npx @modelcontextprotocol/inspector node "${path.resolve(__dirname, 'mco-server.js')}"`); console.log(''); console.log('๐Ÿ“‹ Or add this to your MCP client configuration:'); console.log(`{ "mcpServers": { "mco-orchestration": { "command": "node", "args": ["${path.resolve(__dirname, 'mco-server.js')}"], "env": { "MCO_CONFIG_DIR": "${resolvedDir}" } } } }`); console.log(''); // Check if directory exists if (!await fs.pathExists(resolvedDir)) { console.error(`Directory ${resolvedDir} does not exist.`); process.exit(1); } // Set environment variable for config directory process.env.MCO_CONFIG_DIR = resolvedDir; // Start MCP server const serverPath = path.resolve(__dirname, 'mco-server.js'); const server = spawn('node', [serverPath], { stdio: 'inherit', env: { ...process.env, MCO_CONFIG_DIR: resolvedDir } }); // Handle server exit server.on('close', (code) => { if (code !== 0) { console.error(`Server exited with code ${code}`); process.exit(code); } }); } catch (error) { console.error('Error starting MCP server:', error); process.exit(1); } }); // Sample command - Create sample workflow project program .command('sample') .description('Create a sample workflow project') .argument('[project-name]', 'Name of the project directory', 'sample-workflow') .action(async (projectName) => { try { // Create project directory const projectDir = path.resolve(process.cwd(), projectName); await fs.ensureDir(projectDir); console.log(`Creating sample workflow project in ${projectDir}...`); // Copy sample workflow files const templateDir = path.resolve(__dirname, '../templates/sample-workflow'); await fs.copy(templateDir, projectDir); console.log('Copied sample workflow files.'); console.log(` Sample MCO project created successfully! To start the MCP server: mco serve ${projectName} To validate the SNLP files: mco validate ${projectName} `); } catch (error) { console.error('Error creating sample project:', error); process.exit(1); } }); // Templates command - List available templates program .command('templates') .description('List available templates') .action(() => { console.log('Available templates:'); console.log('- Research Assistant: Multi-step research workflows'); console.log('- Software Development: Code generation workflows'); console.log('- Content Creation: Writing and editing workflows'); console.log('- Data Analysis: Data processing workflows'); console.log('- Custom: Start from scratch'); }); // Deploy command - Deploy to cloud MCP service program .command('deploy') .description('Deploy to cloud MCP service') .argument('[config-dir]', 'Directory containing SNLP files', '.') .action((configDir) => { console.log(`Deploying MCO configuration from ${configDir} to cloud service...`); console.log('This feature is not yet implemented.'); }); // Parse command-line arguments program.parse(process.argv); // If no command is provided, show help if (!process.argv.slice(2).length) { program.outputHelp(); }