Skip to main content

Shared utilities for MCP servers, including robust logging, JSON repair, and debug tools with automatic cache clearing.

Project description

MCP Logger Utils

A robust, shared logging and utility package for MCP (Model Context Protocol) servers, especially tailored for Claude Code environments.

Features

  • Isolated Logging: Prevents conflicts with other libraries using loguru.
  • Automatic Truncation: Automatically shortens large strings, base64 data, and long lists (like embeddings) in logs to keep them clean and readable.
  • Universal Decorator: The @debug_tool decorator works seamlessly with both async and sync functions.
  • Safe Serialization: Handles non-serializable types (datetime, Path, etc.), preventing the logger from crashing.
  • Rich Context: Logs function arguments, return values, execution time, and detailed error tracebacks.
  • Configurable: Customize log directory, level, and truncation limits via constructor arguments or environment variables.
  • Robust JSON Repair: Includes a powerful utility to parse malformed JSON commonly produced by LLMs.
  • Structured Error Response: Returns a standardized JSON object on tool failure, including a unique error ID.
  • Standardized Response Format: Provides utilities for consistent MCP response formatting across all tools.

Installation

pip install mcp-logger-utils

Or using uv:

uv pip install mcp-logger-utils

Usage

1. Robust Logging with @debug_tool

Decorate your MCP tool functions to get automatic logging of inputs, outputs, performance, and errors.

a. Initialize the Logger

In your MCP server file, create an instance of MCPLogger. You can optionally configure truncation limits.

from mcp_logger_utils import MCPLogger

# Default initialization
mcp_logger = MCPLogger("my-awesome-server")

# Customizing truncation limits
mcp_logger_custom = MCPLogger(
    "my-data-server",
    max_log_str_len=512,      # Allow longer strings in logs
    max_log_list_len=5       # Show fewer list items
)

b. Apply the Decorator

The same decorator works for both async and sync functions.

from mcp_logger_utils import debug_tool

@mcp.tool()
@debug_tool(mcp_logger)
async def process_data(embedding: list, image_data: str) -> dict:
    # `embedding` (if long) and `image_data` (if long) will be
    # automatically truncated in the debug logs.
    return {"status": "processed"}

c. Configuration via Environment Variables

  • MCP_LOG_DIR: Overrides the default log directory (~/.claude/mcp_logs).
  • MCP_LOG_LEVEL: Sets the console log level (e.g., DEBUG, INFO).
  • MCP_DEBUG: Set to true or 1 for verbose DEBUG level logging.

2. JSON Repair Utility

When working with LLMs, you often get responses that are almost JSON but contain small errors or are wrapped in text. This utility provides a robust way to handle such cases.

repair_and_parse_json(content, logger_instance=None)

This function takes a string and does its best to return a valid Python dict or list.

  • It automatically extracts JSON from markdown code blocks (e.g., ```json ... ```).
  • It uses the json-repair library to fix common syntax errors.
  • If parsing fails, it safely returns the original string.

Example: Creating a Robust Tool

Here is how you can combine @debug_tool and repair_and_parse_json to build a tool that reliably processes LLM output.

from mcp_logger_utils import MCPLogger, debug_tool, repair_and_parse_json
# from some_llm_library import get_llm_response

# Initialize logger
mcp_logger = MCPLogger("llm-processor-tool")

@mcp.tool()
@debug_tool(mcp_logger)
async def get_structured_data_from_llm(prompt: str) -> dict:
    """
    Calls an LLM to get structured data and robustly parses the response.
    """
    # 1. Get a response from an LLM. It might be messy.
    messy_response = "Here is the JSON you requested: ```json\n{\n  \"name\": \"Claude\",\n  \"version\": 3.0,\n  \"is_helpful\": true, // He is very helpful!\n}\n```"
    # messy_response = await get_llm_response(prompt)

    # 2. Use the utility to clean and parse it.
    # The logger passed to it will log the repair steps for easy debugging.
    parsed_data = repair_and_parse_json(messy_response, logger_instance=mcp_logger.logger)

    # 3. Check if parsing was successful before proceeding.
    if not isinstance(parsed_data, dict):
        raise ValueError(f"Failed to parse a valid dictionary from the LLM response. Got: {parsed_data}")

    # 4. Now you can safely work with the clean data.
    parsed_data["processed_at"] = "2024-07-19"
    return parsed_data

Why this is a good pattern:

  1. Observability: The @debug_tool logs the raw, messy input from the LLM, so you can always see exactly what your tool received.
  2. Robustness: Your tool doesn't crash on slightly malformed JSON.
  3. Clarity: The code explicitly shows the step where data is being cleaned, making the logic easy to follow.

3. Standardized Response Format

All MCP tools should return consistent JSON responses. This package provides utilities to ensure consistency:

from mcp_logger_utils import create_success_response, create_error_response
import time

@mcp.tool()
@debug_tool(mcp_logger)
async def my_tool(param: str) -> str:
    start_time = time.time()
    
    try:
        # Your tool logic here
        result = {"processed": param, "status": "complete"}
        
        # Return standardized success response
        return create_success_response(result, "my_tool", start_time)
        
    except Exception as e:
        # Return standardized error response
        return create_error_response(str(e), "my_tool", start_time)

The response format is:

{
    "success": true,
    "data": {...},
    "error": null,
    "metadata": {
        "duration_ms": 123,
        "tool": "my_tool",
        "version": "2025-07-21",
        "timestamp": "2025-07-21T12:34:56.789Z"
    }
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_logger_utils-0.2.9.tar.gz (5.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_logger_utils-0.2.9-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

Details for the file mcp_logger_utils-0.2.9.tar.gz.

File metadata

  • Download URL: mcp_logger_utils-0.2.9.tar.gz
  • Upload date:
  • Size: 5.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.11

File hashes

Hashes for mcp_logger_utils-0.2.9.tar.gz
Algorithm Hash digest
SHA256 df292630e323ef1fa602f03f9fa79c46303b48dc5e75f5ad1715bc385168e0a7
MD5 cc4719eaf468bd61c5f1143b1874904f
BLAKE2b-256 177c62a54f16c25fb1ba97cf7bc5b336d5cf2219cdf152843ad4d8ad7b6cb89e

See more details on using hashes here.

File details

Details for the file mcp_logger_utils-0.2.9-py3-none-any.whl.

File metadata

File hashes

Hashes for mcp_logger_utils-0.2.9-py3-none-any.whl
Algorithm Hash digest
SHA256 aba8c59446a4541d6ff5f277428daf01a06aac08be5beef474a4618275a08c52
MD5 8ffaed052820df6a598ba26c02a2f372
BLAKE2b-256 d94bd83570721d8b4cdea32ebb6a89cc2167183b800314b9e1ccf3af6efa040a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page