Skip to content

feat(mcp): deleted_state trash listing for list_charts and list_dashboards#41855

Open
gkneighb wants to merge 1 commit into
apache:masterfrom
gkneighb:feat/mcp-deleted-state-list-filter
Open

feat(mcp): deleted_state trash listing for list_charts and list_dashboards#41855
gkneighb wants to merge 1 commit into
apache:masterfrom
gkneighb:feat/mcp-deleted-state-list-filter

Conversation

@gkneighb

@gkneighb gkneighb commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

Adds a deleted_state parameter ("include" / "only") to the list_charts and list_dashboards MCP tools, mirroring the REST chart_deleted_state / dashboard_deleted_state rison filters introduced with soft-delete (#40128 / #40129). Without it, an MCP client has no way to enumerate trashed objects — which makes trash effectively invisible to LLM agents (and unrestorable, once restore tools land: #41842).

Design notes:

  • The REST filter classes are reused, not reimplemented. ChartDeletedStateFilter / DashboardDeletedStateFilter own the restore-audience scoping (only owners — or admins — may enumerate soft-deleted rows). ModelListCore passes them through BaseDAO.list's existing custom_filters hook via a small DeletedStateBoundFilter adapter, because the DAO invokes custom filters as apply(query, None) and the FAB filter treats None as "live rows only" — the adapter binds the caller's actual value. Keeping the audience scoping in one class means the cross-entity deleted-state contract can't drift between REST and MCP.
  • Session-scoped visibility bypass via the skip_visibility_filter context manager. The soft-delete ORM listener appends deleted_at IS NULL at execution time, and BaseDAO.list executes twice (count + fetch), so a per-query bypass is not enough. The context manager guarantees release even on exceptions, so code running later in the same request sees normal filtered visibility — the same scope-discipline the REST layer implements via SoftDeleteApiMixin.
  • deleted_at is forced into loaded columns whenever deleted_state is used (and added to the ChartInfo/DashboardInfo schemas + serializers), so trashed rows are distinguishable from live ones in include mode.
  • Resources whose ModelListCore doesn't configure a deleted-state filter reject the parameter with a clear error.

Part of a series filling out MCP resource-lifecycle coverage (delete: #41472, restore: #41842).

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

N/A (MCP service tools; no UI changes)

TESTING INSTRUCTIONS

Unit tests (10 new):

pytest tests/unit_tests/mcp_service/chart/tool/test_list_charts_deleted_state.py \
       tests/unit_tests/mcp_service/dashboard/tool/test_list_dashboards_deleted_state.py \
       tests/unit_tests/mcp_service/test_mcp_core.py

The underlying filter semantics (audience scoping, include/only behavior) are covered by the existing REST integration suite (tests/integration_tests/charts/soft_delete_tests.py), and the skip_visibility_filter context manager by tests/unit_tests/models/test_soft_delete_mixin.py — this PR reuses both mechanisms rather than duplicating them.

Manual: with FEATURE_FLAGS = {"SOFT_DELETE": True}, delete a chart you own, then call list_charts with {"deleted_state": "only"} — the trashed chart is returned with a non-null deleted_at. As a non-admin, another user's trashed charts do not appear.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags: SOFT_DELETE (to produce trashed rows; the parameter itself is not gated)
  • 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

🤖 Generated with Claude Code

https://claude.ai/code/session_014z1fQxTadTEvpCJLx9WnB8

…oards

Expose the soft-delete trash (apache#40128, apache#40129) to MCP list tools via a
deleted_state param ('include'/'only'). Reuses the REST
Chart/DashboardDeletedStateFilter classes — which own the restore-
audience scoping (owners or admins only) — through BaseDAO.list's
custom_filters hook, with a DeletedStateBoundFilter adapter binding the
caller's value since the DAO invokes custom filters with value=None.
The DAO call is wrapped in the skip_visibility_filter context manager
so the soft-delete ORM listener is bypassed for both the count and
fetch executions, with guaranteed release. deleted_at is forced into
loaded columns and added to ChartInfo/DashboardInfo so trashed rows
are distinguishable in 'include' mode. 10 unit tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014z1fQxTadTEvpCJLx9WnB8
@dosubot dosubot Bot added api Related to the REST API dashboard Namespace | Anything related to the Dashboard labels Jul 7, 2026
@bito-code-review

bito-code-review Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #811aea

Actionable Suggestions - 0
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset/mcp_service/app.py - 1
Review Details
  • Files reviewed - 11 · Commit Range: 8eb3b58..8eb3b58
    • superset/mcp_service/app.py
    • superset/mcp_service/chart/schemas.py
    • superset/mcp_service/chart/tool/list_charts.py
    • superset/mcp_service/dashboard/schemas.py
    • superset/mcp_service/dashboard/tool/list_dashboards.py
    • superset/mcp_service/mcp_core.py
    • tests/unit_tests/mcp_service/chart/tool/test_generate_chart.py
    • tests/unit_tests/mcp_service/chart/tool/test_list_charts_deleted_state.py
    • tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_tools.py
    • tests/unit_tests/mcp_service/dashboard/tool/test_list_dashboards_deleted_state.py
    • tests/unit_tests/mcp_service/test_mcp_core.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

@github-actions github-actions Bot removed the api Related to the REST API label Jul 7, 2026


@pytest.fixture(autouse=True)
def mock_auth():

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.

Suggestion: Add an explicit return type hint to this fixture function so it complies with the required type-annotation rule. [custom_rule]

Severity Level: Minor ⚠️

Why it matters? 🤔

The new fixture function mock_auth omits a return type annotation, which violates the Python type-hint requirement for newly added or modified functions that can be annotated.

Rule source 📖

.cursor/rules/dev-standard.mdc (line 28)

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** tests/unit_tests/mcp_service/dashboard/tool/test_list_dashboards_deleted_state.py
**Line:** 45:45
**Comment:**
	*Custom Rule: Add an explicit return type hint to this fixture function so it complies with the required type-annotation rule.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +395 to +403
dao_kwargs = {
"filters": filters,
"order_column": order_column or "changed_on",
"order_direction": str(order_direction or "desc"),
"page": page,
"page_size": page_size,
"search": search,
"columns_to_load": columns_to_load,
}

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.

Suggestion: Add an explicit type annotation to this dictionary to satisfy the type-hint requirement for relevant local variables. [custom_rule]

Severity Level: Minor ⚠️

Why it matters? 🤔

This is a newly introduced local dictionary in Python code and it has no explicit type annotation. That matches the rule requiring type hints for relevant variables that can be annotated, so the suggestion is valid.

Rule source 📖

.cursor/rules/dev-standard.mdc (line 28)

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset/mcp_service/mcp_core.py
**Line:** 395:403
**Comment:**
	*Custom Rule: Add an explicit type annotation to this dictionary to satisfy the type-hint requirement for relevant local variables.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

return mcp


@pytest.fixture(autouse=True)

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.

Suggestion: Add an explicit return type hint to this fixture function (for example, a generator/yield-compatible return annotation) to satisfy required Python typing. [custom_rule]

Severity Level: Minor ⚠️

Why it matters? 🤔

The rule requires new or modified Python functions to include type hints when they can be annotated. This fixture function is defined without any return type annotation, so the suggestion correctly identifies a real violation.

Rule source 📖

.cursor/rules/dev-standard.mdc (line 28)

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** tests/unit_tests/mcp_service/chart/tool/test_list_charts_deleted_state.py
**Line:** 47:47
**Comment:**
	*Custom Rule: Add an explicit return type hint to this fixture function (for example, a generator/yield-compatible return annotation) to satisfy required Python typing.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@bito-code-review

Copy link
Copy Markdown
Contributor

The suggestion to add an explicit return type hint to the fixture function is correct and aligns with standard Python type-annotation practices. To resolve this, you should update the function signature to include the appropriate return type, for example: def mock_auth() -> Any:.

Regarding other comments on this PR, I have checked the available review data, and there are no additional comments recorded in the provided review file. Therefore, no further fixes are required at this time.

tests/unit_tests/mcp_service/dashboard/tool/test_list_dashboards_deleted_state.py

@pytest.fixture
def mock_auth() -> Any:
    # ... implementation ...

@netlify

netlify Bot commented Jul 7, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 8eb3b58
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a4d20ed5770f400084058a3
😎 Deploy Preview https://deploy-preview-41855--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.

@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 24.32432% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.72%. Comparing base (e52240b) to head (8eb3b58).
⚠️ Report is 30 commits behind head on master.

Files with missing lines Patch % Lines
superset/mcp_service/mcp_core.py 16.12% 26 Missing ⚠️
superset/mcp_service/chart/tool/list_charts.py 0.00% 1 Missing ⚠️
...rset/mcp_service/dashboard/tool/list_dashboards.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #41855      +/-   ##
==========================================
- Coverage   64.77%   64.72%   -0.06%     
==========================================
  Files        2689     2690       +1     
  Lines      148945   149128     +183     
  Branches    34369    34409      +40     
==========================================
+ Hits        96486    96526      +40     
- Misses      50693    50831     +138     
- Partials     1766     1771       +5     
Flag Coverage Δ
hive 39.14% <24.32%> (-0.06%) ⬇️
mysql 57.76% <24.32%> (-0.11%) ⬇️
postgres 57.82% <24.32%> (-0.11%) ⬇️
presto 40.67% <24.32%> (-0.06%) ⬇️
python 59.23% <24.32%> (-0.10%) ⬇️
sqlite 57.40% <24.32%> (-0.10%) ⬇️
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.

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

Labels

dashboard Namespace | Anything related to the Dashboard size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant