Skip to main content
Glama

dbt-mcp

Official
by dbt-labs
tools.py3.98 kB
import functools import inspect import logging from collections.abc import Callable, Sequence from typing import Any from mcp.server.fastmcp import FastMCP from pydantic import Field from dbt_mcp.lsp.providers.lsp_client_provider import LSPClientProvider from dbt_mcp.prompts.prompts import get_prompt from dbt_mcp.tools.annotations import create_tool_annotations from dbt_mcp.tools.definitions import ToolDefinition from dbt_mcp.tools.register import register_tools from dbt_mcp.tools.tool_names import ToolName logger = logging.getLogger(__name__) async def register_lsp_tools( server: FastMCP, lspClientProvider: LSPClientProvider, exclude_tools: Sequence[ToolName] | None = None, ) -> None: register_tools( server, await list_lsp_tools(lspClientProvider), exclude_tools or [], ) async def list_lsp_tools( lspClientProvider: LSPClientProvider, ) -> list[ToolDefinition]: """Register dbt Fusion tools with the MCP server. Args: config: LSP configuration containing LSP settings Returns: List of tool definitions for LSP tools """ def call_with_lsp_client(func: Callable) -> Callable: """Call a function with the LSP connection manager.""" @functools.wraps(func) async def wrapper(*args, **kwargs) -> Any: return await func(lspClientProvider, *args, **kwargs) # remove the lsp_client argument from the signature wrapper.__signature__ = inspect.signature(func).replace( # type: ignore parameters=[ param for param in inspect.signature(func).parameters.values() if param.name != "lsp_client_provider" ] ) return wrapper return [ ToolDefinition( fn=call_with_lsp_client(get_column_lineage), description=get_prompt("lsp/get_column_lineage"), annotations=create_tool_annotations( title="get_column_lineage", read_only_hint=False, destructive_hint=False, idempotent_hint=True, ), ), ] async def get_column_lineage( lsp_client_provider: LSPClientProvider, model_id: str = Field(description=get_prompt("lsp/args/model_id")), column_name: str = Field(description=get_prompt("lsp/args/column_name")), ) -> dict[str, Any]: """Get column lineage for a specific model column. Args: lsp_client: The LSP client instance model_id: The dbt model identifier column_name: The column name to trace lineage for Returns: Dictionary with either: - 'nodes' key containing lineage information on success - 'error' key containing error message on failure """ try: lsp_client = await lsp_client_provider.get_client() response = await lsp_client.get_column_lineage( model_id=model_id, column_name=column_name, ) # Check for LSP-level errors if "error" in response: logger.error(f"LSP error getting column lineage: {response['error']}") return {"error": f"LSP error: {response['error']}"} # Validate response has expected data if "nodes" not in response or not response["nodes"]: logger.warning(f"No column lineage found for {model_id}.{column_name}") return { "error": f"No column lineage found for model {model_id} and column {column_name}" } return {"nodes": response["nodes"]} except TimeoutError: error_msg = f"Timeout waiting for column lineage (model: {model_id}, column: {column_name})" logger.error(error_msg) return {"error": error_msg} except Exception as e: error_msg = ( f"Failed to get column lineage for {model_id}.{column_name}: {str(e)}" ) logger.error(error_msg) return {"error": error_msg}

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dbt-labs/dbt-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server