UNPKG

tryaii-mcp-server

Version:

TryAII MCP Server - 15+ AI models with comparison, cost tracking, and collective intelligence

136 lines 4.35 kB
import { EventEmitter } from 'events'; import { v4 as uuidv4 } from 'uuid'; import { logger } from '../utils/logger.js'; export class McpConnection extends EventEmitter { socket; id = uuidv4(); buffer = ''; constructor(socket) { super(); this.socket = socket; this.setupSocket(); } setupSocket() { this.socket.setEncoding('utf8'); this.socket.setKeepAlive(true); this.socket.on('data', this.handleData.bind(this)); this.socket.on('close', () => { logger.info('MCP connection socket closed', { connectionId: this.id }); this.emit('close'); }); this.socket.on('error', (error) => { logger.error('MCP connection socket error', { connectionId: this.id, error }); this.emit('error', error); }); logger.info('MCP connection established', { connectionId: this.id, remoteAddress: this.socket.remoteAddress, remotePort: this.socket.remotePort }); } handleData(data) { this.buffer += data; const lines = this.buffer.split('\n'); this.buffer = lines.pop() || ''; for (const line of lines) { if (line.trim()) { try { const message = JSON.parse(line); logger.debug('Received MCP message', { connectionId: this.id, method: message.method, id: message.id, hasParams: !!message.params }); this.emit('request', message); } catch (error) { logger.error('Failed to parse MCP message', { connectionId: this.id, line: line.substring(0, 200), // Truncate for logging error }); this.sendError(-32700, 'Parse error', null); } } } } sendResponse(response) { if (this.socket.destroyed) { logger.warn('Attempted to send response to destroyed socket', { connectionId: this.id, responseId: response.id }); return; } try { const message = JSON.stringify(response) + '\n'; this.socket.write(message); logger.debug('Sent MCP response', { connectionId: this.id, id: response.id, hasError: !!response.error, hasResult: !!response.result }); } catch (error) { logger.error('Failed to send MCP response', { connectionId: this.id, responseId: response.id, error }); } } sendError(code, message, id) { const errorResponse = { jsonrpc: '2.0', id: id === null ? 0 : id, error: { code, message } }; this.sendResponse(errorResponse); } sendNotification(method, params) { if (this.socket.destroyed) { logger.warn('Attempted to send notification to destroyed socket', { connectionId: this.id, method }); return; } try { const notification = { jsonrpc: '2.0', method, ...(params && { params }) }; const message = JSON.stringify(notification) + '\n'; this.socket.write(message); logger.debug('Sent MCP notification', { connectionId: this.id, method }); } catch (error) { logger.error('Failed to send MCP notification', { connectionId: this.id, method, error }); } } close() { if (!this.socket.destroyed) { this.socket.destroy(); } } isConnected() { return !this.socket.destroyed; } getRemoteAddress() { return this.socket.remoteAddress; } getRemotePort() { return this.socket.remotePort; } } //# sourceMappingURL=McpConnection.js.map