Skip to main content
Glama

R Econometrics MCP Server

MIT License
187
  • Linux
  • Apple
setup_automation.py16.7 kB
""" RMCP Automated Setup Scripts Provides automated setup for new users and development environments: 1. Auto-configure Claude Desktop 2. Install and configure VS Code + Continue extension 3. Set up Docker development environment 4. Install R packages 5. Create sample configurations Usage: python setup_automation.py [--claude-desktop] [--vscode] [--docker] [--r-packages] [--all] """ import json import os import platform import shutil import subprocess import sys from pathlib import Path from typing import List, Optional class RMCPSetupAutomation: """Automated setup for RMCP development environment.""" def __init__(self, verbose: bool = False): self.verbose = verbose self.system = platform.system() def log(self, message: str, level: str = "INFO"): """Log message with appropriate formatting.""" if level == "ERROR": print(f"❌ {message}") elif level == "WARNING": print(f"⚠️ {message}") elif level == "SUCCESS": print(f"✅ {message}") elif level == "INFO": print(f"ℹ️ {message}") def run_command( self, command: List[str], timeout: int = 30 ) -> tuple[bool, str, str]: """Run command and return (success, stdout, stderr).""" try: result = subprocess.run( command, capture_output=True, text=True, timeout=timeout ) return result.returncode == 0, result.stdout, result.stderr except (subprocess.TimeoutExpired, FileNotFoundError) as e: return False, "", str(e) def setup_claude_desktop(self) -> bool: """Auto-configure Claude Desktop for RMCP.""" self.log("Setting up Claude Desktop configuration...", "INFO") # Get platform-specific config path if self.system == "Darwin": config_path = ( Path.home() / "Library/Application Support/Claude/claude_desktop_config.json" ) elif self.system == "Windows": config_path = ( Path.home() / "AppData/Roaming/Claude/claude_desktop_config.json" ) else: config_path = Path.home() / ".config/claude/claude_desktop_config.json" # Create directory if it doesn't exist config_path.parent.mkdir(parents=True, exist_ok=True) # Determine best RMCP command approach rmcp_config = None # Test if rmcp command is in PATH success, _, _ = self.run_command(["rmcp", "--version"]) if success: rmcp_config = {"command": "rmcp", "args": ["start"], "env": {}} self.log("Using 'rmcp' command from PATH", "INFO") else: # Fall back to Python module approach rmcp_config = { "command": "python3", "args": ["-m", "rmcp.cli", "start"], "env": {"PYTHONPATH": str(Path.cwd())}, } self.log("Using Python module approach for RMCP", "INFO") # Create or update configuration config = {"mcpServers": {"rmcp": rmcp_config}} # If config already exists, merge with existing if config_path.exists(): try: with open(config_path) as f: existing_config = json.load(f) if "mcpServers" in existing_config: existing_config["mcpServers"]["rmcp"] = rmcp_config config = existing_config else: existing_config["mcpServers"] = {"rmcp": rmcp_config} config = existing_config self.log("Updated existing Claude Desktop configuration", "INFO") except json.JSONDecodeError: self.log("Existing config invalid, creating new one", "WARNING") # Write configuration with open(config_path, "w") as f: json.dump(config, f, indent=2) self.log(f"Claude Desktop configured at: {config_path}", "SUCCESS") # Test the configuration command = rmcp_config["command"] env = os.environ.copy() env.update(rmcp_config.get("env", {})) success, stdout, _ = self.run_command([command, "--version"], timeout=10) if success: self.log(f"Configuration test passed: {stdout.strip()}", "SUCCESS") return True else: self.log("Configuration test failed - command not accessible", "WARNING") return False def setup_vscode(self) -> bool: """Install and configure VS Code with Continue extension.""" self.log("Setting up VS Code integration...", "INFO") # Check if VS Code is installed vs_code_commands = [ "code", "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code", ] vs_code_cmd = None for cmd in vs_code_commands: success, _, _ = self.run_command([cmd, "--version"]) if success: vs_code_cmd = cmd self.log("VS Code found", "SUCCESS") break if not vs_code_cmd: self.log("VS Code not found", "ERROR") self.log("Install VS Code from: https://code.visualstudio.com/", "INFO") return False # Install Continue extension self.log("Installing Continue extension...", "INFO") success, stdout, stderr = self.run_command( [vs_code_cmd, "--install-extension", "Continue.continue"] ) if success: self.log("Continue extension installed successfully", "SUCCESS") elif "already installed" in stderr.lower(): self.log("Continue extension already installed", "SUCCESS") else: self.log(f"Failed to install Continue extension: {stderr}", "ERROR") return False # Create sample Continue configuration continue_config_path = Path.home() / ".continue/config.json" continue_config_path.parent.mkdir(exist_ok=True) if not continue_config_path.exists(): sample_config = { "models": [ { "title": "Claude 3.5 Sonnet", "provider": "anthropic", "model": "claude-3-5-sonnet-20241022", "apiKey": "your-api-key-here", } ], "mcpServers": { "rmcp": { "command": "rmcp" if shutil.which("rmcp") else "python3", "args": ( ["start"] if shutil.which("rmcp") else ["-m", "rmcp.cli", "start"] ), "env": ( {} if shutil.which("rmcp") else {"PYTHONPATH": str(Path.cwd())} ), } }, } with open(continue_config_path, "w") as f: json.dump(sample_config, f, indent=2) self.log( f"Sample Continue config created at: {continue_config_path}", "SUCCESS" ) self.log("Edit the config to add your API key", "INFO") return True def setup_docker_environment(self) -> bool: """Set up Docker development environment.""" self.log("Setting up Docker environment...", "INFO") # Check Docker availability success, stdout, _ = self.run_command(["docker", "--version"]) if not success: self.log("Docker not found", "ERROR") self.log("Install Docker from: https://www.docker.com/", "INFO") return False self.log(f"Docker found: {stdout.strip()}", "SUCCESS") # Check if Dockerfile exists dockerfile_path = Path.cwd() / "docker" / "Dockerfile" if not dockerfile_path.exists(): self.log("Dockerfile not found in docker/ directory", "ERROR") return False # Build development Docker image self.log("Building RMCP Docker image...", "INFO") success, stdout, stderr = self.run_command( [ "docker", "build", "-f", "docker/Dockerfile", "--target", "development", "-t", "rmcp-dev", ".", ], timeout=300, ) if success: self.log("RMCP Docker image built successfully", "SUCCESS") # Test the image self.log("Testing Docker image...", "INFO") success, stdout, _ = self.run_command( ["docker", "run", "--rm", "rmcp-dev", "rmcp", "--version"], timeout=30 ) if success: self.log(f"Docker image test passed: {stdout.strip()}", "SUCCESS") return True else: self.log("Docker image test failed", "WARNING") return False else: self.log(f"Docker build failed: {stderr[:200]}", "ERROR") return False def setup_r_packages(self) -> bool: """Install required R packages.""" self.log("Setting up R packages...", "INFO") # Check R availability success, stdout, _ = self.run_command(["R", "--version"]) if not success: self.log("R not found", "ERROR") self.log("Install R from: https://www.r-project.org/", "INFO") return False self.log("R found", "SUCCESS") # Install required packages required_packages = [ "jsonlite", "dplyr", "ggplot2", "forecast", "plm", "lmtest", "sandwich", "AER", "vars", "tseries", "nortest", "car", "rpart", "randomForest", "gridExtra", "tidyr", "rlang", "readxl", "base64enc", "reshape2", "knitr", "broom", ] self.log(f"Installing {len(required_packages)} R packages...", "INFO") package_list = '", "'.join(required_packages) r_install_cmd = ( f'install.packages(c("{package_list}"), repos="https://cran.rstudio.com/")' ) success, stdout, stderr = self.run_command( ["R", "-e", r_install_cmd], timeout=600 ) if success: self.log("R packages installed successfully", "SUCCESS") return True else: self.log(f"R package installation failed: {stderr[:200]}", "ERROR") self.log("You may need to install packages manually in R", "INFO") return False def create_sample_configurations(self) -> bool: """Create sample configuration files.""" self.log("Creating sample configuration files...", "INFO") samples_dir = Path.cwd() / "sample_configs" samples_dir.mkdir(exist_ok=True) # Claude Desktop config claude_config = { "mcpServers": {"rmcp": {"command": "rmcp", "args": ["start"], "env": {}}} } with open(samples_dir / "claude_desktop_config.json", "w") as f: json.dump(claude_config, f, indent=2) # VS Code settings vscode_settings = { "continue.mcpServers": {"rmcp": {"command": "rmcp", "args": ["start"]}} } with open(samples_dir / "vscode_settings.json", "w") as f: json.dump(vscode_settings, f, indent=2) # Docker compose for development docker_compose = """version: '3.8' services: rmcp: build: . ports: - "8000:8000" volumes: - "./data:/data" environment: - RMCP_LOG_LEVEL=DEBUG command: rmcp serve-http --host 0.0.0.0 --port 8000 """ with open(samples_dir / "docker-compose.yml", "w") as f: f.write(docker_compose) # README for samples readme = """# RMCP Sample Configurations This directory contains sample configuration files for various RMCP integrations: ## Claude Desktop (`claude_desktop_config.json`) Copy to: - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` - Windows: `%APPDATA%/Claude/claude_desktop_config.json` - Linux: `~/.config/claude/claude_desktop_config.json` ## VS Code (`vscode_settings.json`) Add to your VS Code settings.json file. ## Docker Development (`docker-compose.yml`) Use for local development with Docker: ```bash docker-compose up ``` ## Usage Notes - Replace `rmcp` command with `python3 -m rmcp.cli` if RMCP is not in PATH - Add appropriate PYTHONPATH environment variables as needed - Modify ports and paths according to your setup """ with open(samples_dir / "README.md", "w") as f: f.write(readme) self.log(f"Sample configurations created in: {samples_dir}", "SUCCESS") return True def run_setup(self, components: List[str]) -> bool: """Run setup for specified components.""" print("🛠️ RMCP Automated Setup") print("=" * 40) results = {} if "claude-desktop" in components or "all" in components: results["Claude Desktop"] = self.setup_claude_desktop() if "vscode" in components or "all" in components: results["VS Code"] = self.setup_vscode() if "docker" in components or "all" in components: results["Docker"] = self.setup_docker_environment() if "r-packages" in components or "all" in components: results["R Packages"] = self.setup_r_packages() if "samples" in components or "all" in components: results["Sample Configs"] = self.create_sample_configurations() # Results summary print("\n📊 Setup Results:") print("=" * 20) success_count = 0 for component, success in results.items(): status = "✅ SUCCESS" if success else "❌ FAILED" print(f"{status}: {component}") if success: success_count += 1 print( f"\nOverall: {success_count}/{len(results)} components set up successfully" ) if success_count == len(results): print("\n🎉 Setup completed successfully!") print("\nNext steps:") print("1. Restart Claude Desktop to load new configuration") print("2. Test RMCP integration in Claude Desktop") print("3. Run: python tests/local/validate_local_setup.py") else: print("\n⚠️ Some setup steps failed. Check the errors above.") return success_count == len(results) def main(): """Main entry point.""" import argparse parser = argparse.ArgumentParser(description="Automated RMCP setup") parser.add_argument( "--claude-desktop", action="store_true", help="Set up Claude Desktop configuration", ) parser.add_argument( "--vscode", action="store_true", help="Set up VS Code with Continue extension" ) parser.add_argument( "--docker", action="store_true", help="Set up Docker environment" ) parser.add_argument("--r-packages", action="store_true", help="Install R packages") parser.add_argument( "--samples", action="store_true", help="Create sample configuration files" ) parser.add_argument("--all", action="store_true", help="Set up all components") parser.add_argument( "--verbose", "-v", action="store_true", help="Enable verbose output" ) args = parser.parse_args() # If no specific components selected, show help if not any( [ args.claude_desktop, args.vscode, args.docker, args.r_packages, args.samples, args.all, ] ): parser.print_help() return components = [] if args.claude_desktop: components.append("claude-desktop") if args.vscode: components.append("vscode") if args.docker: components.append("docker") if args.r_packages: components.append("r-packages") if args.samples: components.append("samples") if args.all: components = ["all"] setup = RMCPSetupAutomation(verbose=args.verbose) success = setup.run_setup(components) sys.exit(0 if success else 1) if __name__ == "__main__": main()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/finite-sample/rmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server