feat(mcp): add list_tags and get_tag_info MCP tools#40349
feat(mcp): add list_tags and get_tag_info MCP tools#40349aminghadersohi wants to merge 2 commits into
Conversation
Adds list_tags and get_tag_info MCP tools in a new superset/mcp_service/tag/ domain, following the existing database/dataset/dashboard patterns. Registers both tools in app.py and covers them with unit tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…upport
TagFilter documents 'ct' as a valid operator but ColumnOperatorEnum was
missing it, causing ValidationError when constructing TagFilter with opr="ct".
Added ct = "ct" with ilike("%val%") mapping, updated TYPE_OPERATOR_MAP for
string columns, and updated base_dao_test to cover the new operator.
geido
left a comment
There was a problem hiding this comment.
Reviewed: follows the established MCP tool pattern (mirrors list_dashboards/get_dashboard_info). RBAC enforced via class_permission_name="Tag" matching the existing Tag REST API. Filter columns locked to Literal["name", "type"] preventing arbitrary-column queries. The new ct operator uses SQLAlchemy parameterized ilike — no injection vector. Information exposure is no broader than the existing public Tag REST API. Page size and pagination bounds enforced.
There was a problem hiding this comment.
Code Review Agent Run #20b468
Actionable Suggestions - 1
-
superset/mcp_service/tag/schemas.py - 1
- SEMANTIC_DUPLICATION: Repeated utility function · Line 216-220
Additional Suggestions - 1
-
superset/mcp_service/tag/tool/list_tags.py - 1
-
Unused parameter in function · Line 95-95The `_serialize_tag` function accepts a `cols` parameter (line 95) that is never used — it only passes `obj` to `serialize_tag_object`. The `item_serializer` callable passed to `ModelListCore` expects `Callable[[T, List[str]], S | None]` but this wrapper ignores the second argument. If column filtering is intended to be handled by `serialize_tag_object`, verify this is working correctly; otherwise remove the unused parameter.
-
Filtered by Review Rules
Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.
-
tests/unit_tests/dao/base_dao_test.py - 1
- Test SQL expectation incorrect · Line 76-81
-
superset/mcp_service/tag/schemas.py - 1
- BROAD_EXCEPTION: Bare Exception catch · Line 199-204
Review Details
-
Files reviewed - 11 · Commit Range:
62b33b7..ba361ff- superset/daos/base.py
- superset/mcp_service/app.py
- superset/mcp_service/tag/__init__.py
- superset/mcp_service/tag/schemas.py
- superset/mcp_service/tag/tool/__init__.py
- superset/mcp_service/tag/tool/get_tag_info.py
- superset/mcp_service/tag/tool/list_tags.py
- tests/unit_tests/dao/base_dao_test.py
- tests/unit_tests/mcp_service/tag/__init__.py
- tests/unit_tests/mcp_service/tag/tool/__init__.py
- tests/unit_tests/mcp_service/tag/tool/test_tag_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
| def _humanize_timestamp(dt: datetime | None) -> str | None: | ||
| if dt is None: | ||
| return None | ||
| now = datetime.now(dt.tzinfo) if dt.tzinfo else datetime.now() | ||
| return humanize.naturaltime(now - dt) |
There was a problem hiding this comment.
The _humanize_timestamp function is duplicated across 5 schema files (tag, chart, dashboard, database, dataset) with identical implementation. Per BITO.md rule 9460, this semantic duplication increases maintenance risk — any fix or behavior change must be applied in 5 places.
Code Review Run #20b468
Should Bito avoid suggestions like this for future reviews? (Manage Rules)
- Yes, avoid them
SUMMARY
Adds two new MCP (Model Context Protocol) tools for the
tagdomain, enabling AI assistants to discover and inspect Superset tags:list_tags: Lists tags with filtering (column-based), text search, pagination, sorting, andselect_columnsprojection. Backed byTagDAO.list, usingModelListCore.get_tag_info: Returns metadata for a single tag by numeric ID. Backed byTagDAO.find_by_id, usingModelGetInfoCore.Key design decisions:
TagFilter.colis limited tonameandtype(the only indexed/filterable columns)TagInfoextends the sharedsystem.schemas.TagInfobase to avoid duplicationselect_columnsfiltering is implemented via@model_serializer(mode="wrap")onTagInfoid,name,type(excludes heavy audit fields)searchandfiltersare mutually exclusive (validated at the schema level)ct(contains/ilike) operator toColumnOperatorEnumandTYPE_OPERATOR_MAP, which was documented but missing from the enumBEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
N/A — backend-only MCP tools
TESTING INSTRUCTIONS
list_tags/get_tag_info.ADDITIONAL INFORMATION