Skip to content

Commit b4459ec

Browse files
committed
update profile management to handle client-specific profile activation and switching
1 parent e2d4833 commit b4459ec

File tree

5 files changed

+96
-16
lines changed

5 files changed

+96
-16
lines changed

src/mcpm/clients/base.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import logging
88
import os
99
import platform
10+
import re
1011
from typing import Any, Dict, List, Optional, Union
1112

1213
from pydantic import TypeAdapter
@@ -158,6 +159,35 @@ def deactivate_profile(self) -> bool:
158159
"""
159160
pass
160161

162+
def get_associated_profile(self) -> Optional[str]:
163+
"""
164+
Get the associated profile for this client
165+
166+
Returns:
167+
Optional[str]: Name of the associated profile, or None if no profile is associated
168+
"""
169+
router_service = self.get_server(ROUTER_SERVER_NAME)
170+
if not router_service:
171+
# No associated profile
172+
return None
173+
174+
# Extract profile name from router service
175+
if isinstance(router_service, STDIOServerConfig):
176+
if hasattr(router_service, "args") and "--headers" in router_service.args:
177+
try:
178+
idx = router_service.args.index("profile")
179+
if idx < len(router_service.args) - 1:
180+
return router_service.args[idx + 1]
181+
except ValueError:
182+
pass
183+
else:
184+
if hasattr(router_service, "url") and "profile=" in router_service.url:
185+
matched = re.search(r"profile=([^&]+)", router_service.url)
186+
if matched:
187+
return matched.group(1)
188+
189+
return None
190+
161191

162192
class JSONClientManager(BaseClientManager):
163193
"""

src/mcpm/clients/client_config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ def set_active_client(self, client_name: Optional[str]) -> bool:
5454

5555
# Set the active client
5656
result = self.config_manager.set_config("active_client", client_name)
57+
# refresh the active profile
58+
client = ClientRegistry.get_client_manager(client_name)
59+
self.set_active_profile(client.get_associated_profile()) # type: ignore
5760
self._refresh_config()
5861
return result
5962

src/mcpm/clients/managers/claude_desktop.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from mcpm.clients.base import JSONClientManager
1010
from mcpm.schemas.server_config import ServerConfig
11-
from mcpm.utils.router_server import format_server_url_with_proxy_param
11+
from mcpm.utils.router_server import format_server_url_with_proxy_headers
1212

1313
logger = logging.getLogger(__name__)
1414

@@ -114,7 +114,7 @@ def is_server_disabled(self, server_name: str) -> bool:
114114
return "disabledServers" in config and server_name in config["disabledServers"]
115115

116116
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)
117+
return format_server_url_with_proxy_headers(self.client_key, profile_name, base_url)
118118

119119
# Uses base class implementation of remove_server
120120

src/mcpm/commands/client.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def list_clients():
4646
table.add_column("Client Name", style="cyan")
4747
table.add_column("Installation", style="yellow")
4848
table.add_column("Status", style="green")
49+
table.add_column("Profile", style="magenta")
4950

5051
active_client = ClientRegistry.get_active_client()
5152
installed_clients = ClientRegistry.detect_installed_clients()
@@ -61,8 +62,12 @@ def list_clients():
6162
# Get client info for more details
6263
client_info = ClientRegistry.get_client_info(client)
6364
display_name = client_info.get("name", client)
65+
# Get Profile activated
66+
client_manager = ClientRegistry.get_client_manager(client)
67+
profile = client_manager.get_associated_profile() if client_manager else None
68+
active_profile = f"[bold magenta]{profile}[/]" if profile else ""
6469

65-
table.add_row(f"{display_name} ({client})", install_status, active_status)
70+
table.add_row(f"{display_name} ({client})", install_status, active_status, active_profile)
6671

6772
console.print(table)
6873

