fix(mcp): add dynamic response truncation for oversized info tool responses#39107
Conversation
When info tools (get_chart_info, get_dataset_info, get_dashboard_info, get_instance_info) return responses exceeding the token limit, the ResponseSizeGuardMiddleware now progressively truncates large fields instead of returning an error. Truncation is applied in four phases: 1. Truncate long string fields (description, css, sql) 2. Truncate large list fields (columns, metrics, charts) 3. Aggressively reduce lists and summarize large dicts 4. Replace all collections with summary markers This preserves partial data for the LLM client while staying within the token budget. Non-info tools (list tools, execute_sql) continue to be blocked with actionable error messages as before.
Code Review Agent Run #041747Actionable Suggestions - 0Filtered by Review RulesBito filtered these suggestions based on rules created automatically for your feedback. Manage rules.
Review Details
Bito Usage GuideCommands Type the following command in the pull request comment and save the comment.
Refer to the documentation for additional commands. Configuration This repository uses Documentation & Help |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #39107 +/- ##
==========================================
- Coverage 64.52% 64.46% -0.06%
==========================================
Files 2536 2536
Lines 131208 131324 +116
Branches 30457 30485 +28
==========================================
Hits 84661 84661
- Misses 45084 45200 +116
Partials 1463 1463
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR improves MCP “info” tool reliability by adding a progressive response-truncation fallback when responses exceed the configured token budget, so the middleware can return partial metadata instead of hard-blocking with an error.
Changes:
- Added
truncate_oversized_response()plus helper truncation phases intoken_utils.py, and introduced anINFO_TOOLSallowlist. - Updated
ResponseSizeGuardMiddlewareto attempt truncation for allowlisted info tools before raisingToolError, and to emit a newmcp_response_truncatedmonitoring event on success. - Added unit tests for truncation helpers and middleware integration tests covering truncation vs blocking behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
superset/mcp_service/utils/token_utils.py |
Adds INFO tool allowlist and progressive truncation helpers to fit oversized info responses within the token limit. |
superset/mcp_service/middleware.py |
Tries truncation for info tools before blocking, and logs mcp_response_truncated on successful truncation. |
tests/unit_tests/mcp_service/utils/test_token_utils.py |
Adds unit tests for truncation helpers and truncate_oversized_response(). |
tests/unit_tests/mcp_service/test_middleware.py |
Adds middleware tests ensuring info tools truncate while non-info tools still block. |
Address review feedback: do not append marker dicts into truncated lists as this breaks typed list contracts (e.g. List[TableColumnInfo]). Truncation metadata is communicated through top-level _truncation_notes instead. Also remove misleading "use select_columns" suggestion from truncation messages since info tools don't accept that parameter.
Add Phase 3 (recursive string truncation) to handle strings inside nested structures like charts[i].description, filter_state.dataMask, and native_filters[i].config that top-level truncation misses. Without this, a dashboard with 30 charts each having a 10KB description would still blow the token limit even after list truncation, because the strings inside each chart item were untouched. The recursive walker is depth-capped at 10 to prevent runaway recursion.
Code Review Agent Run #5a4c9aActionable Suggestions - 0Filtered by Review RulesBito filtered these suggestions based on rules created automatically for your feedback. Manage rules.
Review Details
Bito Usage GuideCommands Type the following command in the pull request comment and save the comment.
Refer to the documentation for additional commands. Configuration This repository uses Documentation & Help |
Summary
When MCP info tools (
get_chart_info,get_dataset_info,get_dashboard_info,get_instance_info) return responses exceeding the configured token limit, theResponseSizeGuardMiddlewarenow dynamically truncates large fields instead of blocking the response entirely with an error.Problem
Individual object responses from info tools can exceed the 25K token limit when they contain:
charts[i].descriptioninside dashboard responsesPreviously, these responses were completely blocked. But info tools don't support pagination, so the LLM client had no fallback.
Solution
Five-phase progressive truncation that preserves partial data while fitting within the token budget:
charts[i].description,filter_state.dataMask)Design decisions
List[TableColumnInfo]stays homogeneous)execute_sql,get_chart_data) continue to be blocked with actionable error messages — truncating tabular data would lose integrityjson_metadata/position_jsonat the schema level and usesDashboardChartSummaryinstead of fullChartInfo; this PR adds a safety net for anything that still exceeds limitsMonitoring
mcp_response_truncatedlogged when truncation succeeds (tool name, original/truncated token counts, which fields were truncated)_response_truncated: trueand_truncation_notesmetadataChanges
superset/mcp_service/utils/token_utils.py: Addedtruncate_oversized_response(),_truncate_strings_recursive(), and helper functionssuperset/mcp_service/middleware.py: Added_try_truncate_info_response()method toResponseSizeGuardMiddlewareTesting