Skip to content

Commit 9185fa0

Browse files
committed
feat(cli): add --path option to client edit command
Adds a '--path' option to the 'mcpm client edit' command, allowing users to specify a custom path to the client's configuration file. This provides greater flexibility for managing client configurations that are not in their default locations.
1 parent 7835623 commit 9185fa0

File tree

13 files changed

+85
-78
lines changed

13 files changed

+85
-78
lines changed

src/mcpm/clients/base.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ class BaseClientManager(abc.ABC):
3232
download_url = "" # URL to download the client
3333
config_path: str
3434

35-
def __init__(self):
35+
def __init__(self, config_path_override: Optional[str] = None):
3636
"""Initialize the client manager"""
3737
self._system = platform.system()
38+
if config_path_override:
39+
self.config_path = config_path_override
3840

3941
@abc.abstractmethod
4042
def get_servers(self) -> Dict[str, Any]:
@@ -169,9 +171,9 @@ class JSONClientManager(BaseClientManager):
169171

170172
configure_key_name: str = "mcpServers"
171173

172-
def __init__(self):
174+
def __init__(self, config_path_override: Optional[str] = None):
173175
"""Initialize the JSON client manager"""
174-
super().__init__()
176+
super().__init__(config_path_override=config_path_override)
175177
self._config = None
176178

177179
def _load_config(self) -> Dict[str, Any]:
@@ -386,9 +388,9 @@ class YAMLClientManager(BaseClientManager):
386388
YAML-based client managers with varying configuration formats.
387389
"""
388390

389-
def __init__(self):
391+
def __init__(self, config_path_override: Optional[str] = None):
390392
"""Initialize the YAML client manager"""
391-
super().__init__()
393+
super().__init__(config_path_override=config_path_override)
392394
self.yaml_handler: YAML = YAML()
393395

394396
def _load_config(self) -> Dict[str, Any]:

src/mcpm/clients/client_registry.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,37 @@ class ClientRegistry:
3333
# Client configuration manager for system-wide client settings
3434
_client_config_manager = ClientConfigManager()
3535

36-
# Dictionary mapping client keys to manager instances
36+
# Dictionary mapping client keys to manager classes
3737
_CLIENT_MANAGERS = {
38-
"claude-code": ClaudeCodeManager(),
39-
"claude-desktop": ClaudeDesktopManager(),
40-
"windsurf": WindsurfManager(),
41-
"cursor": CursorManager(),
42-
"cline": ClineManager(),
43-
"continue": ContinueManager(),
44-
"goose-cli": GooseClientManager(),
45-
"5ire": FiveireManager(),
46-
"roo-code": RooCodeManager(),
47-
"trae": TraeManager(),
48-
"vscode": VSCodeManager(),
38+
"claude-code": ClaudeCodeManager,
39+
"claude-desktop": ClaudeDesktopManager,
40+
"windsurf": WindsurfManager,
41+
"cursor": CursorManager,
42+
"cline": ClineManager,
43+
"continue": ContinueManager,
44+
"goose-cli": GooseClientManager,
45+
"5ire": FiveireManager,
46+
"roo-code": RooCodeManager,
47+
"trae": TraeManager,
48+
"vscode": VSCodeManager,
4949
}
5050

5151
@classmethod
52-
def get_client_manager(cls, client_name: str) -> Optional[BaseClientManager]:
52+
def get_client_manager(cls, client_name: str, config_path_override: Optional[str] = None) -> Optional[BaseClientManager]:
5353
"""
5454
Get the client manager for a given client name
5555
5656
Args:
5757
client_name: Name of the client
58+
config_path_override: Optional path to override the default config file location
5859
5960
Returns:
6061
BaseClientManager: Client manager instance or None if not found
6162
"""
62-
return cls._CLIENT_MANAGERS.get(client_name)
63+
manager_class = cls._CLIENT_MANAGERS.get(client_name)
64+
if manager_class:
65+
return manager_class(config_path_override=config_path_override)
66+
return None
6367

6468
@classmethod
6569
def get_all_client_managers(cls) -> Dict[str, BaseClientManager]:
@@ -69,7 +73,7 @@ def get_all_client_managers(cls) -> Dict[str, BaseClientManager]:
6973
Returns:
7074
Dict[str, BaseClientManager]: Dictionary mapping client names to manager instances
7175
"""
72-
return cls._CLIENT_MANAGERS
76+
return {name: manager() for name, manager in cls._CLIENT_MANAGERS.items()}
7377

