#!/usr/bin/env sh # Interactive first-run setup for the remote notebooklm-mcp deploy. # Picks a tunnel, generates strong secrets, and writes deploy/.env. # Invoked by `make setup`. Re-runnable only after you remove .env. set -eu cd "$(dirname "$0")" if [ -e .env ]; then echo "✗ deploy/.env already exists — refusing to overwrite it (it may hold secrets)." echo " Edit it by hand, or 'rm .env' first to start over." exit 1 fi # Find a Python 3 with the stdlib `secrets` module (>=3.6). Probing the import # (not just `command -v`) rejects a `python` that is really Python 2. PY="" for c in python3 python; do if "$c" -c "import secrets" >/dev/null 2>&1; then PY="$c"; break; fi done [ -n "$PY" ] || { printf '%s\n' "✗ Need python3 (with the secrets module) on PATH."; exit 1; } gen() { "$PY" -c "import secrets; print(secrets.token_urlsafe($1))"; } printf 'Tunnel — [1] Cloudflare (needs a domain) [2] Tailscale Funnel (no domain) [1]: ' read -r choice case "$choice" in 2 | tailscale | ts) TUNNEL=tailscale ;; *) TUNNEL=cloudflare ;; esac printf 'Also connect from claude.ai (self-hosted OAuth, one password)? [y/N]: ' read -r want_oauth case "$want_oauth" in y | Y | yes) OAUTH=1 ;; *) OAUTH= ;; esac if [ "$TUNNEL" = cloudflare ]; then printf 'CF_TUNNEL_TOKEN (Cloudflare Zero Trust → Networks → Tunnels; blank to fill later): ' else printf 'TS_AUTHKEY (Tailscale → Settings → Keys; blank to fill later): ' fi read -r TUN_TOKEN BASE_URL= if [ -n "$OAUTH" ]; then printf 'Public https origin claude.ai reaches (e.g. https://host.example.com): ' read -r BASE_URL BASE_URL=${BASE_URL%/} # normalize to a bare origin (server rejects a trailing path) fi TOKEN=$(gen 32) OAUTH_PW=$(gen 24) # .env holds full-account secrets — create it 0600 (umask before the redirect, so # there's no world-readable window between create and a later chmod). umask 077 { # printf '%s', never echo — a token can begin with '-' or (elsewhere) contain # backslashes, both of which some echo implementations would mangle. printf '%s\n' "# Generated by 'make setup'. Treat as secret (gitignored). See .env.example for all options." printf 'TUNNEL=%s\n' "$TUNNEL" printf 'NOTEBOOKLM_MCP_TOKEN=%s\n' "$TOKEN" if [ -n "$OAUTH" ]; then printf 'NOTEBOOKLM_MCP_OAUTH_PASSWORD=%s\n' "$OAUTH_PW" printf 'NOTEBOOKLM_MCP_OAUTH_BASE_URL=%s\n' "$BASE_URL" fi if [ "$TUNNEL" = cloudflare ]; then printf 'CF_TUNNEL_TOKEN=%s\n' "$TUN_TOKEN" [ -n "$OAUTH" ] && printf '%s\n' "NOTEBOOKLM_MCP_TRUST_PROXY=1" else printf 'TS_AUTHKEY=%s\n' "$TUN_TOKEN" fi } > .env echo echo "✓ Wrote deploy/.env — TUNNEL=$TUNNEL, bearer token generated${OAUTH:+, OAuth password generated}." echo "Next:" echo " 1. Bootstrap the master token once (deploy/README.md §1) if you haven't." echo " 2. Finish the tunnel setup (deploy/README.md §3)." [ -z "$TUN_TOKEN" ] && echo " …then put the tunnel token in deploy/.env." echo " 3. make up"