Skip to content

Commit 7ee2e0d

Browse files
committed
Deprecate Connection.log for consistency with the logging capability
Address PR review: `Connection.log()` sends the same `notifications/message` the logging capability covers and `Context.log`'s docstring steers users to it, so it now carries the same SEP-2577 `@deprecated` marker. Its two test call sites get `# pyright: ignore[reportDeprecated]`, and the migration guide lists it among the deprecated logging entry points.
1 parent 8cfdd44 commit 7ee2e0d

14 files changed

Lines changed: 52 additions & 46 deletions

File tree

README.v2.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ mcp = MCPServer(name="Progress Example")
360360
@mcp.tool()
361361
async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str:
362362
"""Execute a task with progress updates."""
363-
await ctx.info(f"Starting: {task_name}")
363+
await ctx.info(f"Starting: {task_name}") # pyright: ignore[reportDeprecated]
364364

365365
for i in range(steps):
366366
progress = (i + 1) / steps
@@ -369,7 +369,7 @@ async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str
369369
total=1.0,
370370
message=f"Step {i + 1}/{steps}",
371371
)
372-
await ctx.debug(f"Completed step {i + 1}")
372+
await ctx.debug(f"Completed step {i + 1}") # pyright: ignore[reportDeprecated]
373373

374374
return f"Task '{task_name}' completed"
375375
```
@@ -707,7 +707,7 @@ mcp = MCPServer(name="Progress Example")
707707
@mcp.tool()
708708
async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str:
709709
"""Execute a task with progress updates."""
710-
await ctx.info(f"Starting: {task_name}")
710+
await ctx.info(f"Starting: {task_name}") # pyright: ignore[reportDeprecated]
711711

712712
for i in range(steps):
713713
progress = (i + 1) / steps
@@ -716,7 +716,7 @@ async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str
716716
total=1.0,
717717
message=f"Step {i + 1}/{steps}",
718718
)
719-
await ctx.debug(f"Completed step {i + 1}")
719+
await ctx.debug(f"Completed step {i + 1}") # pyright: ignore[reportDeprecated]
720720

721721
return f"Task '{task_name}' completed"
722722
```
@@ -982,10 +982,10 @@ mcp = MCPServer(name="Notifications Example")
982982
async def process_data(data: str, ctx: Context) -> str:
983983
"""Process data with logging."""
984984
# Different log levels
985-
await ctx.debug(f"Debug: Processing '{data}'")
986-
await ctx.info("Info: Starting processing")
987-
await ctx.warning("Warning: This is experimental")
988-
await ctx.error("Error: (This is just a demo)")
985+
await ctx.debug(f"Debug: Processing '{data}'") # pyright: ignore[reportDeprecated]
986+
await ctx.info("Info: Starting processing") # pyright: ignore[reportDeprecated]
987+
await ctx.warning("Warning: This is experimental") # pyright: ignore[reportDeprecated]
988+
await ctx.error("Error: (This is just a demo)") # pyright: ignore[reportDeprecated]
989989

990990
# Notify about resource changes
991991
await ctx.session.send_resource_list_changed()

docs/migration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1224,7 +1224,7 @@ The user-facing methods for these features now carry `typing_extensions.deprecat
12241224

12251225
- Sampling: `ServerSession.create_message()`, `ClientPeer.sample()`
12261226
- Roots: `ServerSession.list_roots()`, `ClientPeer.list_roots()`, `ClientSession.send_roots_list_changed()`, `Client.send_roots_list_changed()`
1227-
- Logging: `ServerSession.send_log_message()`, `ClientSession.set_logging_level()`, `Client.set_logging_level()`, and `MCPServer` `Context.log()`. The `Context.debug()` / `info()` / `warning()` / `error()` helpers delegate to `log()`, so they warn through it rather than carrying their own marker.
1227+
- Logging: `ServerSession.send_log_message()`, `Connection.log()`, `ClientSession.set_logging_level()`, `Client.set_logging_level()`, and the `MCPServer` `Context` helpers `log()`, `debug()`, `info()`, `warning()`, `error()`
12281228

12291229
The runtime warning is emitted as `mcp.MCPDeprecationWarning`, which subclasses `UserWarning` (not `DeprecationWarning`) so it is visible by default. To silence it, filter that category:
12301230

examples/servers/everything-server/mcp_everything_server/server.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,13 @@ def test_multiple_content_types() -> list[TextContent | ImageContent | EmbeddedR
143143
@mcp.tool()
144144
async def test_tool_with_logging(ctx: Context) -> str:
145145
"""Tests tool that emits log messages during execution"""
146-
await ctx.info("Tool execution started")
146+
await ctx.info("Tool execution started") # pyright: ignore[reportDeprecated]
147147
await asyncio.sleep(0.05)
148148

149-
await ctx.info("Tool processing data")
149+
await ctx.info("Tool processing data") # pyright: ignore[reportDeprecated]
150150
await asyncio.sleep(0.05)
151151

152-
await ctx.info("Tool execution completed")
152+
await ctx.info("Tool execution completed") # pyright: ignore[reportDeprecated]
153153
return "Tool with logging executed successfully"
154154

155155

@@ -314,13 +314,13 @@ def test_error_handling() -> str:
314314
@mcp.tool()
315315
async def test_reconnection(ctx: Context) -> str:
316316
"""Tests SSE polling by closing stream mid-call (SEP-1699)"""
317-
await ctx.info("Before disconnect")
317+
await ctx.info("Before disconnect") # pyright: ignore[reportDeprecated]
318318

319319
await ctx.close_sse_stream()
320320

321321
await asyncio.sleep(0.2) # Wait for client to reconnect
322322

323-
await ctx.info("After reconnect")
323+
await ctx.info("After reconnect") # pyright: ignore[reportDeprecated]
324324
return "Reconnection test completed"
325325

326326

examples/snippets/servers/notifications.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
async def process_data(data: str, ctx: Context) -> str:
88
"""Process data with logging."""
99
# Different log levels
10-
await ctx.debug(f"Debug: Processing '{data}'")
11-
await ctx.info("Info: Starting processing")
12-
await ctx.warning("Warning: This is experimental")
13-
await ctx.error("Error: (This is just a demo)")
10+
await ctx.debug(f"Debug: Processing '{data}'") # pyright: ignore[reportDeprecated]
11+
await ctx.info("Info: Starting processing") # pyright: ignore[reportDeprecated]
12+
await ctx.warning("Warning: This is experimental") # pyright: ignore[reportDeprecated]
13+
await ctx.error("Error: (This is just a demo)") # pyright: ignore[reportDeprecated]
1414

1515
# Notify about resource changes
1616
await ctx.session.send_resource_list_changed()

examples/snippets/servers/tool_progress.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
@mcp.tool()
77
async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str:
88
"""Execute a task with progress updates."""
9-
await ctx.info(f"Starting: {task_name}")
9+
await ctx.info(f"Starting: {task_name}") # pyright: ignore[reportDeprecated]
1010

1111
for i in range(steps):
1212
progress = (i + 1) / steps
@@ -15,6 +15,6 @@ async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str
1515
total=1.0,
1616
message=f"Step {i + 1}/{steps}",
1717
)
18-
await ctx.debug(f"Completed step {i + 1}")
18+
await ctx.debug(f"Completed step {i + 1}") # pyright: ignore[reportDeprecated]
1919

2020
return f"Task '{task_name}' completed"

src/mcp/server/connection.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020

2121
import anyio
2222
from pydantic import BaseModel
23+
from typing_extensions import deprecated
2324

2425
from mcp.shared.dispatcher import CallOptions, Outbound
25-
from mcp.shared.exceptions import NoBackChannelError
26+
from mcp.shared.exceptions import MCPDeprecationWarning, NoBackChannelError
2627
from mcp.shared.peer import Meta, dump_params
2728
from mcp.types import (
2829
ClientCapabilities,
@@ -209,6 +210,7 @@ async def ping(self, *, meta: Meta | None = None, opts: CallOptions | None = Non
209210
"""
210211
await self.send_raw_request("ping", dump_params(None, meta), opts)
211212

213+
@deprecated("The logging capability is deprecated as of 2026-07-28 (SEP-2577).", category=MCPDeprecationWarning)
212214
async def log(self, level: LoggingLevel, data: Any, logger: str | None = None, *, meta: Meta | None = None) -> None:
213215
"""Send a `notifications/message` log entry on the standalone stream. Best-effort."""
214216
params: dict[str, Any] = {"level": level, "data": data}

src/mcp/server/mcpserver/context.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,18 +268,22 @@ async def close_standalone_sse_stream(self) -> None:
268268
await self._request_context.close_standalone_sse_stream()
269269

270270
# Convenience methods for common log levels
271+
@deprecated("The logging capability is deprecated as of 2026-07-28 (SEP-2577).", category=MCPDeprecationWarning)
271272
async def debug(self, data: Any, *, logger_name: str | None = None) -> None:
272273
"""Send a debug log message."""
273274
await self.log("debug", data, logger_name=logger_name) # pyright: ignore[reportDeprecated]
274275

276+
@deprecated("The logging capability is deprecated as of 2026-07-28 (SEP-2577).", category=MCPDeprecationWarning)
275277
async def info(self, data: Any, *, logger_name: str | None = None) -> None:
276278
"""Send an info log message."""
277279
await self.log("info", data, logger_name=logger_name) # pyright: ignore[reportDeprecated]
278280

281+
@deprecated("The logging capability is deprecated as of 2026-07-28 (SEP-2577).", category=MCPDeprecationWarning)
279282
async def warning(self, data: Any, *, logger_name: str | None = None) -> None:
280283
"""Send a warning log message."""
281284
await self.log("warning", data, logger_name=logger_name) # pyright: ignore[reportDeprecated]
282285

286+
@deprecated("The logging capability is deprecated as of 2026-07-28 (SEP-2577).", category=MCPDeprecationWarning)
283287
async def error(self, data: Any, *, logger_name: str | None = None) -> None:
284288
"""Send an error log message."""
285289
await self.log("error", data, logger_name=logger_name) # pyright: ignore[reportDeprecated]

tests/interaction/mcpserver/test_context.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ async def test_context_logging_helpers_send_log_notifications(connect: Connect)
4141

4242
@mcp.tool()
4343
async def narrate(ctx: Context) -> str:
44-
await ctx.debug("d")
45-
await ctx.info("i")
46-
await ctx.warning("w")
47-
await ctx.error("e")
44+
await ctx.debug("d") # pyright: ignore[reportDeprecated]
45+
await ctx.info("i") # pyright: ignore[reportDeprecated]
46+
await ctx.warning("w") # pyright: ignore[reportDeprecated]
47+
await ctx.error("e") # pyright: ignore[reportDeprecated]
4848
return "done"
4949

5050
async def collect(params: LoggingMessageNotificationParams) -> None:
@@ -136,7 +136,7 @@ async def test_report_progress_without_a_progress_token_sends_nothing(connect: C
136136
@mcp.tool()
137137
async def mill(ctx: Context) -> str:
138138
await ctx.report_progress(1, 3)
139-
await ctx.info("milling done")
139+
await ctx.info("milling done") # pyright: ignore[reportDeprecated]
140140
return "milled"
141141

142142
async def collect(message: IncomingMessage) -> None:
@@ -250,8 +250,8 @@ async def test_set_logging_level_is_rejected_and_messages_are_never_filtered(con
250250

251251
@mcp.tool()
252252
async def chatter(ctx: Context) -> str:
253-
await ctx.debug("noise")
254-
await ctx.error("signal")
253+
await ctx.debug("noise") # pyright: ignore[reportDeprecated]
254+
await ctx.error("signal") # pyright: ignore[reportDeprecated]
255255
return "done"
256256

257257
async def collect(params: LoggingMessageNotificationParams) -> None:

tests/interaction/mcpserver/test_tools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ def doomed() -> str:
414414
async def grow(ctx: Context) -> str:
415415
mcp.add_tool(extra, name="extra")
416416
mcp.remove_tool("doomed")
417-
await ctx.info("tool set changed")
417+
await ctx.info("tool set changed") # pyright: ignore[reportDeprecated]
418418
return "mutated"
419419

420420
async def collect(message: IncomingMessage) -> None:

tests/interaction/transports/test_flows.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ async def test_concurrent_clients_on_one_stateful_server_receive_only_their_own_
3232
@mcp.tool()
3333
async def announce(label: str, ctx: Context) -> str:
3434
"""Emit one info-level log carrying the caller's label, then return it."""
35-
await ctx.info(label)
35+
await ctx.info(label) # pyright: ignore[reportDeprecated]
3636
return label
3737

3838
received_a: list[object] = []

0 commit comments

Comments
 (0)