type LogLevel = "info" | "warn" | "error" | "debug";
interface LoggerOptions {
service: string;
}
interface Logger {
info: (message: string, data?: unknown) => void;
warn: (message: string, data?: unknown) => void;
error: (message: string, data?: unknown) => void;
debug: (message: string, data?: unknown) => void;
}
/**
* Create a logger that writes to stderr (important for stdio transport!)
* When using stdio transport, stdout is reserved for MCP protocol messages,
* so all logging must go to stderr.
*/
export function createLogger(options: LoggerOptions): Logger {
const { service } = options;
const log = (level: LogLevel, message: string, data?: unknown) => {
const timestamp = new Date().toISOString();
const prefix = `[${timestamp}] [${level.toUpperCase()}] [${service}]`;
const output =
data !== undefined
? `${prefix} ${message} ${JSON.stringify(data)}`
: `${prefix} ${message}`;
// Always write to stderr for stdio transport compatibility
process.stderr.write(`${output}\n`);
};
return {
info: (message, data) => log("info", message, data),
warn: (message, data) => log("warn", message, data),
error: (message, data) => log("error", message, data),
debug: (message, data) => log("debug", message, data),
};
}
// Default logger instance
export const logger = createLogger({ service: "mcp-server" });