|
2 | 2 |
|
3 | 3 | import json |
4 | 4 | import os |
| 5 | +import platform |
| 6 | +import subprocess |
5 | 7 | import sys |
6 | 8 | from pathlib import Path |
7 | 9 | from typing import Any |
|
13 | 15 | MCP_PACKAGE = "mcp[cli]" |
14 | 16 |
|
15 | 17 |
|
| 18 | +def find_uv_path() -> str | None: |
| 19 | + """Find the full path to the 'uv' executable across platforms""" |
| 20 | + |
| 21 | + system = platform.system() |
| 22 | + |
| 23 | + if system == "Windows": |
| 24 | + try: |
| 25 | + result = subprocess.run( |
| 26 | + ["where", "uv"], capture_output=True, text=True, check=True |
| 27 | + ) |
| 28 | + paths = result.stdout.strip().split("\n") |
| 29 | + return paths[0] if paths else None |
| 30 | + except subprocess.CalledProcessError: |
| 31 | + return None |
| 32 | + else: |
| 33 | + try: |
| 34 | + result = subprocess.run( |
| 35 | + ["which", "uv"], capture_output=True, text=True, check=True |
| 36 | + ) |
| 37 | + return result.stdout.strip() |
| 38 | + except subprocess.CalledProcessError: |
| 39 | + return None |
| 40 | + |
| 41 | + |
16 | 42 | def get_claude_config_path() -> Path | None: |
17 | 43 | """Get the Claude config directory based on platform.""" |
18 | 44 | if sys.platform == "win32": |
@@ -117,7 +143,15 @@ def update_claude_config( |
117 | 143 | # Add fastmcp run command |
118 | 144 | args.extend(["mcp", "run", file_spec]) |
119 | 145 |
|
120 | | - server_config: dict[str, Any] = {"command": "uv", "args": args} |
| 146 | + uv_path = find_uv_path() |
| 147 | + if uv_path: |
| 148 | + server_config: dict[str, Any] = {"command": uv_path, "args": args} |
| 149 | + logger.debug(f"Using full path to uv: {uv_path}") |
| 150 | + else: |
| 151 | + server_config: dict[str, Any] = {"command": "uv", "args": args} |
| 152 | + logger.warning( |
| 153 | + "Could not determine full path to uv executable, using without path" |
| 154 | + ) |
121 | 155 |
|
122 | 156 | # Add environment variables if specified |
123 | 157 | if env_vars: |
|
0 commit comments