This is an automated email from the ASF dual-hosted git repository.

aminghadersohi pushed a commit to branch amin/mcp-list-reports
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/amin/mcp-list-reports by this 
push:
     new 2158b6a7abb fix(mcp): align get_schema report columns with ReportInfo 
serializer
2158b6a7abb is described below

commit 2158b6a7abb9321186d240d9b9a16a0b67554abc
Author: Amin Ghadersohi <[email protected]>
AuthorDate: Thu May 28 14:56:24 2026 +0000

    fix(mcp): align get_schema report columns with ReportInfo serializer
    
    Add REPORT_FILTER_COLUMNS constant (the ReportFilter.col whitelist) and
    an include_filter_columns allowlist parameter to ModelGetSchemaCore.
    Pass include_filter_columns=REPORT_FILTER_COLUMNS to _get_report_schema_core
    so that get_schema(model_type="report") only advertises filter columns that
    list_reports actually accepts, preventing clients from discovering and then
    being rejected for ORM-only filters like timezone, sql, email_subject, etc.
---
 superset/mcp_service/common/schema_discovery.py |  5 +++++
 superset/mcp_service/mcp_core.py                | 11 +++++++++++
 superset/mcp_service/system/tool/get_schema.py  |  2 ++
 3 files changed, 18 insertions(+)

diff --git a/superset/mcp_service/common/schema_discovery.py 
b/superset/mcp_service/common/schema_discovery.py
index 391e3ff3d07..10abbc7a6f2 100644
--- a/superset/mcp_service/common/schema_discovery.py
+++ b/superset/mcp_service/common/schema_discovery.py
@@ -648,6 +648,11 @@ REPORT_SORTABLE_COLUMNS = [
     "created_on",
 ]
 REPORT_SEARCH_COLUMNS = ["name", "description"]
+# Allowlist of filter columns exposed via get_schema and accepted by 
ReportFilter.
+# Must stay in sync with the Literal in ReportFilter.col (schemas.py).
+REPORT_FILTER_COLUMNS: frozenset[str] = frozenset(
+    {"name", "type", "active", "dashboard_id", "chart_id", "created_by_fk"}
+)
 REPORT_EXTRA_COLUMNS: dict[str, ColumnMetadata] = {
     "changed_on_humanized": ColumnMetadata(
         name="changed_on_humanized",
diff --git a/superset/mcp_service/mcp_core.py b/superset/mcp_service/mcp_core.py
index 7b903e8f6d1..25607ce1e02 100644
--- a/superset/mcp_service/mcp_core.py
+++ b/superset/mcp_service/mcp_core.py
@@ -757,6 +757,7 @@ class ModelGetSchemaCore(BaseCore, Generic[S]):
         default_sort: str = "changed_on",
         default_sort_direction: Literal["asc", "desc"] = "desc",
         exclude_filter_columns: set[str] | None = None,
+        include_filter_columns: frozenset[str] | None = None,
         logger: logging.Logger | None = None,
     ) -> None:
         """
@@ -774,6 +775,10 @@ class ModelGetSchemaCore(BaseCore, Generic[S]):
             default_sort_direction: Default sort direction
             exclude_filter_columns: Column names to omit from filter discovery
                 (e.g., sensitive fields like passwords or connection URIs)
+            include_filter_columns: When set, only these column names are 
advertised
+                as filterable. Applied after exclude_filter_columns. Use this 
when
+                the list tool's filter schema accepts fewer columns than the 
DAO
+                exposes (e.g., ReportFilter vs. the full ReportSchedule ORM 
model).
             logger: Optional logger instance
         """
         super().__init__(logger)
@@ -794,6 +799,7 @@ class ModelGetSchemaCore(BaseCore, Generic[S]):
         # Hide user-directory columns from filter discovery, except the small
         # set callers may legitimately filter by ID (resolved via find_users).
         self.exclude_filter_columns.update(USER_DIRECTORY_FIELDS - 
USER_FILTER_FIELDS)
+        self.include_filter_columns = include_filter_columns
 
     def _get_filter_columns(self) -> Dict[str, List[str]]:
         """Get filterable columns and operators from the DAO."""
@@ -822,6 +828,11 @@ class ModelGetSchemaCore(BaseCore, Generic[S]):
                     for k, v in result.items()
                     if k not in self.exclude_filter_columns
                 }
+            # Apply allowlist: keep only explicitly permitted filter columns
+            if self.include_filter_columns is not None:
+                result = {
+                    k: v for k, v in result.items() if k in 
self.include_filter_columns
+                }
             return result
         except Exception as e:
             self._log_warning(
diff --git a/superset/mcp_service/system/tool/get_schema.py 
b/superset/mcp_service/system/tool/get_schema.py
index 9df93266cbd..df123f8d4b4 100644
--- a/superset/mcp_service/system/tool/get_schema.py
+++ b/superset/mcp_service/system/tool/get_schema.py
@@ -52,6 +52,7 @@ from superset.mcp_service.common.schema_discovery import (
     GetSchemaResponse,
     ModelSchemaInfo,
     REPORT_DEFAULT_COLUMNS,
+    REPORT_FILTER_COLUMNS,
     REPORT_SEARCH_COLUMNS,
     REPORT_SORTABLE_COLUMNS,
 )
@@ -164,6 +165,7 @@ def _get_report_schema_core() -> 
ModelGetSchemaCore[ModelSchemaInfo]:
         default_sort="changed_on",
         default_sort_direction="desc",
         exclude_filter_columns=set(SELF_REFERENCING_FILTER_COLUMNS),
+        include_filter_columns=REPORT_FILTER_COLUMNS,
         logger=logger,
     )
 

Reply via email to