Skip to content

Commit 30677b7

Browse files
committed
Refactor client registry
1 parent 83c6378 commit 30677b7

File tree

17 files changed

+258
-230
lines changed

17 files changed

+258
-230
lines changed

src/mcpm/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ def main(ctx, help_flag):
7373
console.print(panel)
7474

7575
# Get information about installed clients
76-
from mcpm.utils.client_detector import detect_installed_clients
77-
installed_clients = detect_installed_clients()
76+
from mcpm.utils.client_registry import ClientRegistry
77+
installed_clients = ClientRegistry.detect_installed_clients()
7878

7979
# Display active client information and main help
8080
client_status = "[green]✓[/]" if installed_clients.get(active_client, False) else "[yellow]⚠[/]"

src/mcpm/clients/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22
Client integrations for MCPM - manages client-specific configurations
33
"""
44

5+
from mcpm.clients.base import BaseClientManager
56
from mcpm.clients.claude_desktop import ClaudeDesktopManager
67
from mcpm.clients.windsurf import WindsurfManager
8+
from mcpm.clients.cursor import CursorManager
79

8-
__all__ = ['ClaudeDesktopManager', 'WindsurfManager']
10+
__all__ = [
11+
'BaseClientManager',
12+
'ClaudeDesktopManager',
13+
'WindsurfManager',
14+
'CursorManager'
15+
]

src/mcpm/clients/base.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
class BaseClientManager:
1515
"""Base class for all client managers providing a common interface"""
1616

17+
# Client information properties
18+
client_key = "" # Client identifier (e.g., "claude-desktop")
19+
display_name = "" # Human-readable name (e.g., "Claude Desktop")
20+
download_url = "" # URL to download the client
21+
1722
def __init__(self, config_path: str):
1823
"""Initialize with a configuration path"""
1924
self.config_path = config_path
@@ -192,15 +197,27 @@ def remove_server(self, server_name: str) -> bool:
192197
# To be implemented by subclasses
193198
raise NotImplementedError("Subclasses must implement remove_server")
194199

200+
def get_client_info(self) -> Dict[str, str]:
201+
"""Get information about this client
202+
203+
Returns:
204+
Dict: Information about the client including display name, download URL, and config path
205+
"""
206+
return {
207+
"name": self.display_name,
208+
"download_url": self.download_url,
209+
"config_file": self.config_path
210+
}
211+
195212
def is_client_installed(self) -> bool:
196213
"""Check if this client is installed
197214
198215
Returns:
199216
bool: True if client is installed, False otherwise
200217
"""
201-
# Default implementation - can be overridden by subclasses
202-
client_dir = os.path.dirname(self.config_path)
203-
return os.path.isdir(client_dir)
218+
# Default implementation checks if the config directory exists
219+
# Can be overridden by subclasses
220+
return os.path.isdir(os.path.dirname(self.config_path))
204221

205222
def disable_server(self, server_name: str) -> bool:
206223
"""Temporarily disable (stash) a server without removing its configuration

src/mcpm/clients/claude_desktop.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
class ClaudeDesktopManager(BaseClientManager):
2525
"""Manages Claude Desktop MCP server configurations"""
2626

27+
# Client information
28+
client_key = "claude-desktop"
29+
display_name = "Claude Desktop"
30+
download_url = "https://claude.ai/download"
31+
2732
def __init__(self, config_path: str = CLAUDE_CONFIG_PATH):
2833
super().__init__(config_path)
2934

src/mcpm/clients/cursor.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
class CursorManager(BaseClientManager):
2525
"""Manages Cursor MCP server configurations"""
2626

27+
# Client information
28+
client_key = "cursor"
29+
display_name = "Cursor"
30+
download_url = "https://cursor.sh/download"
31+
2732
def __init__(self, config_path: str = CURSOR_CONFIG_PATH):
2833
super().__init__(config_path)
2934

src/mcpm/clients/windsurf.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
class WindsurfManager(BaseClientManager):
2525
"""Manages Windsurf MCP server configurations"""
2626

27+
# Client information
28+
client_key = "windsurf"
29+
display_name = "Windsurf"
30+
download_url = "https://codeium.com/windsurf/download"
31+
2732
def __init__(self, config_path: str = WINDSURF_CONFIG_PATH):
2833
super().__init__(config_path)
2934

src/mcpm/commands/add.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from mcpm.utils.repository import RepositoryManager
1414
from mcpm.utils.server_config import ServerConfig
15-
from mcpm.utils.client_manager import get_active_client, get_active_client_manager, get_active_client_info
15+
from mcpm.utils.client_registry import ClientRegistry
1616

