Skip to main content
Glama

DollhouseMCP

by DollhouseMCP
LOGGER_IMPLEMENTATION_DETAILS.mdโ€ข3.34 kB
# Logger Implementation Details - July 10, 2025 ## Why We Needed a Custom Logger ### The MCP Protocol Constraint - MCP uses stdout/stderr for JSON-RPC communication - ANY non-JSON output breaks the protocol - Even a single console.log crashes the connection - Error: `Unexpected token 'S', "[SECURITY]"... is not valid JSON` ## Implementation Strategy ### 1. Dual-Mode Operation ```typescript class MCPLogger { private isMCPConnected = false; // Called after MCP handshake public setMCPConnected(): void { this.isMCPConnected = true; } } ``` ### 2. Memory Storage with Circular Buffer ```typescript private logs: LogEntry[] = []; private maxLogs = 1000; // Prevent unbounded memory growth if (this.logs.length > this.maxLogs) { this.logs.shift(); } ``` ### 3. Test Environment Detection ```typescript // CRITICAL: Check must be INSIDE the method, not at module level if (!this.isMCPConnected) { const isTest = process.env.NODE_ENV === 'test'; if (!isTest) { console.error(fullMessage); } } ``` ## Key Lessons Learned ### 1. NODE_ENV Timing Issue **Problem**: Initially checked `process.env.NODE_ENV` at module load **Issue**: Jest sets NODE_ENV after modules are loaded **Solution**: Check NODE_ENV inside the log method every time ### 2. Test Updates Required **Problem**: Tests expected console output **Solution**: Update tests to check in-memory logs instead ### 3. Docker Test Failures **Problem**: Docker tests checked for "Loaded persona:" in output **Solution**: Check for initialization messages instead ## Integration Points ### 1. Server Initialization ```typescript // src/index.ts const transport = new StdioServerTransport(); await transport.connect(server); logger.setMCPConnected(); // Critical timing! ``` ### 2. Security Monitor ```typescript // Used to use console.error for alerts // Now uses logger.error with structured data logger.error('๐Ÿšจ CRITICAL SECURITY ALERT ๐Ÿšจ', { type: event.type, details: event.details }); ``` ### 3. Future Debug Tool ```typescript // Planned MCP tool to retrieve logs export async function getLogs(args: GetLogsArgs) { const logs = logger.getLogs(args.count, args.level); return formatLogsForMCP(logs); } ``` ## Performance Considerations 1. **Memory Usage**: ~1MB for 1000 full log entries 2. **CPU Impact**: Minimal - no async operations 3. **Circular Buffer**: O(1) for adds, O(n) for shifts ## Future Enhancements (Issue #190) 1. **Log Levels**: Filter by DEBUG/INFO/WARN/ERROR 2. **Configuration**: Environment variables for buffer size 3. **Structured Metadata**: Add file/line information 4. **Lazy Serialization**: Defer JSON.stringify until needed ## Critical Code Paths ### All Console Replacements - `src/index.ts` - Server lifecycle logging - `src/security/securityMonitor.ts` - Security alerts - `src/marketplace/GitHubClient.ts` - API errors - `src/persona/PersonaLoader.ts` - Loading messages - `src/update/BackupManager.ts` - Backup operations - `src/update/SignatureVerifier.ts` - GPG operations ### Test Files Updated - `__tests__/security/securityMonitor.test.ts` - `__tests__/basic.test.ts` - `.github/workflows/docker-testing.yml` ## Remember - NEVER use console.* in MCP server code - Always use logger.* instead - Test environment must suppress ALL output - Logger is a singleton - import and use directly

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/DollhouseMCP/DollhouseMCP'

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