okta-mcp-server
Version:
Model Context Protocol (MCP) server for Okta API operations with support for bulk operations and caching
91 lines • 3.23 kB
JavaScript
/**
* Protocol-safe logger for MCP servers
* Ensures logs don't interfere with stdio protocol communication
*/
import { appendFileSync, existsSync, mkdirSync } from 'fs';
import { join } from 'path';
const LOG_LEVELS = {
debug: 0,
info: 1,
warn: 2,
error: 3,
};
class ProtocolSafeLogger {
level;
name;
logFile = null;
useFileLogging;
constructor(name, level = 'info') {
this.name = name;
this.level = level;
this.useFileLogging = process.env.MCP_LOG_FILE === 'true' || process.env.LOG_TO_FILE === 'true';
if (this.useFileLogging) {
this.initializeFileLogging();
}
}
initializeFileLogging() {
const logDir = process.env.LOG_DIR || join(process.cwd(), 'logs');
if (!existsSync(logDir)) {
mkdirSync(logDir, { recursive: true });
}
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
this.logFile = join(logDir, `okta-mcp-${timestamp}.log`);
}
shouldLog(level) {
return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
}
log(level, message, ...args) {
if (!this.shouldLog(level))
return;
const timestamp = new Date().toISOString();
const logData = {
timestamp,
level: level.toUpperCase(),
name: this.name,
message,
...(args.length > 0 && { data: args }),
};
const logLine = JSON.stringify(logData) + '\n';
if (this.useFileLogging && this.logFile) {
// Log to file to avoid interfering with stdio protocol
try {
appendFileSync(this.logFile, logLine);
}
catch (error) {
// Fallback to console if file logging fails, but only in development
if (process.env.NODE_ENV === 'development') {
console.error('[Logger Error]', error);
}
}
}
else if (process.env.NODE_ENV === 'development' && !process.env.MCP_SERVER_MODE) {
// Only log to console in development when not in MCP server mode
console.error(logLine);
}
// In production or MCP server mode, suppress all console output to avoid protocol interference
}
debug(message, ...args) {
this.log('debug', message, ...args);
}
info(message, ...args) {
this.log('info', message, ...args);
}
warn(message, ...args) {
this.log('warn', message, ...args);
}
error(message, ...args) {
this.log('error', message, ...args);
}
child(bindings) {
const childLogger = new ProtocolSafeLogger(`${this.name}:${bindings['module'] || 'child'}`, this.level);
return childLogger;
}
}
// Export singleton logger
const logLevel = process.env.LOG_LEVEL || (process.env.NODE_ENV === 'production' ? 'info' : 'debug');
// Set MCP_SERVER_MODE when running as MCP server
if (process.argv.includes('--mcp') || process.env.MCP_SERVER === 'true') {
process.env.MCP_SERVER_MODE = 'true';
}
export const protocolSafeLogger = new ProtocolSafeLogger('okta-mcp-server', logLevel);
//# sourceMappingURL=protocol-safe-logger.js.map