1717
console = Console()
1818
repo_manager = RepositoryManager()
@@ -28,15 +28,15 @@ def add(server_name, force=False):
2828
mcpm add everything --force
2929
"""
3030
# Get the active client info
31-
client = get_active_client()
31+
client = ClientRegistry.get_active_client()
3232
if not client:
3333
console.print("[bold red]Error:[/] No active client found.")
3434
console.print("Please set an active client with 'mcpm client set <client>'.")
3535
return
3636
console.print(f"[yellow]Using active client: {client}[/]")
3737

3838
# Get client manager
39-
client_manager = get_active_client_manager()
39+
client_manager = ClientRegistry.get_active_client_manager()
4040
if client_manager is None:
4141
console.print(f"[bold red]Error:[/] Unsupported client '{client}'.")
4242
return
@@ -70,7 +70,8 @@ def add(server_name, force=False):
7070
console.print(f"[dim]Author: {author_name} {author_url}[/]")
7171

7272
# Get client display name from the utility
73-
_, client_display_name, _ = get_active_client_info()
73+
client_info = ClientRegistry.get_client_info(client)
74+
client_display_name = client_info.get("name", client)
7475

7576
# Confirm addition
7677
if not force and not Confirm.ask(f"Add this server to {client_display_name}?"):

src/mcpm/commands/client.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from rich.panel import Panel
99

1010
from mcpm.utils.config import ConfigManager
11+
from mcpm.utils.client_registry import ClientRegistry
1112

1213
console = Console()
1314
config_manager = ConfigManager()
@@ -27,15 +28,15 @@ def client(client_name, list):
2728
mcpm client claude-desktop # Set Claude Desktop as the active client
2829
"""
2930
# Get the list of supported clients
30-
supported_clients = config_manager.get_supported_clients()
31+
supported_clients = ClientRegistry.get_supported_clients()
3132

3233
# List all supported clients if requested
3334
if list:
3435
table = Table(title="Supported MCP Clients")
3536
table.add_column("Client Name", style="cyan")
3637
table.add_column("Status", style="green")
3738

38-
active_client = config_manager.get_active_client()
39+
active_client = ClientRegistry.get_active_client()
3940

4041
for client in sorted(supported_clients):
4142
status = "[bold green]ACTIVE[/]" if client == active_client else ""
@@ -46,7 +47,7 @@ def client(client_name, list):
4647

4748
# If no client name specified, show the current active client
4849
if not client_name:
49-
active_client = config_manager.get_active_client()
50+
active_client = ClientRegistry.get_active_client()
5051
console.print(f"Current active client: [bold cyan]{active_client}[/]")
5152

5253
# Display some helpful information about setting clients
@@ -67,12 +68,12 @@ def client(client_name, list):
6768
return
6869

6970
# Set the active client
70-
if client_name == config_manager.get_active_client():
71+
if client_name == ClientRegistry.get_active_client():
7172
console.print(f"[bold yellow]Note:[/] {client_name} is already the active client")
7273
return
7374

7475
# Attempt to set the active client
75-
success = config_manager.set_active_client(client_name)
76+
success = ClientRegistry.set_active_client(client_name)
7677
if success:
7778
console.print(f"[bold green]Success:[/] Active client set to {client_name}")
7879

src/mcpm/commands/edit.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from rich.panel import Panel
1111
from rich.prompt import Confirm
1212

13-
from mcpm.utils.client_manager import get_active_client_info
13+
from mcpm.utils.client_registry import ClientRegistry
1414

1515
console = Console()
1616

@@ -29,7 +29,10 @@ def edit(edit, create):
2929
mcpm edit --create # Create a basic config file if it doesn't exist
3030
"""
3131
# Get the active client manager and related information
32-
client_manager, client_name, install_url = get_active_client_info()
32+
client_manager = ClientRegistry.get_active_client_manager()
33+
client = ClientRegistry.get_active_client()
34+
client_info = ClientRegistry.get_client_info(client)
35+
client_name = client_info.get("name", client)
3336

3437
# Check if client is supported
3538
if client_manager is None:

src/mcpm/commands/list.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from rich.table import Table
88
from rich.markup import escape
99

10-
from mcpm.utils.client_manager import get_active_client_info
10+
from mcpm.utils.client_registry import ClientRegistry
1111

1212
console = Console()
1313

@@ -48,7 +48,10 @@ def list(available, outdated):
4848
console.print("[bold yellow]Checking for outdated MCP servers...[/]")
4949

5050
# Get the active client manager and information
51-
client_manager, client_name, _ = get_active_client_info()
51+
client_manager = ClientRegistry.get_active_client_manager()
52+
client = ClientRegistry.get_active_client()
53+
client_info = ClientRegistry.get_client_info(client)
54+
client_name = client_info.get("name", client)
5255

5356
# Check if client is supported
5457
if client_manager is None:
@@ -105,7 +108,10 @@ def list(available, outdated):
105108

106109
else:
107110
# Get the active client manager and information
108-
client_manager, client_name, _ = get_active_client_info()
111+
client_manager = ClientRegistry.get_active_client_manager()
112+
client = ClientRegistry.get_active_client()
113+
client_info = ClientRegistry.get_client_info(client)
114+
client_name = client_info.get("name", client)
109115

110116
# Check if client is supported
111117
if client_manager is None:

0 commit comments

Comments
 (0)