mcp(fix[wait]): Stop using the deprecated MCP Logging capability - #110
mcp(fix[wait]): Stop using the deprecated MCP Logging capability#110tony wants to merge 2 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #110 +/- ##
==========================================
+ Coverage 86.08% 86.10% +0.02%
==========================================
Files 46 46
Lines 3593 3584 -9
Branches 516 515 -1
==========================================
- Hits 3093 3086 -7
+ Misses 355 354 -1
+ Partials 145 144 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
a2d5718 to
5dbc028
Compare
Code reviewFound 2 issues:
Every prior deliverable in the file carries its own ref, added before merge — Lines 20 to 26 in 5dbc028
Precedent in the same file: Lines 22 to 25 in 5dbc028 Checked and not flagged: no correctness bugs. Both Separately, |
5dbc028 to
9fae3b2
Compare
why: MCP deprecated the protocol-level Logging capability in SEP-2577, effective revision 2026-07-28, naming stderr as the migration path for stdio servers. wait_for_text was the only place this server exercised it -- three ctx.warning calls reaching the wire as notifications/message. The `logging` capability itself is advertised by FastMCP's handshake, not by us; these three call sites are the only part that is ours to remove. Note FastMCP will not flag this for us. In 4.0.0a2 ctx.sample() emits a warn-once FastMCPDeprecationWarning, but the logging path carries only a static `# ty: ignore[deprecated]` on send_log_message and warns nothing at runtime, so an SDK upgrade would keep this working silently until the multi-round-trip follow-up removes it. what: - Drop _maybe_log; warn through the module logger already at wait.py:36 - Make _compile_patterns synchronous now that it awaits nothing, and drop the ctx argument from both call sites - Leave ctx.report_progress alone; progress is not deprecated and the 2026-07-28 draft keeps it on the request's response stream - Move four tests onto caplog and drop the two stub Context.warning methods the tool no longer calls - Correct the one wait_for_text doc sentence naming the old mechanism
why: The channel change is visible to any client that subscribed to MCP log notifications, and it supersedes an explicit promise in the 0.1.0a19 notes that the trim-risk signal is "delivered only as an MCP warning notification". what: - Add a breaking-changes entry and a matching MIGRATION section
9fae3b2 to
f78baac
Compare
Closes #109.
MCP deprecated the protocol-level Logging capability in SEP-2577, effective with the
2026-07-28revision, naming stderr as the migration path for stdio servers.wait_for_textwas the only place this server exercised it: threectx.warningcalls reaching the wire asnotifications/message. They are now ordinarylibtmux_mcp.*log records.Scoped to exactly that. The
loggingcapability is advertised by FastMCP's own handshake, not by anything in this repo — the three call sites are the only part that is ours to remove.Checked against the full registry
All six entries in the deprecated features registry, against
src/andtests/:wait.py:434,:730,:838via_maybe_logincludeContext: "thisServer"/"allServers"include_context=Falsehit is pydantic'sValidationError.errors()fastmcp.json:9,server.py:468)FastMCP will not flag this for you
Worth recording, because it rules out waiting for a warning. In
fastmcp4.0.0a2 the two SEP-2577 features are handled differently:ctx.sample()emits a warn-onceFastMCPDeprecationWarning(fastmcp_slim/fastmcp/server/context.py:113, fired at:1092and:1209).send_log_messagecarries only a static# ty: ignore[deprecated](context.py:1659) with the comment "Deprecated upstream in SDK v2 but deliberately kept per compat directive; removed with the multi-round-trip follow-up."So an SDK upgrade would keep these three calls working silently until MRTR removes them. This was findable only by reading the registry.
Behavior
ctx.report_progressis untouched — progress is not deprecated, and the2026-07-28draft explicitly keeps it flowing on the response stream of the request it relates to.No result field was added. Two of the three warnings are already in the tool result — an invalid regex raises a tool error carrying the identical text, and a timeout is
outcome == "timeout". The third, the history-limit trim-risk band, is a diagnostic;WaitForTextResultdocuments field count as load-bearing (outputSchemais re-sent every request), so a field no agent branches on would be a permanent tax._compile_patternsbecomes synchronous, since removing theawaitleft it with nothing to await.Verification
ruff check,ruff format --check,mypy(65 files),pytest --reruns 0(801 passed),just build-docsclean.The four migrated tests were checked with a negative control rather than trusted for passing: removing the timeout
logger.warningfrom the source turnstest_wait_for_text_warns_on_timeoutred withmessages = []. Note for future readers —caplog.at_level(..., logger=...)does not scope capture (records reachcaplog.recordsby propagation to root), so aiming the fixture at a bogus logger name does not fail these tests. Thelogger=argument is kept for level-setting and to match the suite's convention.