aminghadersohi opened a new pull request, #44143:
URL: https://github.com/apache/superset/pull/44143
### SUMMARY
Improve dataset discovery and add optional role-based MCP dataset routing:
- Search `description` alongside schema, SQL, table name, and UUID. The
existing DAO supports it through escaped, case-insensitive substring
predicates. The original implementation omitted it, and the later change
returning descriptions did not change search; no documented exclusion rationale
was found.
- Preserve existing query provenance (`dataset_id` / `dataset_name`, and
`get_table` source identity), strengthen regression coverage, and instruct
clients to compare discovery candidates, disclose ambiguous alternatives, and
cite the actual query source. No redundant provenance response format is
introduced.
- Add `MCP_DATASET_ROLE_ALLOWLIST`, mapping effective role names to dataset
UUIDs. Role lists are unioned, then constrained by normal dataset access.
`None` preserves existing behavior; an empty mapping permits no datasets.
Unconfigured roles contribute nothing, including Admin. Permissions, query
validation, and RLS remain unchanged.
- Enforce routing in the shared MCP invocation layer, and filter discovery
before count/pagination. Requests outside scope refuse explicitly and never
select a substitute.
**Conservative scoped-mode surface:** dataset discovery/info,
`query_dataset`, built-in-dataset `get_table`, `health_check`, and
`get_schema`. Other operations refuse when this optional mode is enabled,
including SQL Lab, chart/dashboard data and previews, cached query results,
external semantic views, mutations, and extension tools. Their data cannot all
be reliably attributed to registered dataset UUIDs. This avoids pretending to
enforce SQL lineage. Scope is a usability control over registered datasets, not
a security boundary or physical-table allowlist.
**Search cost:** a local synthetic SQLite benchmark with 100,000 rows,
approximately 500-byte SQL and 1 KB descriptions, measured median
count-plus-page latency across six iterations:
| Search | Four fields | With description |
| --- | ---: | ---: |
| Description-only match | 399 ms | 613 ms |
| No match | 391 ms | 730 ms |
Both plans remain a catalog scan; no joins or queries are added. This is
measurable overhead, not an indexed-search optimization. Documentation calls
out large-catalog latency and deployment-specific benchmarking. The production
DAO is also exercised against SQLite in the regression test.
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Not applicable (MCP backend).
Before: business terms appearing only in descriptions were undiscoverable.
After: those datasets appear among the search candidates. Existing searches
with no matches already return zero results; there is no server-side
recent-dataset fallback to preserve or remove.
Before: MCP had no per-role routing scope. After: operators can opt into a
curated dataset-only tool surface, without granting any additional access.
### TESTING INSTRUCTIONS
1. Give an accessible dataset a description containing a term absent from
its name, schema, SQL, and UUID. Call `list_datasets` with that term and verify
it appears. Verify unmatched terms return no results and literal `%`/`_` are
escaped.
2. Configure two roles with overlapping UUID lists. Give a user both roles
and access to only a subset of the union. Verify discovery and queries expose
only the intersection, including correct count/page behavior.
3. Query an accessible dataset outside the allowlist by numeric ID, numeric
string, and UUID. Verify an explicit refusal and no query execution or
substitution. An allowlisted but inaccessible dataset must also refuse.
4. Query an allowed dataset with `query_dataset` and `get_table`; verify the
response identifies the requested source. Confirm normal query validation and
RLS remain in effect.
5. With scope enabled, try SQL, chart data/preview, and external-view
queries; verify refusal. With `MCP_DATASET_ROLE_ALLOWLIST = None`, verify
existing behavior is preserved.
Validation:
```bash
pytest tests/unit_tests/mcp_service/test_dataset_scope.py \
tests/unit_tests/mcp_service/dataset/tool/test_dataset_tools.py \
tests/unit_tests/mcp_service/dataset/tool/test_query_dataset.py \
tests/unit_tests/mcp_service/semantic_layer/tool/test_get_table.py
uvx pre-commit run --files <changed files>
```
The focused suite passes (240 tests). Broader MCP tests are also being run;
the known clean-tree failure
`test_tools_call_health_check_over_real_asgi_transport` is excluded from that
local run, not modified or skipped in the repository.
### ADDITIONAL INFORMATION
- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration (follow approval process in
[SIP-59](https://github.com/apache/superset/issues/13351))
- [ ] Migration is atomic, supports rollback & is backwards-compatible
- [ ] Confirm DB migration upgrade and downgrade tested
- [ ] Runtime estimates and downtime expectations provided
- [x] Introduces new feature or API
- [ ] Removes existing feature or API
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]