fix: align Context logging methods with MCP spec data type (#2366)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Max Isbey <224885523+maxisbey@users.noreply.github.com>
This commit is contained in:
Gyeongjun Paik (Kent) 2026-04-15 06:41:51 +09:00 • committed by GitHub
commit 3d7b311de0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,7 +1,7 @@
from __future__ import annotations
from collections.abc import Iterable
from typing import TYPE_CHECKING, Any, Generic, Literal
from typing import TYPE_CHECKING, Any, Generic
from pydantic import AnyUrl, BaseModel
@ -14,6 +14,7 @@ from mcp.server.elicitation import (
elicit_with_validation,
)
from mcp.server.lowlevel.helper_types import ReadResourceContents
from mcp.types import LoggingLevel
if TYPE_CHECKING:
from mcp.server.mcpserver.server import MCPServer
@ -186,29 +187,23 @@ class Context(BaseModel, Generic[LifespanContextT, RequestT]):
async def log(
self,
level: Literal["debug", "info", "warning", "error"],
message: str,
level: LoggingLevel,
data: 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
level: Log level (debug, info, notice, warning, error, critical,
alert, emergency)
data: The data to be logged. Any JSON serializable type is allowed
(string, dict, list, number, bool, etc.) per the MCP specification.
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=data,
logger=logger_name,
related_request_id=self.request_id,
)
@ -261,20 +256,18 @@ class Context(BaseModel, Generic[LifespanContextT, RequestT]):
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) -> 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)
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) -> 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)
async def warning(
self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None
) -> None:
async def warning(self, data: 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", data, 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, data: 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", data, logger_name=logger_name)