Skip to content

Commit 912be1c

Browse files
authored
Share multi-project project_id description for Discovery and Semantic layer (#758)
## Summary Consolidated `project_id` description between multi-project semantic layer and discovery usages. ## Checklist - [x] I have performed a self-review of my code - [x] I have made corresponding changes to the documentation (in https://github.com/dbt-labs/docs.getdbt.com) if required -- Mention it here - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes
1 parent e2a02d2 commit 912be1c

5 files changed

Lines changed: 33 additions & 30 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
kind: Enhancement or New Feature
2+
body: Share multi-project project_id description for Discovery and Semantic layer
3+
time: 2026-05-06T10:12:33.706765-05:00

src/dbt_mcp/discovery/param_descriptions.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
"""JSON Schema parameter descriptions and Field() defaults for Discovery MCP tools."""
1+
"""JSON Schema parameter descriptions for Discovery MCP tools."""
22

3-
from pydantic import Field
3+
from dbt_mcp.tools.multiproject_params import MULTI_PROJECT_PROJECT_ID_DESCRIPTION
44

5-
DISCOVERY_PROJECT_ID_DESCRIPTION = (
6-
"The dbt Cloud project ID to query. "
7-
"Use list_projects_and_environments to discover available project IDs."
8-
)
9-
10-
PROJECT_ID_FIELD = Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)
5+
DISCOVERY_PROJECT_ID_DESCRIPTION = MULTI_PROJECT_PROJECT_ID_DESCRIPTION
116

127
SOURCE_NAMES_FILTER = (
138
"Filter by top-level source names from the project `sources:` YAML "

src/dbt_mcp/discovery/tools_multiproject.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
SourcesFetcher,
2323
)
2424
from dbt_mcp.discovery.param_descriptions import (
25+
DISCOVERY_PROJECT_ID_DESCRIPTION,
2526
MACRO_INCLUDE_DEFAULT_DBT_PACKAGES,
2627
MACRO_PACKAGE_NAMES,
2728
MACRO_RETURN_PACKAGE_NAMES_ONLY,
2829
MODEL_PERF_INCLUDE_TESTS,
2930
MODEL_PERF_NUM_RUNS,
30-
PROJECT_ID_FIELD,
3131
SOURCE_NAMES_FILTER,
3232
SOURCE_UNIQUE_IDS_FILTER,
3333
)
@@ -123,7 +123,7 @@ def __init__(
123123
)
124124
async def get_mart_models(
125125
context: MultiProjectDiscoveryToolContext,
126-
project_id: int = PROJECT_ID_FIELD,
126+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
127127
) -> list[dict]:
128128
config = await context.config_provider.get_config(project_id=project_id)
129129
mart_models = await context.models_fetcher.fetch_models(
@@ -142,7 +142,7 @@ async def get_mart_models(
142142
)
143143
async def get_all_models(
144144
context: MultiProjectDiscoveryToolContext,
145-
project_id: int = PROJECT_ID_FIELD,
145+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
146146
) -> list[dict]:
147147
# TODO: push code into fetchers
148148
config = await context.config_provider.get_config(project_id=project_id)
@@ -158,7 +158,7 @@ async def get_all_models(
158158
)
159159
async def get_model_details(
160160
context: MultiProjectDiscoveryToolContext,
161-
project_id: int = PROJECT_ID_FIELD,
161+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
162162
name: str | None = NAME_FIELD,
163163
unique_id: str | None = UNIQUE_ID_FIELD,
164164
) -> list[dict]:
@@ -180,7 +180,7 @@ async def get_model_details(
180180
)
181181
async def get_model_parents(
182182
context: MultiProjectDiscoveryToolContext,
183-
project_id: int = PROJECT_ID_FIELD,
183+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
184184
name: str | None = NAME_FIELD,
185185
unique_id: str | None = UNIQUE_ID_FIELD,
186186
) -> list[dict]:
@@ -199,7 +199,7 @@ async def get_model_parents(
199199
)
200200
async def get_model_children(
201201
context: MultiProjectDiscoveryToolContext,
202-
project_id: int = PROJECT_ID_FIELD,
202+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
203203
name: str | None = NAME_FIELD,
204204
unique_id: str | None = UNIQUE_ID_FIELD,
205205
) -> list[dict]:
@@ -218,7 +218,7 @@ async def get_model_children(
218218
)
219219
async def get_model_health(
220220
context: MultiProjectDiscoveryToolContext,
221-
project_id: int = PROJECT_ID_FIELD,
221+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
222222
name: str | None = NAME_FIELD,
223223
unique_id: str | None = UNIQUE_ID_FIELD,
224224
) -> list[dict]:
@@ -239,7 +239,7 @@ async def get_model_health(
239239
)
240240
async def get_model_performance(
241241
context: MultiProjectDiscoveryToolContext,
242-
project_id: int = PROJECT_ID_FIELD,
242+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
243243
name: str | None = NAME_FIELD,
244244
unique_id: str | None = UNIQUE_ID_FIELD,
245245
num_runs: int = Field(
@@ -272,7 +272,7 @@ async def get_model_performance(
272272
)
273273
async def get_lineage(
274274
context: MultiProjectDiscoveryToolContext,
275-
project_id: int = PROJECT_ID_FIELD,
275+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
276276
unique_id: str = UNIQUE_ID_REQUIRED_FIELD,
277277
types: list[LineageResourceType] | None = TYPES_FIELD,
278278
depth: int = DEPTH_FIELD,
@@ -292,7 +292,7 @@ async def get_lineage(
292292
)
293293
async def get_exposures(
294294
context: MultiProjectDiscoveryToolContext,
295-
project_id: int = PROJECT_ID_FIELD,
295+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
296296
) -> list[dict]:
297297
config = await context.config_provider.get_config(project_id=project_id)
298298
return await context.exposures_fetcher.fetch_exposures(config=config)
@@ -307,7 +307,7 @@ async def get_exposures(
307307
)
308308
async def get_exposure_details(
309309
context: MultiProjectDiscoveryToolContext,
310-
project_id: int = PROJECT_ID_FIELD,
310+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
311311
name: str | None = NAME_FIELD,
312312
unique_id: str | None = UNIQUE_ID_FIELD,
313313
) -> list[dict]:
@@ -329,7 +329,7 @@ async def get_exposure_details(
329329
)
330330
async def get_all_sources(
331331
context: MultiProjectDiscoveryToolContext,
332-
project_id: int = PROJECT_ID_FIELD,
332+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
333333
source_names: Annotated[
334334
list[str] | None, Field(description=SOURCE_NAMES_FILTER)
335335
] = None,
@@ -352,7 +352,7 @@ async def get_all_sources(
352352
)
353353
async def get_source_details(
354354
context: MultiProjectDiscoveryToolContext,
355-
project_id: int = PROJECT_ID_FIELD,
355+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
356356
name: str | None = NAME_FIELD,
357357
unique_id: str | None = UNIQUE_ID_FIELD,
358358
) -> list[dict]:
@@ -374,7 +374,7 @@ async def get_source_details(
374374
)
375375
async def get_all_macros(
376376
context: MultiProjectDiscoveryToolContext,
377-
project_id: int = PROJECT_ID_FIELD,
377+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
378378
package_names: Annotated[
379379
list[str] | None, Field(description=MACRO_PACKAGE_NAMES)
380380
] = None,
@@ -403,7 +403,7 @@ async def get_all_macros(
403403
)
404404
async def get_macro_details(
405405
context: MultiProjectDiscoveryToolContext,
406-
project_id: int = PROJECT_ID_FIELD,
406+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
407407
name: str | None = NAME_FIELD,
408408
unique_id: str | None = UNIQUE_ID_FIELD,
409409
) -> list[dict]:
@@ -425,7 +425,7 @@ async def get_macro_details(
425425
)
426426
async def get_seed_details(
427427
context: MultiProjectDiscoveryToolContext,
428-
project_id: int = PROJECT_ID_FIELD,
428+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
429429
name: str | None = NAME_FIELD,
430430
unique_id: str | None = UNIQUE_ID_FIELD,
431431
) -> list[dict]:
@@ -447,7 +447,7 @@ async def get_seed_details(
447447
)
448448
async def get_semantic_model_details(
449449
context: MultiProjectDiscoveryToolContext,
450-
project_id: int = PROJECT_ID_FIELD,
450+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
451451
name: str | None = NAME_FIELD,
452452
unique_id: str | None = UNIQUE_ID_FIELD,
453453
) -> list[dict]:
@@ -469,7 +469,7 @@ async def get_semantic_model_details(
469469
)
470470
async def get_snapshot_details(
471471
context: MultiProjectDiscoveryToolContext,
472-
project_id: int = PROJECT_ID_FIELD,
472+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
473473
name: str | None = NAME_FIELD,
474474
unique_id: str | None = UNIQUE_ID_FIELD,
475475
) -> list[dict]:
@@ -491,7 +491,7 @@ async def get_snapshot_details(
491491
)
492492
async def get_test_details(
493493
context: MultiProjectDiscoveryToolContext,
494-
project_id: int = PROJECT_ID_FIELD,
494+
project_id: Annotated[int, Field(description=DISCOVERY_PROJECT_ID_DESCRIPTION)],
495495
name: str | None = NAME_FIELD,
496496
unique_id: str | None = UNIQUE_ID_FIELD,
497497
) -> list[dict]:

src/dbt_mcp/semantic_layer/param_descriptions.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
"""JSON Schema parameter descriptions for Semantic Layer MCP tools."""
22

33
from dbt_mcp.dbt_admin.param_descriptions import PAGINATION_LIMIT
4+
from dbt_mcp.tools.multiproject_params import MULTI_PROJECT_PROJECT_ID_DESCRIPTION
45

56
# Reuse Admin API wording for semantic query row limits (single source of truth).
67
QUERY_RESULT_LIMIT = PAGINATION_LIMIT
78

8-
SEMANTIC_LAYER_PROJECT_ID = (
9-
"Numeric dbt Cloud project ID to use for this Semantic Layer call"
10-
)
9+
SEMANTIC_LAYER_PROJECT_ID = MULTI_PROJECT_PROJECT_ID_DESCRIPTION
1110

1211
SEMANTIC_SEARCH_METRICS = "Filter metrics by substring match against the metric name"
1312

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""Shared MCP parameter descriptions for multi-project (dbt Cloud) tool variants."""
2+
3+
MULTI_PROJECT_PROJECT_ID_DESCRIPTION = (
4+
"dbt Cloud numeric project ID for this call. "
5+
"Use list_projects to discover valid project IDs."
6+
)

0 commit comments

Comments
 (0)