aeo-scanner 2.2.0__tar.gz → 2.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/PKG-INFO +5 -8
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/README.md +4 -7
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/pyproject.toml +1 -1
- aeo_scanner-2.2.2/server.json +27 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/src/server.py +52 -34
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/package-lock.json +1117 -71
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/package.json +4 -2
- aeo_scanner-2.2.2/workers/src/api-client.test.ts +197 -0
- aeo_scanner-2.2.2/workers/src/api-client.ts +198 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/src/index.ts +1 -1
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/src/resources.ts +1 -1
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/src/tools.ts +21 -23
- aeo_scanner-2.2.0/.github/workflows/publish.yml +0 -26
- aeo_scanner-2.2.0/server.json +0 -36
- aeo_scanner-2.2.0/workers/src/api-client.ts +0 -156
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/.gitignore +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/.mcp.json +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/LICENSE +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/aeo-icon.svg +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/scoring-methodology.md +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/src/__init__.py +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/uv.lock +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/.gitignore +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/.oxfmtrc.json +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/.oxlintrc.json +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/README.md +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/src/prompts.ts +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/src/scoring-methodology.ts +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/tsconfig.json +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/worker-configuration.d.ts +0 -0
- {aeo_scanner-2.2.0 → aeo_scanner-2.2.2}/workers/wrangler.jsonc +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aeo-scanner
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: MCP server for AI search visibility auditing. Triple scoring: AEO (search findability), GEO (citation readiness), Agent Readiness (agent interaction). Plus AI Identity Card and business profile detection.
|
|
5
5
|
Author-email: Convrgent <hello@convrgent.ai>
|
|
6
6
|
License: MIT
|
|
@@ -56,7 +56,7 @@ claude mcp add aeo-scanner -- uvx aeo-scanner
|
|
|
56
56
|
| Tool | What it does | Price |
|
|
57
57
|
|------|-------------|-------|
|
|
58
58
|
| `scan_site` | Quick triple-score scan + AI Identity Card + mention readiness + business profile + top issues | **Free** |
|
|
59
|
-
| `audit_site` | Full
|
|
59
|
+
| `audit_site` | Full 67+ check breakdown across 12 categories (4 AEO + 4 GEO + 4 Agent) | $1.00 |
|
|
60
60
|
| `compare_sites` | Two-site gap analysis + category winners + overtake fix code | $3.00 |
|
|
61
61
|
| `fix_site` | Generated fix code with two-tier score projections — apply directly with Claude Code | $5.00 |
|
|
62
62
|
|
|
@@ -68,12 +68,9 @@ Rate limits: 20 scans/hour per IP, 5 per URL per day.
|
|
|
68
68
|
|
|
69
69
|
## Paid tools
|
|
70
70
|
|
|
71
|
-
`audit_site`, `compare_sites`, and `fix_site`
|
|
71
|
+
`audit_site`, `compare_sites`, and `fix_site` are pay-per-call via the [x402 protocol](https://www.x402.org/) — USDC on Base or Solana. No API key, no account.
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
2. Set `AEO_API_KEY` in your MCP config
|
|
75
|
-
|
|
76
|
-
Or pay per call with USDC via [x402 protocol](https://www.x402.org/) (Base network).
|
|
73
|
+
Without payment, the tool returns a structured `payment_required` error containing the full x402 payload (payTo address, amount, asset). x402-capable clients retry automatically with a signed `X-PAYMENT` header; other agents can relay the payment details to their operator.
|
|
77
74
|
|
|
78
75
|
## Workflow
|
|
79
76
|
|
|
@@ -87,7 +84,7 @@ The included `optimize_site` prompt guides the full workflow:
|
|
|
87
84
|
|
|
88
85
|
## Scoring
|
|
89
86
|
|
|
90
|
-
|
|
87
|
+
67+ checks across 12 categories. See the built-in `aeo://reference/scoring-methodology` resource for full details.
|
|
91
88
|
|
|
92
89
|
**AEO categories:** Structured Data (30%), Meta & Technical (20%), AI Accessibility (25%), Content Quality (25%)
|
|
93
90
|
|
|
@@ -39,7 +39,7 @@ claude mcp add aeo-scanner -- uvx aeo-scanner
|
|
|
39
39
|
| Tool | What it does | Price |
|
|
40
40
|
|------|-------------|-------|
|
|
41
41
|
| `scan_site` | Quick triple-score scan + AI Identity Card + mention readiness + business profile + top issues | **Free** |
|
|
42
|
-
| `audit_site` | Full
|
|
42
|
+
| `audit_site` | Full 67+ check breakdown across 12 categories (4 AEO + 4 GEO + 4 Agent) | $1.00 |
|
|
43
43
|
| `compare_sites` | Two-site gap analysis + category winners + overtake fix code | $3.00 |
|
|
44
44
|
| `fix_site` | Generated fix code with two-tier score projections — apply directly with Claude Code | $5.00 |
|
|
45
45
|
|
|
@@ -51,12 +51,9 @@ Rate limits: 20 scans/hour per IP, 5 per URL per day.
|
|
|
51
51
|
|
|
52
52
|
## Paid tools
|
|
53
53
|
|
|
54
|
-
`audit_site`, `compare_sites`, and `fix_site`
|
|
54
|
+
`audit_site`, `compare_sites`, and `fix_site` are pay-per-call via the [x402 protocol](https://www.x402.org/) — USDC on Base or Solana. No API key, no account.
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
2. Set `AEO_API_KEY` in your MCP config
|
|
58
|
-
|
|
59
|
-
Or pay per call with USDC via [x402 protocol](https://www.x402.org/) (Base network).
|
|
56
|
+
Without payment, the tool returns a structured `payment_required` error containing the full x402 payload (payTo address, amount, asset). x402-capable clients retry automatically with a signed `X-PAYMENT` header; other agents can relay the payment details to their operator.
|
|
60
57
|
|
|
61
58
|
## Workflow
|
|
62
59
|
|
|
@@ -70,7 +67,7 @@ The included `optimize_site` prompt guides the full workflow:
|
|
|
70
67
|
|
|
71
68
|
## Scoring
|
|
72
69
|
|
|
73
|
-
|
|
70
|
+
67+ checks across 12 categories. See the built-in `aeo://reference/scoring-methodology` resource for full details.
|
|
74
71
|
|
|
75
72
|
**AEO categories:** Structured Data (30%), Meta & Technical (20%), AI Accessibility (25%), Content Quality (25%)
|
|
76
73
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "aeo-scanner"
|
|
3
|
-
version = "2.2.
|
|
3
|
+
version = "2.2.2"
|
|
4
4
|
description = "MCP server for AI search visibility auditing. Triple scoring: AEO (search findability), GEO (citation readiness), Agent Readiness (agent interaction). Plus AI Identity Card and business profile detection."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = {text = "MIT"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.Convrgent/aeo-scanner",
|
|
4
|
+
"title": "AEO Scanner",
|
|
5
|
+
"description": "AI visibility for ChatGPT/Perplexity/Claude — triple score (AEO+GEO+Agent) with fix code. Free.",
|
|
6
|
+
"repository": {
|
|
7
|
+
"url": "https://github.com/Convrgent/aeo-saas",
|
|
8
|
+
"source": "github"
|
|
9
|
+
},
|
|
10
|
+
"version": "2.2.2",
|
|
11
|
+
"remotes": [
|
|
12
|
+
{
|
|
13
|
+
"type": "streamable-http",
|
|
14
|
+
"url": "https://aeo-mcp.convrgent.ai/mcp"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"packages": [
|
|
18
|
+
{
|
|
19
|
+
"registryType": "pypi",
|
|
20
|
+
"identifier": "aeo-scanner",
|
|
21
|
+
"version": "2.2.2",
|
|
22
|
+
"transport": {
|
|
23
|
+
"type": "stdio"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -9,42 +9,59 @@ mcp = FastMCP(
|
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
API_BASE = os.environ.get("AEO_API_URL", "https://scan.convrgent.ai")
|
|
12
|
-
AEO_API_KEY = os.environ.get("AEO_API_KEY")
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def _payment_required_response() -> str:
|
|
24
|
-
"""
|
|
13
|
+
# Single source of truth for tool name + price per endpoint — mirrors
|
|
14
|
+
# TOOL_PRICING in mcp/workers/src/api-client.ts. Keep the two in sync.
|
|
15
|
+
TOOL_PRICING = {
|
|
16
|
+
"/api/aeo/audit": ("audit_site", "$1.00"),
|
|
17
|
+
"/api/aeo/compare": ("compare_sites", "$3.00"),
|
|
18
|
+
"/api/aeo/fix": ("fix_site", "$5.00"),
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _payment_required_response(resp: httpx.Response, tool: str, price: str) -> str:
|
|
23
|
+
"""Pass the backend's x402 v2 payload through verbatim so x402-capable
|
|
24
|
+
agents can auto-pay, and agents without a wallet can relay payTo/amount
|
|
25
|
+
to their operator. Never swallow the payload behind a static message —
|
|
26
|
+
that was the exact bug fixed in the worker (PR #3, 2026-04-17). The old
|
|
27
|
+
AEO_API_KEY / Bearer flow was dead config: the backend only ever checked
|
|
28
|
+
x402 payment headers."""
|
|
29
|
+
try:
|
|
30
|
+
x402_payload = resp.json()
|
|
31
|
+
except Exception:
|
|
32
|
+
x402_payload = {"raw": resp.text[:500]}
|
|
25
33
|
return json.dumps(
|
|
26
34
|
{
|
|
27
35
|
"error": "payment_required",
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
"status": 402,
|
|
37
|
+
"tool": tool,
|
|
38
|
+
"price": price,
|
|
39
|
+
"message": (
|
|
40
|
+
f"{tool} is pay-per-call ({price}) via the x402 protocol — USDC on "
|
|
41
|
+
"Base or Solana. Retry with a signed X-PAYMENT header from an "
|
|
42
|
+
"x402-capable client, or relay the payment details below to your "
|
|
43
|
+
"operator. The x402 payload has the payTo address, amount, and asset."
|
|
44
|
+
),
|
|
45
|
+
"x402": x402_payload,
|
|
46
|
+
"docs": "https://www.x402.org/",
|
|
47
|
+
"free_alternative": "scan_site is free — try it to see the three scores before paying for the full audit.",
|
|
36
48
|
},
|
|
37
49
|
indent=2,
|
|
38
50
|
)
|
|
39
51
|
|
|
40
52
|
|
|
41
53
|
async def _handle_paid_request(endpoint: str, payload: dict) -> str:
|
|
42
|
-
"""Call a paid endpoint with proper 402 handling.
|
|
43
|
-
|
|
54
|
+
"""Call a paid endpoint with proper 402 handling.
|
|
55
|
+
|
|
56
|
+
X-MCP-Tool tags the request as MCP-originated so the backend can measure
|
|
57
|
+
discovery->tool-call conversion (mirrors mcp/workers/src/api-client.ts).
|
|
58
|
+
"""
|
|
59
|
+
tool, price = TOOL_PRICING[endpoint]
|
|
60
|
+
headers = {"Content-Type": "application/json", "X-MCP-Tool": tool}
|
|
44
61
|
async with httpx.AsyncClient(timeout=180) as client:
|
|
45
62
|
resp = await client.post(f"{API_BASE}{endpoint}", json=payload, headers=headers)
|
|
46
63
|
if resp.status_code == 402:
|
|
47
|
-
return _payment_required_response()
|
|
64
|
+
return _payment_required_response(resp, tool, price)
|
|
48
65
|
if resp.status_code >= 400:
|
|
49
66
|
try:
|
|
50
67
|
error_data = resp.json()
|
|
@@ -68,13 +85,13 @@ async def scan_site(url: str, pages: int = 5) -> str:
|
|
|
68
85
|
and Agent Readiness Score (0-100, AI agent interaction). Also returns
|
|
69
86
|
AI Identity Card with mention readiness (0-100, predicts how likely AI
|
|
70
87
|
will mention the brand), detected competitors, business profile
|
|
71
|
-
(commerce/saas/media/general), and top issues.
|
|
72
|
-
12 categories. Free — no
|
|
88
|
+
(commerce/saas/media/general), and top issues. 67+ checks across
|
|
89
|
+
12 categories. Free — no payment or setup needed."""
|
|
73
90
|
async with httpx.AsyncClient(timeout=120) as client:
|
|
74
91
|
resp = await client.post(
|
|
75
92
|
f"{API_BASE}/api/aeo/scan",
|
|
76
93
|
json={"url": url, "pages": min(max(1, pages), 5)},
|
|
77
|
-
headers={"Content-Type": "application/json"},
|
|
94
|
+
headers={"Content-Type": "application/json", "X-MCP-Tool": "scan_site"},
|
|
78
95
|
)
|
|
79
96
|
if resp.status_code >= 400:
|
|
80
97
|
try:
|
|
@@ -96,13 +113,13 @@ async def scan_site(url: str, pages: int = 5) -> str:
|
|
|
96
113
|
async def audit_site(
|
|
97
114
|
url: str, pages: int = 5, categories: list[str] | None = None
|
|
98
115
|
) -> str:
|
|
99
|
-
"""Full AI visibility audit across
|
|
116
|
+
"""Full AI visibility audit across 67+ checks in 12 categories:
|
|
100
117
|
AEO (structured data, meta & technical, AI accessibility, content quality),
|
|
101
118
|
GEO (brand narrative, citation readiness with 3 research-backed checks,
|
|
102
119
|
authority signals, entity definition), and Agent Readiness (machine
|
|
103
120
|
identity, API discoverability, structured actions, programmatic access).
|
|
104
121
|
Returns AI Identity Card with mention readiness and detected competitors.
|
|
105
|
-
|
|
122
|
+
Pay per call ($1.00) via x402 — USDC on Base or Solana."""
|
|
106
123
|
payload: dict = {"url": url, "pages": min(max(1, pages), 5)}
|
|
107
124
|
if categories:
|
|
108
125
|
payload["categories"] = categories
|
|
@@ -117,7 +134,7 @@ async def compare_sites(url: str, competitor_url: str, pages: int = 5) -> str:
|
|
|
117
134
|
fix code with projected scores after closing gaps. Use when the user
|
|
118
135
|
wants to benchmark against a competitor or when scan_site detects
|
|
119
136
|
competitors in the AI Identity Card.
|
|
120
|
-
|
|
137
|
+
Pay per call ($3.00) via x402 — USDC on Base or Solana."""
|
|
121
138
|
return await _handle_paid_request(
|
|
122
139
|
"/api/aeo/compare",
|
|
123
140
|
{"url": url, "competitorUrl": competitor_url, "maxPages": min(max(1, pages), 5)},
|
|
@@ -132,7 +149,7 @@ async def fix_site(url: str, pages: int = 5, format: str = "generic") -> str:
|
|
|
132
149
|
quick wins (critical + high fixes only) and full implementation
|
|
133
150
|
ceiling (all fixes). Content recommendations include research citations.
|
|
134
151
|
Set format to 'claude_code' for Claude Code optimized output.
|
|
135
|
-
|
|
152
|
+
Pay per call ($5.00) via x402 — USDC on Base or Solana."""
|
|
136
153
|
return await _handle_paid_request(
|
|
137
154
|
"/api/aeo/fix",
|
|
138
155
|
{"url": url, "pages": min(max(1, pages), 5), "format": format},
|
|
@@ -141,7 +158,7 @@ async def fix_site(url: str, pages: int = 5, format: str = "generic") -> str:
|
|
|
141
158
|
|
|
142
159
|
@mcp.resource("aeo://reference/scoring-methodology")
|
|
143
160
|
async def scoring_methodology() -> str:
|
|
144
|
-
"""How AEO, GEO, and Agent Readiness scores are calculated across
|
|
161
|
+
"""How AEO, GEO, and Agent Readiness scores are calculated across 67+ checks in 12 categories. Includes mention readiness, business profiles, and research sources."""
|
|
145
162
|
path = os.path.join(os.path.dirname(__file__), "..", "scoring-methodology.md")
|
|
146
163
|
with open(path) as f:
|
|
147
164
|
return f.read()
|
|
@@ -184,9 +201,10 @@ Priority focus: {priority}
|
|
|
184
201
|
If priority is "auto", use the detected business profile to decide emphasis.
|
|
185
202
|
|
|
186
203
|
If any paid tool returns a payment_required error, tell the user:
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
-
|
|
204
|
+
- The tools are pay-per-call via the x402 protocol (USDC on Base or Solana)
|
|
205
|
+
- The error includes the full x402 payload (payTo address, amount, asset)
|
|
206
|
+
- An x402-capable client can retry with a signed X-PAYMENT header
|
|
207
|
+
- Details: https://www.x402.org/ and https://scan.convrgent.ai
|
|
190
208
|
"""
|
|
191
209
|
|
|
192
210
|
|