feat(semantic-layer): add get_dimension_values tool#782
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a Semantic Layer get_dimension_values tool for discovering dimension filter values before calling query_metrics.
Changes:
- Registers the new Semantic Layer tool and adds parameter descriptions/prompt documentation.
- Adds
DimensionValuesResponseand fetcher logic using the Semantic Layer SDK. - Adds unit coverage for response creation and basic fetch/truncation behavior, plus README/changelog updates.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/dbt_mcp/semantic_layer/client.py |
Adds fetcher support for retrieving and truncating dimension values. |
src/dbt_mcp/semantic_layer/tools.py |
Exposes get_dimension_values as an MCP tool. |
src/dbt_mcp/semantic_layer/types.py |
Adds the structured response dataclass. |
src/dbt_mcp/semantic_layer/param_descriptions.py |
Adds descriptions for the new tool parameters. |
src/dbt_mcp/prompts/semantic_layer/get_dimension_values.md |
Adds tool usage guidance and examples. |
src/dbt_mcp/tools/tool_names.py |
Adds the new tool enum value. |
src/dbt_mcp/tools/toolsets.py |
Includes the new tool in the Semantic Layer toolset. |
src/dbt_mcp/tools/readme_mappings.py |
Adds the README description mapping. |
tests/unit/semantic_layer/test_client.py |
Adds unit tests for dimension values behavior. |
README.md |
Documents the new Semantic Layer tool. |
docs/diagram.mmd |
Adds a Mermaid architecture diagram including the new tool. |
.changes/unreleased/Enhancement or New Feature-20260519-141400.yaml |
Adds an enhancement changelog entry. |
.changes/unreleased/Bug Fix-20260519-142146.yaml |
Adds a bug-fix changelog entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add DimensionValuesResponse dataclass to semantic_layer/types.py with values list and truncated flag. Include tests to verify the type can be instantiated and used correctly.
The SDK's dimension_values returns a pa.Table, not a list[str]. Extract the first column via .column(0).to_pylist() before slicing. Update protocol stub return type and tests to use real pa.Table mock return values.
…validation - DimensionValuesResponse.values widened from list[str] to list[Any] to handle non-string dimension types (integers, dates, etc.) - get_dimension_values now wraps body in try/except, re-raising as RuntimeError via _format_semantic_layer_error for clean error propagation - limit param gains ge=1 validation to prevent empty/negative-slice bugs - Add boundary test: N items with limit=N yields truncated=False - Add get_dimension_values to docs/diagram.mmd Semantic Layer subgraph
… to empty string Null values are not valid filter values and would produce invalid where clauses if returned. Also adds a test covering null omission and corrects the changelog entry describing the list[str] fix.
4392825 to
b685479
Compare
| ToolName.LIST_SAVED_QUERIES, | ||
| ToolName.GET_DIMENSIONS, | ||
| ToolName.GET_ENTITIES, | ||
| ToolName.GET_DIMENSION_VALUES, |
There was a problem hiding this comment.
Nearly all docs today are automated via existing scripts in scripts/ and the use of task docs:generate. This mermaid diagram is not included in that and will drift.
Should we (1) include this mermaid generation in docs automation in this PR or (2) exclude the file from here and open another PR for this addition in particular?
| # SDK doesn't support server-side limiting; truncation is applied client-side. | ||
| raw: list[str] = [ | ||
| str(v) for v in raw_table.column(dimension).to_pylist() if v is not None | ||
| ] |
There was a problem hiding this comment.
I tested this locally and a bug came up - the SDK looks to return column names in uppercase and if the dimension is passed as lowercase, there is a mismatch and we get Error: Error executing tool get_dimension_values: 'Field "<field_name>" does not exist in schema'
I was able to fix it by adding a change locally to implement a case-insensitive lookup
There was a problem hiding this comment.
Non-blocker!
mock_sl_client setup and SemanticLayerConfig construction are copy-pasted across all the tests here - may be worth to extract them into class level fixtures for sake of being DRY
| @@ -28,6 +30,7 @@ | |||
| ) | |||
| from dbt_mcp.semantic_layer.types import ( | |||
| DimensionToolResponse, | |||
| DimensionValuesResponse, | |||
| EntityToolResponse, | |||
| GetMetricsCompiledSqlSuccess, | |||
| ListMetricsResponse, | |||
There was a problem hiding this comment.
Do we also need to add these and register the new tool in src/dbt_mcp/semantic_layer/tools_multiproject.py as well? SL tools are registered in both the single and multiproject modules.
Summary
get_dimension_valuestool to the Semantic Layer toolsetlimit(default 100); atruncatedflag signals when more values exist beyond the limitquery_metricsto discover valid filter values forwhereclausesImplementation notes
SyncSemanticLayerClient.dimension_values(ADBC / Arrow Flight SQL), which is lightweight — no metric aggregationDimensionValuesResponse(values: list[str], truncated: bool); all column values are stringified for consistent handling regardless of the underlying dimension type (dates, integers, etc.)limitis validated asge=1to prevent empty-but-non-truncated responses_format_semantic_layer_error)Test plan
uv run pytest tests/unit/semantic_layer/test_client.py -k "dimension_values" -vuv run pytest tests/unit/ -x -qtask check