UNPKG

qasphere-mcp

Version:
88 lines (87 loc) 2.57 kB
import * as fs from 'node:fs'; import * as path from 'node:path'; /** * A wrapper transport that logs all MCP communication to a file */ export class LoggingTransport { wrapped; logStream; logFile; sessionId; constructor(wrapped, logFile) { // Store wrapped transport this.wrapped = wrapped; // Set up logging this.logFile = logFile; // Create log directory if it doesn't exist const logDir = path.dirname(this.logFile); if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }); } // Create log stream this.logStream = fs.createWriteStream(this.logFile, { flags: 'a' }); // Log initial connection information this.log({ type: 'connection_info', timestamp: new Date().toISOString(), message: 'LoggingTransport initialized', }); // Set up forwarding of events this.wrapped.onmessage = (message) => { this.log({ type: 'received', timestamp: new Date().toISOString(), message, }); if (this.onmessage) this.onmessage(message); }; this.wrapped.onerror = (error) => { this.log({ type: 'error', timestamp: new Date().toISOString(), error: error.message, stack: error.stack, }); if (this.onerror) this.onerror(error); }; this.wrapped.onclose = () => { this.log({ type: 'close', timestamp: new Date().toISOString(), message: 'Connection closed', }); if (this.onclose) this.onclose(); // Close the log stream when the connection closes this.logStream.end(); }; } // Implementation of Transport interface onclose; onerror; onmessage; async start() { return this.wrapped.start(); } async close() { return this.wrapped.close(); } async send(message) { this.log({ type: 'sent', timestamp: new Date().toISOString(), message, }); return this.wrapped.send(message); } log(data) { try { this.logStream.write(`${JSON.stringify(data)}\n`); } catch (error) { console.error('Failed to write to log file:', error); } } }