@@ -83,15 +88,6 @@ def set_client(client_name):
8388
8489
CLIENT is the name of the client to set as active.
8590
"""
86-
# block the user to change client with a specific profile activated, or user will fail to deactivate a profile
87-
# cause mcpm router is not attached to the client switched
88-
active_profile = ClientRegistry.get_active_profile()
89-
if active_profile:
90-
console.print(
91-
f"[bold blue]Note:[/] Profile '{active_profile}' needs to be deactivated before switching clients."
92-
)
93-
console.print("Please run [bold cyan]mcpm deactivate[/] to release the current profile.")
94-
return
9591

9692
# Get the list of supported clients
9793
supported_clients = ClientRegistry.get_supported_clients()
@@ -107,10 +103,13 @@ def set_client(client_name):
107103
console.print(f"[bold yellow]Note:[/] {client_name} is already the active client")
108104
return
109105

110-
# Attempt to set the active client
106+
# Attempt to set the active client with active profile inner switched
111107
success = ClientRegistry.set_active_client(client_name)
112108
if success:
113109
console.print(f"[bold green]Success:[/] Active client set to {client_name}")
110+
active_profile = ClientRegistry.get_active_profile()
111+
if active_profile:
112+
console.print(f"[bold green]Success:[/] Active profile set to {active_profile}")
114113

115114
# Provide information about what this means
116115
panel = Panel(

src/mcpm/commands/profile.py

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ def activate(profile_name, client=None):
3636
client_registry = ClientRegistry()
3737
config_manager = ConfigManager()
3838

39+
activate_this_client: bool = client is None
40+
3941
if client:
42+
if client == ClientRegistry.get_active_client():
43+
activate_this_client = True
44+
4045
console.print(f"[bold cyan]Activating profile '{profile_name}' in client '{client}'...[/]")
4146
client_manager = ClientRegistry.get_client_manager(client)
4247
if client_manager is None:
@@ -54,9 +59,11 @@ def activate(profile_name, client=None):
5459
console.print(f"[bold red]Error:[/] Client '{client}' not found.")
5560
return
5661
success = client_manager.activate_profile(profile_name, config_manager.get_router_config())
57-
if success:
62+
if success and activate_this_client:
5863
client_registry.set_active_profile(profile_name)
5964
console.print(f"\n[green]Profile '{profile_name}' activated successfully.[/]\n")
65+
elif success:
66+
console.print(f"\n[green]Profile '{profile_name}' activated successfully for client '{client}'.[/]\n")
6067
else:
6168
console.print(f"[bold red]Error:[/] Failed to activate profile '{profile_name}'.")
6269

@@ -69,15 +76,20 @@ def deactivate(client=None):
6976
7077
Unsets the active profile.
7178
"""
79+
deactivate_this_client: bool = client is None
80+
7281
# Set the active profile
7382
active_profile = ClientRegistry.get_active_profile()
74-
if active_profile is None:
83+
if deactivate_this_client and active_profile is None:
7584
console.print("[bold yellow]No active profile found.[/]\n")
7685
return
7786
console.print(f"\n[green]Deactivating profile '{active_profile}'...[/]")
7887
client_registry = ClientRegistry()
7988

8089
if client:
90+
if client == ClientRegistry.get_active_client():
91+
deactivate_this_client = True
92+
8193
console.print(f"[bold cyan]Deactivating profile '{active_profile}' in client '{client}'...[/]")
8294
client_manager = ClientRegistry.get_client_manager(client)
8395
if client_manager is None:
@@ -95,9 +107,11 @@ def deactivate(client=None):
95107
console.print(f"[bold red]Error:[/] Client '{client}' not found.")
96108
return
97109
success = client_manager.deactivate_profile()
98-
if success:
110+
if success and deactivate_this_client:
99111
client_registry.set_active_profile(None)
100112
console.print(f"\n[yellow]Profile '{active_profile}' deactivated successfully.[/]\n")
113+
elif success:
114+
console.print(f"\n[yellow]Profile '{active_profile}' deactivated successfully for client '{client}'.[/]\n")
101115
else:
102116
console.print(f"[bold red]Error:[/] Failed to deactivate profile '{active_profile}' in client '{client}'.")
103117

@@ -197,6 +211,22 @@ def remove(profile_name):
197211
if not profile_config_manager.delete_profile(profile_name):
198212
console.print(f"[bold red]Error:[/] Profile '{profile_name}' not found.")
199213
return
214+
# Check whether any client is associated with the deleted profile
215+
clients = ClientRegistry.get_supported_clients()
216+
for client in clients:
217+
client_manager = ClientRegistry.get_client_manager(client)
218+
if client_manager:
219+
profile_this_client_associated = client_manager.get_associated_profile()
220+
if profile_this_client_associated == profile_name:
221+
# Deactivate the profile in this client
222+
client_manager.deactivate_profile()
223+
console.print(f"\n[green]Profile '{profile_name}' deactivated successfully for client '{client}'.[/]\n")
224+
225+
# fresh the active_profile
226+
activated_profile = ClientRegistry.get_active_profile()
227+
if activated_profile == profile_name:
228+
ClientRegistry.set_active_profile(None)
229+
200230
console.print(f"\n[green]Profile '{profile_name}' deleted successfully.[/]\n")
201231

202232

@@ -212,4 +242,22 @@ def rename(profile_name):
212242
if not profile_config_manager.rename_profile(profile_name, new_profile_name):
213243
console.print(f"[bold red]Error:[/] Profile '{profile_name}' not found.")
214244
return
245+
# Check whether any client is associated with the profile to be renamed
246+
clients = ClientRegistry.get_supported_clients()
247+
config_manager = ConfigManager()
248+
for client in clients:
249+
client_manager = ClientRegistry.get_client_manager(client)
250+
if client_manager:
251+
profile_this_client_associated = client_manager.get_associated_profile()
252+
if profile_this_client_associated == profile_name:
253+
# fresh the config
254+
client_manager.deactivate_profile()
255+
client_manager.activate_profile(new_profile_name, config_manager.get_router_config())
256+
console.print(f"\n[green]Profile '{profile_name}' deactivated successfully for client '{client}'.[/]\n")
257+
258+
# fresh the active_profile
259+
activated_profile = ClientRegistry.get_active_profile()
260+
if activated_profile == profile_name:
261+
ClientRegistry.set_active_profile(new_profile_name)
262+
215263
console.print(f"\n[green]Profile '{profile_name}' renamed to '{new_profile_name}' successfully.[/]\n")

0 commit comments

Comments
 (0)