{"_id":"@anygpt/mcp-logger","name":"@anygpt/mcp-logger","dist-tags":{"latest":"0.3.0"},"versions":{"0.3.0":{"name":"@anygpt/mcp-logger","version":"0.3.0","description":"File-based logging for MCP servers","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"publishConfig":{"access":"public"},"scripts":{},"keywords":["mcp","logging","file-logger"],"author":{"name":"Petr Plenkov"},"license":"MIT","dependencies":{},"devDependencies":{},"gitHead":"ee0eafad2507f7d79dd8b3e8bf1d57cbd078852f","_id":"@anygpt/mcp-logger@0.3.0","_nodeVersion":"24.10.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-rSPTRwr5lbQrSfePTD6N9yvuj+kWaxTgls16qCK1NCSizUdUCVXy/MVWAQa4kN+bvjP89MmlRH3TslcnEq1IzQ==","shasum":"aae52eff38befbedcf2949c7509860d31da7505a","tarball":"https://registry.npmjs.org/@anygpt/mcp-logger/-/mcp-logger-0.3.0.tgz","fileCount":6,"unpackedSize":25256,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDHKDo9JEX1WvUTIJJiiCR0k8piL4VNVqYxYOUZqwh1GQIhANpD9KmeE9zt8dhgJ94H2GjX/RQZf8HpHgQ0w9oFwTLw"}]},"_npmUser":{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"},"directories":{},"maintainers":[{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-logger_0.3.0_1761045477494_0.9734504973636668"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-21T11:17:57.386Z","0.3.0":"2025-10-21T11:17:57.736Z","modified":"2025-10-21T11:17:58.067Z"},"maintainers":[{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"}],"description":"File-based logging for MCP servers","keywords":["mcp","logging","file-logger"],"author":{"name":"Petr Plenkov"},"license":"MIT","readme":"# @anygpt/mcp-logger\n\nFile-based logging for MCP servers with automatic rotation and multiple output formats.\n\n## Features\n\n- ✅ **File-based logging** - No console output, logs to files only\n- ✅ **Automatic log rotation** - Rotate logs based on file size\n- ✅ **Multiple log levels** - debug, info, warn, error\n- ✅ **JSON and text formats** - Choose your preferred format\n- ✅ **Async write queue** - Prevents race conditions\n- ✅ **Optional stderr output** - For debugging during development\n- ✅ **Child loggers** - Create contextual loggers\n- ✅ **Metadata support** - Attach structured data to logs\n\n## Installation\n\n```bash\nnpm install @anygpt/mcp-logger\n```\n\n## Usage\n\n### Basic Usage\n\n```typescript\nimport { createLogger } from '@anygpt/mcp-logger';\n\nconst logger = createLogger({\n  logFile: './logs/my-server.log',\n  level: 'info',\n  serverName: 'my-mcp-server',\n});\n\nlogger.info('Server started');\nlogger.warn('Connection slow');\nlogger.error('Failed to connect', error);\n```\n\n### Configuration Options\n\n```typescript\ninterface LoggerConfig {\n  /** Log file path (default: './logs/mcp-server.log') */\n  logFile?: string;\n\n  /** Minimum log level (default: 'info') */\n  level?: 'debug' | 'info' | 'warn' | 'error';\n\n  /** Max file size before rotation in bytes (default: 10MB) */\n  maxSize?: number;\n\n  /** Max number of rotated files to keep (default: 5) */\n  maxFiles?: number;\n\n  /** Also log to stderr for debugging (default: false) */\n  enableStderr?: boolean;\n\n  /** Server name in log entries (default: 'mcp-server') */\n  serverName?: string;\n\n  /** Include timestamps (default: true) */\n  includeTimestamp?: boolean;\n\n  /** Format logs as JSON (default: false) */\n  jsonFormat?: boolean;\n}\n```\n\n### Log Rotation\n\nLogs automatically rotate when they reach `maxSize`:\n\n```typescript\nconst logger = createLogger({\n  logFile: './logs/server.log',\n  maxSize: 10 * 1024 * 1024, // 10MB\n  maxFiles: 5, // Keep 5 rotated files\n});\n\n// Files created:\n// - server.log (current)\n// - server.log.1 (most recent rotation)\n// - server.log.2\n// - server.log.3\n// - server.log.4\n// - server.log.5 (oldest, will be deleted on next rotation)\n```\n\n### JSON Format\n\nEnable JSON format for structured logging:\n\n```typescript\nconst logger = createLogger({\n  logFile: './logs/server.log',\n  jsonFormat: true,\n});\n\nlogger.info('User logged in', { userId: '123', ip: '192.168.1.1' });\n\n// Output:\n// {\"timestamp\":\"2024-01-15T10:30:00.000Z\",\"level\":\"info\",\"serverName\":\"mcp-server\",\"message\":\"User logged in\",\"metadata\":{\"userId\":\"123\",\"ip\":\"192.168.1.1\"}}\n```\n\n### Child Loggers\n\nCreate child loggers with additional context:\n\n```typescript\nconst mainLogger = createLogger({\n  logFile: './logs/server.log',\n  serverName: 'main-server',\n});\n\nconst toolLogger = mainLogger.child({ serverName: 'tool-executor' });\n\nmainLogger.info('Server started');\ntoolLogger.info('Tool executed');\n\n// Output:\n// [2024-01-15T10:30:00.000Z] [main-server] INFO: Server started\n// [2024-01-15T10:30:05.000Z] [tool-executor] INFO: Tool executed\n```\n\n### Error Logging\n\nLog errors with full stack traces:\n\n```typescript\ntry {\n  await riskyOperation();\n} catch (error) {\n  logger.error('Operation failed', error as Error, {\n    operation: 'riskyOperation',\n    userId: '123',\n  });\n}\n\n// Output:\n// [2024-01-15T10:30:00.000Z] [mcp-server] ERROR: Operation failed\n//   Error: Connection timeout\n//   Stack: Error: Connection timeout\n//     at riskyOperation (file.ts:10:15)\n//     ...\n//   Metadata: {\n//     \"operation\": \"riskyOperation\",\n//     \"userId\": \"123\"\n//   }\n```\n\n### Flushing Logs\n\nEnsure all logs are written before exiting:\n\n```typescript\nconst logger = createLogger({ logFile: './logs/server.log' });\n\nlogger.info('Starting shutdown');\nawait logger.flush(); // Wait for all logs to be written\nprocess.exit(0);\n```\n\n## Integration with MCP Servers\n\n### MCP Discovery Server Example\n\n```typescript\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { createLogger } from '@anygpt/mcp-logger';\n\nconst logger = createLogger({\n  logFile: './logs/mcp-discovery.log',\n  level: process.env.LOG_LEVEL || 'info',\n  serverName: 'mcp-discovery',\n  maxSize: 10 * 1024 * 1024,\n  maxFiles: 5,\n});\n\nconst server = new Server(\n  { name: 'mcp-discovery-server', version: '1.0.0' },\n  { capabilities: { tools: {} } }\n);\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n  logger.info('Tool called', { tool: request.params.name });\n  try {\n    const result = await executeTool(request.params.name);\n    logger.info('Tool executed successfully', { tool: request.params.name });\n    return result;\n  } catch (error) {\n    logger.error('Tool execution failed', error as Error, {\n      tool: request.params.name,\n    });\n    throw error;\n  }\n});\n\n// Flush logs on shutdown\nprocess.on('SIGINT', async () => {\n  logger.info('Shutting down');\n  await logger.flush();\n  process.exit(0);\n});\n```\n\n## Log Output Examples\n\n### Text Format (Default)\n\n```\n[2024-01-15T10:30:00.000Z] [mcp-server] INFO: Server started\n[2024-01-15T10:30:05.000Z] [mcp-server] INFO: Tool executed\n  Metadata: {\n    \"toolName\": \"search_tools\",\n    \"duration\": 123\n  }\n[2024-01-15T10:30:10.000Z] [mcp-server] ERROR: Connection failed\n  Error: ECONNREFUSED\n  Stack: Error: ECONNREFUSED\n    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16)\n```\n\n### JSON Format\n\n```json\n{\"timestamp\":\"2024-01-15T10:30:00.000Z\",\"level\":\"info\",\"serverName\":\"mcp-server\",\"message\":\"Server started\"}\n{\"timestamp\":\"2024-01-15T10:30:05.000Z\",\"level\":\"info\",\"serverName\":\"mcp-server\",\"message\":\"Tool executed\",\"metadata\":{\"toolName\":\"search_tools\",\"duration\":123}}\n{\"timestamp\":\"2024-01-15T10:30:10.000Z\",\"level\":\"error\",\"serverName\":\"mcp-server\",\"message\":\"Connection failed\",\"error\":{\"message\":\"ECONNREFUSED\",\"stack\":\"Error: ECONNREFUSED\\n    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16)\",\"code\":\"ECONNREFUSED\"}}\n```\n\n## Environment Variables\n\nControl logging via environment variables:\n\n```bash\n# Set log level\nexport LOG_LEVEL=debug\n\n# Enable stderr output\nexport LOG_STDERR=true\n\n# Set log file path\nexport LOG_FILE=./logs/custom.log\n```\n\n```typescript\nconst logger = createLogger({\n  level: (process.env.LOG_LEVEL as LogLevel) || 'info',\n  enableStderr: process.env.LOG_STDERR === 'true',\n  logFile: process.env.LOG_FILE || './logs/mcp-server.log',\n});\n```\n\n## Best Practices\n\n1. **Always flush logs before exit**:\n   ```typescript\n   process.on('SIGINT', async () => {\n     await logger.flush();\n     process.exit(0);\n   });\n   ```\n\n2. **Use appropriate log levels**:\n   - `debug` - Detailed debugging information\n   - `info` - General informational messages\n   - `warn` - Warning messages for potential issues\n   - `error` - Error messages for failures\n\n3. **Include metadata for context**:\n   ```typescript\n   logger.info('Request processed', {\n     requestId: '123',\n     duration: 456,\n     userId: 'user-789',\n   });\n   ```\n\n4. **Use child loggers for components**:\n   ```typescript\n   const toolLogger = mainLogger.child({ serverName: 'tool-executor' });\n   const cacheLogger = mainLogger.child({ serverName: 'cache-manager' });\n   ```\n\n5. **Configure rotation for production**:\n   ```typescript\n   const logger = createLogger({\n     maxSize: 50 * 1024 * 1024, // 50MB\n     maxFiles: 10, // Keep 10 rotated files\n   });\n   ```\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-dfc5124b5e94eeb27f5920ba0791509f"}