#!/bin/sh # Tests for bin/check-mcp-env. # # The fault this gate exists for is silent, which is why it needs a gate at # all. An `.mcp.json` server whose Authorization header interpolates a # variable nothing in the session environment defines does not error: the # header goes out empty, the server answers 401, and Claude Code reports # "requires authentication". That is indistinguishable from a revoked or # expired credential, and on 2026-09-07 it cost a full investigation on koala # to establish that the credential was fine and the variable was simply never # set. # # So the property is: every ${VAR} a LIVE server interpolates must be a # variable the session env-file actually defines. # # The `_parked` block is deliberately exempt. Parked servers reference # variables nothing provides on purpose -- that is what parked means -- and a # gate that flagged them would be reporting the intended state as a fault. # # Fixtures drive the checker through argv, so no test touches the real host. set -u ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) CHECK="$ROOT/bin/check-mcp-env" pass=0 fail=0 WORK=${TMPDIR:-/tmp}/mcp_config_test.$$ if [ ! -f "$CHECK" ]; then printf 'FAIL: %s does not exist\n' "$CHECK" exit 1 fi cleanup() { rm -rf "$WORK"; } trap cleanup EXIT INT TERM mkdir -p "$WORK" if ! command -v jq >/dev/null 2>&1; then printf 'SKIP: jq not installed -- bin/check-mcp-env cannot be exercised\n' exit 0 fi # ok / bad ok() { pass=$((pass+1)); printf ' ok %s\n' "$1"; } bad() { fail=$((fail+1)); printf ' FAIL %s %s\n' "$1" "${2:-}"; } # run -> sets $rc and $out run() { out=$("$CHECK" "$1" "$2" 2>&1); rc=$? } ENVFILE="$WORK/op-env" cat > "$ENVFILE" <<'ENVEOF' BRAIN_MCP_TOKEN=op://HomeLab/brain/token DMABE_GITEA_API_TOKEN=op://HomeLab/gitea/token ENVEOF # --- a live server whose variable IS defined --------------------------------- cat > "$WORK/good.json" <<'JSONEOF' {"mcpServers":{"brain":{"type":"http","url":"https://x/mcp", "headers":{"Authorization":"Bearer ${BRAIN_MCP_TOKEN}"}}}} JSONEOF run "$WORK/good.json" "$ENVFILE" [ "$rc" -eq 0 ] && ok "defined variable passes" || bad "defined variable passes" "rc=$rc $out" # --- a live server whose variable is NOT defined ------------------------------ # The exact shape that broke: the server looks correct and fails at runtime. cat > "$WORK/missing.json" <<'JSONEOF' {"mcpServers":{"gitea":{"type":"http","url":"https://x/mcp", "headers":{"Authorization":"Bearer ${GITEA_MCP_STATIC_TOKEN}"}}}} JSONEOF run "$WORK/missing.json" "$ENVFILE" if [ "$rc" -ne 0 ]; then case "$out" in *gitea*GITEA_MCP_STATIC_TOKEN*) ok "undefined variable is flagged, naming server and variable" ;; *) bad "undefined variable is flagged, naming server and variable" "report did not name both: $out" ;; esac else bad "undefined variable is flagged, naming server and variable" "rc=0" fi # --- a server with no headers at all (the `infra` shape) ---------------------- # Unauthenticated by design. Nothing to resolve, so nothing to flag. cat > "$WORK/noauth.json" <<'JSONEOF' {"mcpServers":{"infra":{"type":"http","url":"https://x/mcp"}}} JSONEOF run "$WORK/noauth.json" "$ENVFILE" [ "$rc" -eq 0 ] && ok "header-less server is not flagged" || bad "header-less server is not flagged" "rc=$rc $out" # --- parked servers are exempt ------------------------------------------------ cat > "$WORK/parked.json" <<'JSONEOF' {"mcpServers":{"brain":{"type":"http","url":"https://x/mcp", "headers":{"Authorization":"Bearer ${BRAIN_MCP_TOKEN}"}}}, "_parked":{"_reason":"no identity provides these yet", "cad":{"type":"http","url":"https://x/mcp", "headers":{"Authorization":"Bearer ${CAD_MCP_TOKEN}"}}}} JSONEOF run "$WORK/parked.json" "$ENVFILE" if [ "$rc" -eq 0 ]; then ok "parked server is exempt" else bad "parked server is exempt" "rc=$rc $out" fi # --- malformed JSON must not pass silently ------------------------------------ # A config the checker cannot read is an unverified config, not a clean one. printf '{"mcpServers":{' > "$WORK/broken.json" run "$WORK/broken.json" "$ENVFILE" [ "$rc" -ne 0 ] && ok "unparseable config does not report success" || bad "unparseable config does not report success" "rc=0" # --- a missing env-file is unverifiable, not clean ---------------------------- run "$WORK/good.json" "$WORK/no-such-env" [ "$rc" -ne 0 ] && ok "missing env-file does not report success" || bad "missing env-file does not report success" "rc=0" printf '\n%s: %d passed, %d failed\n' "$(basename "$0")" "$pass" "$fail" [ "$fail" -eq 0 ]