Skip to content

feat(mcp): add list and get tools for row level security and plugins - #40347

Merged
aminghadersohi merged 6 commits into
apache:masterfrom
aminghadersohi:amin/mcp-rls-plugins
May 30, 2026
Merged

feat(mcp): add list and get tools for row level security and plugins#40347
aminghadersohi merged 6 commits into
apache:masterfrom
aminghadersohi:amin/mcp-rls-plugins

Conversation

@aminghadersohi

@aminghadersohi aminghadersohi commented May 22, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

Adds four new MCP (Model Context Protocol) tools to Apache Superset across two new domains:

Row Level Security (superset/mcp_service/rls/):

  • list_rls_filters — list RLS filters with filtering, search, column selection, sorting, and pagination. Requires admin access.
  • get_rls_filter_info — get full RLS filter details by ID (name, type, tables, roles, clause, group key). Requires admin access.

Dynamic Plugins (superset/mcp_service/plugin/):

  • list_plugins — list registered dynamic plugins with filtering, search, column selection, sorting, and pagination.
  • get_plugin_info — get plugin details by ID (name, key, bundle_url, timestamps).

Both domains follow the established MCP service patterns:

  • @tool decorator with class_permission_name for RBAC ("Row Level Security", "DynamicPlugin")
  • ModelListCore / ModelGetInfoCore from mcp_core.py for reusable list/get logic
  • Pydantic schemas with model_serializer for column-filtered responses
  • ColumnOperator/ColumnOperatorEnum for structured filter objects
  • event_logger instrumentation and FastMCP ctx logging

The DynamicPluginDAO is co-located in superset/mcp_service/plugin/dao.py since no top-level DAO existed for the DynamicPlugin model.

The DEFAULT_INSTRUCTIONS in app.py are updated to clarify that get_schema covers chart/dataset/dashboard/database resource types only; RLS and plugin tools document their filterable/sortable columns inline in their docstrings.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

N/A — backend MCP tools only.

TESTING INSTRUCTIONS

  1. Start the MCP service
  2. Connect with an MCP client (e.g. Claude Desktop)
  3. Call list_rls_filters — returns paginated RLS filters with id, name, filter_type, clause by default
  4. Call list_rls_filters with select_columns: ["id", "name", "tables", "roles"] — includes relationship data
  5. Call get_rls_filter_info with a valid RLS filter ID — returns full filter details
  6. Call list_plugins — returns paginated plugin list with id, name, key, bundle_url by default
  7. Call get_plugin_info with a valid plugin ID — returns full plugin details

Unit tests: pytest tests/unit_tests/mcp_service/rls/ tests/unit_tests/mcp_service/plugin/

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

Live Test Results

Tested on staging Preset workspace (build ID: 36a56752, MCP server: claude.ai preset stg).

list_rls_filters

Request:

{}

Response:

{
  "rls_filters": [
    {"id": 1, "name": "QA Test - Country Filter", "filter_type": "Regular", "clause": "publisher = 'Nintendo'"}
  ],
  "count": 1,
  "total_count": 1,
  "page": 1,
  "page_size": 10,
  "total_pages": 1,
  "has_previous": false,
  "has_next": false,
  "columns_requested": ["id", "name", "filter_type", "clause"],
  "columns_loaded": ["id", "name", "filter_type", "clause"],
  "columns_available": ["id", "name", "description", "filter_type", "tables", "clause", "group_key", "created_on", "changed_on"],
  "sortable_columns": ["id", "name", "filter_type", "changed_on"],
  "filters_applied": [],
  "pagination": {"page": 1, "page_size": 10, "total_count": 1, "total_pages": 1, "has_next": false, "has_previous": false},
  "timestamp": "2026-05-29T17:13:05.492602Z"
}

✅ 1 RLS filter returned, no error.


get_rls_filter_info

Request:

{"identifier": 1}

Response:

{
  "id": 1,
  "name": "QA Test - Country Filter",
  "description": "QA test for ticket 100910",
  "filter_type": "Regular",
  "tables": [{"id": 2, "table_name": "Video Game Sales"}],
  "roles": [{"id": 17, "name": "new role"}],
  "clause": "publisher = 'Nintendo'",
  "group_key": "",
  "created_on": "2026-03-10T13:12:14.214592",
  "changed_on": "2026-03-10T17:20:59.654195"
}

✅ Full RLS filter detail returned including tables and roles, no error.


list_plugins

Request:

{}

Response:

{
  "plugins": [],
  "count": 0,
  "total_count": 0,
  "page": 1,
  "page_size": 10,
  "total_pages": 0,
  "has_previous": false,
  "has_next": false,
  "columns_requested": ["id", "name", "key", "bundle_url"],
  "columns_loaded": ["id", "name", "key", "bundle_url"],
  "columns_available": ["id", "name", "key", "bundle_url", "changed_on", "created_on"],
  "sortable_columns": ["id", "name", "key", "changed_on", "created_on"],
  "filters_applied": [],
  "pagination": {"page": 1, "page_size": 10, "total_count": 0, "total_pages": 0, "has_next": false, "has_previous": false},
  "timestamp": "2026-05-29T17:13:07.920617Z"
}

✅ Empty list, no permission error (this workspace has no custom plugins installed), columns_available present.


get_plugin_info

Request:

{"identifier": 9999}

Response:

{
  "error": "PluginInfo with identifier '9999' not found",
  "error_type": "not_found",
  "timestamp": "2026-05-29T17:13:09.104378Z"
}

✅ Structured not_found error, no permission error, no crash.

@aminghadersohi
aminghadersohi marked this pull request as ready for review May 22, 2026 04:04
@dosubot dosubot Bot added api Related to the REST API authentication:row-level-security Related to Row Level Security plugins labels May 22, 2026
@aminghadersohi
aminghadersohi requested a review from geido May 22, 2026 04:05

@geido geido left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed carefully given the sensitivity of RLS data. class_permission_name="Row Level Security" is in ADMIN_ONLY_VIEW_MENUS, so non-admins cannot see filter clauses, tables, or associated roles. MCP_RBAC_ENABLED defaults to True and check_tool_permission enforces can_read at call time. The deliberate bypass of USER_DIRECTORY_FIELDS for the RLS roles column is correct — that field represents policy scope, not user directory metadata, and the bypass only applies after the Admin gate has passed. Plugin tools expose only non-sensitive metadata.

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

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.

Code Review Agent Run #f6e20e

Actionable Suggestions - 1
  • superset/mcp_service/plugin/tool/list_plugins.py - 1
    • Type mismatch in serializer signature · Line 78-78
Additional Suggestions - 1
  • superset/mcp_service/rls/tool/list_rls_filters.py - 1
    • Serializer naming inconsistency · Line 78-78
      Rename the `_serialize` function to `_serialize_rls_filter` and update the `item_serializer` argument accordingly to match naming conventions used by other list tools.
Filtered by Review Rules

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

  • superset/mcp_service/rls/tool/get_rls_filter_info.py - 1
    • Async/sync context manager mismatch · Line 69-78
  • superset/mcp_service/plugin/schemas.py - 1
    • Missing filterable columns in schema · Line 62-62
Review Details
  • Files reviewed - 19 · Commit Range: 10ea6da..6e3a325
    • superset/mcp_service/app.py
    • superset/mcp_service/plugin/__init__.py
    • superset/mcp_service/plugin/dao.py
    • superset/mcp_service/plugin/schemas.py
    • superset/mcp_service/plugin/tool/__init__.py
    • superset/mcp_service/plugin/tool/get_plugin_info.py
    • superset/mcp_service/plugin/tool/list_plugins.py
    • superset/mcp_service/privacy.py
    • superset/mcp_service/rls/__init__.py
    • superset/mcp_service/rls/schemas.py
    • superset/mcp_service/rls/tool/__init__.py
    • superset/mcp_service/rls/tool/get_rls_filter_info.py
    • superset/mcp_service/rls/tool/list_rls_filters.py
    • tests/unit_tests/mcp_service/plugin/__init__.py
    • tests/unit_tests/mcp_service/plugin/tool/__init__.py
    • tests/unit_tests/mcp_service/plugin/tool/test_plugin_tools.py
    • tests/unit_tests/mcp_service/rls/__init__.py
    • tests/unit_tests/mcp_service/rls/tool/__init__.py
    • tests/unit_tests/mcp_service/rls/tool/test_rls_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

AI Code Review powered by Bito Logo

Comment thread superset/mcp_service/plugin/tool/list_plugins.py Outdated
@aminghadersohi

Copy link
Copy Markdown
Contributor Author

Addressed review feedback:

  • Fixed _serialize signature in both list_plugins.py and list_rls_filters.py: changed cols: list[str] | Nonecols: list[str] to match ModelListCore's item_serializer: Callable[[T, List[str]], S | None] contract (re: #discussion_r3292322761)
  • Updated filter_user_directory_fields docstring to mention roles

@github-actions github-actions Bot removed api Related to the REST API plugins labels May 27, 2026
@netlify

netlify Bot commented May 27, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 02e4137
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a1a56f5958b8800087663b4
😎 Deploy Preview https://deploy-preview-40347--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment thread superset/mcp_service/rls/tool/list_rls_filters.py
@codecov

codecov Bot commented May 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.59016% with 108 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.00%. Comparing base (62b4ee3) to head (69d170c).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
superset/mcp_service/rls/tool/list_rls_filters.py 29.72% 26 Missing ⚠️
superset/mcp_service/plugin/tool/list_plugins.py 35.71% 18 Missing ⚠️
superset/mcp_service/rls/schemas.py 81.44% 17 Missing and 1 partial ⚠️
superset/mcp_service/plugin/schemas.py 81.17% 15 Missing and 1 partial ⚠️
...uperset/mcp_service/plugin/tool/get_plugin_info.py 43.47% 13 Missing ⚠️
...perset/mcp_service/rls/tool/get_rls_filter_info.py 43.47% 13 Missing ⚠️
superset/mcp_service/plugin/dao.py 0.00% 4 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##           master   #40347    +/-   ##
========================================
  Coverage   64.00%   64.00%            
========================================
  Files        2629     2638     +9     
  Lines      141299   141604   +305     
  Branches    32545    32560    +15     
========================================
+ Hits        90432    90629   +197     
- Misses      49314    49420   +106     
- Partials     1553     1555     +2     
Flag Coverage Δ
hive 39.69% <64.59%> (+0.11%) ⬆️
mysql 58.52% <64.59%> (+0.02%) ⬆️
postgres 58.60% <64.59%> (+0.02%) ⬆️
presto 41.31% <64.59%> (+0.10%) ⬆️
python 60.10% <64.59%> (+0.02%) ⬆️
sqlite 58.25% <64.59%> (+0.02%) ⬆️
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.

@aminghadersohi

aminghadersohi commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

Integration test results

list_rls_filters ✅ and get_rls_filter_info ✅ both work correctly.

list_plugins ❌ and get_plugin_info ❌ fail with:

Permission denied: can_read on DynamicPlugin for user <workspace-admin>

In a multi-tenant deployment where workspace admins are mapped to a custom FAB role that does not include can_read on DynamicPlugin, these tools will fail. This permission exists on the standard Superset Admin role.

This likely needs a permission adjustment in the deployment's role config, or the plugin tools should use a less-restrictive permission if plugins are meant to be readable by any admin.

@aminghadersohi

aminghadersohi commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed staging report.

After investigating the permission setup:

Root cause: The plugin tools use class_permission_name="DynamicPlugin", which maps to the FAB DynamicPlugin model view — the correct and semantically appropriate permission for reading dynamic plugin records. The MCP auth layer calls security_manager.can_access("can_read", "DynamicPlugin").

In OSS Superset, DynamicPlugin is in READ_ONLY_MODEL_VIEWS (and transitively GAMMA_READ_ONLY_MODEL_VIEWS), so can_read on DynamicPlugin is granted to the standard Admin role via normal role sync. A custom admin role that does not explicitly include this permission will see the failure above.

Comparison with RLS tools: list_rls_filters / get_rls_filter_info use class_permission_name="Row Level Security", which is in ADMIN_ONLY_VIEW_MENUS. Those work because the deployment's role config explicitly grants can_read on Row Level Security. DynamicPlugin is simply missing from that same explicit grant list.

No OSS change needed: Switching class_permission_name to something unrelated (e.g., Dataset) would be semantically wrong — the tools read plugin records, not datasets. The current permission is correct.

Fix: Add can_read on DynamicPlugin to the custom admin role mapping in the deployment's role config, the same way can_read on Row Level Security is already granted there.

@bito-code-review

bito-code-review Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Bito Review Failed - Technical Failure

Bito encountered technical difficulties while fetching pull request comments. To retry, type /review in a comment and save. If the issue persists, contact support@bito.ai.

@aminghadersohi

Copy link
Copy Markdown
Contributor Author

A couple of schema issues worth addressing before merge:

RlsFilterInfo missing description
The RowLevelSecurityFilter model has a description column (Column(Text)). For an LLM trying to explain what an RLS filter does and why it exists, description is the single most useful field. Recommend adding it to RlsFilterInfo, serialize_rls_filter_object, and ALL_RLS_COLUMNS.

RlsFilterInfo missing created_on
The model has AuditMixinNullable so both created_on and changed_on are available. The schema includes changed_on but omits created_on. All sibling schemas in this suite include both timestamps. Recommend adding for consistency.

RlsColumnFilter naming
Every other filter class in the suite follows <Resource>Filter (e.g. QueryFilter, TagFilter, ReportFilter). RlsColumnFilter is the only outlier. Minor, but suggest renaming to RlsFilter for consistency (same feedback applies to TaskColumnFilter in #40344).

@aminghadersohi

Copy link
Copy Markdown
Contributor Author

Applied cross-PR feedback from Richard's thorough review on #40344 and #40348 — same patterns addressed here where applicable.

Checked each of Richard's patterns against this PR:

  • Config/feature flag guards (action-log/task issue): RLSRestApi and DynamicPluginsView are registered unconditionally in initialization/__init__.py with no equivalent is_enabled() guard — no MCP-level flag to mirror.
  • Datetime filter type coercion: RLS and plugin filter classes (RlsFilter.col: Literal["name", "filter_type"], plugin col: Literal["name", "key"]) have no datetime filter columns, so the dttm-as-string issue does not apply.
  • DEFAULT_INSTRUCTIONS (tools undocumented): All four tools are already in app.py's DEFAULT_INSTRUCTIONS (lines 127–132) with correct section headers.
  • columns_available advertising non-serializable fields: ALL_RLS_COLUMNS and ALL_PLUGIN_COLUMNS exactly match the fields defined in RlsFilterInfo and PluginInfo respectively — no advertised columns are silently dropped.
  • get_schema filter whitelist mismatch: get_schema only supports chart/dataset/dashboard/database model types; RLS and plugin tools are not in _SCHEMA_CORE_FACTORIES and document their filter columns inline in the tool docstring.
  • User-controlled payload returned raw (LLM injection risk): RLS and plugin tools return typed, structured data — no user-authored free-form JSON blobs equivalent to the action-log json field.

@aminghadersohi

Copy link
Copy Markdown
Contributor Author

Applied Richard's latest round of review feedback from #40344 and #40348 — cross-applicable patterns updated here.

@bito-code-review

bito-code-review Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #34e01a

Actionable Suggestions - 0
Review Details
  • Files reviewed - 6 · Commit Range: 6e3a325..544df09
    • superset/mcp_service/plugin/tool/list_plugins.py
    • superset/mcp_service/privacy.py
    • superset/mcp_service/rls/tool/list_rls_filters.py
    • tests/unit_tests/mcp_service/rls/tool/test_rls_tools.py
    • superset/mcp_service/rls/schemas.py
    • superset/mcp_service/rls/tool/get_rls_filter_info.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

Copy link
Copy Markdown
Contributor Author

Synced latest changes from #40344 and #40348 — applied all cross-applicable updates.

@aminghadersohi
aminghadersohi force-pushed the amin/mcp-rls-plugins branch from 544df09 to 02e4137 Compare May 30, 2026 03:18
aminghadersohi and others added 5 commits May 30, 2026 03:56
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…er roles to be returned

RLS filter `roles` (which roles a filter applies to) are core RLS data,
not user-directory metadata. Including 'roles' in USER_DIRECTORY_FIELDS
caused filter_user_directory_columns() to strip it from any requested
select_columns list, making it impossible to retrieve via list_rls_filters.

No dashboard/chart/dataset schema defines a 'roles' field, so removing it
from the block set has no privacy impact on other tools.

Fixes test_list_rls_filters_returns_tables_and_roles.
…in RLS list tool

'roles' on a dashboard/chart exposes who has access to the resource and
should be stripped by the USER_DIRECTORY_FIELDS privacy filter.

'roles' in an RLS filter is which roles the filter applies to — it is
core filter data, not user-directory metadata. The RLS list tool now
derives its column selection directly from ALL_RLS_COLUMNS (bypassing
ModelListCore's USER_DIRECTORY_FIELDS filtering) so that RLS roles are
selectable while dashboard roles remain hidden.

Fixes three failing unit tests:
- test_list_dashboards_omits_requested_user_directory_fields
- test_get_allowed_fields_always_denies_user_directory_fields
- test_filter_sensitive_data_strips_user_directory_fields_even_if_allowed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… ValueError in list_rls_filters

- Rename _serialize → _serialize_plugin in list_plugins.py and
  _serialize → _serialize_rls_filter in list_rls_filters.py to match
  naming convention used by all other list tools
- Fix type annotation cols: list[str] | None → list[str] in both
  serializer signatures to match ModelListCore Callable expectation
- Strip USER_DIRECTORY_FIELDS from select_columns before run_tool in
  list_rls_filters so a roles-only request no longer raises ValueError;
  the existing model_dump bypass restores roles in the output
- Add regression test for roles-only select_columns edge case

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@aminghadersohi
aminghadersohi force-pushed the amin/mcp-rls-plugins branch from 02e4137 to 69d170c Compare May 30, 2026 04:07

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

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.

Code Review Agent Run #28c2d8

Actionable Suggestions - 1
  • superset/mcp_service/plugin/tool/get_plugin_info.py - 1
Additional Suggestions - 2
  • superset/mcp_service/rls/tool/get_rls_filter_info.py - 1
    • Inconsistent tag in related tools · Line 41-41
      Inconsistent tag assignment: `get_rls_filter_info` uses `tags=["discovery"]` but its sibling `list_rls_filters` (line 48) uses `tags=["core"]`. All 15 `list_*.py` tools in the codebase use `tags=["core"]`; the `get_rls_filter_info` tool should follow the same pattern for consistent categorization in MCP tooling.
      Code suggestion
      --- a/superset/mcp_service/rls/tool/get_rls_filter_info.py
      +++ b/superset/mcp_service/rls/tool/get_rls_filter_info.py
       @@ -38,7 +38,7 @@
       
        @tool(
      -    tags=["discovery"],
      +    tags=["core"],
            class_permission_name="Row Level Security",
            annotations=ToolAnnotations(
                title="Get RLS filter info",
  • superset/mcp_service/plugin/tool/list_plugins.py - 1
    • Unused parameter cols · Line 78-79
      The `_serialize_plugin` closure accepts `cols: list[str]` but never uses it — `serialize_plugin_object` returns all fields regardless. Other serializers (e.g., `_serialize_user`) conditionally use `cols` for relationship loading. Consider passing `cols` through for consistency and future column-filtering support.
      Code suggestion
      --- a/superset/mcp_service/plugin/tool/list_plugins.py
      +++ b/superset/mcp_service/plugin/tool/list_plugins.py
       @@ -75,7 +75,10 @@ async def list_plugins(
                from superset.mcp_service.plugin.dao import DynamicPluginDAO
       
                def _serialize_plugin(obj: object, cols: list[str]) -> PluginInfo | None:
      -            return serialize_plugin_object(obj)
      +            # Note: cols parameter available for future column-based filtering
      +            # Current serialize_plugin_object returns all fields.
      +            # Use cols if selective field serialization is needed later.
      +            return serialize_plugin_object(obj)
       
                list_tool = ModelListCore(
Filtered by Review Rules

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

  • superset/mcp_service/rls/tool/list_rls_filters.py - 1
  • superset/mcp_service/rls/tool/get_rls_filter_info.py - 1
    • Broad exception catch masking errors · Line 92-92
  • superset/mcp_service/privacy.py - 1
Review Details
  • Files reviewed - 19 · Commit Range: 5771bce..69d170c
    • superset/mcp_service/app.py
    • superset/mcp_service/plugin/__init__.py
    • superset/mcp_service/plugin/dao.py
    • superset/mcp_service/plugin/schemas.py
    • superset/mcp_service/plugin/tool/__init__.py
    • superset/mcp_service/plugin/tool/get_plugin_info.py
    • superset/mcp_service/plugin/tool/list_plugins.py
    • superset/mcp_service/privacy.py
    • superset/mcp_service/rls/__init__.py
    • superset/mcp_service/rls/schemas.py
    • superset/mcp_service/rls/tool/__init__.py
    • superset/mcp_service/rls/tool/get_rls_filter_info.py
    • superset/mcp_service/rls/tool/list_rls_filters.py
    • tests/unit_tests/mcp_service/plugin/__init__.py
    • tests/unit_tests/mcp_service/plugin/tool/__init__.py
    • tests/unit_tests/mcp_service/plugin/tool/test_plugin_tools.py
    • tests/unit_tests/mcp_service/rls/__init__.py
    • tests/unit_tests/mcp_service/rls/tool/__init__.py
    • tests/unit_tests/mcp_service/rls/tool/test_rls_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

AI Code Review powered by Bito Logo


return result

except Exception as e:

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.

Avoid catching blind Exception

Replace the broad Exception catch with specific exception types (e.g., ValueError, KeyError, or custom exceptions) to improve error handling and debugging.

Code suggestion
Check the AI-generated fix before applying
Suggested change
except Exception as e:
except (ValueError, KeyError, AttributeError) as e:

Code Review Run #28c2d8


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

  • Yes, avoid them

@aminghadersohi
aminghadersohi merged commit 87be424 into apache:master May 30, 2026
58 of 59 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants