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]

Reply via email to