Skip to content

fix(mcp): prevent encoding error on tools/list when middleware raises#40446

Merged
aminghadersohi merged 4 commits into
apache:masterfrom
aminghadersohi:amin/fix-mcp-list-tools-encoding
May 26, 2026
Merged

fix(mcp): prevent encoding error on tools/list when middleware raises#40446
aminghadersohi merged 4 commits into
apache:masterfrom
aminghadersohi:amin/fix-mcp-list-tools-encoding

Conversation

@aminghadersohi
Copy link
Copy Markdown
Contributor

Summary

StructuredContentStripperMiddleware.on_list_tools had no exception handling. When inner middleware raises ToolError, it propagated to the MCP SDK layer which cannot encode a ToolError as a tools/list response — producing the cryptic "encoding without a string argument" error visible to Claude.ai users across all MCP tools simultaneously.

Fix: wrap the call_next call in on_list_tools with try/except and return [] on any exception. GlobalErrorHandlerMiddleware already logs and records event_logger entries for the underlying error, so no observability is lost.

Note: on_call_tool already had this protection — on_list_tools was the remaining unguarded path.

Changes

  • superset/mcp_service/middleware.py — add try/except to StructuredContentStripperMiddleware.on_list_tools, return [] on exception
  • tests/unit_tests/mcp_service/test_middleware_logging.py — new test test_list_tools_exception_returns_empty_list exercises the full middleware chain

Testing

All 15 middleware tests pass including the new one.

pytest tests/unit_tests/mcp_service/test_middleware_logging.py -v
# 15 passed in 0.80s

@aminghadersohi aminghadersohi requested a review from Copilot May 26, 2026 15:20
@aminghadersohi aminghadersohi marked this pull request as ready for review May 26, 2026 15:21
@aminghadersohi aminghadersohi marked this pull request as draft May 26, 2026 15:22
@dosubot dosubot Bot added the change:backend Requires changing the backend label May 26, 2026
@netlify
Copy link
Copy Markdown

netlify Bot commented May 26, 2026

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit df9b623
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a15bae2c4fffa0008b0a1cc
😎 Deploy Preview https://deploy-preview-40446--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@aminghadersohi aminghadersohi force-pushed the amin/fix-mcp-list-tools-encoding branch from 541fe01 to df9b623 Compare May 26, 2026 15:23
StructuredContentStripperMiddleware.on_list_tools had no exception
handling. When inner middleware (GlobalErrorHandlerMiddleware.on_message)
raises ToolError, it propagated uncaught to the MCP SDK layer. The SDK
cannot encode a ToolError as a tools/list response, producing the cryptic
"encoding without a string argument" error visible to Claude.ai users.

Fix: wrap the inner call in try/except and return [] on any exception.
GlobalErrorHandlerMiddleware already logs and records event_logger entries
for the underlying error, so no observability is lost.

Also adds a unit test that exercises the full middleware chain and asserts
the empty-list fallback.
@aminghadersohi aminghadersohi force-pushed the amin/fix-mcp-list-tools-encoding branch from df9b623 to e8643a2 Compare May 26, 2026 15:29
The duckdb 1.4.2→1.5.3 change in requirements/development.txt is an
upstream maintenance task unrelated to this fix. It belongs in a
separate PR.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens Superset’s MCP middleware stack to avoid MCP SDK transport encoding failures when tools/list encounters an exception (notably when inner middleware raises ToolError), by ensuring tools/list always returns a list-shaped response.

Changes:

  • Add exception handling to StructuredContentStripperMiddleware.on_list_tools to return [] when call_next raises.
  • Add a unit test exercising the real middleware chain to confirm exceptions during tools/list produce [].
  • Update the pinned dev dependency duckdb version in requirements/development.txt.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
superset/mcp_service/middleware.py Wrap on_list_tools middleware call with try/except and return an empty list on failure to prevent transport encoding errors.
tests/unit_tests/mcp_service/test_middleware_logging.py Add test covering the tools/list exception path through the real middleware chain.
requirements/development.txt Bump duckdb pinned version in dev requirements.

Comment thread requirements/development.txt Outdated
@bito-code-review
Copy link
Copy Markdown
Contributor

The comment in the PR suggests that the duckdb version bump in requirements/development.txt may be accidental, as this file is autogenerated and pinned. The user is advised to ensure the upgrade is intentional and to update inputs like requirements/*.in or pyproject.toml before re-running the script to maintain consistency.

pyproject.toml was missing from the change-detector python patterns,
so check-python-deps was silently skipped on pyproject.toml-only PRs.
This means dependency bumps in pyproject.toml could land without
regenerating requirements/development.txt, leaving them out of sync.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 26, 2026

Codecov Report

❌ Patch coverage is 0% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.19%. Comparing base (8b551d3) to head (f122bb4).

Files with missing lines Patch % Lines
superset/mcp_service/middleware.py 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #40446      +/-   ##
==========================================
- Coverage   64.20%   64.19%   -0.01%     
==========================================
  Files        2592     2592              
  Lines      139226   139229       +3     
  Branches    32326    32326              
==========================================
  Hits        89385    89385              
- Misses      48306    48309       +3     
  Partials     1535     1535              
Flag Coverage Δ
hive 39.24% <0.00%> (-0.01%) ⬇️
mysql 58.76% <0.00%> (-0.01%) ⬇️
postgres 58.84% <0.00%> (-0.01%) ⬇️
presto 40.92% <0.00%> (-0.01%) ⬇️
python 60.39% <0.00%> (-0.01%) ⬇️
sqlite 58.48% <0.00%> (-0.01%) ⬇️
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions Bot added the risk:ci-script PR modifies scripts that execute in CI (supply chain risk) label May 26, 2026
Runs uv-pip-compile.sh to sync requirements/development.txt with
pyproject.toml after duckdb was bumped from 1.4.2 to 1.5.2 in apache#40381
but requirements were not regenerated.
Copy link
Copy Markdown
Member

@kgabryje kgabryje left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@aminghadersohi aminghadersohi merged commit 952a6f3 into apache:master May 26, 2026
79 of 97 checks passed
@bito-code-review
Copy link
Copy Markdown
Contributor

Bito Automatic Review Skipped – PR Already Merged

Bito scheduled an automatic review for this pull request, but the review was skipped because this PR was merged before the review could be run.
No action is needed if you didn't intend to review it. To get a review, you can type /review in a comment and save it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:backend Requires changing the backend risk:ci-script PR modifies scripts that execute in CI (supply chain risk) size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants