gkneighb opened a new pull request, #40399:
URL: https://github.com/apache/superset/pull/40399

   ### SUMMARY
   
   `generate_dashboard` previously accepted only `chart_ids`, 
`dashboard_title`, `description`, and `published`. The layout was 
auto-generated from chart ids; theme (`label_colors`, `color_scheme`, 
`cross_filters_enabled`) and `css` were hardcoded defaults. As a result, LLMs 
building dashboards through MCP could only produce auto-layout, default-styled 
artifacts. Any brand styling, custom row composition, `MARKDOWN` / `HEADER` 
components, or chrome-hiding CSS required falling back to raw REST.
   
   There was also no `update_dashboard` tool, so once a dashboard existed via 
MCP, the only way to change its layout or theme was again raw REST.
   
   This PR exposes the REST-side composition primitives — `position_json`, 
`json_metadata`, and `css` — through two MCP entry points.
   
   ### BEFORE/AFTER
   
   **Before:**
   
   ```
   generate_dashboard({chart_ids: [...], dashboard_title: "..."})
   → Dashboard with auto-generated layout, default theme, no slug, no CSS
   
   To customize: fall back to raw REST PUT /api/v1/dashboard/{id}
   ```
   
   **After:**
   
   ```
   generate_dashboard({
     chart_ids: [81, 80, 78, 79],
     dashboard_title: "Q4 Executive Review",
     slug: "q4-exec-review",
     position_json: {"ROOT_ID": {...}, "GRID_ID": {...}, ...},
     json_metadata_overrides: {
       label_colors: {"Electronics": "#4C78A8", "Furniture": "#E45756"},
       cross_filters_enabled: false
     },
     css: ".header-controls{display:none}",
   })
   → Dashboard with the custom layout, theme, slug, and CSS all applied
   ```
   
   Or patch an existing dashboard's theme later:
   
   ```
   update_dashboard({
     identifier: 42,
     json_metadata_overrides: {label_colors: {"Office Supplies": "#54A24B"}},
     css: ".chart-header{padding:8px}",
   })
   ```
   
   ### CHANGES
   
   **Two new entry points:**
   
   1. **`generate_dashboard`** — four new optional fields:
      - `position_json: dict | None` — explicit layout (replaces auto-gen)
      - `json_metadata_overrides: dict | None` — shallow-merged on top of 
default json_metadata (label_colors, color_scheme, cross_filters_enabled, 
shared_label_colors, etc.)
      - `css: str | None` — dashboard-level CSS
      - `slug: str | None` — URL slug
   
      All optional. Omit to get the existing auto-generated behavior. Fully 
backward-compatible.
   
   2. **`update_dashboard`** — new mutate tool. Accepts the same 
layout/theme/CSS fields plus title, description, slug, published. Only the 
fields explicitly passed are applied; `json_metadata_overrides` is 
shallow-merged with the existing metadata. Empty string on slug/css explicitly 
clears.
   
   **File changes:**
   
   | File | Change |
   |---|---|
   | `superset/mcp_service/dashboard/schemas.py` | `GenerateDashboardRequest` 
adds 4 fields; new `UpdateDashboardRequest` schema |
   | `superset/mcp_service/dashboard/tool/generate_dashboard.py` | Wires the 4 
new fields through to the dashboard model write |
   | `superset/mcp_service/dashboard/tool/update_dashboard.py` | NEW tool — 
looks up by id/uuid/slug via `DashboardDAO.get_by_id_or_slug`, applies only 
explicitly-passed fields, returns structured `DashboardError` on not-found |
   | `superset/mcp_service/dashboard/tool/__init__.py` + 
`superset/mcp_service/app.py` | Register `update_dashboard` |
   
   ### TESTING INSTRUCTIONS
   
   ```bash
   pytest tests/unit_tests/mcp_service/dashboard/
   ```
   
   Specifically:
   
   - 
`tests/unit_tests/mcp_service/dashboard/test_dashboard_schemas.py::TestGenerateDashboardRequestLayoutTheme`
 — 6 tests covering the 4 new optional fields
   - 
`tests/unit_tests/mcp_service/dashboard/test_dashboard_schemas.py::TestUpdateDashboardRequest`
 — 7 tests covering the new schema
   - `tests/unit_tests/mcp_service/dashboard/tool/test_update_dashboard.py` — 5 
async tests covering happy-path update, no-op behavior, not-found, 
title/slug/published combo, empty-slug clears
   
   **142 dashboard tests pass; zero regressions.**
   
   End-to-end verified against a live Superset:
   - `generate_dashboard` with custom `position_json` + `label_colors` + 
`cross_filters_enabled` + `css` + `slug` → all four fields land in DB
   - `update_dashboard` patches title + json_metadata + css on an existing 
dashboard
   - no-op update returns a clear warning
   - not-found identifier returns structured `DashboardError`
   
   ### WHY THIS MATTERS
   
   LLM-driven dashboard construction commonly needs to apply brand palettes, 
hide chrome for print-ready exports, and place charts into specific row 
arrangements (header rows with side legends, KPI rows, trend+map rows, etc.). 
With the old `generate_dashboard`, none of those were reachable in one 
round-trip — the LLM would build a dashboard, then have to fall back to raw 
REST `PUT /api/v1/dashboard/{id}` to set `position_json`/`css`/`json_metadata`. 
That defeats the typed-config story and forces every LLM agent to learn the raw 
REST shape.
   
   ### ADDITIONAL INFORMATION
   
   - [ ] Has associated issue: _(filing alongside, will link)_
   - [ ] Required feature flags: _none_
   - [x] Changes UI: _no_
   - [x] Includes DB Migration: _no_
   - [x] Includes packaged template files: _no_
   - [x] Introduces new feature or API: _yes — adds 4 optional fields to 
`GenerateDashboardRequest` and a new `update_dashboard` MCP tool_
   - [x] Removes existing feature or API: _no_


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to