Skip to content

Commit 6a2d6b5

Browse files
feat: add help info for all commands (#47)
* feat: add help info for all commands * feat: add test * feat: activate profile for client * fix: improve message * feat: improve restart message
1 parent 3499ecb commit 6a2d6b5

File tree

18 files changed

+365
-80
lines changed

18 files changed

+365
-80
lines changed

src/mcpm/cli.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,10 @@ def main(ctx, help_flag):
141141
commands_table.add_row("[yellow]server[/]")
142142
commands_table.add_row(" [cyan]search[/]", "Search available MCP servers.")
143143
commands_table.add_row(" [cyan]add[/]", "Add an MCP server directly to a client.")
144-
commands_table.add_row(" [cyan]cp[/]")
145-
commands_table.add_row(" [cyan]copy[/]", "Copy a server from one client/profile to another.")
146-
commands_table.add_row(" [cyan]mv[/]")
147-
commands_table.add_row(" [cyan]move[/]", "Move a server from one client/profile to another.")
148-
commands_table.add_row(" [cyan]rm[/]")
149-
commands_table.add_row(" [cyan]remove[/]", "Remove an installed MCP server.")
150-
commands_table.add_row(" [cyan]ls[/]")
151-
commands_table.add_row(" [cyan]list[/]", "List all installed MCP servers.")
144+
commands_table.add_row(" [cyan]cp[/]", "Copy a server from one client/profile to another.")
145+
commands_table.add_row(" [cyan]mv[/]", "Move a server from one client/profile to another.")
146+
commands_table.add_row(" [cyan]rm[/]", "Remove an installed MCP server.")
147+
commands_table.add_row(" [cyan]ls[/]", "List all installed MCP servers.")
152148
commands_table.add_row(" [cyan]stash[/]", "Temporarily store a server configuration aside.")
153149
commands_table.add_row(" [cyan]pop[/]", "Restore a previously stashed server configuration.")
154150

@@ -167,15 +163,13 @@ def main(ctx, help_flag):
167163

168164
# Additional helpful information
169165
console.print("")
170-
console.print("[italic]Run [bold]mcpm -h[/] for more information on a command.[/]")
166+
console.print("[italic]Run [bold]mcpm COMMAND -h[/] for more information on a command.[/]")
171167

172168

173169
# Register commands
174170
main.add_command(search.search)
175-
main.add_command(remove.remove)
176171
main.add_command(remove.remove, name="rm")
177172
main.add_command(add.add)
178-
main.add_command(list.list)
179173
main.add_command(list.list, name="ls")
180174

181175
main.add_command(stash.stash)
@@ -185,9 +179,7 @@ def main(ctx, help_flag):
185179
main.add_command(config.config)
186180
main.add_command(inspector.inspector, name="inspector")
187181
main.add_command(profile.profile, name="profile")
188-
main.add_command(transfer.move)
189182
main.add_command(transfer.move, name="mv")
190-
main.add_command(transfer.copy)
191183
main.add_command(transfer.copy, name="cp")
192184
main.add_command(profile.activate)
193185
main.add_command(profile.deactivate)

src/mcpm/clients/base.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
from ruamel.yaml import YAML
1414

1515
from mcpm.schemas.server_config import ServerConfig, STDIOServerConfig
16+
from mcpm.utils.config import ROUTER_SERVER_NAME
17+
from mcpm.utils.router_server import format_server_url
1618

1719
logger = logging.getLogger(__name__)
1820

@@ -132,6 +134,30 @@ def is_client_installed(self) -> bool:
132134
"""
133135
pass
134136

137+
@abc.abstractmethod
138+
def activate_profile(self, profile_name: str, router_config: Dict[str, Any]) -> bool:
139+
"""
140+
Activate a profile in the client config
141+
142+
Args:
143+
profile_name: Name of the profile
144+
router_config: Router configuration
145+
146+
Returns:
147+
bool: Success or failure
148+
"""
149+
pass
150+
151+
@abc.abstractmethod
152+
def deactivate_profile(self) -> bool:
153+
"""
154+
Deactivate a profile in the client config
155+
156+
Returns:
157+
bool: Success or failure
158+
"""
159+
pass
160+
135161

136162
class JSONClientManager(BaseClientManager):
137163
"""
@@ -350,6 +376,33 @@ def is_client_installed(self) -> bool:
350376
# Can be overridden by subclasses
351377
return os.path.isdir(os.path.dirname(self.config_path))
352378

379+
def activate_profile(self, profile_name: str, router_config: Dict[str, Any]) -> bool:
380+
"""Activate a profile in the client config
381+
382+
Args:
383+
profile_name: Name of the profile
384+
385+
Returns:
386+
bool: Success or failure
387+
"""
388+
host = router_config["host"]
389+
port = router_config["port"]
390+
default_base_url = f"http://{host}:{port}/sse"
391+
392+
server_config = self._format_router_server(profile_name, default_base_url)
393+
return self.add_server(server_config)
394+
395+
def _format_router_server(self, profile_name, base_url) -> ServerConfig:
396+
return format_server_url(self.client_key, profile_name, base_url)
397+
398+
def deactivate_profile(self) -> bool:
399+
"""Deactivate a profile in the client config
400+
401+
Returns:
402+
bool: Success or failure
403+
"""
404+
return self.remove_server(ROUTER_SERVER_NAME)
405+
353406

354407
class YAMLClientManager(BaseClientManager):
355408
"""
@@ -589,3 +642,30 @@ def is_client_installed(self) -> bool:
589642
"""
590643
# Check if the config directory exists
591644
return os.path.isdir(os.path.dirname(self.config_path))
645+
646+
def activate_profile(self, profile_name: str, router_config: Dict[str, Any]) -> bool:
647+
"""Activate a profile in the client config
648+
649+
Args:
650+
profile_name: Name of the profile
651+
652+
Returns:
653+
bool: Success or failure
654+
"""
655+
host = router_config["host"]
656+
port = router_config["port"]
657+
default_base_url = f"http://{host}:{port}/sse"
658+
659+
server_config = self._format_router_server(profile_name, default_base_url)
660+
return self.add_server(server_config)
661+
662+
def _format_router_server(self, profile_name, base_url) -> ServerConfig:
663+
return format_server_url(self.client_key, profile_name, base_url)
664+
665+
def deactivate_profile(self) -> bool:
666+
"""Deactivate a profile in the client config
667+
668+
Returns:
669+
bool: Success or failure
670+
"""
671+
return self.remove_server(ROUTER_SERVER_NAME)

src/mcpm/clients/client_registry.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from mcpm.clients.managers.fiveire import FiveireManager
1818
from mcpm.clients.managers.goose import GooseClientManager
1919
from mcpm.clients.managers.windsurf import WindsurfManager
20+
from mcpm.utils.config import ConfigManager
2021
from mcpm.utils.scope import CLIENT_PREFIX, PROFILE_PREFIX
2122

2223
logger = logging.getLogger(__name__)
@@ -205,3 +206,37 @@ def determine_active_scope(cls) -> str | None:
205206
if client:
206207
return f"{CLIENT_PREFIX}{client}"
207208
return None
209+
210+
@classmethod
211+
def activate_profile(cls, client_name: str, profile_name: str) -> bool:
212+
"""
213+
Activate a profile in the client config
214+
215+
Args:
216+
client_name: Name of the client
217+
profile_name: Name of the profile
218+
219+
Returns:
220+
bool: Success or failure
221+
"""
222+
router_config = ConfigManager().get_router_config()
223+
client = cls.get_client_manager(client_name)
224+
if client is None:
225+
return False
226+
return client.activate_profile(profile_name, router_config)
227+
228+
@classmethod
229+
def deactivate_profile(cls, client_name: str) -> bool:
230+
"""
231+
Deactivate a profile in the client config
232+
233+
Args:
234+
profile_name: Name of the profile
235+
236+
Returns:
237+
bool: Success or failure
238+
"""
239+
client = cls.get_client_manager(client_name)
240+
if client is None:
241+
return False
242+
return client.deactivate_profile()

src/mcpm/clients/managers/claude_desktop.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from typing import Any, Dict
88

99
from mcpm.clients.base import JSONClientManager
10+
from mcpm.schemas.server_config import ServerConfig
11+
from mcpm.utils.router_server import format_server_url_with_proxy_param
1012

1113
logger = logging.getLogger(__name__)
1214

@@ -111,6 +113,9 @@ def is_server_disabled(self, server_name: str) -> bool:
111113
config = self._load_config()
112114
return "disabledServers" in config and server_name in config["disabledServers"]
113115

116+
def _format_router_server(self, profile_name, base_url) -> ServerConfig:
117+
return format_server_url_with_proxy_param(self.client_key, profile_name, base_url)
118+
114119
# Uses base class implementation of remove_server
115120

116121
# Uses base class implementation of get_server

src/mcpm/clients/managers/continue_extension.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from mcpm.clients.base import YAMLClientManager
1212
from mcpm.schemas.server_config import ServerConfig, STDIOServerConfig
13+
from mcpm.utils.router_server import format_server_url_with_proxy_headers
1314

1415
logger = logging.getLogger(__name__)
1516

@@ -203,3 +204,6 @@ def from_client_format(self, server_name: str, client_config: Dict[str, Any]) ->
203204
}
204205
server_data.update(client_config)
205206
return TypeAdapter(ServerConfig).validate_python(server_data)
207+
208+
def _format_router_server(self, profile_name, base_url) -> ServerConfig:
209+
return format_server_url_with_proxy_headers(self.client_key, profile_name, base_url)

src/mcpm/commands/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313

1414
@click.group()
15+
@click.help_option("-h", "--help")
1516
def config():
1617
"""Manage MCPM configuration.
1718
@@ -21,6 +22,7 @@ def config():
2122

2223

2324
@config.command()
25+
@click.help_option("-h", "--help")
2426
def clear_cache():
2527
"""Clear the local repository cache.
2628

src/mcpm/commands/list.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919

2020
@click.command(name="list")
2121
@click.option("--target", "-t", help="Target to list servers from")
22+
@click.help_option("-h", "--help")
2223
def list(target: str | None = None):
2324
"""List all installed MCP servers.
2425
2526
Examples:
27+
28+
\b
2629
mcpm list
27-
mcpm list -t <scope>
30+
mcpm list -t @cursor
2831
"""
2932
if target is None:
3033
target = ClientRegistry.determine_active_scope()

0 commit comments

Comments
 (0)