mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 15:19:10 +02:00
feat: add --config-path flag to claude-desktop install command (#3380)
* feat: add --config-path flag to claude-desktop install command * feat: add --config-path flag to claude-desktop install command * docs: add --config-path option to install-mcp documentation * fix: show specific error message when provided --config-path does not exist
This commit is contained in:
parent
d4a8354ba2
commit
34d848b16a
3 changed files with 48 additions and 7 deletions
|
|
@ -65,6 +65,7 @@ See [Server Configuration](/deployment/server-configuration) for the full config
|
|||
| Python | `--python` | Python version (e.g., `3.11`) |
|
||||
| Project | `--project` | Run within a uv project directory |
|
||||
| Requirements | `--with-requirements` | Install from a requirements file |
|
||||
| Config Path | `--config-path` | Custom path to Claude Desktop config directory (`claude-desktop` only) |
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
@ -92,6 +93,10 @@ fastmcp install cursor server.py --env-file .env
|
|||
fastmcp install claude-desktop server.py \
|
||||
--python 3.11 \
|
||||
--with-requirements requirements.txt
|
||||
|
||||
# With custom config path (claude-desktop only)
|
||||
fastmcp install claude-desktop server.py \
|
||||
--config-path "C:\Users\username\AppData\Local\Packages\Claude_xyz\LocalCache\Roaming\Claude"
|
||||
```
|
||||
|
||||
## Generating MCP JSON
|
||||
|
|
|
|||
|
|
@ -17,8 +17,19 @@ from .shared import process_common_args
|
|||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
def get_claude_config_path() -> Path | None:
|
||||
"""Get the Claude config directory based on platform."""
|
||||
def get_claude_config_path(config_path: Path | None = None) -> Path | None:
|
||||
"""Get the Claude config directory based on platform.
|
||||
|
||||
Args:
|
||||
config_path: Optional custom path to the Claude Desktop config directory
|
||||
"""
|
||||
|
||||
if config_path:
|
||||
if not config_path.exists():
|
||||
print(f"[red]The specified config path does not exist: {config_path}[/red]")
|
||||
return None
|
||||
return config_path
|
||||
|
||||
if sys.platform == "win32":
|
||||
path = Path(Path.home(), "AppData", "Roaming", "Claude")
|
||||
elif sys.platform == "darwin":
|
||||
|
|
@ -46,6 +57,7 @@ def install_claude_desktop(
|
|||
python_version: str | None = None,
|
||||
with_requirements: Path | None = None,
|
||||
project: Path | None = None,
|
||||
config_path: Path | None = None,
|
||||
) -> bool:
|
||||
"""Install FastMCP server in Claude Desktop.
|
||||
|
||||
|
|
@ -59,16 +71,18 @@ def install_claude_desktop(
|
|||
python_version: Optional Python version to use
|
||||
with_requirements: Optional requirements file to install from
|
||||
project: Optional project directory to run within
|
||||
config_path: Optional custom path to Claude Desktop config directory
|
||||
|
||||
Returns:
|
||||
True if installation was successful, False otherwise
|
||||
"""
|
||||
config_dir = get_claude_config_path()
|
||||
config_dir = get_claude_config_path(config_path=config_path)
|
||||
if not config_dir:
|
||||
print(
|
||||
"[red]Claude Desktop config directory not found.[/red]\n"
|
||||
"[blue]Please ensure Claude Desktop is installed and has been run at least once to initialize its config.[/blue]"
|
||||
)
|
||||
if not config_path:
|
||||
print(
|
||||
"[red]Claude Desktop config directory not found.[/red]\n"
|
||||
"[blue]Please ensure Claude Desktop is installed and has been run at least once to initialize its config.[/blue]"
|
||||
)
|
||||
return False
|
||||
|
||||
config_file = config_dir / "claude_desktop_config.json"
|
||||
|
|
@ -180,6 +194,13 @@ async def claude_desktop_command(
|
|||
help="Run the command within the given project directory",
|
||||
),
|
||||
] = None,
|
||||
config_path: Annotated[
|
||||
Path | None,
|
||||
cyclopts.Parameter(
|
||||
"--config-path",
|
||||
help="Custom path to Claude Desktop config directory",
|
||||
),
|
||||
] = None,
|
||||
) -> None:
|
||||
"""Install an MCP server in Claude Desktop.
|
||||
|
||||
|
|
@ -204,6 +225,7 @@ async def claude_desktop_command(
|
|||
python_version=python,
|
||||
with_requirements=with_requirements,
|
||||
project=project,
|
||||
config_path=config_path,
|
||||
)
|
||||
|
||||
if not success:
|
||||
|
|
|
|||
|
|
@ -142,6 +142,20 @@ class TestClaudeDesktopInstall:
|
|||
assert bound.arguments["project"] == Path("/my/project")
|
||||
assert bound.arguments["with_requirements"] == Path("reqs.txt")
|
||||
|
||||
def test_claude_desktop_with_config_path(self):
|
||||
"""Test claude-desktop install with custom config path."""
|
||||
command, bound, _ = install_app.parse_args(
|
||||
["claude-desktop", "server.py", "--config-path", "/custom/path/Claude"]
|
||||
)
|
||||
|
||||
assert bound.arguments["config_path"] == Path("/custom/path/Claude")
|
||||
|
||||
def test_claude_desktop_without_config_path(self):
|
||||
"""Test claude-desktop install without config path defaults to None."""
|
||||
command, bound, _ = install_app.parse_args(["claude-desktop", "server.py"])
|
||||
|
||||
assert bound.arguments.get("config_path") is None
|
||||
|
||||
|
||||
class TestCursorInstall:
|
||||
"""Test cursor install command."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue