UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

157 lines (138 loc) 4.37 kB
#!/usr/bin/env node /** * @claude-flow/cli - CLI Entry Point * * Claude Flow V3 Command Line Interface * * Auto-detects MCP mode when stdin is piped and no args provided. * This allows: echo '{"jsonrpc":"2.0",...}' | npx @claude-flow/cli */ import { randomUUID } from 'crypto'; // Check if we should run in MCP server mode // Conditions: // 1. stdin is being piped AND no CLI arguments provided (auto-detect) // 2. stdin is being piped AND args are "mcp start" (explicit, e.g. npx claude-flow@alpha mcp start) const cliArgs = process.argv.slice(2); const isExplicitMCP = cliArgs.length >= 1 && cliArgs[0] === 'mcp' && (cliArgs.length === 1 || cliArgs[1] === 'start'); const isMCPMode = !process.stdin.isTTY && (process.argv.length === 2 || isExplicitMCP); if (isMCPMode) { // Run MCP server mode const { listMCPTools, callMCPTool, hasTool } = await import('../dist/src/mcp-client.js'); const VERSION = '3.0.0'; const sessionId = `mcp-${Date.now()}-${randomUUID().slice(0, 8)}`; console.error( `[${new Date().toISOString()}] INFO [claude-flow-mcp] (${sessionId}) Starting in stdio mode` ); let buffer = ''; process.stdin.setEncoding('utf8'); process.stdin.on('data', async (chunk) => { buffer += chunk; let lines = buffer.split('\n'); buffer = lines.pop() || ''; for (const line of lines) { if (line.trim()) { try { const message = JSON.parse(line); const response = await handleMessage(message); if (response) { console.log(JSON.stringify(response)); } } catch (error) { console.log(JSON.stringify({ jsonrpc: '2.0', id: null, error: { code: -32700, message: 'Parse error' }, })); } } } }); process.stdin.on('end', () => { process.exit(0); }); async function handleMessage(message) { if (!message.method) { return { jsonrpc: '2.0', id: message.id, error: { code: -32600, message: 'Invalid Request: missing method' }, }; } const params = message.params || {}; switch (message.method) { case 'initialize': return { jsonrpc: '2.0', id: message.id, result: { protocolVersion: '2024-11-05', serverInfo: { name: 'claude-flow', version: VERSION }, capabilities: { tools: { listChanged: true }, resources: { subscribe: true, listChanged: true }, }, }, }; case 'tools/list': { const tools = listMCPTools(); return { jsonrpc: '2.0', id: message.id, result: { tools: tools.map(tool => ({ name: tool.name, description: tool.description, inputSchema: tool.inputSchema, })), }, }; } case 'tools/call': { const toolName = params.name; const toolParams = params.arguments || {}; if (!hasTool(toolName)) { return { jsonrpc: '2.0', id: message.id, error: { code: -32601, message: `Tool not found: ${toolName}` }, }; } try { const result = await callMCPTool(toolName, toolParams, { sessionId }); return { jsonrpc: '2.0', id: message.id, result: { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }, }; } catch (error) { return { jsonrpc: '2.0', id: message.id, error: { code: -32603, message: error instanceof Error ? error.message : 'Tool execution failed', }, }; } } case 'notifications/initialized': return null; case 'ping': return { jsonrpc: '2.0', id: message.id, result: {} }; default: return { jsonrpc: '2.0', id: message.id, error: { code: -32601, message: `Method not found: ${message.method}` }, }; } } } else { // Run normal CLI mode const { CLI } = await import('../dist/src/index.js'); const cli = new CLI(); cli.run().catch((error) => { console.error('Fatal error:', error.message); process.exit(1); }); }