Skip to content

Commit 3771be0

Browse files
niechenclaude
andcommitted
Remove outdated concepts from config system
- Remove active_client, active_target, and active_profile concepts - Remove stashed_servers functionality - Remove save_share_config and read_share_config methods - Simplify ClientConfigManager to only essential methods - Update client ls command to remove ACTIVE indicator - Fix all tests to work without outdated concepts - Update test fixtures to use config_path_override parameter 🤖 Generated with Claude Code Co-Authored-By: Claude <[email protected]>
1 parent dc6eb07 commit 3771be0

File tree

9 files changed

+42
-286
lines changed

9 files changed

+42
-286
lines changed

src/mcpm/clients/client_config.py

Lines changed: 2 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
"""
44

55
import logging
6-
from typing import Any, Dict, List, Optional
6+
from typing import List
77

88
from mcpm.utils.config import ConfigManager
9-
from mcpm.utils.scope import ScopeType, extract_from_scope
109

1110
logger = logging.getLogger(__name__)
1211

1312

1413
class ClientConfigManager:
15-
"""Manages client-specific configuration including active client and stashed servers"""
14+
"""Manages client-specific configuration"""
1615

1716
def __init__(self):
1817
"""Initialize the client config manager"""
@@ -23,43 +22,6 @@ def _refresh_config(self):
2322
"""Refresh the local config cache from the config manager"""
2423
self._config = self.config_manager.get_config()
2524

26-
def get_active_client(self) -> str | None:
27-
target = self.get_active_target()
28-
if not target:
29-
return
30-
scope_type, scope = extract_from_scope(target)
31-
if scope_type != ScopeType.CLIENT:
32-
return
33-
return scope
34-
35-
def set_active_target(self, target_name: str | None) -> bool:
36-
"""Set the active target
37-
38-
Args:
39-
target_name: Name of target to set as active
40-
41-
Returns:
42-
bool: Success or failure
43-
"""
44-
# Set the active target
45-
result = self.config_manager.set_config("active_target", target_name)
46-
self._refresh_config()
47-
return result
48-
49-
def get_active_target(self) -> str | None:
50-
"""Get the name of the currently active target or None if not set"""
51-
self._refresh_config()
52-
return self._config.get("active_target")
53-
54-
def get_active_profile(self) -> str | None:
55-
target = self.get_active_target()
56-
if not target:
57-
return
58-
scope_type, scope = extract_from_scope(target)
59-
if scope_type != ScopeType.PROFILE:
60-
return
61-
return scope
62-
6325
def get_supported_clients(self) -> List[str]:
6426
"""Get a list of supported client names"""
6527
# Import here to avoid circular imports
@@ -80,145 +42,3 @@ def get_client_manager(self, client_name: str):
8042
from mcpm.clients.client_registry import ClientRegistry
8143

8244
return ClientRegistry.get_client_manager(client_name)
83-
84-
def stash_server(self, scope_name: str, server_name: str, server_config: Any) -> bool:
85-
"""Store a disabled server configuration in the global config
86-
87-
Args:
88-
scope_name: Name of the scope the server belongs to
89-
server_name: Name of the server to stash
90-
server_config: Server configuration to stash (ServerConfig object or dict)
91-
92-
Returns:
93-
bool: Success or failure
94-
"""
95-
# Refresh config to ensure we have the latest state
96-
self._refresh_config()
97-
98-
# Ensure stashed_servers section exists
99-
if "stashed_servers" not in self._config:
100-
self._config["stashed_servers"] = {}
101-
102-
# Ensure client section exists
103-
if scope_name not in self._config["stashed_servers"]:
104-
self._config["stashed_servers"][scope_name] = {}
105-
106-
# Convert ServerConfig to dict if needed
107-
try:
108-
# If it's a ServerConfig object with to_dict method
109-
if hasattr(server_config, "to_dict") and callable(server_config.to_dict):
110-
server_dict = server_config.to_dict()
111-
else:
112-
# Assume it's already a dict or JSON serializable
113-
server_dict = server_config
114-
115-
# Add the server configuration
116-
stashed_servers = self._config.get("stashed_servers", {})
117-
if scope_name not in stashed_servers:
118-
stashed_servers[scope_name] = {}
119-
stashed_servers[scope_name][server_name] = server_dict
120-
121-
# Use set_config to save the updated stashed_servers
122-
result = self.config_manager.set_config("stashed_servers", stashed_servers)
123-
self._refresh_config()
124-
return result
125-
except Exception as e:
126-
logger.error(f"Failed to save stashed server: {e}")
127-
return False
128-
129-
def pop_server(self, scope_name: str, server_name: str) -> Optional[Dict[str, Any]]:
130-
"""Retrieve a stashed server configuration from the global config
131-
132-
Args:
133-
scope_name: Name of the scope the server belongs to
134-
server_name: Name of the server to retrieve
135-
136-
Returns:
137-
Dict: Server configuration or None if not found
138-
"""
139-
# Refresh config to ensure we have the latest state
140-
self._refresh_config()
141-
142-
# Check if stashed_servers section exists
143-
stashed_servers = self._config.get("stashed_servers", {})
144-
if not stashed_servers:
145-
return None
146-
147-
# Check if scope section exists
148-
if scope_name not in stashed_servers:
149-
return None
150-
151-
# Check if server exists
152-
if server_name not in stashed_servers[scope_name]:
153-
return None
154-
155-
# Get the server configuration
156-
server_config = stashed_servers[scope_name][server_name]
157-
158-
# Remove the server from stashed servers
159-
del stashed_servers[scope_name][server_name]
160-
161-
# Clean up empty scope section if needed
162-
if not stashed_servers[scope_name]:
163-
del stashed_servers[scope_name]
164-
165-
# Clean up empty stashed_servers section if needed
166-
if not stashed_servers:
167-
# Set to None to remove the key completely
168-
self.config_manager.set_config("stashed_servers", None)
169-
else:
170-
# Update with modified stashed_servers
171-
self.config_manager.set_config("stashed_servers", stashed_servers)
172-
173-
# Refresh config after changes
174-
self._refresh_config()
175-
176-
return server_config
177-
178-
def is_server_stashed(self, scope_name: str, server_name: str) -> bool:
179-
"""Check if a server is stashed in the global config
180-
181-
Args:
182-
scope_name: Name of the scope the server belongs to
183-
server_name: Name of the server to check
184-
185-
Returns:
186-
bool: True if server is stashed, False otherwise
187-
"""
188-
# Refresh config to ensure we have the latest state
189-
self._refresh_config()
190-
191-
# Check if stashed_servers section exists
192-
stashed_servers = self._config.get("stashed_servers", {})
193-
if not stashed_servers:
194-
return False
195-
196-
# Check if scope section exists
197-
if scope_name not in stashed_servers:
198-
return False
199-
200-
# Check if server exists
201-
return server_name in stashed_servers[scope_name]
202-
203-
def get_stashed_servers(self, scope_name: str) -> Dict[str, Dict[str, Any]]:
204-
"""Get all stashed servers for a client
205-
206-
Args:
207-
scope_name: Name of the scope to get stashed servers for
208-
209-
Returns:
210-
Dict: Dictionary of server configurations by name
211-
"""
212-
# Refresh config to ensure we have the latest state
213-
self._refresh_config()
214-
215-
# Check if stashed_servers section exists
216-
stashed_servers = self._config.get("stashed_servers", {})
217-
if not stashed_servers:
218-
return {}
219-
220-
# Check if scope section exists
221-
if scope_name not in stashed_servers:
222-
return {}
223-
224-
return stashed_servers[scope_name]

src/mcpm/clients/client_registry.py

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -113,30 +113,6 @@ def get_all_client_info(cls) -> Dict[str, Dict[str, str]]:
113113
"""
114114
return {client_name: manager().get_client_info() for client_name, manager in cls._CLIENT_MANAGERS.items()}
115115

116-
@classmethod
117-
def get_active_client(cls) -> str | None:
118-
"""
119-
Get the active client name from the config manager
120-
121-
Returns:
122-
str | None: Name of the active client or None if not set
123-
"""
124-
return cls._client_config_manager.get_active_client()
125-
126-
@classmethod
127-
def get_active_client_manager(cls) -> Optional[BaseClientManager]:
128-
"""
129-
Get the client manager for the active client
130-
131-
Returns:
132-
BaseClientManager: Client manager instance for the active client, or None if not found
133-
"""
134-
active_client = cls.get_active_client()
135-
if not active_client:
136-
return None
137-
138-
return cls.get_client_manager(active_client)
139-
140116
@classmethod
141117
def get_recommended_client(cls) -> str | None:
142118
"""
@@ -164,36 +140,3 @@ def get_supported_clients(cls) -> List[str]:
164140
List[str]: List of supported client names
165141
"""
166142
return list(cls._CLIENT_MANAGERS.keys())
167-
168-
@classmethod
169-
def get_active_profile(cls) -> str | None:
170-
"""
171-
Get the active profile from the config manager
172-
173-
Returns:
174-
str | None: Name of the active profile, or None if not set
175-
"""
176-
return cls._client_config_manager.get_active_profile()
177-
178-
@classmethod
179-
def get_active_target(cls) -> str | None:
180-
"""
181-
Get the active target (client or profile) from the config manager
182-
183-
Returns:
184-
str | None: Name of the active client or profile, or None if not set
185-
"""
186-
return cls._client_config_manager.get_active_target()
187-
188-
@classmethod
189-
def set_active_target(cls, target: str | None) -> bool:
190-
"""
191-
Set the active target (client or profile) in the config manager
192-
193-
Args:
194-
target: Name of the client or profile
195-
196-
Returns:
197-
bool: Success or failure
198-
"""
199-
return cls._client_config_manager.set_active_target(target)

