UNPKG

@alcyone-labs/simple-mcp-logger

Version:

Logging solution for MCP servers. Prevents console output from corrupting MCP protocol communication. Drop-in replacement for console, Winston, and Pino with automatic STDOUT suppression in MCP mode.

271 lines (270 loc) 7.3 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const SimpleMcpLogger = require("../SimpleMcpLogger-D6nWOVH5.cjs"); const TransportStream = require("winston-transport"); class SimpleMcpWinstonTransport extends TransportStream { constructor(options = {}) { super(options); this.options = options; const level = this.mapWinstonLevelToMcp(options.level || "info"); this.logger = new SimpleMcpLogger.Logger({ level, mcpMode: options.mcpMode || false, prefix: options.prefix, logToFile: options.logToFile }); } /** * Emit method for Winston compatibility */ emit(event, ...args) { return super.emit(event, ...args); } /** * Map Winston log levels to SimpleMcpLogger levels */ mapWinstonLevelToMcp(winstonLevel) { const levelMap = { "error": "error", "warn": "warn", "info": "info", "http": "info", "verbose": "debug", "debug": "debug", "silly": "debug" }; return levelMap[winstonLevel] || "info"; } /** * Log method called by Winston */ log(info, callback) { const level = this.mapWinstonLevelToMcp(info.level); const message = info.message || ""; const { level: _, message: __, timestamp: ___, ...meta } = info; const cleanMeta = {}; for (const [key, value] of Object.entries(meta)) { if (typeof key === "string" && !key.startsWith("Symbol(") && key !== "splat") { cleanMeta[key] = value; } } const args = Object.keys(cleanMeta).length > 0 ? [cleanMeta] : []; switch (level) { case "debug": this.logger.debug(message, ...args); break; case "info": this.logger.info(message, ...args); break; case "warn": this.logger.warn(message, ...args); break; case "error": this.logger.error(message, ...args); break; default: this.logger.info(message, ...args); } setImmediate(() => { this.emit("logged", info); }); if (callback) { callback(); } } /** * Set MCP mode */ setMcpMode(enabled) { this.logger.setMcpMode(enabled); } /** * Set log level */ setLevel(level) { this.logger.setLevel(level); } /** * Set prefix */ setPrefix(prefix) { this.logger.setPrefix(prefix); } /** * Create child logger */ child(prefix) { const childLogger = this.logger.child(prefix); const transport = new SimpleMcpWinstonTransport(this.options); transport.logger = childLogger; return transport; } /** * Get the underlying SimpleMcpLogger instance */ getLogger() { return this.logger; } /** * Set log file path */ async setLogFile(filePath) { await this.logger.setLogFile(filePath); } /** * Close file stream */ async close() { await this.logger.close(); } } function createWinstonTransport(options = {}) { return new SimpleMcpWinstonTransport(options); } class SimpleMcpPinoTransport { constructor(options = {}) { this.options = options; const level = this.mapPinoLevelToMcp(options.level || "info"); this.logger = new SimpleMcpLogger.Logger({ level, mcpMode: options.mcpMode || false, prefix: options.prefix, logToFile: options.logToFile }); } /** * Map Pino log levels to SimpleMcpLogger levels */ mapPinoLevelToMcp(pinoLevel) { if (typeof pinoLevel === "number") { if (pinoLevel >= 60) return "error"; if (pinoLevel >= 50) return "error"; if (pinoLevel >= 40) return "warn"; if (pinoLevel >= 30) return "info"; if (pinoLevel >= 20) return "debug"; return "debug"; } const levelMap = { "fatal": "error", "error": "error", "warn": "warn", "info": "info", "debug": "debug", "trace": "debug" }; return levelMap[pinoLevel] || "info"; } /** * Transform function for Pino transport */ transform(chunk) { try { const logObj = typeof chunk === "string" ? JSON.parse(chunk) : chunk; const level = this.mapPinoLevelToMcp(logObj.level); const message = logObj.msg || ""; const { level: _, msg: __, time: ___, hostname: ____, pid: _____, ...meta } = logObj; const cleanMeta = {}; for (const [key, value] of Object.entries(meta)) { if (typeof key === "string" && !key.startsWith("Symbol(") && key !== "v") { cleanMeta[key] = value; } } const args = Object.keys(cleanMeta).length > 0 ? [cleanMeta] : []; switch (level) { case "debug": this.logger.debug(message, ...args); break; case "info": this.logger.info(message, ...args); break; case "warn": this.logger.warn(message, ...args); break; case "error": this.logger.error(message, ...args); break; default: this.logger.info(message, ...args); } } catch (error) { this.logger.error("Failed to parse log message", error); } } /** * Set MCP mode */ setMcpMode(enabled) { this.logger.setMcpMode(enabled); } /** * Set log level */ setLevel(level) { this.logger.setLevel(level); } /** * Set prefix */ setPrefix(prefix) { this.logger.setPrefix(prefix); } /** * Create child logger */ child(prefix) { const childLogger = this.logger.child(prefix); const transport = new SimpleMcpPinoTransport(this.options); transport.logger = childLogger; return transport; } /** * Get the underlying SimpleMcpLogger instance */ getLogger() { return this.logger; } /** * Set log file path */ async setLogFile(filePath) { await this.logger.setLogFile(filePath); } /** * Close file stream */ async close() { await this.logger.close(); } } function createPinoTransport(options = {}) { return new SimpleMcpPinoTransport(options); } function createPinoDestination(options = {}) { const transport = new SimpleMcpPinoTransport(options); return { write(chunk) { transport.transform(chunk); }, async end() { await transport.close(); }, async destroy() { await transport.close(); } }; } function createPinoLogger(_options = {}) { if (typeof window !== "undefined") { throw new Error("createPinoLogger is not supported in browser environments. Use createPinoDestination with a browser-compatible Pino build instead."); } throw new Error( "createPinoLogger is deprecated for bundling compatibility. Please import Pino directly and use createPinoDestination instead:\n\nimport pino from 'pino';\nimport { createPinoDestination } from '@alcyone-labs/simple-mcp-logger';\n\nconst destination = createPinoDestination({ level: 'info' });\nconst logger = pino({ level: 'info' }, destination);" ); } exports.SimpleMcpPinoTransport = SimpleMcpPinoTransport; exports.SimpleMcpWinstonTransport = SimpleMcpWinstonTransport; exports.createPinoDestination = createPinoDestination; exports.createPinoLogger = createPinoLogger; exports.createPinoTransport = createPinoTransport; exports.createWinstonTransport = createWinstonTransport; //# sourceMappingURL=index.cjs.map