From 9804e6f8c0d08b8603a80d59a6a305d24943e5bb Mon Sep 17 00:00:00 2001 From: internet-dot <207546839+internet-dot@users.noreply.github.com> Date: Tue, 7 Apr 2026 03:58:48 +0000 Subject: [PATCH] Fix: Change context logging methods to accept Any type per MCP spec The MCP spec defines the logging data field as 'unknown' (any JSON serializable type), but the context logging methods (debug, info, warning, error, log) only accepted str. This prevented sending structured log data like dicts or lists. Changed message parameter type from str to Any in all logging methods. Removed the extra parameter since callers can now pass structured data directly as the message. Fixes #397 --- src/mcp/server/mcpserver/context.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/mcp/server/mcpserver/context.py b/src/mcp/server/mcpserver/context.py index 1538adc7c..6af0b3205 100644 --- a/src/mcp/server/mcpserver/context.py +++ b/src/mcp/server/mcpserver/context.py @@ -187,28 +187,21 @@ async def elicit_url( async def log( self, level: Literal["debug", "info", "warning", "error"], - message: str, + message: Any, *, logger_name: str | None = None, - extra: dict[str, Any] | None = None, ) -> None: """Send a log message to the client. Args: level: Log level (debug, info, warning, error) - message: Log message + message: Log data (any JSON-serializable type) logger_name: Optional logger name - extra: Optional dictionary with additional structured data to include """ - if extra: - log_data = {"message": message, **extra} - else: - log_data = message - await self.request_context.session.send_log_message( level=level, - data=log_data, + data=message, logger=logger_name, related_request_id=self.request_id, ) @@ -261,20 +254,20 @@ async def close_standalone_sse_stream(self) -> None: await self._request_context.close_standalone_sse_stream() # Convenience methods for common log levels - async def debug(self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None: + async def debug(self, message: Any, *, logger_name: str | None = None) -> None: """Send a debug log message.""" - await self.log("debug", message, logger_name=logger_name, extra=extra) + await self.log("debug", message, logger_name=logger_name) - async def info(self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None: + async def info(self, message: Any, *, logger_name: str | None = None) -> None: """Send an info log message.""" - await self.log("info", message, logger_name=logger_name, extra=extra) + await self.log("info", message, logger_name=logger_name) async def warning( - self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None + self, message: Any, *, logger_name: str | None = None ) -> None: """Send a warning log message.""" - await self.log("warning", message, logger_name=logger_name, extra=extra) + await self.log("warning", message, logger_name=logger_name) - async def error(self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None: + async def error(self, message: Any, *, logger_name: str | None = None) -> None: """Send an error log message.""" - await self.log("error", message, logger_name=logger_name, extra=extra) + await self.log("error", message, logger_name=logger_name)