{"_id":"@alcyone-labs/simple-mcp-logger","_rev":"5-af3e115b2599ded9fddb9ff10d38b75b","name":"@alcyone-labs/simple-mcp-logger","dist-tags":{"latest":"1.2.1"},"versions":{"1.0.0":{"name":"@alcyone-labs/simple-mcp-logger","version":"1.0.0","keywords":["mcp","model-context-protocol","mcp-server","logger","console","logging","winston transport","pino transport","stdout-safe","protocol-safe","json-rpc","simple-logger","browser-logger"],"author":{"name":"Nicolas Embleton","email":"nicolas.embleton@gmail.com"},"license":"MIT","_id":"@alcyone-labs/simple-mcp-logger@1.0.0","maintainers":[{"name":"nembleton","email":"nicolas.embleton@gmail.com"}],"homepage":"https://github.com/alcyone-labs/simple-mcp-logger#readme","bugs":{"url":"https://github.com/alcyone-labs/simple-mcp-logger/issues"},"dist":{"shasum":"a704cb5922e2710ed31731a219093d0d0a577766","tarball":"https://registry.npmjs.org/@alcyone-labs/simple-mcp-logger/-/simple-mcp-logger-1.0.0.tgz","fileCount":13,"integrity":"sha512-AI5Bkmm3mXLIF1S7yqZLb4q4RuvVWklj71l83N+msyGZIYFfzik9Ztz+lRYI8aS99HNW+k8gU1GvzXEk2DGdjw==","signatures":[{"sig":"MEYCIQCXWyJkKOTextJpO2n6VqaPTQCnF4sLP6UwSev5yy7J/gIhANKKEaZJ5lHGJZ1rJu3AmUJ8I5RjQXCDiVHFg0MJE/ZF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":106558},"main":"./dist/index.cjs","type":"module","_from":"file:alcyone-labs-simple-mcp-logger-1.0.0.tgz","types":"./dist/index.d.ts","access":"public","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./adapters":{"types":"./dist/adapters/index.d.ts","import":"./dist/adapters/index.mjs","require":"./dist/adapters/index.cjs"}},"scripts":{"dev":"vite build --watch","test":"vitest","build":"vite build","clean":"rm -rf dist","test:run":"vitest run","publish:npm":"npm publish --access public","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"nembleton","actor":{"name":"nembleton","type":"user","email":"nicolas.embleton@gmail.com"},"email":"nicolas.embleton@gmail.com"},"_resolved":"/private/var/folders/27/xlh5p6rd54vgnqk_t2kq551c0000gn/T/a361376437aa60e75a3dfc1d20e0fc0e/alcyone-labs-simple-mcp-logger-1.0.0.tgz","_integrity":"sha512-AI5Bkmm3mXLIF1S7yqZLb4q4RuvVWklj71l83N+msyGZIYFfzik9Ztz+lRYI8aS99HNW+k8gU1GvzXEk2DGdjw==","repository":{"url":"git+https://github.com/alcyone-labs/simple-mcp-logger.git","type":"git"},"_npmVersion":"10.9.2","description":"Logging solution for MCP servers. Prevents console output from corrupting MCP protocol communication. Drop-in replacement for console, Winston, and Pino with automatic STDOUT suppression in MCP mode.","directories":{},"_nodeVersion":"22.17.0","_hasShrinkwrap":false,"devDependencies":{"pino":"^9.7.0","vite":"^7.0.3","vitest":"^3.2.4","winston":"^3.17.0","typescript":"^5.8.3","@types/node":"^24.0.12","@types/winston":"^2.4.4","vite-plugin-dts":"^4.5.4","winston-transport":"^4.9.0","@vitest/coverage-v8":"^3.2.4"},"peerDependencies":{"pino":"^8.0.0 || ^9.0.0","winston":"^3.0.0","winston-transport":"^4.0.0"},"peerDependenciesMeta":{"pino":{"optional":true},"winston":{"optional":true},"winston-transport":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/simple-mcp-logger_1.0.0_1752079510928_0.5389989317926211","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@alcyone-labs/simple-mcp-logger","version":"1.0.1","keywords":["mcp","model-context-protocol","mcp-server","logger","console","logging","winston transport","pino transport","stdout-safe","protocol-safe","json-rpc","simple-logger","browser-logger"],"author":{"name":"Nicolas Embleton","email":"nicolas.embleton@gmail.com"},"license":"MIT","_id":"@alcyone-labs/simple-mcp-logger@1.0.1","maintainers":[{"name":"nembleton","email":"nicolas.embleton@gmail.com"}],"homepage":"https://github.com/alcyone-labs/simple-mcp-logger#readme","bugs":{"url":"https://github.com/alcyone-labs/simple-mcp-logger/issues"},"dist":{"shasum":"27ab69da3e3691964787855108974c54f03feef7","tarball":"https://registry.npmjs.org/@alcyone-labs/simple-mcp-logger/-/simple-mcp-logger-1.0.1.tgz","fileCount":21,"integrity":"sha512-8kZiaFlPVLpwqMYDt6+uhcHvNYg91Qdkx5oUBByHSHzayyI21rlaB8TeR2iz1AXXo3sMb9fTUhziAJspoPL1ZQ==","signatures":[{"sig":"MEQCIFIKmLYlUmX45740DLItOfJ6o7dlSiJuX+xxduKOYuAaAiAw/PUIkioLunfA0qYPTbY8hDKnSwPmJO1X8gkcPkpQ3w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112487},"main":"./dist/index.cjs","type":"module","_from":"file:alcyone-labs-simple-mcp-logger-1.0.1.tgz","types":"./dist/index.d.ts","access":"public","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./adapters":{"types":"./dist/adapters/index.d.ts","import":"./dist/adapters/index.mjs","require":"./dist/adapters/index.cjs"}},"scripts":{"dev":"vite build --watch","test":"vitest","build":"vite build","clean":"rm -rf dist","test:run":"vitest run","publish:npm":"npm publish --access public","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"nembleton","email":"nicolas.embleton@gmail.com"},"_resolved":"/private/var/folders/27/xlh5p6rd54vgnqk_t2kq551c0000gn/T/9c7dce58c576d0f17819b660b415834e/alcyone-labs-simple-mcp-logger-1.0.1.tgz","_integrity":"sha512-8kZiaFlPVLpwqMYDt6+uhcHvNYg91Qdkx5oUBByHSHzayyI21rlaB8TeR2iz1AXXo3sMb9fTUhziAJspoPL1ZQ==","repository":{"url":"git+https://github.com/alcyone-labs/simple-mcp-logger.git","type":"git"},"_npmVersion":"10.9.2","description":"Logging solution for MCP servers. Prevents console output from corrupting MCP protocol communication. Drop-in replacement for console, Winston, and Pino with automatic STDOUT suppression in MCP mode.","directories":{},"_nodeVersion":"22.17.0","_hasShrinkwrap":false,"devDependencies":{"pino":"^9.7.0","vite":"^7.0.3","vitest":"^3.2.4","winston":"^3.17.0","typescript":"^5.8.3","@types/node":"^24.0.12","@types/winston":"^2.4.4","vite-plugin-dts":"^4.5.4","winston-transport":"^4.9.0","@vitest/coverage-v8":"^3.2.4"},"peerDependencies":{"pino":"^8.0.0 || ^9.0.0","winston":"^3.0.0","winston-transport":"^4.0.0"},"peerDependenciesMeta":{"pino":{"optional":true},"winston":{"optional":true},"winston-transport":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/simple-mcp-logger_1.0.1_1752423587239_0.5223278296076532","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@alcyone-labs/simple-mcp-logger","version":"1.1.0","keywords":["mcp","model-context-protocol","mcp-server","logger","console","logging","winston transport","pino transport","stdout-safe","protocol-safe","json-rpc","simple-logger","browser-logger"],"author":{"name":"Nicolas Embleton","email":"nicolas.embleton@gmail.com"},"license":"MIT","_id":"@alcyone-labs/simple-mcp-logger@1.1.0","maintainers":[{"name":"nembleton","email":"nicolas.embleton@gmail.com"}],"homepage":"https://github.com/alcyone-labs/simple-mcp-logger#readme","bugs":{"url":"https://github.com/alcyone-labs/simple-mcp-logger/issues"},"dist":{"shasum":"ba966509aa7942c3981292cb189474f6a6f24a1f","tarball":"https://registry.npmjs.org/@alcyone-labs/simple-mcp-logger/-/simple-mcp-logger-1.1.0.tgz","fileCount":25,"integrity":"sha512-ty1F/+815Bo8PPA8csH2vGNApiqfZhhcOKWyZztmTJiszB40wtPz2bedQ4CorLZvU/1fSbwqAjEy4pBOHC8pJg==","signatures":[{"sig":"MEUCIQDB9NcCm0QSrPzG8/l81FN9ouwaGn9kvlFS8biy5H9vYQIgaAH33XVBi5K4yDfG9kltXTfksKgQq3yo8zqOw7HTKOA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":143390},"main":"./dist/index.cjs","type":"module","_from":"file:alcyone-labs-simple-mcp-logger-1.1.0.tgz","types":"./dist/index.d.ts","access":"public","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./adapters":{"types":"./dist/adapters/index.d.ts","import":"./dist/adapters/index.mjs","require":"./dist/adapters/index.cjs"}},"scripts":{"dev":"vite build --watch","test":"vitest","build":"vite build","clean":"rm -rf dist","test:run":"vitest run","publish:npm":"npm publish --access public","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"nembleton","email":"nicolas.embleton@gmail.com"},"_resolved":"/private/var/folders/27/xlh5p6rd54vgnqk_t2kq551c0000gn/T/3468747989a8faea8d8cd38b74cf1939/alcyone-labs-simple-mcp-logger-1.1.0.tgz","_integrity":"sha512-ty1F/+815Bo8PPA8csH2vGNApiqfZhhcOKWyZztmTJiszB40wtPz2bedQ4CorLZvU/1fSbwqAjEy4pBOHC8pJg==","repository":{"url":"git+https://github.com/alcyone-labs/simple-mcp-logger.git","type":"git"},"_npmVersion":"11.4.2","description":"Logging solution for MCP servers. Prevents console output from corrupting MCP protocol communication. Drop-in replacement for console, Winston, and Pino with automatic STDOUT suppression in MCP mode.","directories":{},"_nodeVersion":"24.3.0","_hasShrinkwrap":false,"devDependencies":{"pino":"^9.7.0","vite":"^7.0.3","vitest":"^3.2.4","winston":"^3.17.0","typescript":"^5.8.3","@types/node":"^24.0.12","@types/winston":"^2.4.4","vite-plugin-dts":"^4.5.4","winston-transport":"^4.9.0","@vitest/coverage-v8":"^3.2.4"},"peerDependencies":{"pino":"^8.0.0 || ^9.0.0","winston":"^3.0.0","winston-transport":"^4.0.0"},"peerDependenciesMeta":{"pino":{"optional":true},"winston":{"optional":true},"winston-transport":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/simple-mcp-logger_1.1.0_1752685126235_0.5064139989027576","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@alcyone-labs/simple-mcp-logger","version":"1.2.0","keywords":["mcp","model-context-protocol","mcp-server","logger","console","logging","winston transport","pino transport","stdout-safe","protocol-safe","json-rpc","simple-logger","browser-logger"],"author":{"name":"Nicolas Embleton","email":"nicolas.embleton@gmail.com"},"license":"MIT","_id":"@alcyone-labs/simple-mcp-logger@1.2.0","maintainers":[{"name":"nembleton","email":"nicolas.embleton@gmail.com"}],"homepage":"https://github.com/alcyone-labs/simple-mcp-logger#readme","bugs":{"url":"https://github.com/alcyone-labs/simple-mcp-logger/issues"},"dist":{"shasum":"141383c933c86362e33654c2adbc074bcb23e4da","tarball":"https://registry.npmjs.org/@alcyone-labs/simple-mcp-logger/-/simple-mcp-logger-1.2.0.tgz","fileCount":25,"integrity":"sha512-l1bRUdKH/6FyU66oMnNQ/54aq94aSECrn+r2Ssic2EyNk+FJquaeBMDSz8k0rWODaWTBa95T0lfm7yz5LIgV/w==","signatures":[{"sig":"MEUCICGQNlijKDzgb/uEJK7LyaJV9HzJ/QMcicRjz4SYfNQcAiEAnhpHlTI3BPm3MPOo+383X7Q5ege+OITW5zC1+VbD/+g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":164774},"main":"./dist/index.cjs","type":"module","_from":"file:alcyone-labs-simple-mcp-logger-1.2.0.tgz","types":"./dist/index.d.ts","access":"public","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./adapters":{"types":"./dist/adapters/index.d.ts","import":"./dist/adapters/index.mjs","require":"./dist/adapters/index.cjs"}},"scripts":{"dev":"vite build --watch","test":"vitest","build":"vite build","clean":"rm -rf dist","test:run":"vitest run","publish:npm":"npm publish --access public","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"nembleton","email":"nicolas.embleton@gmail.com"},"_resolved":"/private/var/folders/27/xlh5p6rd54vgnqk_t2kq551c0000gn/T/43f949180899dac807ac12713543652a/alcyone-labs-simple-mcp-logger-1.2.0.tgz","_integrity":"sha512-l1bRUdKH/6FyU66oMnNQ/54aq94aSECrn+r2Ssic2EyNk+FJquaeBMDSz8k0rWODaWTBa95T0lfm7yz5LIgV/w==","repository":{"url":"git+https://github.com/alcyone-labs/simple-mcp-logger.git","type":"git"},"_npmVersion":"11.4.2","description":"Logging solution for MCP servers. Prevents console output from corrupting MCP protocol communication. Drop-in replacement for console, Winston, and Pino with automatic STDOUT suppression in MCP mode.","directories":{},"_nodeVersion":"24.4.1","_hasShrinkwrap":false,"devDependencies":{"pino":"^9.7.0","vite":"^7.0.3","vitest":"^3.2.4","winston":"^3.17.0","typescript":"^5.8.3","@types/node":"^24.0.12","@types/winston":"^2.4.4","vite-plugin-dts":"^4.5.4","winston-transport":"^4.9.0","@vitest/coverage-v8":"^3.2.4"},"peerDependencies":{"pino":"^8.0.0 || ^9.0.0","winston":"^3.0.0","winston-transport":"^4.0.0"},"peerDependenciesMeta":{"pino":{"optional":true},"winston":{"optional":true},"winston-transport":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/simple-mcp-logger_1.2.0_1753454875188_0.8331901225521379","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@alcyone-labs/simple-mcp-logger","version":"1.2.1","description":"Logging solution for MCP servers. Prevents console output from corrupting MCP protocol communication. Drop-in replacement for console, Winston, and Pino with automatic STDOUT suppression in MCP mode.","type":"module","main":"./dist/index.cjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","maintainers":[{"name":"nembleton","email":"nicolas.embleton@gmail.com"}],"access":"public","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./adapters":{"types":"./dist/adapters/index.d.ts","import":"./dist/adapters/index.mjs","require":"./dist/adapters/index.cjs"}},"keywords":["mcp","model-context-protocol","mcp-server","logger","console","logging","winston transport","pino transport","stdout-safe","protocol-safe","json-rpc","simple-logger","browser-logger"],"author":{"name":"Nicolas Embleton","email":"nicolas.embleton@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alcyone-labs/simple-mcp-logger.git"},"peerDependencies":{"pino":"^8.0.0 || ^9.0.0","winston":"^3.0.0","winston-transport":"^4.0.0"},"peerDependenciesMeta":{"winston":{"optional":true},"winston-transport":{"optional":true},"pino":{"optional":true}},"devDependencies":{"@types/node":"^24.0.12","@types/winston":"^2.4.4","@vitest/coverage-v8":"^3.2.4","pino":"^9.7.0","typescript":"^5.8.3","vite":"^7.0.3","vite-plugin-dts":"^4.5.4","vitest":"^3.2.4","winston":"^3.17.0","winston-transport":"^4.9.0"},"scripts":{"build":"vite build","test":"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","dev":"vite build --watch","clean":"rm -rf dist","publish:npm":"npm publish --access public"},"_id":"@alcyone-labs/simple-mcp-logger@1.2.1","bugs":{"url":"https://github.com/alcyone-labs/simple-mcp-logger/issues"},"homepage":"https://github.com/alcyone-labs/simple-mcp-logger#readme","_integrity":"sha512-jjZ9vcjmDEkJJ9aj7PBi/7P/Xg6KpJZ9M9bvNM61w2Cyj0q69DZ19V6y8nvrWqLvikWQ5eeTsSoZ65Y46ljSWg==","_resolved":"/private/var/folders/27/xlh5p6rd54vgnqk_t2kq551c0000gn/T/0e3385fded0de2a7c415054fab15188a/alcyone-labs-simple-mcp-logger-1.2.1.tgz","_from":"file:alcyone-labs-simple-mcp-logger-1.2.1.tgz","_nodeVersion":"24.4.1","_npmVersion":"11.4.2","dist":{"integrity":"sha512-jjZ9vcjmDEkJJ9aj7PBi/7P/Xg6KpJZ9M9bvNM61w2Cyj0q69DZ19V6y8nvrWqLvikWQ5eeTsSoZ65Y46ljSWg==","shasum":"57e2a575e5be0f83781d445116bfbd81679dfdfa","tarball":"https://registry.npmjs.org/@alcyone-labs/simple-mcp-logger/-/simple-mcp-logger-1.2.1.tgz","fileCount":25,"unpackedSize":164797,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDKr7DkgsR/9kkkXdq4GSS1b16gPbAMrkicMtif3TRh7AIhAOiSFgIYn/cwSxfJztx669cOw01Gtm+PtoYuLPoVnhdk"}]},"_npmUser":{"name":"nembleton","email":"nicolas.embleton@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/simple-mcp-logger_1.2.1_1753456220755_0.8187938930114116"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-09T16:45:10.809Z","modified":"2025-07-25T15:10:21.280Z","1.0.0":"2025-07-09T16:45:11.151Z","1.0.1":"2025-07-13T16:19:47.426Z","1.1.0":"2025-07-16T16:58:46.410Z","1.2.0":"2025-07-25T14:47:55.404Z","1.2.1":"2025-07-25T15:10:21.020Z"},"bugs":{"url":"https://github.com/alcyone-labs/simple-mcp-logger/issues"},"author":{"name":"Nicolas Embleton","email":"nicolas.embleton@gmail.com"},"license":"MIT","homepage":"https://github.com/alcyone-labs/simple-mcp-logger#readme","keywords":["mcp","model-context-protocol","mcp-server","logger","console","logging","winston transport","pino transport","stdout-safe","protocol-safe","json-rpc","simple-logger","browser-logger"],"repository":{"type":"git","url":"git+https://github.com/alcyone-labs/simple-mcp-logger.git"},"description":"Logging solution for MCP servers. Prevents console output from corrupting MCP protocol communication. Drop-in replacement for console, Winston, and Pino with automatic STDOUT suppression in MCP mode.","maintainers":[{"name":"nembleton","email":"nicolas.embleton@gmail.com"}],"readme":"# SimpleMcpLogger\n\n**The logging solution for MCP (Model Context Protocol) servers**\n\nSimpleMcpLogger solves a critical problem in MCP development: **preventing console output from breaking MCP communication**. When building MCP servers, any stray `console.log()` or logging output to STDOUT can corrupt the JSON-RPC protocol, causing client communication failures.\n\nThis library provides a **drop-in replacement** for console and popular loggers (Winston, Pino) that automatically suppresses output in MCP mode while preserving full logging functionality during development and testing.\n\n## The MCP Problem\n\nMCP servers communicate via JSON-RPC over STDOUT/STDIN. Any non-MCP output to **STDOUT** breaks the protocol, but **STDERR is perfectly safe** for debugging:\n\n```typescript\n// ❌ This breaks MCP communication (writes to STDOUT)\nconsole.log(\"Debug info\"); // Corrupts STDOUT → Protocol failure\nlogger.info(\"Processing request\"); // Invalid MCP message → Connection lost\n\n// ✅ This works perfectly (suppressed STDOUT, safe STDERR)\nmcpLogger.info(\"Processing request\"); // Suppressed in MCP mode\nmcpLogger.mcpError(\"Debug info\", data); // Safe: writes to STDERR\n```\n\n**Key insight**: STDOUT is reserved for MCP protocol messages, but STDERR is available for debugging and logging without breaking communication.\n\n**SimpleMcpLogger ensures your MCP servers work reliably** by preventing accidental STDOUT output while providing safe STDERR channels for debugging.\n\n## Features\n\n- **MCP-compliant** - Automatically suppresses STDOUT output in MCP mode to prevent protocol corruption\n- **Drop-in replacement** - Compatible with console, Winston, and Pino APIs\n- **Protocol protection** - Prevents accidental console output from breaking MCP communication\n- **File logging** - Persistent logging to files with automatic directory creation\n- **Development-friendly** - Full logging during development, silent in production MCP mode\n- **Bundling optimized** - Modular design with separate adapter packages\n- **TypeScript-first** - Complete type safety and IntelliSense support\n- **Zero dependencies** - Core logger has no external dependencies\n- **Adapter ecosystem** - Winston and Pino transports for existing codebases\n- **Battle-tested** - Comprehensive test suite with real-world MCP scenarios\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [MCP Server Usage](#mcp-server-usage-primary-use-case)\n  - [Enhanced MCP Logger (v1.2.0+)](#enhanced-mcp-logger-v120)\n  - [Hijacking Console for MCP Safety](#hijacking-console-for-mcp-safety)\n  - [Environment Detection](#environment-detection)\n- [API Reference](#api-reference)\n  - [Logger Class](#logger-class)\n  - [Factory Functions](#factory-functions)\n- [Adapters for Existing Codebases](#adapters-for-existing-codebases)\n  - [Winston Adapter](#winston-adapter)\n  - [Pino Adapter](#pino-adapter)\n- [MCP Best Practices](#mcp-best-practices)\n  - [Migration to Enhanced API](#-migration-to-enhanced-api)\n- [Browser Usage](#browser-usage)\n- [File Logging](#file-logging)\n- [Migration Guide](#migration-guide)\n- [Why This Matters for MCP Development](#why-this-matters-for-mcp-development)\n\n## Installation\n\n```bash\nnpm install @alcyone-labs/simple-mcp-logger\n```\n\n### Bundling-Friendly Design\n\nSimpleMcpLogger uses a modular design to keep your bundles small:\n\n- **Main package** (`@alcyone-labs/simple-mcp-logger`) - Core logger with zero external dependencies\n- **Adapters** (`@alcyone-labs/simple-mcp-logger/adapters`) - Winston/Pino adapters with peer dependencies\n\nThis means you only bundle what you actually use!\n\n```typescript\n// Core logger (no external dependencies bundled)\nimport { Logger } from \"@alcyone-labs/simple-mcp-logger\";\n\n// Adapters (requires peer dependencies)\nimport { SimpleMcpWinstonTransport } from \"@alcyone-labs/simple-mcp-logger/adapters\";\n```\n\n## Quick Start\n\n### Basic Usage\n\n```typescript\nimport { Logger, logger } from \"@alcyone-labs/simple-mcp-logger\";\n\n// Use the global logger instance\nlogger.info(\"Hello, world!\");\nlogger.error(\"Something went wrong\");\n\n// Create a custom logger\nconst myLogger = new Logger({\n  level: \"debug\",\n  prefix: \"MyApp\",\n  mcpMode: false,\n});\n\nmyLogger.debug(\"Debug message\");\nmyLogger.info(\"Info message\");\n\n// Create a logger with file output\nconst fileLogger = new Logger({\n  level: \"info\",\n  prefix: \"MyApp\",\n  logToFile: \"./logs/app.log\", // Logs to file, directory created automatically\n});\n\nfileLogger.info(\"This goes to both console and file\");\n\n// For MCP servers: use mcpError() for debugging (safe STDERR output)\nmyLogger.mcpError(\"Debug info visible in client logs\");\n```\n\n## MCP Server Usage (Primary Use Case)\n\n**This is why SimpleMcpLogger exists**: to prevent console output from corrupting MCP protocol communication.\n\n### The Problem\n\nMCP servers communicate via JSON-RPC over STDOUT. Any logging to **STDOUT** breaks this, but **STDERR is safe**:\n\n```typescript\n// ❌ BROKEN: These write to STDOUT and corrupt MCP communication\nconsole.log(\"Processing request\"); // STDOUT → Protocol corruption\nlogger.info(\"Debug info\"); // STDOUT → JSON-RPC breaks\n\n// Client receives: {\"jsonrpc\":\"2.0\",...}Processing request{\"id\":1,...}\n// Result: Invalid JSON, connection fails\n\n// ✅ SAFE: STDERR doesn't interfere with MCP protocol\nconsole.error(\"Debug info\"); // STDERR → Safe for debugging\nprocess.stderr.write(\"Log data\"); // STDERR → Visible to client logs\n```\n\n### The Solution\n\nSimpleMcpLogger automatically suppresses **STDOUT** output in MCP mode while preserving **STDERR** for debugging:\n\n```typescript\nimport { createMcpLogger } from \"@alcyone-labs/simple-mcp-logger\";\n\n// Create MCP-safe logger (automatically detects MCP environment)\nconst logger = createMcpLogger(\"MyMcpServer\");\n\n// ✅ SAFE: These are suppressed in MCP mode (no STDOUT output)\nlogger.info(\"Processing request\"); // Silent in MCP mode\nlogger.debug(\"User data:\", userData); // Silent in MCP mode\nlogger.warn(\"Rate limit approaching\"); // Silent in MCP mode\n\n// ✅ SAFE: Critical debugging via STDERR (visible to client logs)\nlogger.mcpError(\"Database connection failed\"); // STDERR → Always visible\nlogger.mcpError(\"Request state:\", requestData); // STDERR → Safe debugging\n\n// ✅ SAFE: MCP logger with file output (console suppressed, file enabled)\nconst fileLogger = createMcpLogger(\"MyMcpServer\", \"./logs/mcp.log\");\nfileLogger.info(\"Processing request\"); // Silent in MCP mode, written to file\nfileLogger.error(\"Error occurred\"); // Silent in MCP mode, written to file\n```\n\n### Enhanced MCP Logger (v1.2.0+)\n\n**🚨 Important**: The default `createMcpLogger()` only captures **error-level logs**. For comprehensive logging in MCP servers, use the new options-based API:\n\n```typescript\n// ❌ DEFAULT: Only captures errors (backward compatible)\nconst basicLogger = createMcpLogger(\"MyServer\", \"./logs/mcp.log\");\nbasicLogger.debug(\"Not captured\"); // Silent - below error level\nbasicLogger.info(\"Not captured\");  // Silent - below error level\nbasicLogger.error(\"Captured\");     // ✅ Written to file\n\n// ✅ ENHANCED: Capture ALL log levels with options API\nconst comprehensiveLogger = createMcpLogger({\n  prefix: \"MyServer\",\n  logToFile: \"./logs/mcp.log\",\n  level: \"debug\",        // Captures debug, info, warn, error\n  mcpMode: true          // MCP compliant (default)\n});\n\ncomprehensiveLogger.debug(\"✅ Captured\"); // Written to file\ncomprehensiveLogger.info(\"✅ Captured\");  // Written to file\ncomprehensiveLogger.warn(\"✅ Captured\");  // Written to file\ncomprehensiveLogger.error(\"✅ Captured\"); // Written to file\n```\n\n**Options-Based API** (Recommended for new projects):\n\n```typescript\ninterface McpLoggerOptions {\n  level?: LogLevel;      // 'debug' | 'info' | 'warn' | 'error' | 'silent'\n  mcpMode?: boolean;     // Default: true (MCP compliant)\n  prefix?: string;       // Optional prefix for all messages\n  logToFile?: string;    // Optional file path for persistent logging\n}\n\n// Comprehensive MCP server logging\nconst logger = createMcpLogger({\n  prefix: \"MCP-Server\",\n  logToFile: \"./logs/server.log\",\n  level: \"info\",         // Captures info, warn, error (recommended)\n  mcpMode: true          // MCP compliant\n});\n\n// Development/debugging with all levels\nconst debugLogger = createMcpLogger({\n  prefix: \"Debug\",\n  logToFile: \"./logs/debug.log\",\n  level: \"debug\",        // Captures everything\n  mcpMode: true\n});\n\n// Non-MCP mode for testing\nconst testLogger = createMcpLogger({\n  prefix: \"Test\",\n  level: \"debug\",\n  mcpMode: false         // Enable console output for testing\n});\n```\n\n### Hijacking Console for MCP Safety\n\nReplace console globally to catch all logging in your MCP server:\n\n```typescript\nimport { createMcpLogger } from \"@alcyone-labs/simple-mcp-logger\";\n\n// Replace console at startup (before any other code runs)\nconst mcpLogger = createMcpLogger(\"MCP-Server\");\nglobalThis.console = mcpLogger as any;\n\n// Now ALL console calls are MCP-safe\nconsole.log(\"This is safe\"); // Suppressed in MCP mode\nconsole.error(\"This is safe too\"); // Suppressed in MCP mode\nsomeLibrary.log(\"Third-party logs\"); // Also safe!\n```\n\n### Environment Detection\n\nSimpleMcpLogger automatically detects MCP environments:\n\n```typescript\n// Automatically enables MCP mode when:\n// - No TTY detected (typical MCP server environment)\n// - MCP_MODE environment variable is set\n// - Explicitly configured\n\nconst logger = createMcpLogger(); // Auto-detects MCP mode\n```\n\n### Console Replacement\n\n```typescript\nimport { Logger } from \"@alcyone-labs/simple-mcp-logger\";\n\n// Replace console globally (do this at application startup)\nconst logger = new Logger({ level: \"info\", prefix: \"App\" });\nglobalThis.console = logger as any;\n\n// Now all console calls use SimpleMcpLogger\nconsole.log(\"This uses SimpleMcpLogger\");\nconsole.error(\"This too\");\n```\n\n**⚠️ Important:** Replace console at application startup before any other logging occurs to avoid infinite loops.\n\n### General Purpose Logging (Non-MCP)\n\n```typescript\nimport { Logger, createCliLogger } from \"@alcyone-labs/simple-mcp-logger\";\n\n// Perfect for web apps, APIs, CLI tools, etc.\nconst appLogger = createCliLogger(\"info\", \"MyApp\");\n\nappLogger.info(\"Server starting on port 3000\");\nappLogger.warn(\"High memory usage detected\");\nappLogger.error(\"Database connection failed\");\n\n// Use all console methods\nappLogger.table([{ user: \"john\", status: \"active\" }]);\nappLogger.time(\"API Response\");\n// ... some operation\nappLogger.timeEnd(\"API Response\");\n```\n\n## API Reference\n\n### Logger Class\n\n#### Constructor\n\n```typescript\nnew Logger(config?: Partial<LoggerConfig>)\n```\n\n#### Configuration Options\n\n```typescript\ninterface LoggerConfig {\n  level: LogLevel; // 'debug' | 'info' | 'warn' | 'error' | 'silent'\n  mcpMode: boolean; // Suppress output when true\n  prefix?: string; // Prefix for all messages\n  logToFile?: string; // Optional file path for persistent logging\n}\n```\n\n#### Methods\n\nAll standard console methods are supported:\n\n- `debug(message: string, ...args: any[]): void`\n- `envDebug(message: string, ...args: any[]): void` - Environment-aware debug logging (only outputs when `DEBUG` env var is truthy)\n- `info(message: string, ...args: any[]): void`\n- `warn(message: string, ...args: any[]): void`\n- `error(message: string, ...args: any[]): void`\n- `log(message: string, ...args: any[]): void` - Alias for info\n- `trace(message?: string, ...args: any[]): void`\n- `table(data: any, columns?: string[]): void`\n- `group(label?: string): void`\n- `groupCollapsed(label?: string): void`\n- `groupEnd(): void`\n- `time(label?: string): void`\n- `timeEnd(label?: string): void`\n- `timeLog(label?: string, ...args: any[]): void`\n- `count(label?: string): void`\n- `countReset(label?: string): void`\n- `assert(condition: boolean, message?: string, ...args: any[]): void`\n- `clear(): void`\n- `dir(obj: any, options?: any): void`\n- `dirxml(obj: any): void`\n\n#### Special Methods\n\n- `mcpError(message: string, ...args: any[]): void` - Always logs even in MCP mode\n- `child(prefix: string): Logger` - Create child logger with combined prefix\n- `setMcpMode(enabled: boolean): void` - Toggle MCP mode\n- `setLevel(level: LogLevel): void` - Change log level\n- `setPrefix(prefix: string): void` - Change prefix\n- `setLogFile(filePath: string): Promise<void>` - Set or change log file path\n- `close(): Promise<void>` - Close file stream and flush pending writes\n\n### Factory Functions\n\n#### createMcpLogger\n\n**New Options-Based API (v1.2.0+)** - Recommended:\n\n```typescript\ninterface McpLoggerOptions {\n  level?: LogLevel;      // Default: 'error' (for backward compatibility)\n  mcpMode?: boolean;     // Default: true\n  prefix?: string;       // Optional prefix\n  logToFile?: string;    // Optional file path\n}\n\ncreateMcpLogger(options: McpLoggerOptions): Logger\n```\n\n**Legacy API** (Deprecated, will be removed in v2.0.0):\n\n```typescript\ncreateMcpLogger(prefix?: string, logToFile?: string): Logger\ncreateMcpLogger(prefix?: string, logToFile?: string, options?: Partial<McpLoggerOptions>): Logger\n```\n\n**Examples:**\n\n```typescript\n// ✅ NEW: Options-based API (recommended)\nconst logger = createMcpLogger({\n  prefix: \"MyServer\",\n  logToFile: \"./logs/mcp.log\",\n  level: \"debug\"         // Capture all levels\n});\n\n// ⚠️ LEGACY: Still works but only captures errors by default\nconst legacyLogger = createMcpLogger(\"MyServer\", \"./logs/mcp.log\");\n\n// ⚠️ LEGACY: With options override\nconst enhancedLegacy = createMcpLogger(\"MyServer\", \"./logs/mcp.log\", {\n  level: \"info\"          // Override to capture more levels\n});\n```\n\n#### createCliLogger\n\n```typescript\n// Create logger for CLI mode\ncreateCliLogger(level?: LogLevel, prefix?: string): Logger\n```\n\n## Adapters for Existing Codebases\n\n**Migrate existing MCP servers to be protocol-safe** without changing your logging code.\n\nIf you have an existing codebase using Winston or Pino, you can add SimpleMcpLogger as a transport to make it MCP-compliant without refactoring your logging calls.\n\n**Bundling-Friendly Design**: Adapters are available as a separate import to avoid bundling dependencies you don't need.\n\n### Installation\n\nFor adapters, you'll need to install the peer dependencies:\n\n```bash\n# For Winston adapter\nnpm install winston winston-transport\n\n# For Pino adapter\nnpm install pino\n\n# Or install both\nnpm install winston winston-transport pino\n```\n\n### Winston Adapter\n\nMake your existing Winston-based MCP server protocol-safe:\n\n```typescript\n// Import adapters separately to avoid bundling unused dependencies\nimport { createWinstonTransport } from \"@alcyone-labs/simple-mcp-logger/adapters\";\nimport winston from \"winston\";\n\n// Replace your existing Winston transports with MCP-safe transport\nconst logger = winston.createLogger({\n  transports: [\n    createWinstonTransport({\n      level: \"debug\",\n      mcpMode: true, // Automatically suppresses STDOUT in MCP mode\n      prefix: \"MCP-Server\",\n      logToFile: \"./logs/mcp-server.log\", // Optional: log to file\n    }),\n  ],\n});\n\n// Your existing logging code works unchanged\nlogger.info(\"Processing MCP request\"); // Safe in MCP mode, written to file\nlogger.error(\"Request failed\"); // Safe in MCP mode, written to file\n```\n\n### Pino Adapter\n\nMake your existing Pino-based MCP server protocol-safe:\n\n```typescript\n// Import adapters separately to avoid bundling unused dependencies\nimport { createPinoDestination } from \"@alcyone-labs/simple-mcp-logger/adapters\";\nimport pino from \"pino\";\n\n// Replace your existing Pino destination with MCP-safe destination\nconst destination = createPinoDestination({\n  level: \"debug\",\n  mcpMode: true, // Automatically suppresses STDOUT in MCP mode\n  prefix: \"MCP-Server\",\n  logToFile: \"./logs/mcp-server.log\", // Optional: log to file\n});\n\nconst logger = pino({ level: \"debug\" }, destination);\n\n// Your existing logging code works unchanged\nlogger.info(\"Processing MCP request\"); // Safe in MCP mode, written to file\nlogger.error(\"Request failed\"); // Safe in MCP mode, written to file\n```\n\n## MCP Best Practices\n\n### 🚨 Critical: Initialize Before Any Logging\n\nReplace console **immediately** at application startup to catch all logging:\n\n```typescript\n// ✅ CORRECT: Do this FIRST, before importing any other modules\nimport { createMcpLogger } from \"@alcyone-labs/simple-mcp-logger\";\nglobalThis.console = createMcpLogger(\"MCP-Server\") as any;\n\n// Now import your application code\nimport \"./my-mcp-server.js\";\n```\n\n```typescript\n// ❌ WRONG: Too late, some logging may have already occurred\nimport \"./my-mcp-server.js\";\nimport { createMcpLogger } from \"@alcyone-labs/simple-mcp-logger\";\nglobalThis.console = createMcpLogger(\"MCP-Server\") as any;\n```\n\n### 🔍 Debugging MCP Servers\n\nUse `mcpError()` for debugging that needs to be visible - it writes to **STDERR** which is safe for MCP:\n\n```typescript\nconst logger = createMcpLogger(\"MCP-Server\");\n\n// Silent in MCP mode (suppressed STDOUT - good for normal operation)\nlogger.info(\"Processing request\"); // No output in MCP mode\nlogger.debug(\"User data:\", userData); // No output in MCP mode\n\n// Always visible via STDERR (safe for MCP protocol - good for debugging)\nlogger.mcpError(\"Critical error:\", error); // STDERR → Visible in client logs\nlogger.mcpError(\"Server state:\", serverState); // STDERR → Safe debugging\nlogger.mcpError(\"Performance metric:\", timing); // STDERR → Monitoring data\n```\n\n**Why STDERR is safe**: MCP protocol only uses STDOUT for JSON-RPC messages. STDERR output appears in client logs without interfering with protocol communication.\n\n### 🔧 Environment-Aware Debug Logging\n\nThe `envDebug()` method provides controlled debug logging that only outputs when the `DEBUG` environment variable is set. This allows you to safely add debug information throughout your codebase without worrying about output pollution in production.\n\n```typescript\nimport { Logger, createMcpLogger } from \"@alcyone-labs/simple-mcp-logger\";\n\nconst logger = createMcpLogger(\"MyApp\");\n\n// These will only output when DEBUG environment variable is truthy\nlogger.envDebug(\"Processing user request\", { userId: 123 });\nlogger.envDebug(\"Database query\", { sql: \"SELECT * FROM users\" });\nlogger.envDebug(\"API response time\", { duration: \"245ms\" });\n\n// Regular debug logging (always respects log level)\nlogger.debug(\"This always logs when level allows\");\n```\n\n**Environment Variable Behavior:**\n\n- `DEBUG=true` or `DEBUG=1` or `DEBUG=anything` → Logging enabled\n- `DEBUG=false` or `DEBUG=0` or `DEBUG=\"\"` or unset → Logging disabled\n\n**Usage Examples:**\n\n```bash\n# Enable debug logging\nDEBUG=1 node my-mcp-server.js\n\n# Disable debug logging (production)\nnode my-mcp-server.js\n\n# Enable with custom value\nDEBUG=verbose node my-mcp-server.js\n```\n\n**Benefits:**\n\n- **Safe for production**: No output pollution when DEBUG is not set\n- **Works with all transports**: Console, file logging, MCP mode, etc.\n- **Respects all logger settings**: Log levels, prefixes, MCP mode\n- **Clear identification**: Debug messages are prefixed with `[ENV-DEBUG]`\n\n**File Logging Example:**\n\n```typescript\n// Logs to file only when DEBUG is set\nconst logger = createMcpLogger(\"MCP-Server\", \"./logs/debug.log\");\n\nlogger.envDebug(\"Server state\", serverState); // Only written when DEBUG=1\n```\n\n### 📡 Understanding STDOUT vs STDERR in MCP\n\n**STDOUT (Protocol Channel)**:\n\n- Reserved exclusively for MCP JSON-RPC messages\n- Any non-MCP output breaks protocol communication\n- Must be kept clean for reliable client connections\n\n**STDERR (Debugging Channel)**:\n\n- Safe for logging, debugging, and monitoring output\n- Visible in client logs without protocol interference\n- Perfect for error reporting and diagnostic information\n\n```typescript\n// ❌ STDOUT - Reserved for MCP protocol\nprocess.stdout.write('{\"jsonrpc\":\"2.0\",...}'); // MCP messages only\n\n// ✅ STDERR - Safe for debugging\nprocess.stderr.write(\"Debug: Processing request\\n\");\nconsole.error(\"Server metrics:\", metrics);\nlogger.mcpError(\"Performance data:\", data);\n```\n\n### 🧪 Testing MCP Servers\n\nDisable MCP mode during testing to see all logs:\n\n```typescript\n// ✅ NEW: Options-based API\nconst logger = createMcpLogger({\n  prefix: \"Test-Server\",\n  level: \"debug\",\n  mcpMode: false         // Enable console output for testing\n});\n\n// ⚠️ LEGACY: Still works\nconst legacyLogger = createMcpLogger(\"Test-Server\", undefined, { mcpMode: false });\n\n// OR use environment variable\nprocess.env.MCP_MODE = \"false\";\nconst autoLogger = createMcpLogger({ prefix: \"Test-Server\" }); // Auto-detects\n```\n\n### 🔄 Migration to Enhanced API\n\n**For New Projects** - Use the options-based API:\n\n```typescript\n// ✅ RECOMMENDED: Comprehensive logging\nconst logger = createMcpLogger({\n  prefix: \"MyMcpServer\",\n  logToFile: \"./logs/server.log\",\n  level: \"info\",         // Captures info, warn, error\n  mcpMode: true\n});\n```\n\n**For Existing Projects** - Gradual migration:\n\n```typescript\n// Step 1: Keep existing code working (no changes needed)\nconst logger = createMcpLogger(\"MyServer\", \"./logs/mcp.log\");\n\n// Step 2: Add comprehensive logging where needed\nconst debugLogger = createMcpLogger({\n  prefix: \"MyServer-Debug\",\n  logToFile: \"./logs/debug.log\",\n  level: \"debug\"         // Capture everything for debugging\n});\n\n// Step 3: Eventually migrate to options-based API\nconst logger = createMcpLogger({\n  prefix: \"MyServer\",\n  logToFile: \"./logs/mcp.log\",\n  level: \"info\"          // Better than error-only default\n});\n```\n\n**Why Migrate?**\n\n- **🔍 See Everything**: Capture debug, info, warn messages (not just errors)\n- **🎛️ Better Control**: Fine-tune log levels per logger instance\n- **🚀 Future-Proof**: Prepared for v2.0 when legacy API is removed\n- **📖 Clearer Intent**: Options object makes configuration explicit\n\n## Browser Usage\n\nSimpleMcpLogger works seamlessly in browser environments! The core logger and most adapters are browser-compatible.\n\n### Basic Browser Usage\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <script type=\"module\">\n      import {\n        Logger,\n        logger,\n        createMcpLogger,\n      } from \"https://unpkg.com/@alcyone-labs/simple-mcp-logger/dist/index.mjs\";\n\n      // Use the global logger\n      logger.info(\"Hello from browser!\");\n\n      // Create a custom logger\n      const browserLogger = new Logger({\n        level: \"debug\",\n        prefix: \"Browser\",\n        mcpMode: false,\n      });\n\n      browserLogger.debug(\"Debug message in browser\");\n      browserLogger.table([{ name: \"John\", age: 30 }]);\n\n      // Replace console globally\n      globalThis.console = browserLogger;\n      console.log(\"Now using SimpleMcpLogger!\");\n    </script>\n  </head>\n  <body>\n    <h1>SimpleMcpLogger Browser Demo</h1>\n    <p>Check the browser console for log messages!</p>\n  </body>\n</html>\n```\n\n### Browser with Bundlers (Webpack, Vite, etc.)\n\n```typescript\nimport { Logger, createMcpLogger } from \"@alcyone-labs/simple-mcp-logger\";\n\n// Create logger for browser app\nconst appLogger = new Logger({\n  level: \"info\",\n  prefix: \"MyApp\",\n  mcpMode: false,\n});\n\n// Use all console methods\nappLogger.log(\"Application started\");\nappLogger.group(\"User Actions\");\nappLogger.info(\"User clicked button\");\nappLogger.warn(\"Form validation warning\");\nappLogger.groupEnd();\n\n// Time operations\nappLogger.time(\"API Call\");\n// ... some async operation\nappLogger.timeEnd(\"API Call\");\n```\n\n### Browser Adapter Support\n\n| Adapter                 | Browser Support | Notes                                   |\n| ----------------------- | --------------- | --------------------------------------- |\n| **Core Logger**         | ✅ Full support | All console methods work                |\n| **Winston Adapter**     | ✅ Full support | Works if Winston is browser-compatible  |\n| **Pino Transport**      | ✅ Full support | Use `createPinoDestination()`           |\n| **Pino Logger Factory** | ❌ Node.js only | Use destination with browser Pino build |\n\n### Browser + Pino Example\n\n```typescript\nimport { createPinoDestination } from \"@alcyone-labs/simple-mcp-logger\";\n// Import browser-compatible Pino build\nimport pino from \"pino/browser\";\n\nconst destination = createPinoDestination({\n  level: \"info\",\n  prefix: \"Browser\",\n});\n\nconst logger = pino({ level: \"info\" }, destination);\nlogger.info(\"Hello from Pino in browser!\");\n```\n\n## File Logging\n\nSimpleMcpLogger supports persistent logging to files with automatic directory creation and proper file stream management.\n\n### Basic File Logging\n\n```typescript\nimport { Logger, createMcpLogger } from \"@alcyone-labs/simple-mcp-logger\";\n\n// Create logger with file output\nconst logger = new Logger({\n  level: \"info\",\n  logToFile: \"./logs/app.log\", // Directory created automatically\n});\n\nlogger.info(\"This goes to both console and file\");\nlogger.error(\"Errors are logged to file too\");\n\n// Always close the logger when done to flush pending writes\nawait logger.close();\n```\n\n### MCP Mode with File Logging\n\nPerfect for MCP servers - suppress console output but maintain file logs:\n\n```typescript\n// MCP logger with file output (console suppressed, file enabled)\nconst mcpLogger = createMcpLogger(\"MCP-Server\", \"./logs/mcp.log\");\n\nmcpLogger.info(\"Processing request\"); // Silent in MCP mode, written to file\nmcpLogger.error(\"Error occurred\"); // Silent in MCP mode, written to file\nmcpLogger.mcpError(\"Debug info\"); // Always visible via STDERR + written to file\n\n// Gracefully close when shutting down\nawait mcpLogger.close();\n```\n\n### Dynamic File Path Changes\n\n```typescript\nconst logger = new Logger({ level: \"info\" });\n\n// Start logging to one file\nawait logger.setLogFile(\"./logs/startup.log\");\nlogger.info(\"Application starting\");\n\n// Switch to a different file\nawait logger.setLogFile(\"./logs/runtime.log\");\nlogger.info(\"Now logging to runtime file\");\n\n// Disable file logging\nawait logger.setLogFile(\"\"); // Empty string disables file logging\n```\n\n### File Logging with Adapters\n\nBoth Winston and Pino adapters support file logging:\n\n```typescript\n// Winston with file logging\nimport { createWinstonTransport } from \"@alcyone-labs/simple-mcp-logger/adapters\";\n\nconst transport = createWinstonTransport({\n  logToFile: \"./logs/winston.log\",\n  mcpMode: true,\n});\n\n// Pino with file logging\nimport { createPinoDestination } from \"@alcyone-labs/simple-mcp-logger/adapters\";\n\nconst destination = createPinoDestination({\n  logToFile: \"./logs/pino.log\",\n  mcpMode: true,\n});\n```\n\n### File Logging Best Practices\n\n1. **Always close loggers** when your application shuts down:\n\n   ```typescript\n   process.on(\"SIGINT\", async () => {\n     await logger.close();\n     process.exit(0);\n   });\n   ```\n\n2. **Use absolute paths** for production deployments:\n\n   ```typescript\n   import { resolve } from \"node:path\";\n\n   const logFile = resolve(process.cwd(), \"logs\", \"app.log\");\n   const logger = new Logger({ logToFile: logFile });\n   ```\n\n3. **Handle file errors gracefully** - SimpleMcpLogger automatically handles permission errors and continues logging to console.\n\n### Bundle Size\n\nThe browser build is optimized and lightweight:\n\n- **ESM build**: ~11KB (2.4KB gzipped)\n- **Tree-shakeable**: Import only what you need\n- **Zero dependencies**: No external runtime dependencies\n\n## Migration Guide\n\n### From console\n\n```typescript\n// Before\nconsole.log(\"Hello\");\nconsole.error(\"Error\");\n\n// After\nimport { logger } from \"@alcyone-labs/simple-mcp-logger\";\nlogger.log(\"Hello\");\nlogger.error(\"Error\");\n\n// Or replace globally\nglobalThis.console = logger as any;\n```\n\n### From Winston\n\n```typescript\n// Before\nimport winston from \"winston\";\nconst logger = winston.createLogger({\n  transports: [new winston.transports.Console()],\n});\n\n// After\nimport { createWinstonTransport } from \"@alcyone-labs/simple-mcp-logger\";\nconst logger = winston.createLogger({\n  transports: [createWinstonTransport()],\n});\n```\n\n### From Pino\n\n```typescript\n// Before\nimport pino from \"pino\";\nconst logger = pino();\n\n// After\nimport { createPinoLogger } from \"@alcyone-labs/simple-mcp-logger\";\nconst logger = createPinoLogger();\n```\n\n## Why This Matters for MCP Development\n\n### The Hidden Problem\n\nMany MCP servers fail in production due to **STDOUT contamination**. Even a single `console.log()` can break the entire MCP communication channel:\n\n```typescript\n// This innocent debug line breaks everything (writes to STDOUT):\nconsole.log(\"Debug: processing request\");\n\n// MCP client expects: {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{...}}\n// But receives: Debug: processing request{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{...}}\n// Result: JSON parse error, connection terminated\n\n// The fix is simple - use STDERR instead:\nconsole.error(\"Debug: processing request\"); // Safe: goes to STDERR\n```\n\n### The Solution Impact\n\nSimpleMcpLogger has prevented countless MCP server failures by:\n\n- **Catching stray console calls** before they reach STDOUT\n- **Preserving development logging** while ensuring production safety\n- **Enabling gradual migration** of existing codebases to MCP compliance\n- **Providing safe STDERR channels** for debugging without protocol interference\n- **Maintaining visibility** into server operations via client-visible STDERR logs\n\n### Real-World Success\n\nTeams using SimpleMcpLogger report:\n\n- **Zero MCP protocol corruption** issues in production\n- **Faster debugging** with safe error logging channels\n- **Seamless migration** of existing Node.js services to MCP servers\n- **Confident deployment** knowing logging won't break client connections\n\n**SimpleMcpLogger isn't just a logger—it's MCP reliability insurance.**\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.\n","readmeFilename":"README.md"}