Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind: Enhancement or New Feature
body: Add new tool to get the MCP server version
time: 2025-06-04T16:27:49.547265+02:00
4 changes: 4 additions & 0 deletions src/dbt_mcp/mcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from dbt_mcp.config.config import load_config
from dbt_mcp.dbt_cli.tools import register_dbt_cli_tools
from dbt_mcp.discovery.tools import register_discovery_tools
from dbt_mcp.meta.tools import register_meta_tools
from dbt_mcp.remote.tools import register_remote_tools
from dbt_mcp.semantic_layer.tools import register_sl_tools
from dbt_mcp.tracking.tracking import UsageTracker
Expand Down Expand Up @@ -90,6 +91,9 @@ async def call_tool(
async def create_dbt_mcp():
dbt_mcp = DbtMCP(usage_tracker=UsageTracker(), name="dbt", lifespan=app_lifespan)

logger.info("Registering meta tools")
register_meta_tools(dbt_mcp)
Comment on lines +94 to +95
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be behind an env var like the other tools, DISABLE_META_TOOLS? By default, I think this should be disabled.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My opposite take 😄 is that

  • I wouldn't want to add another env var (we already have quite a few)
  • using this tool doesn't require any additional config, so I don't think it will do any harm having it On automatically
  • Claude Desktop (and I guess other MCP clients) allow deactivating those at the application layer

image

But those are just my opinions and if it doesn't change yours then I can add an env var 😉

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still lean toward adding an env var, just to be consistent with the other tools. We can disable it by default, and we can document it in CONTRIBUTING.md instead of README.md since it is meant for debugging. So, it shouldn't add much confusion. I don't think Cursor allows you to disable individual tools.

However, it is up to you, though. I think either approach works.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think @reneruck-dbt?

Copy link
Collaborator

@reneruck-dbt reneruck-dbt Jun 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of your arguments are valid.
It is for debugging, makes sense. And yes, we've been very deliberate and flexible about what tools should be enabled in the first place.

In what scenarios would we need this function?
The most likely scenario I can think of is helping an end-user figure out why a certain piece of functionality does not work or works differently than expected.

The first two questions I'd ask would be:

  1. What version of the dbt-mcp server are you running
  2. Show me your config (with redacted API keys)

I'm wondering if that does not point to a different type of print_debug_info kind of tool or maybe even a resource?
For the time being the configuration is kinda manually crafted so the user knows where to find it.
oAuth will come around soon(-ish) and will hopefully wipe away most of this config overhead.
This makes a function like that more interesting.

Should that tool always be available?

Do we want an explicit "debug mode" which brings along this tool (+ others) and maybe more verbose logging?
In that case a ENABLE_DEBUG_MODE flag does make sense, you don't want to confuse the AI and fill the prompt context with tools.

If all we're providing is a get_server_version and end there, I'd see the overhead this tool adds as negligible.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think a tool to print out Cursor/Claude JSON config could be helpful. A tool to dump environment variables could also be helpful. In the near term, I don't think we need to add different logging levels, but that may come up.


if config.semantic_layer_config:
logger.info("Registering semantic layer tools")
register_sl_tools(dbt_mcp, config.semantic_layer_config)
Expand Down
15 changes: 15 additions & 0 deletions src/dbt_mcp/meta/tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import logging
from importlib.metadata import version

from mcp.server.fastmcp import FastMCP

from dbt_mcp.prompts.prompts import get_prompt


logger = logging.getLogger(__name__)


def register_meta_tools(dbt_mcp: FastMCP) -> None:
@dbt_mcp.tool(description=get_prompt("meta/get_dbt_mcp_server_version"))
def get_dbt_mcp_server_version() -> str:
return version("dbt-mcp")
1 change: 1 addition & 0 deletions src/dbt_mcp/prompts/meta/get_dbt_mcp_server_version.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this tool returns the current version of the dbt MCP server
41 changes: 41 additions & 0 deletions tests/unit/meta/test_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import unittest
from unittest.mock import MagicMock, patch

from dbt_mcp.meta.tools import register_meta_tools


class TestMetaTools(unittest.TestCase):
def test_get_dbt_mcp_server_version(self):
# Create a mock FastMCP
mock_fastmcp = MagicMock()

# Capture the registered tools
tools = {}

# Patch the tool decorator to capture functions
def mock_tool_decorator(**kwargs):
def decorator(func):
tools[func.__name__] = func
return func

return decorator

mock_fastmcp.tool = mock_tool_decorator

# Register the tools
register_meta_tools(mock_fastmcp)

# Test the get_dbt_mcp_server_version function
with patch("dbt_mcp.meta.tools.version") as mock_version:
mock_version.return_value = "1.0.0"
result = tools["get_dbt_mcp_server_version"]()

# Verify the version function was called with correct package name
mock_version.assert_called_once_with("dbt-mcp")

# Verify the result
self.assertEqual(result, "1.0.0")


if __name__ == "__main__":
unittest.main()
Loading