Skip to content

Commit 4d4641e

Browse files
author
Architect
committed
Fix: Allow Any type in logging methods per MCP spec (issue #397)
- Changed message: str to data: Any in ctx.info(), ctx.debug(), ctx.warning(), ctx.error() - Updated log() method to accept Any type for data parameter - Now compliant with MCP spec which allows any JSON serializable type - Updated example to demonstrate logging objects and arrays
1 parent 7ba41dc commit 4d4641e

File tree

2 files changed

+17
-14
lines changed

2 files changed

+17
-14
lines changed

examples/mcpserver/logging_and_progress.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
async def echo(text: str, ctx: Context) -> str:
1313
"""Echo the input text sending log messages and progress updates during processing."""
1414
await ctx.report_progress(progress=0, total=100)
15-
await ctx.info("Starting to process echo for input: " + text)
15+
16+
# Test logging with objects (not just strings) - now valid per MCP spec
17+
await ctx.info({"status": "starting", "input_length": len(text), "text": text})
1618

1719
await asyncio.sleep(2)
1820

@@ -21,7 +23,8 @@ async def echo(text: str, ctx: Context) -> str:
2123

2224
await asyncio.sleep(2)
2325

24-
await ctx.info("Finished processing echo for input: " + text)
26+
# Test logging with a list
27+
await ctx.info(["processing", "complete", "returning"])
2528
await ctx.report_progress(progress=100, total=100)
2629

2730
# Progress notifications are process asynchronously by the client.

src/mcp/server/mcpserver/context.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ async def elicit_url(
187187
async def log(
188188
self,
189189
level: Literal["debug", "info", "warning", "error"],
190-
message: str,
190+
data: Any,
191191
*,
192192
logger_name: str | None = None,
193193
extra: dict[str, Any] | None = None,
@@ -196,15 +196,15 @@ async def log(
196196
197197
Args:
198198
level: Log level (debug, info, warning, error)
199-
message: Log message
199+
data: The data to be logged, such as a string message or an object. Any JSON serializable type is allowed.
200200
logger_name: Optional logger name
201201
extra: Optional dictionary with additional structured data to include
202202
"""
203203

204204
if extra:
205-
log_data = {"message": message, **extra}
205+
log_data = {"message": data, **extra}
206206
else:
207-
log_data = message
207+
log_data = data
208208

209209
await self.request_context.session.send_log_message(
210210
level=level,
@@ -261,20 +261,20 @@ async def close_standalone_sse_stream(self) -> None:
261261
await self._request_context.close_standalone_sse_stream()
262262

263263
# Convenience methods for common log levels
264-
async def debug(self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None:
264+
async def debug(self, data: Any, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None:
265265
"""Send a debug log message."""
266-
await self.log("debug", message, logger_name=logger_name, extra=extra)
266+
await self.log("debug", data, logger_name=logger_name, extra=extra)
267267

268-
async def info(self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None:
268+
async def info(self, data: Any, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None:
269269
"""Send an info log message."""
270-
await self.log("info", message, logger_name=logger_name, extra=extra)
270+
await self.log("info", data, logger_name=logger_name, extra=extra)
271271

272272
async def warning(
273-
self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None
273+
self, data: Any, *, logger_name: str | None = None, extra: dict[str, Any] | None = None
274274
) -> None:
275275
"""Send a warning log message."""
276-
await self.log("warning", message, logger_name=logger_name, extra=extra)
276+
await self.log("warning", data, logger_name=logger_name, extra=extra)
277277

278-
async def error(self, message: str, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None:
278+
async def error(self, data: Any, *, logger_name: str | None = None, extra: dict[str, Any] | None = None) -> None:
279279
"""Send an error log message."""
280-
await self.log("error", message, logger_name=logger_name, extra=extra)
280+
await self.log("error", data, logger_name=logger_name, extra=extra)

0 commit comments

Comments
 (0)