Skip to content

feat(mcp): add duplicate_dashboard tool#40959

Open
aminghadersohi wants to merge 1 commit into
masterfrom
mcp-duplicate-dashboard
Open

feat(mcp): add duplicate_dashboard tool#40959
aminghadersohi wants to merge 1 commit into
masterfrom
mcp-duplicate-dashboard

Conversation

@aminghadersohi

Copy link
Copy Markdown
Contributor

SUMMARY

Adds a new duplicate_dashboard MCP tool to the Superset MCP service. The canonical AI workflow this enables: "create a regional/staging variant of this dashboard" — clone a template dashboard, then edit the copy.

Design:

  • Wraps the existing CopyDashboardCommand (the same backend used by the frontend "Save as" flow on /api/v1/dashboard/<id>/copy/).
  • The source dashboard can be identified by numeric ID, UUID, or slug (resolved via DashboardDAO.get_by_id_or_slug, which applies dashboard access filters).
  • DashboardCopySchema's copy data contract requires json_metadata; the tool builds it server-side from the source dashboard's current state (json_metadata plus a positions key from position_json), mirroring exactly what the frontend "Save as" sends. json_metadata is intentionally not exposed as a tool parameter.
  • duplicate_slices: bool = false — when true, every chart on the source dashboard is deep-copied into a new chart object owned by the caller; when false the copy references the same charts.
  • The new title is sanitized for XSS using the same pattern as generate_dashboard (nh3-based sanitize_user_input), with a warning surfaced when content is stripped and a hard error when the title sanitizes to nothing.
  • Structured error responses for source-not-found, access-denied, forbidden (DASHBOARD_RBAC), and copy failures; errors are wrapped for LLM-context safety.
  • Registered as a mutate tool (class_permission_name="Dashboard", method_permission_name="write") and added to MCP_CACHE_CONFIG["excluded_tools"] so responses are never cached.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

N/A — MCP service tool, no UI changes.

TESTING INSTRUCTIONS

  1. Start the MCP service and connect an MCP client.
  2. Call duplicate_dashboard with {"dashboard_id": <existing id|uuid|slug>, "dashboard_title": "My Copy"} — verify a new dashboard is created referencing the same charts, and the returned URL opens it.
  3. Call again with "duplicate_slices": true — verify the new dashboard contains new chart objects (different chart IDs) with the same layout.
  4. Verify error responses for a non-existent dashboard ID and for a dashboard the user cannot access.
  5. Run unit tests: pytest tests/unit_tests/mcp_service/dashboard/tool/test_duplicate_dashboard.py

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

Adds a duplicate_dashboard MCP tool that clones an existing dashboard
via CopyDashboardCommand. The source dashboard can be identified by
numeric ID, UUID, or slug. By default the copy references the same
charts; duplicate_slices=true deep-copies every chart into new objects
owned by the caller.

The tool builds the required json_metadata payload (source metadata
plus a positions key from position_json), mirroring what the frontend
"Save as" flow sends to the /copy/ endpoint. The new title is
sanitized for XSS, and the tool is excluded from MCP response caching.
@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 30.32787% with 85 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.31%. Comparing base (f79a88c) to head (5495f98).
⚠️ Report is 19 commits behind head on master.

Files with missing lines Patch % Lines
.../mcp_service/dashboard/tool/duplicate_dashboard.py 19.48% 62 Missing ⚠️
superset/mcp_service/dashboard/schemas.py 47.72% 23 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #40959      +/-   ##
==========================================
+ Coverage   64.19%   64.31%   +0.12%     
==========================================
  Files        2655     2658       +3     
  Lines      143925   145812    +1887     
  Branches    33181    33522     +341     
==========================================
+ Hits        92386    93785    +1399     
- Misses      49919    50350     +431     
- Partials     1620     1677      +57     
Flag Coverage Δ
hive 39.77% <30.32%> (+0.31%) ⬆️
mysql 58.63% <30.32%> (+0.44%) ⬆️
postgres 58.69% <30.32%> (+0.43%) ⬆️
presto 41.39% <30.32%> (+0.34%) ⬆️
python 60.12% <30.32%> (+0.39%) ⬆️
sqlite 58.32% <30.32%> (+0.44%) ⬆️
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 marked this pull request as ready for review June 12, 2026 21:20
@bito-code-review

bito-code-review Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #e866e5

Actionable Suggestions - 0
Additional Suggestions - 2
  • superset/mcp_service/dashboard/schemas.py - 1
    • Missing schema unit tests · Line 804-841
      DuplicateDashboardResponse lacks direct unit tests. While the error sanitization validator is exercised indirectly via integration tests, BITO.md rule [11731] requires dedicated unit tests for new MCP mutation tool schemas covering request validation, success paths, error handling, and schema serialization. Add tests to test_dashboard_schemas.py following the pattern used for GenerateDashboardResponse.
  • superset/mcp_service/dashboard/tool/duplicate_dashboard.py - 1
    • Inconsistent ctx logging on early returns · Line 164-177
      Early-return error paths at lines 164 and 171 return a DuplicateDashboardResponse with an error but emit no ctx-level log. Add await ctx.warning() calls before those returns for consistency with the DashboardForbiddenError handler and to ensure MCP-level observability for lookup failures.
Filtered by Review Rules

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

  • tests/unit_tests/mcp_service/dashboard/tool/test_duplicate_dashboard.py - 1
Review Details
  • Files reviewed - 6 · Commit Range: 5495f98..5495f98
    • superset/mcp_service/app.py
    • superset/mcp_service/dashboard/schemas.py
    • superset/mcp_service/dashboard/tool/__init__.py
    • superset/mcp_service/dashboard/tool/duplicate_dashboard.py
    • superset/mcp_service/mcp_config.py
    • tests/unit_tests/mcp_service/dashboard/tool/test_duplicate_dashboard.py
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ 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

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant