tryaii-mcp-server
Version:
TryAII MCP Server - 15+ AI models with comparison, cost tracking, and collective intelligence
136 lines • 4.35 kB
JavaScript
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