Skip to content

Commit 280bab3

Browse files
authored
Fix: Use absolute path to uv executable in Claude Desktop config (#440)
1 parent a027d75 commit 280bab3

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

src/mcp/cli/claude.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import json
44
import os
5+
import shutil
56
import sys
67
from pathlib import Path
78
from typing import Any
@@ -30,6 +31,16 @@ def get_claude_config_path() -> Path | None:
3031
return path
3132
return None
3233

34+
def get_uv_path() -> str:
35+
"""Get the full path to the uv executable."""
36+
uv_path = shutil.which("uv")
37+
if not uv_path:
38+
logger.error(
39+
"uv executable not found in PATH, falling back to 'uv'. "
40+
"Please ensure uv is installed and in your PATH"
41+
)
42+
return "uv" # Fall back to just "uv" if not found
43+
return uv_path
3344

3445
def update_claude_config(
3546
file_spec: str,
@@ -54,6 +65,7 @@ def update_claude_config(
5465
Claude Desktop may not be installed or properly set up.
5566
"""
5667
config_dir = get_claude_config_path()
68+
uv_path = get_uv_path()
5769
if not config_dir:
5870
raise RuntimeError(
5971
"Claude Desktop config directory not found. Please ensure Claude Desktop"
@@ -117,7 +129,7 @@ def update_claude_config(
117129
# Add fastmcp run command
118130
args.extend(["mcp", "run", file_spec])
119131

120-
server_config: dict[str, Any] = {"command": "uv", "args": args}
132+
server_config: dict[str, Any] = {"command": uv_path, "args": args}
121133

122134
# Add environment variables if specified
123135
if env_vars:

tests/client/test_config.py

+25
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,28 @@ def test_command_execution(mock_config_path: Path):
4848

4949
assert result.returncode == 0
5050
assert "usage" in result.stdout.lower()
51+
52+
53+
def test_absolute_uv_path(mock_config_path: Path):
54+
"""Test that the absolute path to uv is used when available."""
55+
# Mock the shutil.which function to return a fake path
56+
mock_uv_path = "/usr/local/bin/uv"
57+
58+
with patch("mcp.cli.claude.get_uv_path", return_value=mock_uv_path):
59+
# Setup
60+
server_name = "test_server"
61+
file_spec = "test_server.py:app"
62+
63+
# Update config
64+
success = update_claude_config(file_spec=file_spec, server_name=server_name)
65+
assert success
66+
67+
# Read the generated config
68+
config_file = mock_config_path / "claude_desktop_config.json"
69+
config = json.loads(config_file.read_text())
70+
71+
# Verify the command is the absolute path
72+
server_config = config["mcpServers"][server_name]
73+
command = server_config["command"]
74+
75+
assert command == mock_uv_path

0 commit comments

Comments
 (0)