/**
* Logger utility for MCP server
* Logs to stderr to keep stdout clean for MCP protocol
*/
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
const LOG_LEVELS: Record<LogLevel, number> = {
debug: 0,
info: 1,
warn: 2,
error: 3,
};
let currentLevel: LogLevel = (process.env.LOG_LEVEL as LogLevel) || 'info';
export function setLogLevel(level: LogLevel): void {
currentLevel = level;
}
function shouldLog(level: LogLevel): boolean {
return LOG_LEVELS[level] >= LOG_LEVELS[currentLevel];
}
function formatMessage(level: LogLevel, message: string, meta?: Record<string, unknown>): string {
const timestamp = new Date().toISOString();
const metaStr = meta ? ` ${JSON.stringify(meta)}` : '';
return `[${timestamp}] [${level.toUpperCase()}] ${message}${metaStr}`;
}
export const logger = {
debug(message: string, meta?: Record<string, unknown>): void {
if (shouldLog('debug')) {
console.error(formatMessage('debug', message, meta));
}
},
info(message: string, meta?: Record<string, unknown>): void {
if (shouldLog('info')) {
console.error(formatMessage('info', message, meta));
}
},
warn(message: string, meta?: Record<string, unknown>): void {
if (shouldLog('warn')) {
console.error(formatMessage('warn', message, meta));
}
},
error(message: string, meta?: Record<string, unknown>): void {
if (shouldLog('error')) {
console.error(formatMessage('error', message, meta));
}
},
};
export default logger;