Skip to content
Development
Command

/geo-audit

Run a GEO audit — check AI referral traffic, page compliance, and auto-create improvement issues

BOOST
From plugin
forgedock
11980 skills80 commands
Install
> /plugin marketplace add RapierCraftStudios/ForgeDock
> /plugin install forgedock@forgedock

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/geo-audit

Context preview

What this command does when you run it.

Run a GEO audit — check AI referral traffic, page compliance, and auto-create improvement issues

Command definition

geo-audit.md
description: "Run a GEO audit — check AI referral traffic, page compliance, and auto-create improvement issues"
install: extras

<!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios --> <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->

/geo-audit — GEO Discoverability Audit & Issue Generator

> **Skill names**: `{FORGE_SKILL_PREFIX}` is `forgedock:` (plugin install) or empty (`install.sh`), resolved once per run by `commands/work-on.md` § Skill Name Resolution. If the skill is not found under either name, STOP and report "skill not found" — never run the phase inline.

You are the GEO (Generative Engine Optimization) auditor. Pull AI referral data from Umami and Clarity, check every public page for GEO compliance (structured data, OG tags, freshness, sitemap, llms.txt), and auto-create GitHub issues for gaps.

**You have access to ALL tools** — MCP tools for Clarity, Bash for Umami/curl checks, gh CLI for issues.

**NEVER use plan mode (EnterPlanMode)** — it breaks execution context.

<!-- FORGE:SPEC_LOADED — geo-audit.md loaded and active. Agent is bound by this spec. -->

---

Phase 0: Load Config

Read `forge.yaml` from the current directory (or the path passed as `$ARGUMENTS`). Gate the entire command on the `services.analytics` section existing.

# Verify forge.yaml exists and analytics is configured
GEO_CONFIG=$(python3 - <<'PYEOF'
import yaml, sys, os

config_path = os.environ.get('FORGE_CONFIG', 'forge.yaml')
try:
    cfg = yaml.safe_load(open(config_path))
except FileNotFoundError:
    print('ERROR: forge.yaml not found. Run `cp forge.yaml.example forge.yaml` and configure your project.')
    sys.exit(1)

svc = cfg.get('services', {})
analytics = svc.get('analytics', {})
if not analytics:
    print('ERROR: forge.yaml missing services.analytics section — geo-audit requires analytics to be configured.')
    print('Add services.analytics.umami and/or services.analytics.clarity to forge.yaml.')
    sys.exit(1)

paths = cfg.get('paths', {})
proj = cfg.get('project', {})
creds = paths.get('credentials', {})
creds_file = creds.get('file', '') if isinstance(creds, dict) else ''

domain = svc.get('domain', '')
if not domain:
    print('ERROR: forge.yaml missing services.domain — required for page compliance checks.')
    sys.exit(1)

umami = analytics.get('umami', {})
clarity = analytics.get('clarity', {})
owner = proj.get('owner', '')
repo = proj.get('repo', '')

print(domain)
print('https://' + domain)
print(umami.get('website_id', ''))
print(umami.get('url', ''))
print(clarity.get('project_id', ''))
print(creds_file)
print((owner + '/' + repo) if owner and repo else '')
PYEOF
)

if echo "$GEO_CONFIG" | grep -q '^ERROR:'; then
    echo "$GEO_CONFIG"
    exit 1
fi

# Assign config variables
DOMAIN=$(echo "$GEO_CONFIG" | sed -n '1p')
SITE_URL=$(echo "$GEO_CONFIG" | sed -n '2p')
UMAMI_WEBSITE_ID=$(echo "$GEO_CONFIG" | sed -n '3p')
UMAMI_API=$(echo "$GEO_CONFIG" | sed -n '4p')
CLARITY_PROJECT=$(echo "$GEO_CONFIG" | sed -n '5p')
CREDENTIALS_FILE=$(echo "$GEO_CONFIG" | sed -n '6p')
GH_REPO=$(echo "$GEO_CONFIG" | sed -n '7p')

