#!/bin/bash # Exit immediately if a command exits with a non-zero status. set -e # ======================= Configuration ======================= export REPO_ID="alpgul/mcp-settings" # =========================================================== # --- Define paths --- # Read-only source code directory, built by Dockerfile APP_SRC_DIR="/app" # [Key Fix] Create a writable runtime directory under /tmp RUN_DIR="/tmp/mcphub" CONFIG_FILE_NAME="mcp_settings.json" CONFIG_FILE_PATH="${RUN_DIR}/${CONFIG_FILE_NAME}" export HF_HOME="/tmp/.cache/huggingface" echo "--- MCPHub Persistence Wrapper (v8 - /tmp Runtime) ---" # 1. Create runtime directory and copy application files echo "Creating writable runtime directory at ${RUN_DIR}..." mkdir -p "$RUN_DIR" echo "Copying application files from ${APP_SRC_DIR}..." cp -a "${APP_SRC_DIR}/." "$RUN_DIR/" # 2. Log in to Hugging Face Hub echo "Logging into Hugging Face Hub..." if [ -z "$HF_TOKEN" ]; then echo "Error: HF_TOKEN environment variable is not set. Please provide a Hugging Face token." exit 1a fi hf auth login --token "$HF_TOKEN" &> /dev/null # 3. Download or create the configuration file in the writable directory echo "Preparing config file at ${CONFIG_FILE_PATH}..." # First download to /tmp, then move to the final location TEMP_DOWNLOAD_PATH="/tmp/${CONFIG_FILE_NAME}" python3 -c "from huggingface_hub import hf_hub_download; hf_hub_download(repo_id='$REPO_ID', filename='$CONFIG_FILE_NAME', repo_type='dataset', local_dir='/tmp', etag_timeout=10, resume_download=True)" || true if [ -f "$TEMP_DOWNLOAD_PATH" ]; then mv "$TEMP_DOWNLOAD_PATH" "$CONFIG_FILE_PATH" else echo "Config file not found on Hugging Face Hub, creating default config..." cat > "$CONFIG_FILE_PATH" << 'EOL' { "mcpServers": { "fetch": { "command": "uvx", "args": ["mcp-server-fetch"], "env": { "USER_AGENT": "MCPHub/1.0", "MAX_REDIRECTS": "10" } } } } EOL # Try to upload the default config, but continue even if it fails python3 -c "from huggingface_hub import HfApi; HfApi().upload_file(path_or_fileobj='$CONFIG_FILE_PATH', path_in_repo='$CONFIG_FILE_NAME', repo_id='$REPO_ID', repo_type='dataset', commit_message='feat: Initial empty config')" || true fi echo "Config is ready." # 4. Start the background persistence script echo "Starting persistence sync script in background..." ( # Initialize hash value LAST_HASH="" if [ -f "$CONFIG_FILE_PATH" ]; then LAST_HASH=$(md5sum "$CONFIG_FILE_PATH" | awk '{ print $1 }') fi echo "Initial config hash: $LAST_HASH" while true; do sleep 60 if [ -f "$CONFIG_FILE_PATH" ]; then CURRENT_HASH=$(md5sum "$CONFIG_FILE_PATH" | awk '{ print $1 }') if [ "$CURRENT_HASH" != "$LAST_HASH" ]; then echo "[Sync] Config changed, uploading to Hub..." if ! python3 -c "from huggingface_hub import HfApi; HfApi().upload_file(path_or_fileobj='$CONFIG_FILE_PATH', path_in_repo='$CONFIG_FILE_NAME', repo_id='$REPO_ID', repo_type='dataset', commit_message='chore: Auto-sync settings')"; then echo "Error syncing config file to Hugging Face Hub." else LAST_HASH=$CURRENT_HASH fi fi fi done ) & # 5. [Key Fix] Switch to the writable runtime directory, then start the application echo "Changing directory to ${RUN_DIR}..." cd "$RUN_DIR" echo "Starting MCPHub server in foreground on port ${PORT}..." npm start echo "MCPHub server exited. Container will now stop."