mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 07:09:11 +02:00
Era-gate client.set_logging_level on modern connections
This commit is contained in:
parent
704b74b3ab
commit
fca339084b
2 changed files with 24 additions and 15 deletions
|
|
@ -1351,7 +1351,22 @@ class Client(
|
|||
)
|
||||
|
||||
async def set_logging_level(self, level: mcp_types.LoggingLevel) -> None:
|
||||
"""Send a logging/setLevel request."""
|
||||
"""Send a logging/setLevel request.
|
||||
|
||||
Handshake-era servers only. `logging/setLevel` asks the server to
|
||||
remember a level for the rest of the session, and the 2026-07-28
|
||||
protocol has no session to remember it in — the method is absent from
|
||||
that era's registry. Log *notifications* are unaffected: they ride the
|
||||
request's own stream, so a server's `ctx.info()` still reaches you.
|
||||
Filter by level on the receiving side instead, in your `log_handler`.
|
||||
"""
|
||||
if self.protocol_version in MODERN_PROTOCOL_VERSIONS:
|
||||
raise RuntimeError(
|
||||
"logging/setLevel is not available on MCP 2026-07-28 "
|
||||
"connections; the method requires per-session server state that "
|
||||
"the modern protocol does not have. Filter incoming log "
|
||||
"messages by level in your log_handler instead."
|
||||
)
|
||||
# Deprecated upstream in SDK v2 but deliberately kept per compat directive;
|
||||
# removed with the multi-round-trip follow-up.
|
||||
await self._await_with_session_monitoring(
|
||||
|
|
|
|||
|
|
@ -353,23 +353,17 @@ async def test_session_id_access_does_not_crash_on_modern(sessionless_server, mo
|
|||
|
||||
|
||||
@pytest.mark.parametrize("mode", MODERN_MODES)
|
||||
async def test_set_logging_level_does_not_crash_on_modern(sessionless_server, mode):
|
||||
"""logging/setLevel is a session-id-keyed, deprecated-at-2026 operation.
|
||||
On a sessionless modern in-memory connection it must degrade cleanly (either
|
||||
succeed as a no-op or raise a surfaced MCPError) rather than crash the
|
||||
connection. Characterization: capture whichever the current contract is.
|
||||
async def test_set_logging_level_is_era_gated_on_modern(sessionless_server, mode):
|
||||
"""`logging/setLevel` asks a server to remember a level for the session, and
|
||||
the modern era has no session — the method is absent from its registry. The
|
||||
FastMCP client says so plainly instead of no-opping or surfacing the SDK's
|
||||
opaque "Method not found", and the connection stays usable afterward.
|
||||
"""
|
||||
async with SDKClient(_server(sessionless_server), mode=mode) as client:
|
||||
outcome: str
|
||||
try:
|
||||
await client.set_logging_level("debug") # ty: ignore[deprecated]
|
||||
outcome = "ok"
|
||||
except MCPError:
|
||||
outcome = "mcperror"
|
||||
# Either way the connection is still usable afterward.
|
||||
async with FastMCPClient(sessionless_server, mode=mode) as client:
|
||||
with pytest.raises(RuntimeError, match="2026-07-28"):
|
||||
await client.set_logging_level("debug")
|
||||
result = await client.call_tool("read_session_id", {})
|
||||
assert result.is_error is False
|
||||
assert outcome in {"ok", "mcperror"}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue