How to intermediate · 3 min read

MCP server logging best practices

Quick answer
Use structured logging with timestamps and log levels in your MCP server to capture key events like connections, requests, and errors. Integrate Python's logging module with appropriate handlers and rotate logs to maintain performance and traceability.

PREREQUISITES

  • Python 3.8+
  • pip install mcp
  • Basic knowledge of Python logging module

Setup logging in MCP server

Configure Python's logging module to capture MCP server events with timestamps, log levels, and message formatting. Use rotating file handlers to avoid oversized log files.

python
import logging
from logging.handlers import RotatingFileHandler

# Configure logger
logger = logging.getLogger('mcp_server')
logger.setLevel(logging.DEBUG)

# Create rotating file handler (max 5MB per file, keep 3 backups)
handler = RotatingFileHandler('mcp_server.log', maxBytes=5*1024*1024, backupCount=3)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

# Example usage
logger.info('MCP server starting')

Step by step: Logging key MCP server events

Log connection lifecycle, incoming requests, responses, and errors explicitly. This helps trace issues and monitor server health.

python
from mcp.server.stdio import stdio_server
import logging

logger = logging.getLogger('mcp_server')

@stdio_server
async def main(server):
    logger.info('MCP server started and awaiting connections')
    async for request in server:
        logger.debug(f'Received request: {request}')
        try:
            # Process request (example echo)
            response = {'result': request.get('params', {})}
            await server.send(response)
            logger.debug(f'Sent response: {response}')
        except Exception as e:
            logger.error(f'Error processing request: {e}', exc_info=True)

if __name__ == '__main__':
    import asyncio
    asyncio.run(main())

Common variations

  • Use asynchronous logging handlers for high-throughput MCP servers.
  • Integrate with centralized logging systems like ELK or Splunk via JSON log format.
  • Adjust log levels dynamically for debugging vs production.
python
import logging
import json
from logging.handlers import RotatingFileHandler

class JsonFormatter(logging.Formatter):
    def format(self, record):
        log_record = {
            'timestamp': self.formatTime(record),
            'level': record.levelname,
            'message': record.getMessage(),
            'logger': record.name
        }
        return json.dumps(log_record)

logger = logging.getLogger('mcp_server')
handler = RotatingFileHandler('mcp_server.json.log', maxBytes=5*1024*1024, backupCount=3)
handler.setFormatter(JsonFormatter())
logger.addHandler(handler)
logger.setLevel(logging.INFO)

logger.info('MCP server started with JSON logging')

Troubleshooting logging issues

  • If logs are missing, verify logger and handler levels are set correctly.
  • Check file permissions for log files to ensure write access.
  • Use exc_info=True in logger.error calls to capture stack traces.

Key Takeaways

  • Use Python's logging with rotating file handlers to maintain manageable log sizes.
  • Log all key MCP server events: startup, requests, responses, and errors with timestamps.
  • Consider JSON formatting for logs to integrate with centralized logging platforms.
  • Enable detailed error logging with stack traces for easier debugging.
  • Adjust log verbosity dynamically to balance performance and diagnostic needs.
Verified 2026-04
Verify ↗