fix(mcp): handle integer progressToken in host progress capture - #30977
fix(mcp): handle integer progressToken in host progress capture#30977pdecat wants to merge 1 commit into
Conversation
Greptile SummaryThis PR fixes a
Confidence Score: 5/5Safe to merge — the change is a single-character addition that eliminates log noise with no functional side effects. The fix is a minimal, targeted change to a debug log statement. Progress forwarding was already working correctly before the PR; only the log line was broken. The regression test is well-scoped, mock-only, and directly reproduces the failure condition. No existing tests are modified or weakened. No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/proxy/_experimental/mcp_server/server.py | One-line fix: wraps host_token in str() before slicing to handle integer progressToken values per MCP spec |
| tests/test_litellm/proxy/_experimental/mcp_server/test_mcp_server.py | Adds a focused regression test using mocks and SimpleNamespace to verify integer progressToken no longer triggers a spurious warning |
Reviews (2): Last reviewed commit: "fix(mcp): handle integer progressToken i..." | Re-trigger Greptile
Congrats! CodSpeed is installed 🎉
You will start to see performance impacts in the reports once the benchmarks are run from your default branch.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
@pdecat please rebase this PR to "litellm_internal_staging" |
Per the MCP spec, ProgressToken is `str | int`. The host progress
capture path logged the token with `f"...{host_token[:8]}..."`, which
raises `TypeError: 'int' object is not subscriptable` when a client
sends an integer progress token. The exception was swallowed by the
surrounding try/except and surfaced as a misleading "Could not capture
host progress context: 'int' object is not subscriptable" warning on
every such tool call.
The f-string is built eagerly regardless of log level, so the error
fired even with debug logging off. The progress callback itself is
assigned before the failing log line, so progress forwarding still
worked; the only effect was log noise.
Wrap the token in str() before slicing so both str and int tokens
format safely.
99fa128 to
cb7309c
Compare
|
@Sameerlite oops, rebase done! |
|
Thanks for the PR! The Greptile review is stale after the rebase — triggering a fresh pass. (The fork CI checks — Block fork dependency changes, Verify PR source branch, osv-scan — are standard fork limitations; no action needed on those.) |
|
This is causing issues in different MCP clients after upgrading to from v1.88.0 to v1.92.0. Can we merge with priority and include in the next release please? @tin-berri @Sameerlite |
|
Rebasing to fix conflicts... |
|
Actually, this is superseded by #32402 |
|
The first stable tag to include the fix from the other PR is v1.93.0 from 2026/07/18. |
|
okay that's great then, thank you |
Relevant issues
Fixes #30976
Type
🐛 Bug Fix
Changes
Per the MCP spec,
progressTokenisstring | integer(schema.json#L2302-L2308, represented asstr | intin the Python SDK).The host-progress-capture block in
litellm/proxy/_experimental/mcp_server/server.pylogged the token withf"...{host_token[:8]}...". The[:8]slice assumes a string, so an integer token raisesTypeError: 'int' object is not subscriptable. That exception was swallowed by the surroundingtry/exceptand surfaced as a misleadingCould not capture host progress contextwarning on every tool call from a client using an integer progress token.The f-string is built eagerly regardless of log level, so it fired even with debug logging off.
host_progress_callbackis assigned before the failing log line, so progress forwarding still worked — this was log noise only, no functional impact.This wraps the token in
str()before slicing so both string and integer tokens format safely, and adds a regression test that drives a tool call with an integerprogressTokenand asserts the warning is not emitted.Proof of Fix
The regression test reproduces the exact warning before the fix:
and passes after the fix: