mcp-logger-utils


Namemcp-logger-utils JSON
Version 0.3.0 PyPI version JSON
download
home_pageNone
SummaryShared utilities for MCP servers, including robust logging, JSON repair, and debug tools with automatic cache clearing.
upload_time2025-07-24 21:18:52
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT
keywords debugging json-repair logging mcp model-context-protocol
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # MCP Logger Utils - Enhanced Documentation

A comprehensive logging and utility package for MCP (Model Context Protocol) servers with production-ready features.

## Features

### Core Features
- ๐Ÿ” **Smart Logging** - Automatic truncation of large data structures
- ๐Ÿ›ก๏ธ **PII Protection** - Automatic detection and redaction of sensitive data
- ๐Ÿ”„ **Circular Reference Protection** - Safe logging of complex objects
- ๐Ÿ“Š **Performance Monitoring** - Track slow operations automatically
- ๐Ÿšฆ **Rate Limiting** - Prevent log spam
- ๐Ÿงช **Testing Utilities** - Capture logs in tests
- ๐Ÿ”ง **Debug Tools** - Process management for MCP servers
- ๐ŸŽฏ **Error Deduplication** - Avoid repeated error messages
- ๐Ÿ“ **Structured Logging** - Add request IDs and context
- โš™๏ธ **Runtime Configuration** - Change settings without restart

## Installation

```bash
pip install mcp-logger-utils
```

## Quick Start

### Basic Usage

```python
from mcp_logger_utils import MCPLogger

# Create logger instance
logger = MCPLogger("my-mcp-server")

# Use it like any logger
logger.info("Server starting up...")
logger.debug("Debug information")
logger.success("Operation completed successfully โœ…")
logger.error("Something went wrong")
```

### Available Logging Methods

All standard loguru methods are available with type hints:

```python
logger.trace("Most detailed logging")
logger.debug("Debug information")
logger.info("General information")
logger.success("Success messages โœ…")
logger.warning("Warning messages")
logger.error("Error messages")
logger.critical("Critical issues")
logger.exception("Log with traceback")
```

## Enhanced Features

### 1. PII Protection

Automatically redact sensitive information:

```python
# Enable PII redaction (enabled by default)
logger = MCPLogger("my-server", enable_pii_redaction=True)

# These will be automatically redacted
logger.info("User email: john.doe@example.com")
# Logs: "User email: j***@***.***"

logger.info("Phone: +1-555-123-4567")
# Logs: "Phone: ***-***-****"

logger.info("SSN: 123-45-6789")
# Logs: "SSN: ***-**-****"

# Toggle at runtime
logger.set_pii_redaction(False)  # Disable
logger.set_pii_redaction(True)   # Re-enable
```

### 2. Performance Monitoring

Track slow operations automatically:

```python
# Set threshold for specific functions
@logger.monitor_performance(threshold_ms=100)
async def process_data():
    await asyncio.sleep(0.2)  # Will log warning

# Or set global thresholds
logger.set_performance_threshold("process_data", 100)

@logger.monitor_performance()
async def process_data():
    # Will use the configured threshold
    pass
```

### 3. Rate Limiting

Prevent log spam:

```python
from datetime import timedelta

# Global rate limiting
logger = MCPLogger(
    "my-server",
    rate_limit_window=timedelta(seconds=60),
    rate_limit_max_calls=100
)

# Per-function rate limiting
@logger.rate_limit(max_calls=5, time_window=timedelta(minutes=1))
def noisy_function():
    logger.info("This won't spam logs")
```

### 4. Testing Utilities

Capture logs in tests:

```python
def test_my_function():
    logger = MCPLogger("test")
    
    with logger.capture() as logs:
        my_function()
        
    # Check captured logs
    assert "Expected message" in logs
    assert len(logs.get_messages("ERROR")) == 0
```

### 5. Structured Logging

Add context to all logs:

```python
# Create logger with request ID
request_logger = logger.with_request_id("req-123")
request_logger.info("Processing request")
# Logs include request_id in extra fields

# Temporary context
with logger.contextualize(user_id=456, session="abc"):
    logger.info("User action")
    # These logs have user_id and session in context
```

### 6. Error Deduplication

Avoid repeated error messages:

```python
# Errors are automatically deduplicated
for i in range(100):
    try:
        risky_operation()
    except Exception as e:
        logger.log_error("risky_operation", 0.1, e, {"attempt": i})
        # Only first error and every 10th duplicate are logged
```

### 7. Debug Tool Decorator

Comprehensive debugging for MCP tools:

```python
from mcp_logger_utils import debug_tool

@debug_tool(logger)
async def fetch_data(url: str):
    # Automatically logs:
    # - Function calls with arguments
    # - Execution time
    # - Return values
    # - Exceptions with full context
    response = await http_client.get(url)
    return response.json()

# With exception catching
@debug_tool(logger, catch_exceptions=True)
async def risky_operation():
    # Returns JSON error instead of raising
    raise ValueError("Something went wrong")
```

### 8. Runtime Configuration

Change settings without restart:

```python
# Change log level
logger.set_level("DEBUG")  # More verbose
logger.set_level("WARNING")  # Less verbose

# Toggle features
logger.set_pii_redaction(False)
logger.enable_pii_redaction = True
```

## MCP Server Integration

### Complete Example

```python
from mcp_logger_utils import MCPLogger, debug_tool, create_debug_tools
from fastmcp import FastMCP

# Initialize
mcp = FastMCP("my-mcp-server")
logger = MCPLogger(
    "my-mcp-server",
    enable_pii_redaction=True,
    rate_limit_window=timedelta(minutes=1),
    rate_limit_max_calls=1000
)

# Add debug tools (for development)
create_debug_tools(mcp, "my-mcp-server", logger)

@mcp.tool()
@debug_tool(logger)
async def process_document(content: str, user_email: str):
    """Process document with automatic logging."""
    logger.info(f"Processing document for {user_email}")
    # Email will be redacted in logs
    
    # Long content will be truncated
    logger.debug(f"Content: {content}")
    
    # Process...
    result = await process(content)
    
    return create_success_response(result)

# Performance monitoring
@mcp.tool()
@logger.monitor_performance(threshold_ms=500)
async def analyze_data(data: list):
    """Analyze data with performance tracking."""
    # Will warn if takes > 500ms
    return await heavy_computation(data)
```

## Circular Reference Protection

```python
# Safe to log circular references
obj1 = {"name": "A", "ref": None}
obj2 = {"name": "B", "ref": obj1}
obj1["ref"] = obj2

logger.info(f"Objects: {obj1}")
# Logs: Objects: {"name": "A", "ref": {"name": "B", "ref": "<circular reference>"}}
```

## Response Utilities

Standardized MCP responses:

```python
from mcp_logger_utils import create_success_response, create_error_response

# Success response
return create_success_response(
    {"data": result},
    tool_name="my_tool",
    start_time=start_time
)

# Error response
return create_error_response(
    "Something went wrong",
    tool_name="my_tool",
    start_time=start_time
)
```

## Debug Tools

For MCP server development:

```python
from mcp_logger_utils import create_debug_tools

# Add debug tools to your MCP server
create_debug_tools(mcp, "my-server", logger)

# This adds:
# - debug_reload_server: Kill old instances and reload
# - debug_list_instances: List running instances
# - debug_clear_cache: Clear UV cache
```

## Environment Variables

- `MCP_LOG_LEVEL`: Set default log level (DEBUG, INFO, WARNING, ERROR)
- `MCP_DEBUG`: Set to "true" or "1" for debug mode
- `MCP_LOG_DIR`: Custom log directory (default: ~/.claude/mcp_logs)

## Best Practices

1. **Initialize early**: Create logger at module level
2. **Use structured logging**: Add context with `contextualize()`
3. **Monitor performance**: Add thresholds for critical operations
4. **Enable PII protection**: Always in production
5. **Set rate limits**: Prevent runaway logging
6. **Use debug_tool**: For all MCP tool functions
7. **Capture in tests**: Verify logging behavior

## Migration from Basic Logger

The enhanced logger is 100% backward compatible. Just update your import:

```python
# Old
from mcp_logger_utils import MCPLogger

# New - no code changes needed!
from mcp_logger_utils import MCPLogger
```

Then add enhanced features as needed.

## License

MIT
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "mcp-logger-utils",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "debugging, json-repair, logging, mcp, model-context-protocol",
    "author": null,
    "author_email": "Graham Anderson <graham@grahama.co>",
    "download_url": "https://files.pythonhosted.org/packages/f4/05/d9f2537223c4c85d1bf362c029e40a705eb836066f9fa187c90e74cf2b64/mcp_logger_utils-0.3.0.tar.gz",
    "platform": null,
    "description": "# MCP Logger Utils - Enhanced Documentation\n\nA comprehensive logging and utility package for MCP (Model Context Protocol) servers with production-ready features.\n\n## Features\n\n### Core Features\n- \ud83d\udd0d **Smart Logging** - Automatic truncation of large data structures\n- \ud83d\udee1\ufe0f **PII Protection** - Automatic detection and redaction of sensitive data\n- \ud83d\udd04 **Circular Reference Protection** - Safe logging of complex objects\n- \ud83d\udcca **Performance Monitoring** - Track slow operations automatically\n- \ud83d\udea6 **Rate Limiting** - Prevent log spam\n- \ud83e\uddea **Testing Utilities** - Capture logs in tests\n- \ud83d\udd27 **Debug Tools** - Process management for MCP servers\n- \ud83c\udfaf **Error Deduplication** - Avoid repeated error messages\n- \ud83d\udcdd **Structured Logging** - Add request IDs and context\n- \u2699\ufe0f **Runtime Configuration** - Change settings without restart\n\n## Installation\n\n```bash\npip install mcp-logger-utils\n```\n\n## Quick Start\n\n### Basic Usage\n\n```python\nfrom mcp_logger_utils import MCPLogger\n\n# Create logger instance\nlogger = MCPLogger(\"my-mcp-server\")\n\n# Use it like any logger\nlogger.info(\"Server starting up...\")\nlogger.debug(\"Debug information\")\nlogger.success(\"Operation completed successfully \u2705\")\nlogger.error(\"Something went wrong\")\n```\n\n### Available Logging Methods\n\nAll standard loguru methods are available with type hints:\n\n```python\nlogger.trace(\"Most detailed logging\")\nlogger.debug(\"Debug information\")\nlogger.info(\"General information\")\nlogger.success(\"Success messages \u2705\")\nlogger.warning(\"Warning messages\")\nlogger.error(\"Error messages\")\nlogger.critical(\"Critical issues\")\nlogger.exception(\"Log with traceback\")\n```\n\n## Enhanced Features\n\n### 1. PII Protection\n\nAutomatically redact sensitive information:\n\n```python\n# Enable PII redaction (enabled by default)\nlogger = MCPLogger(\"my-server\", enable_pii_redaction=True)\n\n# These will be automatically redacted\nlogger.info(\"User email: john.doe@example.com\")\n# Logs: \"User email: j***@***.***\"\n\nlogger.info(\"Phone: +1-555-123-4567\")\n# Logs: \"Phone: ***-***-****\"\n\nlogger.info(\"SSN: 123-45-6789\")\n# Logs: \"SSN: ***-**-****\"\n\n# Toggle at runtime\nlogger.set_pii_redaction(False)  # Disable\nlogger.set_pii_redaction(True)   # Re-enable\n```\n\n### 2. Performance Monitoring\n\nTrack slow operations automatically:\n\n```python\n# Set threshold for specific functions\n@logger.monitor_performance(threshold_ms=100)\nasync def process_data():\n    await asyncio.sleep(0.2)  # Will log warning\n\n# Or set global thresholds\nlogger.set_performance_threshold(\"process_data\", 100)\n\n@logger.monitor_performance()\nasync def process_data():\n    # Will use the configured threshold\n    pass\n```\n\n### 3. Rate Limiting\n\nPrevent log spam:\n\n```python\nfrom datetime import timedelta\n\n# Global rate limiting\nlogger = MCPLogger(\n    \"my-server\",\n    rate_limit_window=timedelta(seconds=60),\n    rate_limit_max_calls=100\n)\n\n# Per-function rate limiting\n@logger.rate_limit(max_calls=5, time_window=timedelta(minutes=1))\ndef noisy_function():\n    logger.info(\"This won't spam logs\")\n```\n\n### 4. Testing Utilities\n\nCapture logs in tests:\n\n```python\ndef test_my_function():\n    logger = MCPLogger(\"test\")\n    \n    with logger.capture() as logs:\n        my_function()\n        \n    # Check captured logs\n    assert \"Expected message\" in logs\n    assert len(logs.get_messages(\"ERROR\")) == 0\n```\n\n### 5. Structured Logging\n\nAdd context to all logs:\n\n```python\n# Create logger with request ID\nrequest_logger = logger.with_request_id(\"req-123\")\nrequest_logger.info(\"Processing request\")\n# Logs include request_id in extra fields\n\n# Temporary context\nwith logger.contextualize(user_id=456, session=\"abc\"):\n    logger.info(\"User action\")\n    # These logs have user_id and session in context\n```\n\n### 6. Error Deduplication\n\nAvoid repeated error messages:\n\n```python\n# Errors are automatically deduplicated\nfor i in range(100):\n    try:\n        risky_operation()\n    except Exception as e:\n        logger.log_error(\"risky_operation\", 0.1, e, {\"attempt\": i})\n        # Only first error and every 10th duplicate are logged\n```\n\n### 7. Debug Tool Decorator\n\nComprehensive debugging for MCP tools:\n\n```python\nfrom mcp_logger_utils import debug_tool\n\n@debug_tool(logger)\nasync def fetch_data(url: str):\n    # Automatically logs:\n    # - Function calls with arguments\n    # - Execution time\n    # - Return values\n    # - Exceptions with full context\n    response = await http_client.get(url)\n    return response.json()\n\n# With exception catching\n@debug_tool(logger, catch_exceptions=True)\nasync def risky_operation():\n    # Returns JSON error instead of raising\n    raise ValueError(\"Something went wrong\")\n```\n\n### 8. Runtime Configuration\n\nChange settings without restart:\n\n```python\n# Change log level\nlogger.set_level(\"DEBUG\")  # More verbose\nlogger.set_level(\"WARNING\")  # Less verbose\n\n# Toggle features\nlogger.set_pii_redaction(False)\nlogger.enable_pii_redaction = True\n```\n\n## MCP Server Integration\n\n### Complete Example\n\n```python\nfrom mcp_logger_utils import MCPLogger, debug_tool, create_debug_tools\nfrom fastmcp import FastMCP\n\n# Initialize\nmcp = FastMCP(\"my-mcp-server\")\nlogger = MCPLogger(\n    \"my-mcp-server\",\n    enable_pii_redaction=True,\n    rate_limit_window=timedelta(minutes=1),\n    rate_limit_max_calls=1000\n)\n\n# Add debug tools (for development)\ncreate_debug_tools(mcp, \"my-mcp-server\", logger)\n\n@mcp.tool()\n@debug_tool(logger)\nasync def process_document(content: str, user_email: str):\n    \"\"\"Process document with automatic logging.\"\"\"\n    logger.info(f\"Processing document for {user_email}\")\n    # Email will be redacted in logs\n    \n    # Long content will be truncated\n    logger.debug(f\"Content: {content}\")\n    \n    # Process...\n    result = await process(content)\n    \n    return create_success_response(result)\n\n# Performance monitoring\n@mcp.tool()\n@logger.monitor_performance(threshold_ms=500)\nasync def analyze_data(data: list):\n    \"\"\"Analyze data with performance tracking.\"\"\"\n    # Will warn if takes > 500ms\n    return await heavy_computation(data)\n```\n\n## Circular Reference Protection\n\n```python\n# Safe to log circular references\nobj1 = {\"name\": \"A\", \"ref\": None}\nobj2 = {\"name\": \"B\", \"ref\": obj1}\nobj1[\"ref\"] = obj2\n\nlogger.info(f\"Objects: {obj1}\")\n# Logs: Objects: {\"name\": \"A\", \"ref\": {\"name\": \"B\", \"ref\": \"<circular reference>\"}}\n```\n\n## Response Utilities\n\nStandardized MCP responses:\n\n```python\nfrom mcp_logger_utils import create_success_response, create_error_response\n\n# Success response\nreturn create_success_response(\n    {\"data\": result},\n    tool_name=\"my_tool\",\n    start_time=start_time\n)\n\n# Error response\nreturn create_error_response(\n    \"Something went wrong\",\n    tool_name=\"my_tool\",\n    start_time=start_time\n)\n```\n\n## Debug Tools\n\nFor MCP server development:\n\n```python\nfrom mcp_logger_utils import create_debug_tools\n\n# Add debug tools to your MCP server\ncreate_debug_tools(mcp, \"my-server\", logger)\n\n# This adds:\n# - debug_reload_server: Kill old instances and reload\n# - debug_list_instances: List running instances\n# - debug_clear_cache: Clear UV cache\n```\n\n## Environment Variables\n\n- `MCP_LOG_LEVEL`: Set default log level (DEBUG, INFO, WARNING, ERROR)\n- `MCP_DEBUG`: Set to \"true\" or \"1\" for debug mode\n- `MCP_LOG_DIR`: Custom log directory (default: ~/.claude/mcp_logs)\n\n## Best Practices\n\n1. **Initialize early**: Create logger at module level\n2. **Use structured logging**: Add context with `contextualize()`\n3. **Monitor performance**: Add thresholds for critical operations\n4. **Enable PII protection**: Always in production\n5. **Set rate limits**: Prevent runaway logging\n6. **Use debug_tool**: For all MCP tool functions\n7. **Capture in tests**: Verify logging behavior\n\n## Migration from Basic Logger\n\nThe enhanced logger is 100% backward compatible. Just update your import:\n\n```python\n# Old\nfrom mcp_logger_utils import MCPLogger\n\n# New - no code changes needed!\nfrom mcp_logger_utils import MCPLogger\n```\n\nThen add enhanced features as needed.\n\n## License\n\nMIT",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Shared utilities for MCP servers, including robust logging, JSON repair, and debug tools with automatic cache clearing.",
    "version": "0.3.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/grahamannetts/mcp-logger-utils/issues",
        "Documentation": "https://github.com/grahamannetts/mcp-logger-utils#readme",
        "Homepage": "https://github.com/grahamannetts/mcp-logger-utils",
        "Repository": "https://github.com/grahamannetts/mcp-logger-utils"
    },
    "split_keywords": [
        "debugging",
        " json-repair",
        " logging",
        " mcp",
        " model-context-protocol"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "904616732a02c65d593946a82402f364a62f93a82e3733e55c178f55738954bb",
                "md5": "6ed6d8574f8dc0c522681ff4d1ab8d8a",
                "sha256": "ede2620799ce1ec1690fc2d7d7e875d9e8bba616ca5976c1413454a21940d00e"
            },
            "downloads": -1,
            "filename": "mcp_logger_utils-0.3.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6ed6d8574f8dc0c522681ff4d1ab8d8a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 28090,
            "upload_time": "2025-07-24T21:18:51",
            "upload_time_iso_8601": "2025-07-24T21:18:51.998757Z",
            "url": "https://files.pythonhosted.org/packages/90/46/16732a02c65d593946a82402f364a62f93a82e3733e55c178f55738954bb/mcp_logger_utils-0.3.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f405d9f2537223c4c85d1bf362c029e40a705eb836066f9fa187c90e74cf2b64",
                "md5": "345567dfd5882a22da6b20790660c39f",
                "sha256": "3426c3031d53b929399910daae30f9e59e63593652194e5d76da25e52ad58db2"
            },
            "downloads": -1,
            "filename": "mcp_logger_utils-0.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "345567dfd5882a22da6b20790660c39f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 77435,
            "upload_time": "2025-07-24T21:18:52",
            "upload_time_iso_8601": "2025-07-24T21:18:52.919113Z",
            "url": "https://files.pythonhosted.org/packages/f4/05/d9f2537223c4c85d1bf362c029e40a705eb836066f9fa187c90e74cf2b64/mcp_logger_utils-0.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-24 21:18:52",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "grahamannetts",
    "github_project": "mcp-logger-utils",
    "github_not_found": true,
    "lcname": "mcp-logger-utils"
}
        
Elapsed time: 2.09212s