import subprocess
import asyncio
from typing import Dict, Optional
[docs]
class MCPServerInstaller:
"""Handles installation of MCP servers via different methods"""
[docs]
@staticmethod
async def install_with_uvx(package: str, args: list = None) -> bool:
"""Install package with uvx"""
if args is None:
args = []
try:
# For uvx, we don't need to install, just check if it can run
cmd = ['uvx', '--help']
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
return result.returncode == 0
except Exception as e:
print(f"Error with uvx: {e}")
return False
[docs]
@staticmethod
async def install_with_npx(package: str, args: list = None) -> bool:
"""Install package with npx (similar to uvx, runs without global install)"""
if args is None:
args = []
try:
# For npx, we don't need to install, just check if it can run
cmd = ['npx', '--help']
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
return result.returncode == 0
except Exception as e:
print(f"Error with npx: {e}")
return False
[docs]
@staticmethod
async def install_with_pip(package: str, args: list = None) -> bool:
"""Install package with pip"""
if args is None:
args = []
try:
cmd = ['pip', 'install'] + args + [package]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
return result.returncode == 0
except Exception as e:
print(f"Error installing with pip: {e}")
return False
[docs]
@staticmethod
async def install_with_npm(package: str, args: list = None) -> bool:
"""Install package with npm"""
if args is None:
args = []
try:
cmd = ['npm', 'install', '-g'] + args + [package]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
return result.returncode == 0
except Exception as e:
print(f"Error installing with npm: {e}")
return False