Skip to content

fix(mcp): missing params in MCP tool call logs - #42660

Merged
justinpark merged 1 commit into
apache:masterfrom
justinpark:fix--missing-param-in-mcp-tool-log
Aug 3, 2026
Merged

fix(mcp): missing params in MCP tool call logs#42660
justinpark merged 1 commit into
apache:masterfrom
justinpark:fix--missing-param-in-mcp-tool-log

Conversation

@justinpark

Copy link
Copy Markdown
Member

SUMMARY

LoggingMiddleware and ResponseSizeGuardMiddleware extracted tool call parameters via getattr(context.message, "params", {}). The real MCP SDK type for a tools/call request (mcp.types.CallToolRequestParams) has no params attribute — it exposes name and arguments — so the getattr fallback always silently returned {}. As a result, every MCP tool call log recorded params: {} and dashboard_id/slice_id/dataset_id as null, regardless of what the caller actually sent, making the audit logs useless for debugging or analytics.

Fixed both call sites to read context.message.arguments instead. Also updated the existing unit test mocks, which had been setting context.message.params on MagicMock objects — mirroring the same wrong attribute name as the bug, which is why the regression went undetected — and added a regression test that constructs a real mcp.types.CallToolRequestParams object to catch this class of attribute-name mismatch going forward.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Before:

{"tool": "get_dashboard_info", "agent_id": null, "params": {}, "method": "tools/call", "dashboard_id": null,
  "slice_id": null, "dataset_id": null, "success": false}

After:

{"tool": "get_dashboard_info", "agent_id": null, "params": {"request": {"identifier": 286}}, "method": "tools/call", "dashboard_id": null, "slice_id": null, "dataset_id": null, "success": false}

TESTING INSTRUCTIONS

  • pytest tests/unit_tests/mcp_service/test_middleware.py tests/unit_tests/mcp_service/test_middleware_logging.py -q — all 124 tests pass, including the new regression test (verified it fails against the pre-fix code).
  • Manually verified end-to-end on a live dev pod: ran superset mcp run, called get_dashboard_info via a real MCP client, and confirmed via the logs table in the metadata DB that params now contains the actual call arguments (e.g. {"request": {"identifier": 286}}) instead of {}.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

@bito-code-review

bito-code-review Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #43ec0a

Actionable Suggestions - 0
Review Details
  • Files reviewed - 3 · Commit Range: 1414752..1414752
    • superset/mcp_service/middleware.py
    • tests/unit_tests/mcp_service/test_middleware.py
    • tests/unit_tests/mcp_service/test_middleware_logging.py
  • Files skipped - 0
  • Tools
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@dosubot dosubot Bot added the logging Creates a UI or API endpoint that could benefit from logging. label Jul 31, 2026
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.43%. Comparing base (0981b11) to head (1414752).
⚠️ Report is 5 commits behind head on master.

Files with missing lines Patch % Lines
superset/mcp_service/middleware.py 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #42660      +/-   ##
==========================================
- Coverage   65.45%   65.43%   -0.03%     
==========================================
  Files        2810     2810              
  Lines      159362   159422      +60     
  Branches    36374    36382       +8     
==========================================
+ Hits       104308   104315       +7     
- Misses      53012    53064      +52     
- Partials     2042     2043       +1     
Flag Coverage Δ
hive 38.07% <0.00%> (-0.02%) ⬇️
mysql 57.79% <0.00%> (-0.04%) ⬇️
postgres 57.84% <0.00%> (-0.04%) ⬇️
presto 39.96% <0.00%> (-0.03%) ⬇️
python 59.22% <0.00%> (-0.04%) ⬇️
sqlite 57.46% <0.00%> (-0.04%) ⬇️
unit 100.00% <ø> (ø)

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

☔ View full report in Codecov by Harness.
📢 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.

@aminghadersohi aminghadersohi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verified the fix at HEAD (1414752).

What's logged & sensitivity: the tool-call arguments dict flows only into event_logger curated_payload["params"] (actions mcp_tool_call / mcp_response_size_exceeded) — the human-readable logger.info line at middleware.py:428 still logs only tool/ids/duration, never params. Both param sites route through _sanitize_params, which masks password/token/api_key/secret/credentials/authorization/cookie (case-insensitive, recursing into nested arguments). Non-sensitive args (SQL, dataset ids, search terms) are captured, which is this middleware's intended audit purpose and stays within the operator log-sink trust boundary. No new secret-in-logs class.

Correctness: the real MCP CallToolRequestParams exposes tool args as .arguments, not .params, so the old getattr(context.message, "params", {}) always resolved to {} — params, dashboard_id, slice_id and dataset_id all logged empty. Swapping to .arguments at both sites fixes this; or {} still guards the falsy/None case. Not double-logged, correct field.

Tests: the new regression test uses the real mt.CallToolRequestParams SDK type (a MagicMock auto-vivifies .params and hides the bug), pinning params == {"dashboard_id": 7} and dashboard_id == 7. Confirmed it fails when the 2-line prod change is reverted. The .params.arguments churn in test_middleware.py is necessary mechanical alignment, not vacuous.

CI green (full run, all required checks pass; mergeable). No unresolved threads.

@justinpark
justinpark merged commit ac97484 into apache:master Aug 3, 2026
69 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

logging Creates a UI or API endpoint that could benefit from logging. size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants