Skip to main content
Glama
carter-wzq

geo-audit-mcp

by carter-wzq
README.md
# geo-audit-mcp

Lightweight MCP server for GEO (Generative Engine Optimization) site audits. Checks **31 signals across 6 pillars** — Technical Crawlability, Content Structure, Schema & Metadata, E-E-A-T, Citation Readiness, and Governance — and returns a score, pillar breakdowns, and an actionable fix prompt.

This server provides **one tool only**:

`geo_site_audit`

## Output format

```json
{
  "score": 72,
  "pillars": {
    "technical": { "pass": 4, "fail": 1, "warn": 0, "na": 0, "total": 5, "pct": 80 },
    "content": { "pass": 3, "fail": 0, "warn": 1, "na": 0, "total": 4, "pct": 88 },
    "schema": { "pass": 2, "fail": 1, "warn": 1, "na": 0, "total": 4, "pct": 63 },
    "eeat": { "pass": 4, "fail": 1, "warn": 2, "na": 0, "total": 7, "pct": 71 },
    "citations": { "pass": 6, "fail": 1, "warn": 3, "na": 0, "total": 10, "pct": 75 },
    "governance": { "pass": 1, "fail": 0, "warn": 0, "na": 0, "total": 1, "pct": 100 }
  },
  "checks": [
    { "id": "T1", "pillar": "technical", "title": "Page reachable over HTTPS", "status": "pass", "message": "Page returned HTTP 200." },
    { "id": "B1", "pillar": "content", "title": "Answer-first opening mentions brand", "status": "fail", "message": "Add a 2–3 sentence opening that names your brand...", "evidence": "Welcome to our platform..." }
  ],
  "fixPrompt": "You are improving GEO readiness for MyBrand...",
  "summary": "- [Content] Improve heading hierarchy...",
  "stats": { "words": 1523, "headings": 14, "externalLinks": 8, "jsonLdBlocks": 2 },
  "auditedUrl": "https://example.com/page"
}
```

### What each part means

| Field | Description |
|-------|-------------|
| `score` | Overall GEO readiness score (0–100), weighted across 6 pillars |
| `pillars` | Per-pillar pass/fail/warn counts and percentage |
| `checks` | All 31 individual check results with status, message, and evidence |
| `fixPrompt` | Actionable fix prompt — paste into Claude, Cursor, or your site editor |
| `summary` | Human-readable summary (LLM-generated if `OPENAI_API_KEY` is set, else auto-generated) |
| `stats` | Page-level statistics: word count, headings, external links, JSON-LD blocks |
| `auditedUrl` | The normalized URL that was audited |

## BYOK

This server uses **your own API keys**. Usage and billing are tied to your provider accounts. No API key is strictly required — the audit runs fully offline using static HTML analysis. Optionally set `OPENAI_API_KEY` for LLM-powered summary.

## Required environment variables

| Variable | Required | Description |
|----------|----------|-------------|
| `OPENAI_API_KEY` | Optional | OpenAI API key for LLM-generated audit summary. Without it, the summary is auto-generated from check results. |
| `OPENAI_BASE_URL` | Optional | Custom OpenAI-compatible endpoint (default: `https://api.openai.com/v1`). |
| `OPENAI_HTTPS_PROXY` | Optional | HTTPS proxy URL for OpenAI API calls (e.g. `http://127.0.0.1:7890`). |
| `WEBSITE_HTTPS_PROXY` | Optional | HTTPS proxy URL for fetching the target website. |

## Quick Start

```bash
npm install
npm run build
```

## MCP Config Example

### Claude Desktop (`claude_desktop_config.json`)

```json
{
  "mcpServers": {
    "geo-audit-mcp": {
      "command": "node",
      "args": ["<ABSOLUTE_PATH>/geo-audit-mcp/dist/index.js"],
      "env": {
        "OPENAI_API_KEY": "<YOUR_OPENAI_API_KEY>"
      }
    }
  }
}
```

### Cursor / Windsurf / Other MCP clients

```json
{
  "mcpServers": {
    "geo-audit-mcp": {
      "command": "node",
      "args": ["<ABSOLUTE_PATH>/geo-audit-mcp/dist/index.js"],
      "env": {
        "OPENAI_API_KEY": "<YOUR_OPENAI_API_KEY>",
        "OPENAI_HTTPS_PROXY": "http://127.0.0.1:7890"
      }
    }
  }
}
```

## Tool Input

```json
{
  "url": "https://example.com/pricing",
  "brand_name": "Example",
  "page_type": "product"
}
```

| Parameter | Required | Description |
|-----------|----------|-------------|
| `url` | Yes | Full URL to audit. Must start with `https://` or `http://`. |
| `brand_name` | No | Brand name — improves the accuracy of the opening-content check (B1). |
| `page_type` | No | Hint: `homepage`, `product`, or `article`. Auto-detected from URL path if omitted. |

## What gets checked (31 signals, 6 pillars)

### Technical Crawlability (5 checks)
T1–T5: HTTPS reachability, AI crawler robots.txt rules, llms.txt presence, readable text without JavaScript, canonical URL.

### Content Structure (4 checks)
B1–B4: Answer-first brand mention, heading hierarchy, paragraph chunking, quotable blocks (lists/FAQ).

### Schema & Metadata (4 checks)
C1–C4: Title + meta description, Organization/WebSite JSON-LD, page-type structured data, FAQPage schema.

### E-E-A-T (7 checks)
E1–E7: Author/entity signals, visible byline, About/Contact links, Organization JSON-LD with sameAs, Privacy/Terms links, authority review links, publication date.

### Citation Readiness (10 checks)
R1–R10: External reference links, authoritative review domains, link diversity, in-content links, citable blocks, quotable facts, source attribution, entity sameAs, page citability score, citation-ready passage ratio.

### Governance (1 check)
G1: Sitemap reachability.

## Notes

- The audit fetches the target page via direct HTTP request (with browser-like User-Agent). Some sites with aggressive bot protection may block the request.
- The audit is **stateless** — no data is stored or logged.
- SSRF protection is built in: internal IPs, localhost, and cloud metadata endpoints are blocked.
- If `OPENAI_API_KEY` is set, the summary uses GPT-4.1-mini by default. Set `OPENAI_MODEL` to override.
- Fix prompts are designed to be pasted directly into Claude, Cursor, or your site editor — they target HTML, meta tags, and JSON-LD only.
- **Never commit real credentials into git. Use env vars only.**

Built by [gptmelo.com](https://gptmelo.com) — the GEO brand monitor for ChatGPT.

TDQS

A4.1/5.0

Scored across 1 tool

Disambiguation5/5

With only one tool, there is no possibility of confusion between tools. The single tool's purpose is clearly delineated by its name and description.

Naming Consistency5/5

The sole tool uses a clear, descriptive snake_case name that follows a consistent pattern (geo_site_audit). No inconsistency can exist with only one tool.

Tool Count3/5

While one tool is on the low end, it is borderline acceptable for a specialized, single-purpose server. The server's entire functionality is encapsulated in this one comprehensive audit tool.

Completeness5/5

The single tool fully delivers on the server's purpose: running a complete GEO audit across 31 signals and 6 pillars. No additional tools are needed for the stated scope.

Maintenance

ActivityStale
ResponsivenessNo issues