@automatelab/ai-seo-mcp 0.3.0 → 0.4.1
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.
- package/README.md +37 -18
- package/dist/cli/audit-cli.d.ts +3 -0
- package/dist/cli/audit-cli.d.ts.map +1 -0
- package/dist/cli/audit-cli.js +136 -0
- package/dist/cli/audit-cli.js.map +1 -0
- package/dist/index.js +710 -227
- package/dist/index.js.map +1 -1
- package/dist/lib/cache.d.ts +12 -0
- package/dist/lib/cache.d.ts.map +1 -0
- package/dist/lib/cache.js +51 -0
- package/dist/lib/cache.js.map +1 -0
- package/dist/lib/config.js +1 -1
- package/dist/lib/fetch.d.ts +5 -0
- package/dist/lib/fetch.d.ts.map +1 -1
- package/dist/lib/fetch.js +42 -1
- package/dist/lib/fetch.js.map +1 -1
- package/dist/lib/headless.d.ts +13 -0
- package/dist/lib/headless.d.ts.map +1 -0
- package/dist/lib/headless.js +73 -0
- package/dist/lib/headless.js.map +1 -0
- package/dist/lib/scorecard-html.js +94 -94
- package/dist/output-schemas.d.ts +658 -0
- package/dist/output-schemas.d.ts.map +1 -0
- package/dist/output-schemas.js +265 -0
- package/dist/output-schemas.js.map +1 -0
- package/dist/tools/audit-page.d.ts +11 -0
- package/dist/tools/audit-page.d.ts.map +1 -1
- package/dist/tools/audit-page.js +49 -2
- package/dist/tools/audit-page.js.map +1 -1
- package/dist/tools/audit-schema.d.ts +2 -1
- package/dist/tools/audit-schema.d.ts.map +1 -1
- package/dist/tools/audit-schema.js +2 -1
- package/dist/tools/audit-schema.js.map +1 -1
- package/dist/tools/audit-site.d.ts +41 -0
- package/dist/tools/audit-site.d.ts.map +1 -0
- package/dist/tools/audit-site.js +120 -0
- package/dist/tools/audit-site.js.map +1 -0
- package/dist/tools/audit-sitemap.d.ts +66 -0
- package/dist/tools/audit-sitemap.d.ts.map +1 -0
- package/dist/tools/audit-sitemap.js +264 -0
- package/dist/tools/audit-sitemap.js.map +1 -0
- package/dist/tools/check-technical.d.ts +2 -1
- package/dist/tools/check-technical.d.ts.map +1 -1
- package/dist/tools/check-technical.js +2 -1
- package/dist/tools/check-technical.js.map +1 -1
- package/dist/tools/diff-pages.js +2 -2
- package/dist/tools/diff-pages.js.map +1 -1
- package/dist/tools/extract-entities.d.ts +8 -1
- package/dist/tools/extract-entities.d.ts.map +1 -1
- package/dist/tools/extract-entities.js +110 -3
- package/dist/tools/extract-entities.js.map +1 -1
- package/dist/tools/save-audit-report.d.ts +22 -0
- package/dist/tools/save-audit-report.d.ts.map +1 -0
- package/dist/tools/save-audit-report.js +133 -0
- package/dist/tools/save-audit-report.js.map +1 -0
- package/dist/tools/test-citation.d.ts +51 -0
- package/dist/tools/test-citation.d.ts.map +1 -0
- package/dist/tools/test-citation.js +159 -0
- package/dist/tools/test-citation.js.map +1 -0
- package/package.json +8 -1
- package/smithery.yaml +13 -0
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ Works inside Claude, Cursor, Windsurf, Codex, and any MCP client that speaks std
|
|
|
17
17
|
- **AI crawler access** - GPTBot, OAI-SearchBot, ClaudeBot, and PerplexityBot allowed or blocked in `robots.txt`
|
|
18
18
|
- **`llms.txt`** - present, spec-compliant, links alive
|
|
19
19
|
- **Structured answer extraction** - FAQ headings, BLUF paragraphs, answer-ready blocks
|
|
20
|
-
- **
|
|
20
|
+
- **[[schema]] completeness** - FAQPage, Article, Organization, Person; flags deprecated patterns
|
|
21
21
|
- **Entity clarity** - named entity density and `sameAs` coverage that help AI systems identify the subject
|
|
22
22
|
- **Citation formatting** - canonical URL hygiene, `og:url`, `hreflang`, noindex traps
|
|
23
23
|
- **Sitemap freshness** - `lastmod` signals that tell crawlers the page is current
|
|
@@ -26,13 +26,13 @@ Works inside Claude, Cursor, Windsurf, Codex, and any MCP client that speaks std
|
|
|
26
26
|
|
|
27
27
|
## Run an audit. Get a list of citation-blockers, ranked.
|
|
28
28
|
|
|
29
|
-
> **You:** Run an AI-SEO audit on `https://automatelab.tech/
|
|
29
|
+
> **You:** Run an AI-SEO audit on `https://automatelab.tech/launching-the-ai-seo-mcp/`.
|
|
30
30
|
|
|
31
31
|
Result (truncated):
|
|
32
32
|
|
|
33
33
|
```json
|
|
34
34
|
{
|
|
35
|
-
"url": "https://automatelab.tech/
|
|
35
|
+
"url": "https://automatelab.tech/launching-the-ai-seo-mcp/",
|
|
36
36
|
"score": 61,
|
|
37
37
|
"grade": "C",
|
|
38
38
|
"dimension_scores": {
|
|
@@ -88,6 +88,19 @@ Add to `%APPDATA%\Claude\claude_desktop_config.json` (Windows) or `~/Library/App
|
|
|
88
88
|
|
|
89
89
|
Restart Claude Desktop. Any MCP client that supports stdio transport works - same `command` / `args` pattern.
|
|
90
90
|
|
|
91
|
+
### Optional: headless rendering for SPAs
|
|
92
|
+
|
|
93
|
+
By default `audit_page` reads raw HTML — fast, but misses content on React/Vue/Angular SPAs. Pass `render: "headless"` to spin up Chromium and audit the rendered DOM (adds 3-10s per audit).
|
|
94
|
+
|
|
95
|
+
One-time install:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npm install playwright-core
|
|
99
|
+
npx playwright install chromium
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Then call `audit_page` with `render: "headless"`. Use static for everything else — most marketing sites and docs render fine without it.
|
|
103
|
+
|
|
91
104
|
---
|
|
92
105
|
|
|
93
106
|
## Further reading
|
|
@@ -97,24 +110,30 @@ Restart Claude Desktop. Any MCP client that supports stdio transport works - sam
|
|
|
97
110
|
---
|
|
98
111
|
|
|
99
112
|
<details>
|
|
100
|
-
<summary>
|
|
113
|
+
<summary>MCP tool surface (18 tools)</summary>
|
|
101
114
|
|
|
102
115
|
| Tool | Purpose |
|
|
103
116
|
|------|---------|
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
117
|
+
| `audit.page` | Composite AI-SEO audit with 8-dimension scoring (schema, technical, structure, robots, freshness, authority, entity density, sitemap). |
|
|
118
|
+
| `audit.schema` | Validate JSON-LD against Schema.org rules and AI-citation best practice. Flags deprecated patterns. |
|
|
119
|
+
| `audit.canonical` | Canonical link integrity, trailing-slash hygiene, `og:url` consistency. |
|
|
120
|
+
| `audit.site` | Single-call site sweep: `audit.page` + `check.robots` + `check.sitemap` + `audit.schema` with overall grade and top-5 fixes. |
|
|
121
|
+
| `audit.sitemap` | Site-wide content audit: stride-sample N URLs from the sitemap, run `audit.page` on each, return distribution + worst pages + top findings. |
|
|
122
|
+
| `check.robots` | Parse `robots.txt` and report per-crawler allow/disallow for all known AI crawlers. Surfaces the GPTBot-blocked-but-OAI-SearchBot-allowed trap. |
|
|
123
|
+
| `check.sitemap` | Validate XML sitemaps: presence, URL count, `lastmod` freshness, image/video extensions. |
|
|
124
|
+
| `check.technical` | HEAD tag audit: canonical, OpenGraph, Twitter Card, hreflang, HTTPS, noindex, title hygiene. |
|
|
125
|
+
| `score.ai_overview_eligibility` | Score a page's probability of appearing in Google AI Overviews using current correlation factors. |
|
|
126
|
+
| `score.citation_worthiness` | Score how citable a page or text block is for Perplexity, ChatGPT, Google AI Overviews, and Claude. |
|
|
127
|
+
| `score.test_citation` | Simulate "would an AI engine cite this for this query?" via MCP sampling, with deterministic heuristic fallback. |
|
|
128
|
+
| `llms_txt.generate` | Generate `llms.txt` and optionally `llms-full.txt` from a domain's sitemap. |
|
|
129
|
+
| `llms_txt.validate` | Lint an existing `llms.txt` for spec compliance and broken links. |
|
|
130
|
+
| `rewrite.aeo` | Rewrite content for Answer Engine Optimization (BLUF structure, FAQ format, schema additions). |
|
|
131
|
+
| `rewrite.geo` | Rewrite content for Generative Engine Optimization (entity definitions, comparison tables, synthesis-ready structure). |
|
|
132
|
+
| `extract.entities` | Extract named entities, `sameAs` links, and citation-density score from a page's content and structured data. |
|
|
133
|
+
| `diff.pages` | Compare two URLs for AI citation-worthiness: side-by-side dimension scores, gap analysis, and prioritized fix recommendations for url_a. |
|
|
134
|
+
| `report.save` | Render an `audit.page` / `audit.site` result as a Markdown report and write it to disk under `MCP_WORKSPACE_ROOT`. |
|
|
135
|
+
|
|
136
|
+
> **v0.4.0** renamed tools from flat `snake_case` to dot-notation (`audit.page`, `check.robots`, …) for a navigable hierarchy. Update any saved invocations.
|
|
118
137
|
|
|
119
138
|
Environment variables: see [ENV.md](./ENV.md).
|
|
120
139
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-cli.d.ts","sourceRoot":"","sources":["../../src/cli/audit-cli.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// CLI wrapper around audit_page / audit_site, used by the ai-seo GitHub Action.
|
|
3
|
+
// Not part of the MCP protocol; reads flags and prints results to stdout/stderr.
|
|
4
|
+
//
|
|
5
|
+
// Usage:
|
|
6
|
+
// ai-seo-audit --urls "https://a.com,https://b.com/post" [--min-score 70] [--respect-robots true] [--report-path report.md]
|
|
7
|
+
//
|
|
8
|
+
// Exit code:
|
|
9
|
+
// 0 all audited URLs scored >= min-score
|
|
10
|
+
// 1 any URL scored < min-score (regression)
|
|
11
|
+
// 2 bad arguments / runtime error
|
|
12
|
+
import { appendFileSync } from "node:fs";
|
|
13
|
+
import { auditPage } from "../tools/audit-page.js";
|
|
14
|
+
import { saveAuditReport } from "../tools/save-audit-report.js";
|
|
15
|
+
function parseArgs(argv) {
|
|
16
|
+
const args = {
|
|
17
|
+
urls: [],
|
|
18
|
+
minScore: 70,
|
|
19
|
+
respectRobots: true,
|
|
20
|
+
reportPath: null,
|
|
21
|
+
failOnRegression: true,
|
|
22
|
+
};
|
|
23
|
+
for (let i = 0; i < argv.length; i++) {
|
|
24
|
+
const a = argv[i];
|
|
25
|
+
const next = () => {
|
|
26
|
+
const v = argv[i + 1];
|
|
27
|
+
if (v === undefined)
|
|
28
|
+
throw new Error(`flag ${a} requires a value`);
|
|
29
|
+
i++;
|
|
30
|
+
return v;
|
|
31
|
+
};
|
|
32
|
+
switch (a) {
|
|
33
|
+
case "--urls":
|
|
34
|
+
args.urls = next().split(",").map((s) => s.trim()).filter(Boolean);
|
|
35
|
+
break;
|
|
36
|
+
case "--min-score":
|
|
37
|
+
args.minScore = Number(next());
|
|
38
|
+
break;
|
|
39
|
+
case "--respect-robots":
|
|
40
|
+
args.respectRobots = next().toLowerCase() !== "false";
|
|
41
|
+
break;
|
|
42
|
+
case "--report-path":
|
|
43
|
+
args.reportPath = next();
|
|
44
|
+
break;
|
|
45
|
+
case "--fail-on-regression":
|
|
46
|
+
args.failOnRegression = next().toLowerCase() !== "false";
|
|
47
|
+
break;
|
|
48
|
+
case "--help":
|
|
49
|
+
case "-h":
|
|
50
|
+
console.log("Usage: ai-seo-audit --urls <csv> [--min-score N] [--respect-robots true|false] [--report-path FILE] [--fail-on-regression true|false]");
|
|
51
|
+
process.exit(0);
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
throw new Error(`unknown flag: ${a}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (args.urls.length === 0)
|
|
58
|
+
throw new Error("at least one URL is required via --urls");
|
|
59
|
+
if (!Number.isFinite(args.minScore))
|
|
60
|
+
throw new Error("--min-score must be a number");
|
|
61
|
+
return args;
|
|
62
|
+
}
|
|
63
|
+
function emitGithubOutput(key, value) {
|
|
64
|
+
const file = process.env["GITHUB_OUTPUT"];
|
|
65
|
+
if (!file)
|
|
66
|
+
return;
|
|
67
|
+
const safe = String(value).replace(/\r?\n/g, " ");
|
|
68
|
+
try {
|
|
69
|
+
appendFileSync(file, `${key}=${safe}\n`);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// best-effort; CI step will still see stdout/stderr
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function main() {
|
|
76
|
+
let args;
|
|
77
|
+
try {
|
|
78
|
+
args = parseArgs(process.argv.slice(2));
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
console.error("[ai-seo-audit] argument error:", err instanceof Error ? err.message : String(err));
|
|
82
|
+
process.exit(2);
|
|
83
|
+
}
|
|
84
|
+
const results = [];
|
|
85
|
+
let anyBelow = false;
|
|
86
|
+
let minObserved = 100;
|
|
87
|
+
for (const url of args.urls) {
|
|
88
|
+
try {
|
|
89
|
+
const result = await auditPage({
|
|
90
|
+
url,
|
|
91
|
+
include_raw_html: false,
|
|
92
|
+
respect_robots: args.respectRobots,
|
|
93
|
+
generate_report: false,
|
|
94
|
+
render: "static",
|
|
95
|
+
});
|
|
96
|
+
const below = result.score < args.minScore;
|
|
97
|
+
if (below)
|
|
98
|
+
anyBelow = true;
|
|
99
|
+
if (result.score < minObserved)
|
|
100
|
+
minObserved = result.score;
|
|
101
|
+
console.log(`${below ? "❌" : "✅"} ${url} — score=${result.score} grade=${result.grade} quality=${result.content_quality}`);
|
|
102
|
+
results.push(result);
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
console.error(`[ai-seo-audit] failed for ${url}:`, err instanceof Error ? err.message : String(err));
|
|
106
|
+
anyBelow = true;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (args.reportPath && results.length > 0) {
|
|
110
|
+
// Save the first result; users who pass multiple URLs typically want one report per run,
|
|
111
|
+
// and the action wires --report-path to a single file. Multi-URL reporting can be added if asked.
|
|
112
|
+
try {
|
|
113
|
+
const saved = await saveAuditReport({
|
|
114
|
+
audit_result: results[0],
|
|
115
|
+
path: args.reportPath,
|
|
116
|
+
overwrite: true,
|
|
117
|
+
});
|
|
118
|
+
console.log(`[ai-seo-audit] wrote ${saved.bytes_written}b -> ${saved.saved_to}`);
|
|
119
|
+
emitGithubOutput("report_path", saved.saved_to);
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
console.error("[ai-seo-audit] could not save report:", err instanceof Error ? err.message : String(err));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
emitGithubOutput("min_score_observed", minObserved);
|
|
126
|
+
emitGithubOutput("urls_audited", results.length);
|
|
127
|
+
if (anyBelow && args.failOnRegression) {
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
process.exit(0);
|
|
131
|
+
}
|
|
132
|
+
main().catch((err) => {
|
|
133
|
+
console.error("[ai-seo-audit] fatal:", err);
|
|
134
|
+
process.exit(2);
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=audit-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-cli.js","sourceRoot":"","sources":["../../src/cli/audit-cli.ts"],"names":[],"mappings":"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"}
|