Skip to main content
Servers can send log messages to clients during tool execution. This provides visibility into server operations and helps with debugging.

Handler

from dedalus_mcp.client import ClientCapabilitiesConfig, open_connection
from dedalus_mcp.types import LoggingMessageNotificationParams

def logging_handler(params: LoggingMessageNotificationParams) -> None:
    """Handle log messages from the server."""
    level = params.level.upper()
    data = params.data

    print(f"[{level}] {data}")

Usage

capabilities = ClientCapabilitiesConfig(logging=logging_handler)

async with open_connection(
    url="http://127.0.0.1:8000/mcp",
    transport="streamable-http",
    capabilities=capabilities,
) as client:
    # Server logs will be routed to your handler
    result = await client.call_tool("process", {"file": "data.csv"})

Log Levels

Servers can send logs at different levels:
LevelDescription
debugDetailed debugging information
infoGeneral operational messages
warningWarning conditions
errorError conditions

Structured Logging

Route to your logging framework:
import logging

logger = logging.getLogger("mcp.server")

def logging_handler(params: LoggingMessageNotificationParams) -> None:
    level = getattr(logging, params.level.upper(), logging.INFO)
    logger.log(level, params.data)

Full Example

import asyncio
from dedalus_mcp.client import ClientCapabilitiesConfig, open_connection
from dedalus_mcp.types import LoggingMessageNotificationParams

def logging_handler(params: LoggingMessageNotificationParams) -> None:
    level = params.level.upper()
    print(f"[SERVER {level}] {params.data}")

async def main():
    capabilities = ClientCapabilitiesConfig(logging=logging_handler)

    async with open_connection(
        url="http://127.0.0.1:8000/mcp",
        transport="streamable-http",
        capabilities=capabilities,
    ) as client:
        print(f"Connected: {client.initialize_result.serverInfo.name}")

        tools = await client.list_tools()
        print(f"Available tools: {[t.name for t in tools.tools]}")

        # Call a tool - logs will appear via handler
        result = await client.call_tool("analyze", {"input": "test"})
        print(f"Result: {result.content}")

asyncio.run(main())