From 9fa779546f3cbcc1772c8673aba2b8a0b1d98f5c Mon Sep 17 00:00:00 2001 From: qianchongyang Date: Sun, 22 Mar 2026 23:04:41 +0800 Subject: [PATCH] fix: allow any JSON-serializable type for log message data According to the MCP spec, the data that may be logged can be of any type, not just str. This change updates the logging context methods to accept Any instead of str for the data parameter. Changes: - Change 'message' parameter to 'data' with type Any in log() - Update all convenience methods (debug, info, warning, error) to accept Any for the data parameter - Update docstring to reflect the spec-compliant behavior Fixes #397 --- src/mcp/server/mcpserver/context.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/mcp/server/mcpserver/context.py b/src/mcp/server/mcpserver/context.py index 1538adc7c..2df233cbb 100644 --- a/src/mcp/server/mcpserver/context.py +++ b/src/mcp/server/mcpserver/context.py @@ -187,7 +187,7 @@ async def elicit_url( async def log( self, level: Literal["debug", "info", "warning", "error"], - message: str, + data: Any, *, logger_name: str | None = None, extra: dict[str, Any] | None = None, @@ -196,15 +196,16 @@ async def log( Args: level: Log level (debug, info, warning, error) - message: Log message + data: The data to be logged, such as a string message or an object. + Any JSON serializable type is allowed here. logger_name: Optional logger name extra: Optional dictionary with additional structured data to include """ if extra: - log_data = {"message": message, **extra} + log_data: Any = {"data": data, **extra} else: - log_data = message + log_data = data await self.request_context.session.send_log_message( level=level, @@ -261,20 +262,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, data: Any, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None: """Send a debug log message.""" - await self.log("debug", message, logger_name=logger_name, extra=extra) + await self.log("debug", data, logger_name=logger_name, extra=extra) - async def info(self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None: + async def info(self, data: Any, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None: """Send an info log message.""" - await self.log("info", message, logger_name=logger_name, extra=extra) + await self.log("info", data, logger_name=logger_name, extra=extra) async def warning( - self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None + self, data: Any, *, logger_name: str | None = None, extra: dict[str, Any] | None = None ) -> None: """Send a warning log message.""" - await self.log("warning", message, logger_name=logger_name, extra=extra) + await self.log("warning", data, logger_name=logger_name, extra=extra) - async def error(self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None: + async def error(self, data: Any, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None: """Send an error log message.""" - await self.log("error", message, logger_name=logger_name, extra=extra) + await self.log("error", data, logger_name=logger_name, extra=extra)