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

   ### SUMMARY
   
   Superset MCP tools that return a chart as a **real, interactive 
visualization inside the AI chat** instead of prose the model has to describe.
   
   Built against the **MCP Apps extension (SEP-1865, stable 2026-01-26)** — the 
`ui://` resource + `_meta.ui.resourceUri` mechanism co-authored by Anthropic, 
OpenAI and the mcp-ui authors. Verified working in Claude Desktop.
   
   **What it adds**
   
   | Piece | Location |
   |---|---|
   | `render_chart`, `render_chart_requery`, `render_dashboard` | 
`chart/tool/render_chart.py` |
   | `ui://` resource serving the widget | `chart/resources/chart_viewer.py` |
   | Widget source (React + ECharts + Vite) | `chart/resources/chart_viewer/` |
   | `@tool(meta=...)` plumbing | `superset-core/.../mcp/decorators.py`, 
`core/mcp/core_mcp_injection.py` |
   
   All three tools are thin wrappers over `get_chart_data_core` — the existing, 
already-authorized data path — so **no new data or authorization path is 
introduced**. Chart/dataset RBAC, guest-token scoping and RLS are re-applied on 
every interaction, including drill-down. The widget is static and 
tenant-neutral; per-user data reaches it only through tool results, never baked 
into the resource.
   
   Two existing MCP defaults blocked MCP Apps and are handled without weakening 
them globally:
   
   1. `StructuredContentStripperMiddleware` strips `structuredContent` from 
every tool (a Claude-bridge workaround). A small keep-list 
(`MCP_STRUCTURED_CONTENT_KEEP_TOOLS`) exempts the render tools; everything else 
is still stripped.
   2. The tool-search transform hides tools behind `search_tools`/`call_tool`, 
which prevents widget association. The render tools are pinned in 
`always_visible`.
   
   **Known limitation, stated up front.** Superset builds each chart's query in 
the frontend viz plugin (`buildQuery`), which supplies the time grain, sort, 
pivot structure and any second series. This service rebuilds the query in 
Python when a chart has no saved `query_context`, and that rebuild is lossy — a 
monthly chart can return individual days. Affected charts carry a visible 
notice in the widget rather than presenting the data as the chart's. Reusing 
Superset's own `buildQuery`/`transformProps` is the intended fix and is 
measured as viable (~355 KB for five chart types, ~16 KB marginal each); it is 
deliberately not in this PR.
   
   **Also fixed here (pre-existing, not MCP Apps specific):** a single NULL in 
a temporal column made `get_chart_data` unserializable. `pandas.NaT` subclasses 
`datetime.datetime`, so pydantic_core reads `.year` — `nan` — and raises during 
serialization after the query has already succeeded. Null-ish scalars are now 
normalized at the two points rows leave the query result.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   **Before:** `render_chart` did not exist; chart data reached the model as 
JSON and was described in prose.
   
   **After:** the chart renders inline and interactively in the conversation — 
view switching, click-to-drill (re-queries live), dashboard grids with tabs.
   
   _Screenshots to follow — the widget requires an MCP Apps host to render._
   
   ### TESTING INSTRUCTIONS
   
   **Unit tests**
   
   ```bash
   pytest tests/unit_tests/mcp_service/          # Python
   cd superset/mcp_service/chart/resources/chart_viewer
   npm ci && npm test && npm run build           # widget: 191 tests, tsc, 
bundle
   ```
   
   CI also runs the widget suite via `.github/workflows/mcp-chart-viewer.yml` 
(path-filtered).
   
   **In a real MCP Apps host** (full checklist in 
`chart/CHART_VIEWER_HOST_VERIFICATION.md`)
   
   ```bash
   cd superset/mcp_service/chart/resources/chart_viewer && npm ci && npm run 
build
   cd - && SUPERSET_CONFIG_PATH=$PWD/superset_config.py superset mcp run --port 
5008 --debug
   ```
   
   Connect Claude Desktop to the local MCP endpoint, then in a **brand-new 
conversation**:
   
   1. "Render Superset chart 113" → an interactive chart appears inline
   2. Click the line/bar/area chips → the chart morphs
   3. Click a data point → drill-down re-queries; the row count changes
   4. "Render Superset dashboard 5" → a grid of charts with working tabs
   5. "Render Superset chart 99999" → a readable error, not a protocol error
   
   > Hosts cache the `ui://` bundle and the tool descriptor per conversation. 
Start a new conversation after any rebuild, and restart Desktop after 
restarting the MCP server — its proxy processes do not reconnect on their own.
   
   ### ADDITIONAL INFORMATION
   
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [x] Changes UI
   - [ ] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
     - [ ] Migration is atomic, supports rollback & is backwards-compatible
     - [ ] Confirm DB migration upgrade and downgrade tested
     - [ ] Runtime estimates and downtime expectations provided
   - [x] Introduces new feature or API
   - [ ] Removes existing feature or API
   
   **Notes for reviewers**
   
   - The built widget (`chart_viewer/dist/index.html`) is **not committed**, 
matching the `superset/static/assets` convention: gitignored, produced at build 
time, shipped via `MANIFEST.in`. Until built, the `ui://` resource serves a 
placeholder page that says so.
   - The widget is an npm project living *inside* the Python package so it sits 
next to the resource that serves it. Every other bundler project in this repo 
is a repo-root sibling; if this graduates, moving it is probably the more 
conventional shape.
   - Packaging: the PyPI path is wired (`RELEASING/README.md`); the Docker 
image is still a gap and official images would serve the placeholder.
   - Supersedes #42543, which was closed when its head repository was deleted. 
Content is unchanged plus a merge with current master.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
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