7478
@classmethod
7579
def detect_installed_clients(cls) -> Dict[str, bool]:
@@ -79,7 +83,7 @@ def detect_installed_clients(cls) -> Dict[str, bool]:
7983
Returns:
8084
Dict[str, bool]: Dictionary mapping client names to installed status
8185
"""
82-
return {client_name: manager.is_client_installed() for client_name, manager in cls._CLIENT_MANAGERS.items()}
86+
return {client_name: manager().is_client_installed() for client_name, manager in cls._CLIENT_MANAGERS.items()}
8387

8488
@classmethod
8589
def get_client_info(cls, client_name: str) -> Dict[str, str]:
@@ -105,7 +109,7 @@ def get_all_client_info(cls) -> Dict[str, Dict[str, str]]:
105109
Returns:
106110
Dict[str, Dict[str, str]]: Dictionary mapping client names to display information
107111
"""
108-
return {client_name: manager.get_client_info() for client_name, manager in cls._CLIENT_MANAGERS.items()}
112+
return {client_name: manager().get_client_info() for client_name, manager in cls._CLIENT_MANAGERS.items()}
109113

110114
@classmethod
111115
def get_active_client(cls) -> str | None:

src/mcpm/clients/managers/claude_code.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ class ClaudeCodeManager(JSONClientManager):
2020
display_name = "Claude Code"
2121
download_url = "https://docs.anthropic.com/en/docs/claude-code"
2222

23-
def __init__(self, config_path=None):
23+
def __init__(self, config_path_override: str | None = None):
2424
"""Initialize the Claude Code client manager
2525
2626
Args:
27-
config_path: Optional path to the config file. If not provided, uses default path.
27+
config_path_override: Optional path to override the default config file location
2828
"""
29-
super().__init__()
29+
super().__init__(config_path_override=config_path_override)
3030

31-
if config_path:
32-
self.config_path = config_path
31+
if config_path_override:
32+
self.config_path = config_path_override
3333
else:
3434
self.config_path = os.path.expanduser("~/.claude.json")
3535

src/mcpm/clients/managers/claude_desktop.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ class ClaudeDesktopManager(JSONClientManager):
2020
display_name = "Claude Desktop"
2121
download_url = "https://claude.ai/download"
2222

23-
def __init__(self, config_path=None):
23+
def __init__(self, config_path_override: str | None = None):
2424
"""Initialize the Claude Desktop client manager
2525
2626
Args:
27-
config_path: Optional path to the config file. If not provided, uses default path.
27+
config_path_override: Optional path to override the default config file location
2828
"""
29-
super().__init__()
29+
super().__init__(config_path_override=config_path_override)
3030

31-
if config_path:
32-
self.config_path = config_path
31+
if config_path_override:
32+
self.config_path = config_path_override
3333
else:
3434
# Set config path based on detected platform
3535
if self._system == "Darwin": # macOS

src/mcpm/clients/managers/cline.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ class ClineManager(JSONClientManager):
1515
display_name = "Cline"
1616
download_url = "https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev"
1717

18-
def __init__(self, config_path=None):
18+
def __init__(self, config_path_override: str | None = None):
1919
"""Initialize the Cline client manager
2020
2121
Args:
22-
config_path: Optional path to the config file. If not provided, uses default path.
22+
config_path_override: Optional path to override the default config file location
2323
"""
24-
super().__init__()
24+
super().__init__(config_path_override=config_path_override)
2525

26-
if config_path:
27-
self.config_path = config_path
26+
if config_path_override:
27+
self.config_path = config_path_override
2828
else:
2929
# Set config path based on detected platform
3030
if self._system == "Darwin": # macOS
@@ -123,16 +123,16 @@ class RooCodeManager(ClineManager):
123123
display_name = "Roo Code"
124124
download_url = "https://marketplace.visualstudio.com/items?itemName=RooVeterinaryInc.roo-cline"
125125

126-
def __init__(self, config_path=None):
126+
def __init__(self, config_path_override: str | None = None):
127127
"""Initialize the Roo Code client manager
128128
129129
Args:
130-
config_path: Optional path to the config file. If not provided, uses default path.
130+
config_path_override: Optional path to override the default config file location
131131
"""
132-
super().__init__()
132+
super().__init__(config_path_override=config_path_override)
133133

134-
if config_path:
135-
self.config_path = config_path
134+
if config_path_override:
135+
self.config_path = config_path_override
136136
else:
137137
# Set config path based on detected platform
138138
if self._system == "Darwin": # macOS

