feat(mcp): add list and get tools for alerts and reports#40299
feat(mcp): add list and get tools for alerts and reports#40299aminghadersohi wants to merge 6 commits into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #40299 +/- ##
==========================================
- Coverage 64.14% 63.82% -0.33%
==========================================
Files 2592 2596 +4
Lines 138846 140126 +1280
Branches 32201 32497 +296
==========================================
+ Hits 89069 89439 +370
- Misses 48245 49123 +878
- Partials 1532 1564 +32
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
c126d7f to
942c608
Compare
Adds list_reports and get_report_info MCP tools under a new superset/mcp_service/report/ domain, following the canonical database domain pattern. Includes unit tests and app.py registration.
- Register report model type in get_schema (Fix #1): add _get_report_schema_core factory + "report" entry in _SCHEMA_CORE_FACTORIES; ModelType now includes "report" - Add OwnedByMeMixin/CreatedByMeMixin to ListReportsRequest (Fix #2) - DRY up list_reports.py column constants (Fix #3): import REPORT_* constants and get_report_columns from schema_discovery; pass created_by_me/owned_by_me to run_tool - Extend test coverage (Fix #6): humanized timestamp fields, invalid order_column guard, owned_by_me/created_by_me DAO filter injection Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tools
- Add ReportListCore subclass in list_reports.py that overrides filter
injection to use owners.id (instead of generic owner) and calls the
DAO with filters= kwarg (instead of column_operators=) so tests can
assert on the kwarg by name
- Extract _call_dao_list hook in ModelListCore so subclasses can change
the DAO kwarg name without duplicating run_tool
- Add owners.id to SELF_REFERENCING_FILTER_COLUMNS so it is excluded
from filters_applied in responses
Fixes: test_list_reports_owned_by_me_passed_to_dao,
test_list_reports_created_by_me_passed_to_dao
created_by_fk was removed from SELF_REFERENCING_FILTER_COLUMNS so it now appears in filters_applied, but ReportFilter.col Literal didn't include it, causing pydantic validation error in list_reports responses.
02d7ddf to
3bbdd61
Compare
…e ColumnOperator for filters_applied - ReportFilter.col Literal no longer includes created_by_fk; callers must use the created_by_me flag instead (internal-only filter) - ReportList.filters_applied typed as List[ColumnOperator] so that internally-injected ColumnOperator instances (e.g. created_by_fk from created_by_me=True) pass pydantic validation without coercion errors
|
Closing in favour of #40348 (branch renamed to amin/mcp-list-reports per naming convention) |
There was a problem hiding this comment.
Code Review Agent Run #840a5b
Actionable Suggestions - 1
-
superset/mcp_service/report/schemas.py - 1
- datetime.now() called without timezone · Line 268-268
Additional Suggestions - 2
-
superset/mcp_service/report/tool/get_report_info.py - 1
-
Missing resource access validation · Line 72-85Unlike get_chart_info which validates dataset accessibility (lines 327-330), this tool doesn't verify the report's associated resources are accessible. This could leak information about reports linked to inaccessible dashboards or charts.
-
-
superset/mcp_service/common/schema_discovery.py - 1
-
Dead code: unused constant · Line 679-679Remove the unused REPORT_ALL_COLUMNS constant from schema_discovery.py.
-
Filtered by Review Rules
Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.
-
superset/mcp_service/report/tool/list_reports.py - 1
- Wrong kwarg name in DAO call · Line 122-122
-
superset/mcp_service/report/tool/get_report_info.py - 2
- Broad exception handling · Line 105-118
- Avoid catching blind Exception · Line 105-105
-
superset/mcp_service/common/schema_discovery.py - 1
- Missing computed field in schema · Line 651-664
-
superset/mcp_service/report/schemas.py - 1
- Missing error sanitization · Line 239-243
Review Details
-
Files reviewed - 14 · Commit Range:
2e87c2c..2305683- superset/mcp_service/app.py
- superset/mcp_service/common/schema_discovery.py
- superset/mcp_service/constants.py
- superset/mcp_service/mcp_core.py
- superset/mcp_service/privacy.py
- superset/mcp_service/report/__init__.py
- superset/mcp_service/report/schemas.py
- superset/mcp_service/report/tool/__init__.py
- superset/mcp_service/report/tool/get_report_info.py
- superset/mcp_service/report/tool/list_reports.py
- superset/mcp_service/system/tool/get_schema.py
- tests/unit_tests/mcp_service/report/__init__.py
- tests/unit_tests/mcp_service/report/tool/__init__.py
- tests/unit_tests/mcp_service/report/tool/test_report_tools.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
| """Convert a datetime to a humanized string like '2 hours ago'.""" | ||
| if dt is None: | ||
| return None | ||
| now = datetime.now(dt.tzinfo) if dt.tzinfo else datetime.now() |
There was a problem hiding this comment.
Add timezone argument to datetime.now() call on line 268. Use datetime.now(dt.tzinfo) or datetime.now(timezone.utc) for consistency.
Code suggestion
Check the AI-generated fix before applying
| now = datetime.now(dt.tzinfo) if dt.tzinfo else datetime.now() | |
| now = datetime.now(dt.tzinfo) if dt.tzinfo else datetime.now(timezone.utc) |
Code Review Run #840a5b
Should Bito avoid suggestions like this for future reviews? (Manage Rules)
- Yes, avoid them
SUMMARY
Adds
list_reportsandget_report_infoMCP tools for the Alerts & Reports domain, following the canonical database domain pattern.New files:
superset/mcp_service/report/schemas.py—ReportFilter,ReportInfo,ReportList,ListReportsRequest,GetReportInfoRequest,ReportError,serialize_report_object()superset/mcp_service/report/tool/list_reports.py— lists alerts/reports with filtering, search, paginationsuperset/mcp_service/report/tool/get_report_info.py— fetches a single schedule by numeric IDKey design decisions:
ReportFilterrestricts filterable columns to:name,type,active,dashboard_id,chart_idGetReportInfoRequest.identifierisintonly (ReportSchedulehas no UUID or slug)ownersfield is defined inReportInfobut stripped byfilter_user_directory_fields(same privacy pattern as other list tools)data_model_metadataprivacy gate (reports are user-level content, not database metadata)app.pyand advertised inDEFAULT_INSTRUCTIONSBEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
N/A — backend-only MCP tools
TESTING INSTRUCTIONS
ADDITIONAL INFORMATION