@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
JavaScript
;
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