Skip to content

feat(mcp): add get_chart_sql tool and expose chart filters in get_chart_info#38700

Open
aminghadersohi wants to merge 8 commits intoapache:masterfrom
aminghadersohi:amin/mcp-chart-sql-and-filter-discoverability
Open

feat(mcp): add get_chart_sql tool and expose chart filters in get_chart_info#38700
aminghadersohi wants to merge 8 commits intoapache:masterfrom
aminghadersohi:amin/mcp-chart-sql-and-filter-discoverability

Conversation

@aminghadersohi
Copy link
Copy Markdown
Contributor

@aminghadersohi aminghadersohi commented Mar 17, 2026

User description

SUMMARY

Two improvements to the MCP service based on user feedback around chart SQL retrieval and filter discoverability:

  1. New get_chart_sql tool — Returns the rendered SQL for a chart without executing it, similar to the "View Query" feature in the Superset UI. Useful for agents to inspect, debug, and audit chart-generated SQL. Supports saved charts (by ID/UUID) and unsaved chart state (via form_data_key).

  2. Expose chart filters in get_chart_info — Adds a structured filters field to the ChartInfo response that surfaces adhoc_filters, time_range, granularity_sqla, extra_filters, and custom WHERE/HAVING clauses. This allows MCP consumers to discover what filters are currently applied to a chart and construct filter payloads.

Design decisions:

  • Dedicated get_chart_sql tool rather than enriching get_chart_info with optional properties — the tool name is the documentation, keeps get_chart_info fast (SQL generation involves query builder + Jinja templating), and maps to distinct intents (get_chart_info = config, get_chart_sql = SQL, get_chart_data = data)
  • Filters exposed on get_chart_info (not a separate tool) since they're part of chart configuration

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

N/A — backend MCP tools only, no UI changes.

TESTING INSTRUCTIONS

  1. Start Superset with MCP enabled
  2. Call get_chart_sql with a chart ID → should return the rendered SQL
  3. Call get_chart_info on a chart with filters → the response should include a filters field with structured filter info
  4. Call get_chart_sql with a form_data_key for unsaved chart state → should return SQL for the cached form_data
  5. Call get_chart_sql with an invalid ID → should return a proper error

ADDITIONAL INFORMATION

  • Introduces new feature or API
  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration
  • Removes existing feature or API

CodeAnt-AI Description

Add chart SQL lookup and expose applied filters in chart details

What Changed

  • Chart details now include a structured view of applied filters, including time range, adhoc filters, extra filters, and custom WHERE/HAVING clauses.
  • A new chart SQL tool returns the rendered SQL for a saved chart or an unsaved Explore state without running the query.
  • The SQL tool supports chart IDs, UUIDs, and cached unsaved chart state, and returns clear errors when the chart, cache entry, or dataset cannot be used.

Impact

✅ Easier chart debugging
✅ Clearer filter inspection
✅ Faster SQL review for saved and unsaved charts

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.


MCP Tool Testing Results

Tested against running Superset MCP service (localhost:5008) on 2026-03-24:

Tool Request Result
health_check {} {"status":"healthy","service":"Preset MCP Service"}
get_instance_info {} 13 dashboards, 91 charts, 20 datasets, current_user=Amin (Admin)
list_dashboards {"page":1,"page_size":3} Returned 3/13 dashboards
list_charts {"page":1,"page_size":3} Returned 3/91 charts
list_datasets {"page":1,"page_size":3} Returned 3/20 datasets
get_chart_info {"identifier":4} Returned pie chart "Work Location Preference"
execute_sql {"database_id":2,"sql":"SELECT 1 as test_col"} Returned 1 row in 0.13s
generate_explore_link {"dataset_id":19,"config":{...}} Generated explore URL

All tools executed successfully with proper auth context (Admin user).

@codeant-ai-for-open-source codeant-ai-for-open-source bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Mar 17, 2026
@codeant-ai-for-open-source
Copy link
Copy Markdown
Contributor

Sequence Diagram

This PR adds a new get chart sql tool that returns rendered chart SQL without running the query, supporting both saved charts and unsaved cached chart state. It also enhances get chart info to include a structured filters field extracted from chart form data.

sequenceDiagram
    participant Client
    participant MCP Service
    participant Chart Store
    participant Cache
    participant Query Builder

    Client->>MCP Service: Request get chart sql
    alt Unsaved state with form data key
        MCP Service->>Cache: Load cached chart form data
        Cache-->>MCP Service: Unsaved chart form data
    else Saved chart identifier
        MCP Service->>Chart Store: Load chart and validate dataset access
        Chart Store-->>MCP Service: Saved chart configuration
    end
    MCP Service->>Query Builder: Build query context and render SQL
    Query Builder-->>MCP Service: Rendered SQL result
    MCP Service-->>Client: Return chart SQL response

    Client->>MCP Service: Request get chart info
    MCP Service->>MCP Service: Extract filters from form data
    MCP Service-->>Client: Return chart info with filters
Loading

Generated by CodeAnt AI

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 17, 2026

Codecov Report

❌ Patch coverage is 22.13439% with 197 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.40%. Comparing base (7222327) to head (ceb613e).
⚠️ Report is 58 commits behind head on master.

Files with missing lines Patch % Lines
superset/mcp_service/chart/tool/get_chart_sql.py 12.82% 170 Missing ⚠️
superset/mcp_service/chart/schemas.py 53.57% 26 Missing ⚠️
superset/mcp_service/chart/tool/get_chart_info.py 0.00% 1 Missing ⚠️

❌ Your project check has failed because the head coverage (99.85%) is below the target coverage (100.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #38700      +/-   ##
==========================================
- Coverage   65.54%   64.40%   -1.14%     
==========================================
  Files        1820     2534     +714     
  Lines       72868   130449   +57581     
  Branches    23339    30199    +6860     
==========================================
+ Hits        47758    84019   +36261     
- Misses      25110    44966   +19856     
- Partials        0     1464    +1464     
Flag Coverage Δ
hive 40.38% <22.13%> (?)
mysql 61.28% <22.13%> (?)
postgres 61.35% <22.13%> (?)
presto 40.40% <22.13%> (?)
python 62.94% <22.13%> (?)
sqlite 60.98% <22.13%> (?)
unit 100.00% <ø> (?)

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

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

Copy link
Copy Markdown
Contributor

@bito-code-review bito-code-review bot left a comment

Choose a reason for hiding this comment

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

Code Review Agent Run #57d92b

Actionable Suggestions - 1
  • superset/mcp_service/chart/tool/get_chart_sql.py - 1
Additional Suggestions - 1
  • superset/mcp_service/app.py - 1
    • Missing Unit Tests for New Tool · Line 401-401
      The new get_chart_sql tool has been added without unit tests, which violates the documented development standards in CLAUDE.md. All new tools must have corresponding unit tests to ensure reliability and prevent regressions.
Review Details
  • Files reviewed - 5 · Commit Range: d01bc8a..d01bc8a
    • superset/mcp_service/app.py
    • superset/mcp_service/chart/schemas.py
    • superset/mcp_service/chart/tool/__init__.py
    • superset/mcp_service/chart/tool/get_chart_info.py
    • superset/mcp_service/chart/tool/get_chart_sql.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

@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review bot commented Mar 17, 2026

Code Review Agent Run #587934

Actionable Suggestions - 0
Review Details
  • Files reviewed - 2 · Commit Range: d01bc8a..ef874ae
    • superset/mcp_service/chart/schemas.py
    • superset/mcp_service/chart/tool/get_chart_sql.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

Copy link
Copy Markdown
Contributor

@bito-code-review bito-code-review bot left a comment

Choose a reason for hiding this comment

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

Code Review Agent Run #9638dc

Actionable Suggestions - 1
  • superset/mcp_service/chart/tool/get_chart_sql.py - 1
Review Details
  • Files reviewed - 3 · Commit Range: ef874ae..8774641
    • superset/mcp_service/chart/schemas.py
    • superset/mcp_service/chart/tool/get_chart_sql.py
    • tests/unit_tests/mcp_service/chart/tool/test_get_chart_sql.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

@aminghadersohi aminghadersohi force-pushed the amin/mcp-chart-sql-and-filter-discoverability branch from 8774641 to ec92d9c Compare March 18, 2026 06:54
@codeant-ai-for-open-source codeant-ai-for-open-source bot added size:XXL This PR changes 1000+ lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels Mar 18, 2026
Copy link
Copy Markdown
Contributor

@bito-code-review bito-code-review bot left a comment

Choose a reason for hiding this comment

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

Code Review Agent Run #43b18d

Actionable Suggestions - 1
  • superset/mcp_service/chart/schemas.py - 1
    • Unhandled ValidationError in filter extraction · Line 308-308
Additional Suggestions - 1
  • superset/mcp_service/chart/schemas.py - 1
    • Incomplete field description · Line 115-121
      The description for the filters field claims to include 'all filters' but omits granularity_sqla, which is extracted and included in ChartFiltersInfo.
      Code suggestion
       @@ -118,4 +118,4 @@
      -            "extracted from form_data. Includes adhoc filters, time range, "
      -            "extra filters, and custom WHERE/HAVING clauses."
      +            "extracted from form_data. Includes adhoc filters, time range, "
      +            "extra filters, and custom WHERE/HAVING clauses, granularity_sqla."
Filtered by Review Rules

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

  • superset/mcp_service/chart/tool/get_chart_sql.py - 1
Review Details
  • Files reviewed - 6 · Commit Range: 6a74b07..6fad704
    • superset/mcp_service/app.py
    • superset/mcp_service/chart/schemas.py
    • superset/mcp_service/chart/tool/__init__.py
    • superset/mcp_service/chart/tool/get_chart_info.py
    • superset/mcp_service/chart/tool/get_chart_sql.py
    • tests/unit_tests/mcp_service/chart/tool/test_get_chart_sql.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

…rt_info

Add a dedicated get_chart_sql MCP tool that returns the rendered SQL for a
chart without executing it, similar to the "View Query" feature in the UI.
This enables agents to inspect, debug, and audit chart SQL.

Also expose existing chart filters (adhoc_filters, time_range, extra_filters,
WHERE/HAVING clauses) as a structured field on the get_chart_info response,
improving filter discoverability for MCP consumers.
- Validate extra_filters items are dicts before building ChartFiltersInfo
- Parse combined datasource field (e.g. "123__table") in form_data
- Guard JSON parsing of chart.params with try/except
- Apply walrus operator patterns for auto-walrus pre-commit hook
…t_chart_sql tests

- Fix mypy typeddict-item errors in get_chart_sql by resolving
  datasource_id/datasource_type to proper types before passing to
  QueryContextFactory.create()
- Add isinstance(form_data, dict) guard in extract_filters_from_form_data
  to prevent 'Mock object is not iterable' errors when form_data is not
  a dict (e.g., from Mock objects in test environments)
- Add comprehensive unit tests for the get_chart_sql tool covering:
  - GetChartSqlRequest schema validation
  - _extract_sql_from_result helper (success, empty, error cases)
  - _find_chart_by_identifier helper (numeric, string, UUID, not found)
  - _resolve_effective_form_data helper (saved, cached, fallback)
  - MCP Client integration tests (not found, success, fallback, access denied)
Use importlib.import_module to get the actual module object instead of
the function exported from __init__.py, fixing patch.object calls that
were resolving to the function instead of the module.
- Raise ValueError instead of defaulting to 0 for invalid datasource ID
- Wrap AdhocFilter construction in try/except to skip malformed entries
- Include row_limit from form_data in query context for accurate SQL
- Catch ValueError in callers of _sql_from_form_data
…ter schemas

- Add ValidationError to except clause for AdhocFilter construction so
  Pydantic validation errors from malformed filter fields are caught
- Add item-level validation for extra_filters to reject entries without
  a valid string "col" key
- Catch ValueError/TypeError in outer get_chart_sql handler so malformed
  chart.params or datasource parsing errors do not escape as unhandled
  exceptions
@aminghadersohi aminghadersohi force-pushed the amin/mcp-chart-sql-and-filter-discoverability branch from 6fad704 to a9411af Compare March 24, 2026 09:56
@codeant-ai-for-open-source codeant-ai-for-open-source bot added size:XXL This PR changes 1000+ lines, ignoring generated files and removed size:XXL This PR changes 1000+ lines, ignoring generated files labels Mar 24, 2026
- Extract _resolve_metrics_and_groupby helper to reduce complexity of
  _build_query_context_from_form_data (fixes ruff C901)
- Add fallback metric/dimension field aliases (metric, entity, series,
  columns) so that chart types which store measures/dimensions under
  non-standard keys produce correct SQL in the fallback flow
- Collect SQL from ALL query results in _extract_sql_from_result
  instead of only the first, so composite charts (e.g. mixed
  timeseries) do not silently lose part of their SQL output
Copy link
Copy Markdown
Contributor

@bito-code-review bito-code-review bot left a comment

Choose a reason for hiding this comment

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

Code Review Agent Run #641514

Actionable Suggestions - 1
  • superset/mcp_service/chart/tool/get_chart_sql.py - 1
Review Details
  • Files reviewed - 6 · Commit Range: 704854f..ceb613e
    • superset/mcp_service/app.py
    • superset/mcp_service/chart/schemas.py
    • superset/mcp_service/chart/tool/__init__.py
    • superset/mcp_service/chart/tool/get_chart_info.py
    • superset/mcp_service/chart/tool/get_chart_sql.py
    • tests/unit_tests/mcp_service/chart/tool/test_get_chart_sql.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

Comment on lines +335 to +361
async def get_chart_sql(
request: GetChartSqlRequest, ctx: Context
) -> ChartSql | ChartError:
"""Get the rendered SQL query for a chart without executing it.

Returns the SQL that a chart would execute, similar to the "View Query"
feature in the Superset UI. Useful for understanding, debugging, or
auditing the SQL generated by a chart's configuration.

Supports:
- Numeric ID or UUID lookup
- form_data_key: get SQL for unsaved chart state from Explore view

Example usage:
```json
{
"identifier": 123
}
```

Returns the SQL query string and metadata about the chart.
"""
await ctx.info(
"Starting chart SQL retrieval: identifier=%s, form_data_key=%s"
% (request.identifier, request.form_data_key)
)

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.

Incomplete function body

The get_chart_sql function body is incomplete - it only logs and lacks the core logic for processing the request, chart lookup, and SQL generation. This will cause a runtime error due to no return value. Add the missing implementation using the helper functions defined above.

Code Review Run #641514


Should Bito avoid suggestions like this for future reviews? (Manage Rules)

  • Yes, avoid them

@kgabryje
Copy link
Copy Markdown
Member

Code review

Found 1 issue:

  1. get_chart_sql uses @parse_request(GetChartSqlRequest), but PR fix(mcp): remove @parse_request decorator for cleaner tool schemas #38918 ("fix(mcp): remove @parse_request decorator for cleaner tool schemas", merged 2026-03-29) explicitly removed this decorator from all 19 existing MCP tools. The reason: FastMCP 3.1 handles Pydantic BaseModel parameters natively, and @parse_request causes degraded tool schemas (anyOf [string, object] instead of a clean object schema), leading to worse LLM behavior. After fix(mcp): remove @parse_request decorator for cleaner tool schemas #38918, get_chart_sql is the only tool in the entire MCP service still using this decorator.

from superset.mcp_service.utils.schema_utils import parse_request
logger = logging.getLogger(__name__)

@parse_request(GetChartSqlRequest)
async def get_chart_sql(
request: GetChartSqlRequest, ctx: Context

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

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

Labels

size/XXL size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants