UNPKG

codemesh

Version:

Execute TypeScript code against multiple MCP servers, weaving them together into powerful workflows

61 lines (60 loc) 1.83 kB
import * as fs from 'node:fs'; import * as path from 'node:path'; /** * Simple file logger for stdio MCP servers * Writes to a log file instead of stdout to avoid interfering with JSON-RPC */ class FileLogger { logPath; enabled; constructor(logPath) { // Only enable logging if logPath is explicitly provided this.logPath = logPath || ''; this.enabled = !!logPath; // Ensure log directory exists only if logging is enabled if (this.enabled) { try { const logDir = path.dirname(this.logPath); if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }); } } catch (error) { // Silently fail if we can't create log directory this.enabled = false; } } } write(level, ...args) { if (!this.enabled) return; try { const timestamp = new Date().toISOString(); const message = args .map((arg) => (typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg))) .join(' '); const logLine = `[${timestamp}] [${level}] ${message}\n`; fs.appendFileSync(this.logPath, logLine, { encoding: 'utf-8' }); } catch (error) { // Silently fail - we can't log if logging fails! } } log(...args) { this.write('INFO', ...args); } error(...args) { this.write('ERROR', ...args); } warn(...args) { this.write('WARN', ...args); } info(...args) { this.write('INFO', ...args); } debug(...args) { this.write('DEBUG', ...args); } } // Singleton logger instance export const logger = new FileLogger();