src/mcpm/commands/client.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ def list_clients(verbose):
5050
# Get the list of supported clients
5151
supported_clients = ClientRegistry.get_supported_clients()
5252
installed_clients = ClientRegistry.detect_installed_clients()
53-
active_client = ClientRegistry.get_active_client()
5453

5554
# Count installed clients
5655
installed_count = sum(1 for c in supported_clients if installed_clients.get(c, False))
@@ -75,13 +74,8 @@ def list_clients(verbose):
7574
client_info = ClientRegistry.get_client_info(client_name)
7675
display_name = client_info.get("name", client_name)
7776

78-
# Build client name with code and status indicators
79-
name_parts = [f"{display_name} [dim]({client_name})[/]"]
80-
81-
if client_name == active_client:
82-
name_parts.append("[bold green]ACTIVE[/]")
83-
84-
client_display = " ".join(name_parts)
77+
# Build client name with code
78+
client_display = f"{display_name} [dim]({client_name})[/]"
8579

8680
# Get the client manager to check MCPM servers
8781
client_manager = ClientRegistry.get_client_manager(client_name)

src/mcpm/commands/config.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,49 @@ def set():
4343
console.print(f"[green]Default node executable set to:[/] {node_executable}")
4444

4545

46+
@config.command()
47+
@click.help_option("-h", "--help")
48+
def ls():
49+
"""List all MCPM configuration settings.
50+
51+
Example:
52+
53+
\b
54+
mcpm config ls
55+
"""
56+
config_manager = ConfigManager()
57+
current_config = config_manager.get_config()
58+
59+
if not current_config:
60+
console.print("[yellow]No configuration settings found.[/]")
61+
return
62+
63+
console.print("[bold green]Current configuration:[/]")
64+
for key, value in current_config.items():
65+
console.print(f" [cyan]{key}:[/] {value}")
66+
67+
4668
@config.command()
4769
@click.argument("name", required=True)
4870
@click.help_option("-h", "--help")
49-
def get(name):
50-
"""Get MCPM configuration.
71+
def unset(name):
72+
"""Remove a configuration setting.
5173
5274
Example:
5375
5476
\b
55-
mcpm config get node_executable
77+
mcpm config unset node_executable
5678
"""
5779
config_manager = ConfigManager()
5880
current_config = config_manager.get_config()
81+
5982
if name not in current_config:
60-
console.print(f"[red]Configuration '{name}' not set or not supported.[/]")
83+
console.print(f"[red]Configuration '{name}' is not set.[/]")
6184
return
62-
console.print(f"[green]{name}:[/] {current_config[name]}")
85+
86+
# Remove the configuration by setting it to None
87+
config_manager.set_config(name, None)
88+
console.print(f"[green]Configuration '{name}' has been removed.[/]")
6389

6490

6591
@config.command()

src/mcpm/utils/config.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,10 @@
1313
DEFAULT_CONFIG_DIR = os.path.expanduser("~/.config/mcpm")
1414
DEFAULT_CONFIG_FILE = os.path.join(DEFAULT_CONFIG_DIR, "config.json")
1515
DEFAULT_AUTH_FILE = os.path.join(DEFAULT_CONFIG_DIR, "auth.json")
16-
# default router config
17-
DEFAULT_HOST = "localhost"
16+
# Default port for HTTP mode
1817
DEFAULT_PORT = 6276 # 6276 represents MCPM on a T9 keypad (6=M, 2=C, 7=P, 6=M)
19-
# default splitor pattern
18+
# Default share address
2019
DEFAULT_SHARE_ADDRESS = f"share.mcpm.sh:{DEFAULT_PORT}"
21-
MCPM_AUTH_HEADER = "X-MCPM-SECRET"
22-
MCPM_PROFILE_HEADER = "X-MCPM-PROFILE"
2320

2421
NODE_EXECUTABLES = ["npx", "bunx", "pnpm dlx", "yarn dlx"]
2522

@@ -124,9 +121,3 @@ def save_auth_config(self, api_key: str) -> bool:
124121
self._auth_config["api_key"] = api_key
125122
self._save_auth_config()
126123
return True
127-
128-
def save_share_config(self, share_url: str | None = None, share_pid: int | None = None):
129-
return self.set_config("share", {"url": share_url, "pid": share_pid})
130-
131-
def read_share_config(self) -> Dict[str, Any]:
132-
return self.get_config().get("share", {})

0 commit comments

Comments
 (0)