diff --git a/scripts/deploy-community-bot.sh b/scripts/deploy-community-bot.sh
new file mode 100755
index 0000000..bb3a046
--- /dev/null
+++ b/scripts/deploy-community-bot.sh
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+# Build + deploy the SkateSpots Community Cordn bot to the relay host.
+#
+# scripts/deploy-community-bot.sh
+# scripts/deploy-community-bot.sh --no-build
+#
+# The host defaults to the ssh alias `skatespots-cvm` (same VPS as the relay).
+# Override with SKATESPOTS_COMMUNITY_HOST / SKATESPOTS_COMMUNITY_DIR.
+set -euo pipefail
+cd "$(dirname "$0")/.."
+
+HOST="${SKATESPOTS_COMMUNITY_HOST:-skatespots-cvm}"
+REMOTE_DIR="${SKATESPOTS_COMMUNITY_DIR:-/opt/skatespots-community}"
+REMOTE_STATE="${SKATESPOTS_COMMUNITY_STATE:-/var/lib/skatespots-community/state.json}"
+ARTIFACT="build/community-bot.cjs"
+
+if [[ "${1:-}" != "--no-build" ]]; then
+ scripts/build-community-bot.sh
+fi
+[[ -f "$ARTIFACT" ]] || { echo "missing $ARTIFACT (run without --no-build first)" >&2; exit 1; }
+
+echo "→ uploading to $HOST:$REMOTE_DIR"
+scp -q "$ARTIFACT" "$HOST:/tmp/community-bot.cjs.new"
+
+echo "→ installing + restarting skatespots-community"
+ssh "$HOST" "REMOTE_DIR='$REMOTE_DIR' bash -s" <<'REMOTE'
+set -euo pipefail
+cd "$REMOTE_DIR"
+sudo -n cp community-bot.cjs "community-bot.cjs.bak-$(date +%Y%m%d-%H%M%S)"
+sudo -n mv /tmp/community-bot.cjs.new community-bot.cjs
+sudo -n chmod 644 community-bot.cjs
+# Keep the five newest backups.
+ls -1t community-bot.cjs.bak-* 2>/dev/null | tail -n +6 | xargs -r sudo -n rm -f
+sudo -n systemctl restart skatespots-community
+sleep 3
+if ! systemctl is-active --quiet skatespots-community; then
+ echo "✗ skatespots-community is not active" >&2
+ journalctl -u skatespots-community -n 30 --no-pager >&2 || true
+ exit 1
+fi
+echo "✓ skatespots-community active"
+journalctl -u skatespots-community -n 8 --no-pager | tail -8
+REMOTE
+
+echo "→ refreshing the 0600 state backup in ~/.config/skatespots"
+mkdir -p "$HOME/.config/skatespots"
+chmod 700 "$HOME/.config/skatespots"
+if scp -q "$HOST:$REMOTE_STATE" "$HOME/.config/skatespots/community-state.json"; then
+ chmod 600 "$HOME/.config/skatespots/community-state.json"
+ echo "✓ state backup updated"
+else
+ echo "⚠ could not copy the bot state (service is still running)" >&2
+fi
diff --git a/scripts/ops-health.sh b/scripts/ops-health.sh
index 2239321..8ad8f0e 100755
--- a/scripts/ops-health.sh
+++ b/scripts/ops-health.sh
@@ -213,6 +213,23 @@ if [ -f "$RUN_FILE" ]; then
fi
fi
+# ── Community Cordn bot ─────────────────────────────────────────────────────
+p ""
+p "${B}Community bot${N}"
+COMMUNITY_HOST="${SKATESPOTS_COMMUNITY_HOST:-skatespots-cvm}"
+if command -v ssh >/dev/null 2>&1 && grep -qsE "^Host[[:space:]]+${COMMUNITY_HOST}([[:space:]]|$)" "$HOME/.ssh/config"; then
+ community_state="$(timeout 8 ssh -o BatchMode=yes -o ConnectTimeout=5 "$COMMUNITY_HOST" 'systemctl is-active skatespots-community' 2>/dev/null || true)"
+ if [ "$community_state" = "active" ]; then
+ p " ${G}✓${N} skatespots-community active"
+ else
+ p " ${R}✗${N} skatespots-community: ${community_state:-unreachable}"
+ problems+=("community Cordn bot is ${community_state:-unreachable}")
+ signature+="community-bot;"
+ fi
+else
+ p " ${DIM}ssh alias ${COMMUNITY_HOST} not configured — skipped${N}"
+fi
+
# ── Dependency job ──────────────────────────────────────────────────────────
p ""
p "${B}Dependency job${N}"
diff --git a/src/components/crew/CordnNativePanel.tsx b/src/components/crew/CordnNativePanel.tsx
index cbb0508..a0ef03c 100644
--- a/src/components/crew/CordnNativePanel.tsx
+++ b/src/components/crew/CordnNativePanel.tsx
@@ -1314,6 +1314,9 @@ function AdvancedPanel({
{' '}
{t('socialUi.crewCoordinator.openCordnGroup')}
+
+ {t('cordnUi.cordnWebCaveat')}
+