---

Constants

DOMAIN       = (from forge.yaml → services.domain)
SITE_URL     = (from forge.yaml → "https://" + services.domain)
UMAMI_WEBSITE_ID = (from forge.yaml → services.analytics.umami.website_id)
UMAMI_API    = (from forge.yaml → services.analytics.umami.url)
CLARITY_PROJECT  = (from forge.yaml → services.analytics.clarity.project_id)
CREDENTIALS_FILE = (from forge.yaml → paths.credentials.file)
GH_REPO      = (from forge.yaml → project.owner + "/" + project.repo)
TODAY = (current date in YYYY-MM-DD)
THIRTY_DAYS_AGO = (TODAY minus 30 days)

AI_REFERRERS = [
  "chatgpt.com",
  "claude.ai",
  "gemini.google.com",
  "perplexity.ai",
  "copilot.microsoft.com",
  "grok.com",
  "phind.com",
  "you.com"
]

---

Phase 1: Collect AI Referral Data

1A. Umami — AI Referrer Metrics

Authenticate with Umami (credentials from credentials file set in forge.yaml):

UMAMI_USER=$(python3 -c "import yaml; print(yaml.safe_load(open('$CREDENTIALS_FILE'))['umami']['username'])")
UMAMI_PASS=$(python3 -c "import yaml; print(yaml.safe_load(open('$CREDENTIALS_FILE'))['umami']['password'])")
UMAMI_TOKEN=$(curl -s -X POST "$UMAMI_API/api/auth/login" \
  -H "Content-Type: application/json" \
  -d "{\"username\":\"$UMAMI_USER\",\"password\":\"$UMAMI_PASS\"}" | jq -r '.token')

Then pull referrer metrics for the last 30 days:

START_AT=$(date -d '30 days ago' +%s)000
END_AT=$(date +%s)000
curl -s "$UMAMI_API/api/websites/$UMAMI_WEBSITE_ID/metrics?startAt=${START_AT}&endAt=${END_AT}&type=referrer" \
  -H "Authorization: Bearer $UMAMI_TOKEN" | jq '.'

From the results, filter for AI_REFERRERS. Record each AI referrer's session count. If a referrer appears that is NOT in our known list but looks AI-related (contains "ai", "chat", "copilot", "assistant"), flag it as a new AI referrer.

Also pull landing page metrics to see WHERE AI traffic lands:

curl -s "$UMAMI_API/api/websites/$UMAMI_WEBSITE_ID/metrics?startAt=${START_AT}&endAt=${END_AT}&type=url" \
  -H "Authorization: Bearer $UMAMI_TOKEN" | jq '.'

For previous period comparison (30-60 days ago):

PREV_START=$(date -d '60 days ago' +%s)000
PREV_END=$(date -d '30 days ago' +%s)000
curl -s "$UMAMI_API/api/websites/$UMAMI_WEBSITE_ID/metrics?startAt=${PREV_START}&endAt=${PREV_END}&type=referrer" \
  -H "Authorization: Bearer $UMAMI_TOKEN" | jq '.'

Calculate trend (current vs previous) for each AI referrer.

1B. Clarity — AI Channel Data

Use the MCP Clarity tool to get AI-related traffic:

  • `mcp__clarity__query-analytics-dashboard`: "AITools channel sessions last 7 days"
  • `mcp__clarity__query-analytics-dashboard`: "Top referrers last 7 days"
  • `mcp__clarity__query-analytics-dashboard`: "Sessions from chatgpt.com last 7 days"
  • `mcp__clarity__query-analytics-dashboard`: "Bot browser sessions last 7 days"

Cross-reference Clarity referrer dat

Read more
Ships withforgedock

ForgeDock — autonomous AI dev pipeline for Claude Code. GitHub as agent memory: issue in, PR out.

Get the whole plugin

Other commands on forgedock.