Usage Guide
GEO Optimizer includes three scripts, each targeting a different aspect of AI search visibility. This guide walks through practical usage of each one.
geo_audit.py -- Site Audit
The audit script analyzes a website URL and produces a GEO compliance score from 0 to 100, broken down across five dimensions.
Basic Usage (Text Output)
cd ~/geo-optimizer-skill
./geo scripts/geo_audit.py --url https://example.com
JSON Output (CI/CD Integration)
./geo scripts/geo_audit.py --url https://example.com --format json
Verbose Mode
For debugging or deeper analysis, enable verbose output to see raw data from each check:
./geo scripts/geo_audit.py --url https://example.com --verbose
Save to File
./geo scripts/geo_audit.py --url https://example.com --format json --output report.json
Sample Text Output
============================================================
GEO AUDIT REPORT
URL: https://example.com
============================================================
ROBOTS.TXT 18 / 20
------------------------------------------------
[PASS] robots.txt found
[PASS] OAI-SearchBot allowed
[PASS] ClaudeBot allowed
[PASS] PerplexityBot allowed
[WARN] GPTBot not explicitly mentioned
LLMS.TXT 14 / 20
------------------------------------------------
[PASS] /llms.txt found (1,247 words)
[PASS] Contains H1 heading
[PASS] Contains 4 sections
[WARN] Only 2 external links (recommend 5+)
JSON-LD SCHEMA 20 / 25
------------------------------------------------
[PASS] WebSite schema detected
[PASS] FAQPage schema detected
[FAIL] No WebApplication schema found
META TAGS 18 / 20
------------------------------------------------
[PASS] Title tag present (58 chars)
[PASS] Meta description present (147 chars)
[PASS] Canonical URL set
[WARN] Missing og:image tag
CONTENT QUALITY 12 / 15
------------------------------------------------
[PASS] H1 heading present
[PASS] Contains 8 statistical references
[WARN] No external citation links found
============================================================
TOTAL SCORE 82 / 100
BAND: Good
============================================================
RECOMMENDATIONS:
1. Add WebApplication JSON-LD schema
2. Add external citation links to content
3. Include og:image meta tag
4. Explicitly allow GPTBot in robots.txt
Scoring Breakdown
| Section | Max Points | What It Checks |
|---|---|---|
| robots.txt | 20 | AI citation bots (15 pts) + general bots (5 pts) |
| llms.txt | 20 | File presence (10), H1 heading (3), sections (4), links (3) |
| JSON-LD Schema | 25 | WebSite (10), FAQPage (10), WebApplication (5) |
| Meta Tags | 20 | Title (5), description (8), canonical (3), Open Graph (4) |
| Content Quality | 15 | H1 (4), statistics/data (6), external citation links (5) |
Score bands:
| Score | Band | Meaning |
|---|---|---|
| 91--100 | Excellent | Fully optimized for AI citation |
| 71--90 | Good | Strong foundation, minor gaps |
| 41--70 | Foundation | Key elements present, significant work needed |
| 0--40 | Critical | Major infrastructure missing |
generate_llms_txt.py -- LLMs.txt Generator
The /llms.txt file is a machine-readable index of your website, designed to help AI crawlers understand your site structure. Think of it as a human-readable sitemap specifically for large language models.
Basic Usage
./geo scripts/generate_llms_txt.py --base-url https://example.com
This auto-detects your sitemap (checks /robots.txt, then /sitemap.xml, then /sitemap-index.xml) and outputs the generated llms.txt content to stdout.
Save to File
./geo scripts/generate_llms_txt.py --base-url https://example.com --output llms.txt
With Custom Site Info
./geo scripts/generate_llms_txt.py \
--base-url https://example.com \
--site-name "Example Corp" \
--description "Enterprise solutions for data analytics" \
--output llms.txt
Fetch Page Titles
By default, URLs are listed with their path as the label. Use --fetch-titles to retrieve actual page titles via HTTP:
./geo scripts/generate_llms_txt.py \
--base-url https://example.com \
--fetch-titles \
--output llms.txt
The --fetch-titles flag makes an HTTP request for each URL in your sitemap. For large sites, this can take a while. Use --max-per-section to limit URLs per category.
Specify Sitemap Manually
If auto-detection fails or you want to target a specific sitemap:
./geo scripts/generate_llms_txt.py \
--base-url https://example.com \
--sitemap https://example.com/custom-sitemap.xml \
--output llms.txt
Limit URLs Per Section
./geo scripts/generate_llms_txt.py \
--base-url https://example.com \
--max-per-section 10 \
--output llms.txt
All Flags
| Flag | Required | Default | Description |
|---|---|---|---|
--base-url | Yes | -- | Root URL of the website |
--output | No | stdout | File path to save the output |
--sitemap | No | auto-detect | Manual sitemap URL |
--site-name | No | -- | Custom name for the header |
--description | No | -- | Site description (shown as blockquote) |
--fetch-titles | No | off | Fetch actual page titles via HTTP |
--max-per-section | No | 20 | Maximum URLs per category |
How It Works
- Sitemap Discovery -- checks
/robots.txtforSitemap:directives, then tries common paths - URL Extraction -- parses XML sitemaps, including sitemap indexes (up to 10 sub-sitemaps)
- Filtering -- removes admin pages, file downloads, pagination, and other non-content URLs
- Categorization -- groups URLs by path pattern (Blog, Documentation, Tools, etc.)
- Output -- generates structured markdown with categorized URL lists
Sample Output
# Example Corp
> Enterprise solutions for data analytics
## Tools
- [Data Explorer](https://example.com/tools/data-explorer)
- [Query Builder](https://example.com/tools/query-builder)
## Documentation
- [Getting Started](https://example.com/docs/getting-started)
- [API Reference](https://example.com/docs/api-reference)
- [Configuration](https://example.com/docs/configuration)
## Blog
- [Announcing v2.0](https://example.com/blog/announcing-v2)
- [Performance Tips](https://example.com/blog/performance-tips)
schema_injector.py -- JSON-LD Schema Tools
This script generates, validates, analyzes, and injects JSON-LD structured data into HTML files. Structured data helps AI search engines understand your content type, authorship, and context.
Analyze Existing Schemas
Check what JSON-LD schemas an HTML file already contains:
./geo scripts/schema_injector.py --file index.html --analyze
With full schema output:
./geo scripts/schema_injector.py --file index.html --analyze --verbose
Generate Schema (stdout)
Generate a JSON-LD schema without modifying any files:
./geo scripts/schema_injector.py \
--type website \
--name "Example Corp" \
--url https://example.com \
--description "Enterprise data analytics platform"
Inject Schema Into HTML
Inject a schema directly into an HTML file's <head>:
./geo scripts/schema_injector.py \
--file index.html \
--inject \
--type website \
--name "Example Corp" \
--url https://example.com \
--description "Enterprise data analytics platform"
By default, the injector creates a .bak backup of the original file. Use --no-backup to skip this.
Supported Schema Types
| Type | Schema | Use Case |
|---|---|---|
website | WebSite | Homepage, main site entry point |
webapp | WebApplication | SaaS tools, web utilities |
faq | FAQPage | FAQ sections, Q&A content |
article | Article | Blog posts, news articles |
organization | Organization | Company/business information |
breadcrumb | BreadcrumbList | Navigation hierarchy |
FAQ Schema with Auto-Extraction
Extract FAQ content directly from HTML headings and paragraphs:
./geo scripts/schema_injector.py \
--file faq.html \
--inject \
--type faq \
--auto-extract
Or provide FAQ data from a JSON file:
./geo scripts/schema_injector.py \
--file faq.html \
--inject \
--type faq \
--faq-file questions.json
The JSON file format:
[
{
"question": "What is GEO?",
"answer": "Generative Engine Optimization is the practice of optimizing content for AI search engines."
},
{
"question": "Does it work with ChatGPT?",
"answer": "Yes, GEO techniques improve visibility across ChatGPT, Perplexity, Claude, and Gemini."
}
]
Astro Integration
Generate an Astro-compatible layout snippet for embedding JSON-LD:
./geo scripts/schema_injector.py \
--type website \
--name "Example Corp" \
--url https://example.com \
--astro
This outputs a <script type="application/ld+json"> block ready to paste into an Astro layout's <head>:
---
// In your Astro layout
---
<html>
<head>
<script type="application/ld+json" set:html={JSON.stringify({
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Example Corp",
"url": "https://example.com",
"description": "Enterprise data analytics platform"
})} />
</head>
<body>
<slot />
</body>
</html>
All Flags
| Flag | Description |
|---|---|
--file | HTML file to analyze or modify |
--analyze | Analyze existing schemas (read-only) |
--inject | Inject generated schema into the file |
--type | Schema type: website, webapp, faq, article, organization, breadcrumb |
--name | Site or application name |
--url | Site URL |
--description | Description text |
--author | Author name |
--logo-url | URL to logo image |
--faq-file | JSON file with FAQ items |
--auto-extract | Auto-detect FAQ content from HTML |
--astro | Output Astro-compatible snippet |
--no-backup | Skip creating .bak backup file |
--no-validate | Skip schema validation before injection |
--verbose | Show full schema JSON during analysis |
Next: Configuration -- set up AI context files for your preferred platform.