Skip to main content
Glama
ooples

MCP Console Automation Server

logger.ts2.87 kB
import * as winston from 'winston'; import * as path from 'path'; import * as fs from 'fs'; export class Logger { private static instance: Logger; private logger: winston.Logger; constructor(context: string) { // Detect if we're running as an MCP server (stdio transport) const isMCPServer = process.env.MCP_SERVER_MODE === 'true' || process.argv.includes('--mcp-server') || this.detectStdioMCPMode(); const transports: winston.transport[] = []; // CRITICAL: Never log to console/stdout/stderr in MCP mode to avoid stdio corruption if (!isMCPServer) { transports.push( new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), winston.format.simple() ), }) ); } // Always use file logging for MCP servers if (isMCPServer || process.env.NODE_ENV === 'production') { const logDir = path.join(process.cwd(), 'logs'); if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }); } transports.push( new winston.transports.File({ filename: path.join(logDir, 'mcp-error.log'), level: 'error', format: winston.format.combine( winston.format.timestamp(), winston.format.json() ), }), new winston.transports.File({ filename: path.join(logDir, 'mcp-combined.log'), format: winston.format.combine( winston.format.timestamp(), winston.format.json() ), }) ); } this.logger = winston.createLogger({ level: process.env.LOG_LEVEL || 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.splat(), winston.format.json() ), defaultMeta: { service: 'mcp-console', context, mcpMode: isMCPServer }, transports, // CRITICAL: Prevent any console output in MCP mode silent: isMCPServer && transports.length === 0, }); } private detectStdioMCPMode(): boolean { // Detect if we're likely running as an MCP server via stdio return process.stdin.isTTY === false && process.stdout.isTTY === false; } info(message: string, meta?: any) { this.logger.info(message, meta); } error(message: string, meta?: any) { this.logger.error(message, meta); } warn(message: string, meta?: any) { this.logger.warn(message, meta); } debug(message: string, meta?: any) { this.logger.debug(message, meta); } getWinstonLogger(): winston.Logger { return this.logger; } static getInstance(context: string = 'default'): Logger { if (!Logger.instance) { Logger.instance = new Logger(context); } return Logger.instance; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ooples/mcp-console-automation'

If you have feedback or need assistance with the MCP directory API, please join our Discord server