Skip to main content
Glama
setup.sh8.12 kB
#!/bin/bash set -euo pipefail # ============================================ # SERVER-MCP Initial Setup Script # ============================================ # This script performs initial setup for SERVER-MCP on Ubuntu Server # # Usage: # sudo ./scripts/setup.sh # # What it does: # 1. Creates service user (mcp-agent) # 2. Sets up directory structure # 3. Installs Node.js dependencies # 4. Configures sudoers # 5. Sets file permissions # 6. Creates systemd service or PM2 configuration # ============================================ # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Configuration SERVICE_USER="mcp-agent" INSTALL_DIR="/opt/server-mcp" CONFIG_DIR="/etc/server-mcp" DATA_DIR="/var/lib/server-mcp" LOG_DIR="/var/log/server-mcp" BACKUP_DIR="/var/backups/server-mcp" # Functions log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } check_root() { if [[ $EUID -ne 0 ]]; then log_error "This script must be run as root (use sudo)" exit 1 fi } check_ubuntu() { if [[ ! -f /etc/os-release ]] || ! grep -q "Ubuntu" /etc/os-release; then log_warn "This script is designed for Ubuntu. Proceeding anyway..." fi } install_nodejs() { if command -v node >/dev/null 2>&1; then NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1) if [[ $NODE_VERSION -ge 18 ]]; then log_info "Node.js $NODE_VERSION detected (>= 18.18 required) " return 0 fi fi log_info "Installing Node.js 20 LTS..." curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs log_info "Node.js installed: $(node -v)" } create_service_user() { if id "$SERVICE_USER" &>/dev/null; then log_info "Service user '$SERVICE_USER' already exists " else log_info "Creating service user '$SERVICE_USER'..." useradd -r -s /bin/false -d "$INSTALL_DIR" -c "SERVER-MCP Agent" "$SERVICE_USER" log_info "Service user created " fi } create_directories() { log_info "Creating directory structure..." # Application directory mkdir -p "$INSTALL_DIR" chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR" chmod 750 "$INSTALL_DIR" # Configuration directory mkdir -p "$CONFIG_DIR" chown root:"$SERVICE_USER" "$CONFIG_DIR" chmod 750 "$CONFIG_DIR" # Data directory (SQLite databases) mkdir -p "$DATA_DIR" chown "$SERVICE_USER:$SERVICE_USER" "$DATA_DIR" chmod 700 "$DATA_DIR" # Log directory mkdir -p "$LOG_DIR" chown "$SERVICE_USER:$SERVICE_USER" "$LOG_DIR" chmod 750 "$LOG_DIR" # Backup directory mkdir -p "$BACKUP_DIR" chown "$SERVICE_USER:$SERVICE_USER" "$BACKUP_DIR" chmod 750 "$BACKUP_DIR" # Credential store directory mkdir -p /etc/credstore chmod 700 /etc/credstore log_info "Directories created " } install_dependencies() { log_info "Installing Node.js dependencies..." cd "$INSTALL_DIR" if [[ -f package.json ]]; then sudo -u "$SERVICE_USER" npm install --production log_info "Dependencies installed " else log_warn "No package.json found, skipping dependency installation" fi } build_typescript() { log_info "Building TypeScript..." cd "$INSTALL_DIR" if [[ -f tsconfig.json ]]; then sudo -u "$SERVICE_USER" npm run build log_info "TypeScript compiled " else log_warn "No tsconfig.json found, skipping build" fi } configure_sudoers() { log_info "Configuring sudoers..." SUDOERS_FILE="/etc/sudoers.d/server-mcp" cat > "$SUDOERS_FILE" <<'EOF' # SERVER-MCP sudoers configuration # Service management mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/systemctl status * mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart postgresql mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart redis mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nginx # Database backups mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/pg_dump * mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/pg_dumpall * mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/redis-cli BGSAVE # Docker operations mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/docker ps * mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/docker inspect * mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/docker logs * mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/docker restart * # NGINX configuration mcp-agent ALL=(ALL) NOPASSWD: /usr/sbin/nginx -t mcp-agent ALL=(ALL) NOPASSWD: /usr/sbin/nginx -T # System metrics mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/journalctl * mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/netstat * mcp-agent ALL=(ALL) NOPASSWD: /usr/bin/ss * EOF chmod 440 "$SUDOERS_FILE" visudo -c -f "$SUDOERS_FILE" log_info "Sudoers configured " } create_env_file() { log_info "Creating environment configuration..." ENV_FILE="$CONFIG_DIR/server-mcp.env" if [[ -f "$ENV_FILE" ]]; then log_warn "Environment file already exists, skipping" else cp "$INSTALL_DIR/.env.example" "$ENV_FILE" chown root:"$SERVICE_USER" "$ENV_FILE" chmod 640 "$ENV_FILE" log_warn "Environment file created at $ENV_FILE - PLEASE EDIT WITH YOUR CREDENTIALS" fi } install_systemd_service() { log_info "Installing systemd service..." if [[ -f "$INSTALL_DIR/systemd/server-mcp.service" ]]; then # Update paths in service file sed -i "s|/opt/server-mcp|$INSTALL_DIR|g" "$INSTALL_DIR/systemd/server-mcp.service" sed -i "s|/etc/server-mcp/server-mcp.env|$CONFIG_DIR/server-mcp.env|g" "$INSTALL_DIR/systemd/server-mcp.service" cp "$INSTALL_DIR/systemd/server-mcp.service" /etc/systemd/system/ systemctl daemon-reload log_info "Systemd service installed " log_info "Enable with: sudo systemctl enable server-mcp" log_info "Start with: sudo systemctl start server-mcp" else log_warn "Systemd service file not found, skipping" fi } configure_firewall() { log_info "Configuring firewall (UFW)..." if command -v ufw >/dev/null 2>&1; then # Allow SSH ufw allow 22/tcp # PostgreSQL and Redis are bound to localhost - no external access needed # Enable if not already active if ! ufw status | grep -q "Status: active"; then log_warn "UFW is not active. Enable with: sudo ufw enable" else log_info "Firewall configured " fi else log_warn "UFW not installed, skipping firewall configuration" fi } display_next_steps() { cat <<EOF ${GREEN}======================================== SERVER-MCP Setup Complete! ========================================${NC} ${YELLOW}Next Steps:${NC} 1. ${GREEN}Edit configuration:${NC} sudo nano $CONFIG_DIR/server-mcp.env Required settings: - POSTGRES_PASSWORD - REDIS_PASSWORD (if applicable) - KEYCLOAK_CLIENT_SECRET 2. ${GREEN}Update SQLite paths to use data directory:${NC} SERVER_MCP_SQLITE_PATH=$DATA_DIR/mcp_cache.db SERVER_MCP_QUEUE_PATH=$DATA_DIR/mcp_command_queue.db 3. ${GREEN}Enable and start service:${NC} sudo systemctl enable server-mcp sudo systemctl start server-mcp 4. ${GREEN}Verify status:${NC} sudo systemctl status server-mcp sudo journalctl -u server-mcp -f 5. ${GREEN}Security hardening:${NC} Review: $INSTALL_DIR/docs/SECURITY.md ${YELLOW}Directory Structure:${NC} Application: $INSTALL_DIR Configuration: $CONFIG_DIR Data (SQLite): $DATA_DIR Logs: $LOG_DIR Backups: $BACKUP_DIR ${GREEN}Setup complete!${NC} EOF } # Main execution main() { log_info "Starting SERVER-MCP setup..." check_root check_ubuntu install_nodejs create_service_user create_directories install_dependencies build_typescript configure_sudoers create_env_file install_systemd_service configure_firewall display_next_steps } main "$@"

Latest Blog Posts

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/acampkin95/MCPCentralManager'

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