From 343fbae4312ddc66501a63387139f21949c07fbd Mon Sep 17 00:00:00 2001 From: Aman Sharma Date: Mon, 7 Apr 2025 06:12:28 +0530 Subject: [PATCH 1/3] Fix: Use absolute path to uv executable in Claude Desktop config --- src/mcp/cli/claude.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/mcp/cli/claude.py b/src/mcp/cli/claude.py index 5a0ce0ab4..f5abcdb50 100644 --- a/src/mcp/cli/claude.py +++ b/src/mcp/cli/claude.py @@ -5,6 +5,7 @@ import sys from pathlib import Path from typing import Any +import shutil from mcp.server.fastmcp.utilities.logging import get_logger @@ -30,6 +31,16 @@ def get_claude_config_path() -> Path | None: return path return None +def get_uv_path() -> str: + """Get the full path to the uv executable.""" + uv_path = shutil.which("uv") + if not uv_path: + logger.error( + "uv executable not found in PATH, falling back to 'uv'. " + "Please ensure uv is installed and in your PATH" + ) + return "uv" # Fall back to just "uv" if not found + return uv_path def update_claude_config( file_spec: str, @@ -54,6 +65,7 @@ def update_claude_config( Claude Desktop may not be installed or properly set up. """ config_dir = get_claude_config_path() + uv_path = get_uv_path() if not config_dir: raise RuntimeError( "Claude Desktop config directory not found. Please ensure Claude Desktop" @@ -117,7 +129,7 @@ def update_claude_config( # Add fastmcp run command args.extend(["mcp", "run", file_spec]) - server_config: dict[str, Any] = {"command": "uv", "args": args} + server_config: dict[str, Any] = {"command": uv_path, "args": args} # Add environment variables if specified if env_vars: From 490132a71968cba5435fc230e4e0ae8a8f0075e8 Mon Sep 17 00:00:00 2001 From: Aman Sharma Date: Mon, 7 Apr 2025 06:19:52 +0530 Subject: [PATCH 2/3] Fix: Use absolute path to uv executable in Claude Desktop config --- src/mcp/cli/claude.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mcp/cli/claude.py b/src/mcp/cli/claude.py index f5abcdb50..17c957df2 100644 --- a/src/mcp/cli/claude.py +++ b/src/mcp/cli/claude.py @@ -2,10 +2,10 @@ import json import os +import shutil import sys from pathlib import Path from typing import Any -import shutil from mcp.server.fastmcp.utilities.logging import get_logger From c32c33832b3ec4d15f1e4c9f338385b5e1232487 Mon Sep 17 00:00:00 2001 From: Aman Sharma Date: Mon, 7 Apr 2025 17:05:06 +0530 Subject: [PATCH 3/3] Fix: Use absolute path to uv executable in Claude Desktop config --- tests/client/test_config.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/client/test_config.py b/tests/client/test_config.py index 97030e069..6577d663c 100644 --- a/tests/client/test_config.py +++ b/tests/client/test_config.py @@ -48,3 +48,28 @@ def test_command_execution(mock_config_path: Path): assert result.returncode == 0 assert "usage" in result.stdout.lower() + + +def test_absolute_uv_path(mock_config_path: Path): + """Test that the absolute path to uv is used when available.""" + # Mock the shutil.which function to return a fake path + mock_uv_path = "/usr/local/bin/uv" + + with patch("mcp.cli.claude.get_uv_path", return_value=mock_uv_path): + # Setup + server_name = "test_server" + file_spec = "test_server.py:app" + + # Update config + success = update_claude_config(file_spec=file_spec, server_name=server_name) + assert success + + # Read the generated config + config_file = mock_config_path / "claude_desktop_config.json" + config = json.loads(config_file.read_text()) + + # Verify the command is the absolute path + server_config = config["mcpServers"][server_name] + command = server_config["command"] + + assert command == mock_uv_path \ No newline at end of file