UNPKG

@hivetechs/hive-ai

Version:

Real-time streaming AI consensus platform with HTTP+SSE MCP integration for Claude Code, VS Code, Cursor, and Windsurf - powered by OpenRouter's unified API

159 lines 5.91 kB
/** * Stdio Bridge MCP Server * * Bridges between Claude Code's stdio transport and our HTTP+SSE streaming server. * This allows Claude Code to launch via command while maintaining streaming capabilities. */ export class StdioBridgeMCPServer { httpServerProcess = null; httpServerPort = 3000; async start() { // Start the HTTP+SSE server in background await this.startHttpServer(); // Handle stdio communication this.handleStdioMessages(); } async startHttpServer() { const { MCPPortManager } = await import('../tools/mcp-port-manager.js'); const portManager = new MCPPortManager(); const { port } = await portManager.getBestPort(); this.httpServerPort = port; // Start HTTP server directly (not via command to avoid recursion) const { HiveAIMCPServer } = await import('./server.js'); const httpServer = new HiveAIMCPServer(port); // Start in background httpServer.start().catch(console.error); // Wait for server to be ready await new Promise(resolve => setTimeout(resolve, 3000)); } handleStdioMessages() { process.stdin.setEncoding('utf8'); let buffer = ''; process.stdin.on('data', async (chunk) => { buffer += chunk; // Process complete JSON-RPC messages const lines = buffer.split('\n'); buffer = lines.pop() || ''; for (const line of lines) { if (line.trim()) { try { const request = JSON.parse(line); const response = await this.handleRequest(request); this.sendResponse(response); } catch (error) { this.sendError(null, -32700, 'Parse error'); } } } }); process.stdin.on('end', () => { this.cleanup(); }); } async handleRequest(request) { try { switch (request.method) { case 'initialize': return { jsonrpc: '2.0', id: request.id, result: { protocolVersion: '2025-03-26', capabilities: { tools: { listChanged: true }, resources: {}, prompts: {}, logging: {} }, serverInfo: { name: 'hive-ai-bridge', version: await import('../utils/version-utils.js').then(m => m.getCurrentVersion()) } } }; case 'tools/list': return { jsonrpc: '2.0', id: request.id, result: { tools: [ { name: 'hive_consensus', description: 'Run 4-stage AI consensus with real-time streaming', inputSchema: { type: 'object', properties: { question: { type: 'string', description: 'The question for consensus analysis' } }, required: ['question'] } } ] } }; case 'tools/call': // Bridge tool calls to HTTP server return await this.bridgeToolCall(request); default: return { jsonrpc: '2.0', id: request.id, error: { code: -32601, message: 'Method not found' } }; } } catch (error) { return { jsonrpc: '2.0', id: request.id, error: { code: -32000, message: `Internal error: ${error}` } }; } } async bridgeToolCall(request) { try { // Make HTTP request to our streaming server const response = await fetch(`http://localhost:${this.httpServerPort}/mcp`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(request) }); if (response.ok) { const result = await response.json(); return result; } else { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } } catch (error) { return { jsonrpc: '2.0', id: request.id, error: { code: -32000, message: `Bridge error: ${error}` } }; } } sendResponse(response) { process.stdout.write(JSON.stringify(response) + '\n'); } sendError(id, code, message) { const errorResponse = { jsonrpc: '2.0', id, error: { code, message } }; this.sendResponse(errorResponse); } cleanup() { if (this.httpServerProcess) { this.httpServerProcess.kill(); } } } export async function startStdioBridgeServer() { const server = new StdioBridgeMCPServer(); await server.start(); } //# sourceMappingURL=stdio-bridge-server.js.map