src/mcpm/clients/managers/continue_extension.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ class ContinueManager(YAMLClientManager):
2727
display_name = "Continue"
2828
download_url = "https://marketplace.visualstudio.com/items?itemName=Continue.continue"
2929

30-
def __init__(self, config_path=None):
30+
def __init__(self, config_path_override: Optional[str] = None):
3131
"""Initialize the Continue client manager
3232
3333
Args:
34-
config_path: Optional path to the config file. If not provided, uses default path.
34+
config_path_override: Optional path to override the default config file location
3535
"""
36-
super().__init__()
36+
super().__init__(config_path_override=config_path_override)
3737
# Customize YAML handler
3838
self.yaml_handler.indent(mapping=2, sequence=4, offset=2)
3939
self.yaml_handler.preserve_quotes = True
4040

41-
if config_path:
42-
self.config_path = config_path
41+
if config_path_override:
42+
self.config_path = config_path_override
4343
else:
4444
# Set config path based on detected platform
4545
if self._system == "Windows":

src/mcpm/clients/managers/cursor.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ class CursorManager(JSONClientManager):
1919
display_name = "Cursor"
2020
download_url = "https://cursor.sh/download"
2121

22-
def __init__(self, config_path=None):
22+
def __init__(self, config_path_override: str | None = None):
2323
"""Initialize the Cursor client manager
2424
2525
Args:
26-
config_path: Optional path to the config file. If not provided, uses default path.
26+
config_path_override: Optional path to override the default config file location
2727
"""
28-
super().__init__()
28+
super().__init__(config_path_override=config_path_override)
2929

30-
if config_path:
31-
self.config_path = config_path
30+
if config_path_override:
31+
self.config_path = config_path_override
3232
else:
3333
# Set config path based on detected platform
3434
if self._system == "Windows":

src/mcpm/clients/managers/fiveire.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ class FiveireManager(JSONClientManager):
1717
display_name = "5ire"
1818
download_url = "https://5ire.app/"
1919

20-
def __init__(self, config_path=None):
20+
def __init__(self, config_path_override: Optional[str] = None):
2121
"""Initialize the 5ire client manager
2222
2323
Args:
24-
config_path: Optional path to the config file. If not provided, uses default path.
24+
config_path_override: Optional path to override the default config file location
2525
"""
26-
super().__init__()
26+
super().__init__(config_path_override=config_path_override)
2727

28-
if config_path:
29-
self.config_path = config_path
28+
if config_path_override:
29+
self.config_path = config_path_override
3030
else:
3131
# Set config path based on detected platform
3232
if self._system == "Darwin": # macOS

src/mcpm/clients/managers/goose.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,19 @@ class GooseClientManager(YAMLClientManager):
2626
display_name = "Goose CLI"
2727
download_url = "https://github.com/block/goose/releases/download/stable/download_cli.sh"
2828

29-
def __init__(self, config_path=None):
29+
def __init__(self, config_path_override: Optional[str] = None):
3030
"""Initialize the Goose CLI client manager
3131
3232
Args:
33-
config_path: Optional path to the config file. If not provided, uses default path.
33+
config_path_override: Optional path to override the default config file location
3434
"""
35-
super().__init__()
35+
super().__init__(config_path_override=config_path_override)
3636
# Customize YAML handler
3737
self.yaml_handler.indent(mapping=2, sequence=0, offset=0)
3838
self.yaml_handler.preserve_quotes = True
3939

40-
if config_path:
41-
self.config_path = config_path
40+
if config_path_override:
41+
self.config_path = config_path_override
4242
else:
4343
# Set config path based on detected platform
4444
if self._system == "Windows":

src/mcpm/clients/managers/trae.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ class TraeManager(JSONClientManager):
1818
display_name = "Trae"
1919
download_url = "https://trae.ai/"
2020

21-
def __init__(self, config_path=None):
21+
def __init__(self, config_path_override: str | None = None):
2222
"""Initialize the Trae client manager
2323
2424
Args:
25-
config_path: Optional path to the config file. If not provided, uses default path.
25+
config_path_override: Optional path to override the default config file location
2626
"""
27-
super().__init__()
27+
super().__init__(config_path_override=config_path_override)
2828

29-
if config_path:
30-
self.config_path = config_path
29+
if config_path_override:
30+
self.config_path = config_path_override
3131
else:
3232
# Set config path based on detected platform
3333
if self._system == "Darwin": # macOS

0 commit comments

Comments
 (0)