Fixed serena installation by add serena to claude directly (#357)

Refactor MCP server installation logic to use 'uvx' mode

- Updated the MCPComponent to replace the 'install_command' with 'run_command' for the 'serena' server configuration.
- Renamed the installation method from `_install_uv_mcp_server` to `_install_uvx_mcp_server` to reflect the new command structure.
- Enhanced error handling and logging for the installation and registration processes.
- Adjusted the installation logic to accommodate the new command format and improve clarity.

This change streamlines the installation process for MCP servers and ensures compatibility with the updated command structure.
This commit is contained in:
alexzhang
2025-09-14 23:17:49 +10:00
committed by GitHub
parent 84711cf6b0
commit 5bee15710f

View File

@@ -51,8 +51,8 @@ class MCPComponent(Component):
"serena": { "serena": {
"name": "serena", "name": "serena",
"description": "Semantic code analysis and intelligent editing", "description": "Semantic code analysis and intelligent editing",
"install_method": "uv", "mode": "uvx",
"install_command": "uvx --from git+https://github.com/oraios/serena", "run_command": "uvx --from git+https://github.com/oraios/serena serena start-mcp-server --context ide-assistant --project $(pwd)",
"required": False "required": False
}, },
"morphllm": { "morphllm": {
@@ -165,63 +165,36 @@ class MCPComponent(Component):
} }
} }
def _install_uv_mcp_server(self, server_info: Dict[str, Any], config: Dict[str, Any]) -> bool: def _install_uvx_mcp_server(self, server_info: Dict[str, Any], config: Dict[str, Any]) -> bool:
"""Install a single MCP server using uv""" """Install a single MCP server using uv"""
server_name = server_info["name"] server_name = server_info["name"]
install_command = server_info.get("install_command") run_command = server_info.get("run_command")
if not run_command:
if not install_command: self.logger.error(f"No run command found for uvx-based server {server_name}")
self.logger.error(f"No install_command found for uv-based server {server_name}")
return False return False
try: try:
self.logger.info(f"Installing MCP server using uv: {server_name}")
if self._check_mcp_server_installed(server_name): self.logger.success(f"Successfully installed MCP server (user scope): {server_name}")
self.logger.info(f"MCP server {server_name} already installed")
return True
if config.get("dry_run"): self.logger.info(f"Registering {server_name} with Claude CLI. Run command: {run_command}")
self.logger.info(f"Would install MCP server (user scope): {install_command}")
return True
self.logger.debug(f"Running: {install_command}") reg_result = subprocess.run(
["claude", "mcp", "add", "-s", "user", "--", server_name] + run_command.split(),
cmd_parts = shlex.split(install_command)
result = subprocess.run(
cmd_parts,
capture_output=True, capture_output=True,
text=True, text=True,
timeout=900, # 15 minutes timeout=120,
shell=(sys.platform == "win32") shell=(sys.platform == "win32")
) )
if result.returncode == 0: if reg_result.returncode == 0:
self.logger.success(f"Successfully installed MCP server (user scope): {server_name}") self.logger.success(f"Successfully registered {server_name} with Claude CLI.")
run_command = install_command return True
self.logger.info(f"Registering {server_name} with Claude CLI. Run command: {run_command}")
reg_result = subprocess.run(
["claude", "mcp", "add", "-s", "user", "--", server_name] + run_command.split(),
capture_output=True,
text=True,
timeout=120,
shell=(sys.platform == "win32")
)
if reg_result.returncode == 0:
self.logger.success(f"Successfully registered {server_name} with Claude CLI.")
return True
else:
error_msg = reg_result.stderr.strip() if reg_result.stderr else "Unknown error"
self.logger.error(f"Failed to register MCP server {server_name} with Claude CLI: {error_msg}")
return False
else: else:
error_msg = result.stderr.strip() if result.stderr else "Unknown error" error_msg = reg_result.stderr.strip() if reg_result.stderr else "Unknown error"
self.logger.error(f"Failed to install MCP server {server_name} using uv: {error_msg}\n{result.stdout}") self.logger.error(f"Failed to register MCP server {server_name} with Claude CLI: {error_msg}")
return False return False
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
self.logger.error(f"Timeout installing MCP server {server_name} using uv") self.logger.error(f"Timeout installing MCP server {server_name} using uv")
@@ -255,8 +228,8 @@ class MCPComponent(Component):
def _install_mcp_server(self, server_info: Dict[str, Any], config: Dict[str, Any]) -> bool: def _install_mcp_server(self, server_info: Dict[str, Any], config: Dict[str, Any]) -> bool:
"""Install a single MCP server""" """Install a single MCP server"""
if server_info.get("install_method") == "uv": if server_info.get("mode") == "uvx":
return self._install_uv_mcp_server(server_info, config) return self._install_uvx_mcp_server(server_info, config)
server_name = server_info["name"] server_name = server_info["name"]
npm_package = server_info.get("npm_package") npm_package = server_info.get("npm_package")