UNPKG

mcp-ynab

Version:

Model Context Protocol server for YNAB integration

89 lines (71 loc) 2.16 kB
import { writeFile, appendFile, existsSync, mkdirSync } from 'fs'; import { promisify } from 'util'; import { resolve, dirname } from 'path'; import { fileURLToPath } from 'url'; const writeFileAsync = promisify(writeFile); const appendFileAsync = promisify(appendFile); const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); class Logger { constructor() { this.logsDir = resolve(__dirname, '../../logs'); this.logFile = resolve(this.logsDir, 'mcp-debug.log'); // Don't check enabled in constructor - check at runtime } get enabled() { // Check environment variables at runtime, not construction time return process.env.NODE_ENV === 'development' || process.env.MCP_DEBUG === 'true'; } ensureLogsDirectory() { if (this.enabled && !existsSync(this.logsDir)) { try { mkdirSync(this.logsDir, { recursive: true }); } catch (error) { // Silently fail to avoid breaking MCP protocol } } } async log(level, message, data = null) { if (!this.enabled) return; // Ensure logs directory exists this.ensureLogsDirectory(); const timestamp = new Date().toISOString(); const logEntry = { timestamp, level, message, data, pid: process.pid }; const logLine = JSON.stringify(logEntry) + '\n'; try { await appendFileAsync(this.logFile, logLine); } catch (error) { // Silently fail - don't break MCP protocol } } async info(message, data) { await this.log('INFO', message, data); } async error(message, data) { await this.log('ERROR', message, data); } async debug(message, data) { await this.log('DEBUG', message, data); } async warn(message, data) { await this.log('WARN', message, data); } async startup(message, data) { await this.log('STARTUP', message, data); } async tool(toolName, params, result) { await this.log('TOOL', `Tool executed: ${toolName}`, { tool: toolName, params, success: !result?.error, resultSize: JSON.stringify(result).length }); } } export default new Logger();