@simonecoelhosfo/optimizely-mcp-server
Version:
Optimizely MCP Server for AI assistants with integrated CLI tools
105 lines • 4.02 kB
JavaScript
import * as fs from 'fs';
import * as path from 'path';
/**
* MCP Debug Logger for STDIO communication
*
* IMPORTANT: In MCP servers, stdout is reserved for JSON-RPC communication.
* All debug output must go to stderr or log files to avoid breaking the protocol.
*/
export class MCPDebugLogger {
static logFile;
static isInitialized = false;
static initialize(logPath, projectRoot) {
if (this.isInitialized)
return;
// Use absolute path - accessible from both Windows and WSL
if (logPath) {
this.logFile = logPath;
}
else {
// Default: WSL path that's accessible from Windows
this.logFile = '/mnt/c/Users/LAH/AppData/Local/Programs/cursor/logs/mcp-debug.log';
}
// Ensure log directory exists
const logDir = path.dirname(this.logFile);
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, { recursive: true });
}
// Write initial log entry
this.writeLog('=== MCP Debug Logger Initialized ===');
this.writeLog(`Log file: ${this.logFile}`);
this.writeLog(`Timestamp: ${new Date().toISOString()}`);
this.writeLog('=====================================\n');
this.isInitialized = true;
}
static writeLog(message) {
// const timestamp = new Date().toISOString();
// const logEntry = `[${timestamp}] ${message}\n`;
// // Append to log file
// fs.appendFileSync(this.logFile, logEntry);
// // Also write to stderr (safe for MCP)
// process.stderr.write(logEntry);
}
/**
* Log incoming MCP requests
*/
static logRequest(method, params, id) {
this.writeLog('📥 MCP REQUEST:');
this.writeLog(` Method: ${method}`);
this.writeLog(` ID: ${id || 'notification'}`);
this.writeLog(` Params: ${JSON.stringify(params, null, 2)}`);
this.writeLog('---');
}
/**
* Log outgoing MCP responses
*/
static logResponse(result, id, error) {
if (error) {
this.writeLog('❌ MCP ERROR RESPONSE:');
this.writeLog(` ID: ${id}`);
this.writeLog(` Error: ${JSON.stringify(error, null, 2)}`);
}
else {
this.writeLog('📤 MCP RESPONSE:');
this.writeLog(` ID: ${id}`);
this.writeLog(` Result Preview: ${JSON.stringify(result).substring(0, 500)}...`);
}
this.writeLog('---');
}
/**
* Log raw STDIO communication
*/
static logRawMessage(direction, message) {
this.writeLog(`🔵 RAW ${direction}:`);
this.writeLog(` ${message}`);
this.writeLog('---');
}
/**
* Create a wrapped handler that logs all interactions
*/
static wrapHandler(handlerName, handler) {
return (async (...args) => {
const startTime = Date.now();
const requestId = Math.random().toString(36).substring(7);
this.writeLog(`🎯 HANDLER START: ${handlerName} [${requestId}]`);
this.writeLog(` Args: ${JSON.stringify(args, null, 2)}`);
try {
const result = await handler(...args);
const duration = Date.now() - startTime;
this.writeLog(`✅ HANDLER SUCCESS: ${handlerName} [${requestId}]`);
this.writeLog(` Duration: ${duration}ms`);
this.writeLog(` Result Preview: ${JSON.stringify(result).substring(0, 300)}...`);
return result;
}
catch (error) {
const duration = Date.now() - startTime;
this.writeLog(`❌ HANDLER ERROR: ${handlerName} [${requestId}]`);
this.writeLog(` Duration: ${duration}ms`);
this.writeLog(` Error: ${error.message}`);
this.writeLog(` Stack: ${error.stack}`);
throw error;
}
});
}
}
//# sourceMappingURL=MCPDebugLogger.js.map