seo 0.0.15 → 0.1.0
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/LICENSE +201 -0
- package/PRIVACY.md +95 -0
- package/README.md +338 -35
- package/SECURITY.md +55 -0
- package/TERMS.md +94 -0
- package/TRADEMARKS.md +27 -0
- package/dist/cli.js +125 -0
- package/dist/cli.js.map +1 -0
- package/dist/dist-CSY2_p-j.js +713 -0
- package/dist/dist-CSY2_p-j.js.map +1 -0
- package/dist/dist-FeAUNn9A.js +3 -0
- package/dist/index.d.ts +17921 -0
- package/dist/index.js +26769 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +57 -0
- package/dist/mcp.js +26744 -0
- package/dist/mcp.js.map +1 -0
- package/dist/package-uzXzqDW6.js +23818 -0
- package/dist/package-uzXzqDW6.js.map +1 -0
- package/package.json +101 -23
- package/skills/README.md +81 -0
- package/skills/affected-urls/SKILL.md +39 -0
- package/skills/affected-urls/agents/openai.yaml +4 -0
- package/skills/ai-readiness/SKILL.md +34 -0
- package/skills/ai-readiness/agents/openai.yaml +4 -0
- package/skills/ai-referrals/SKILL.md +31 -0
- package/skills/ai-referrals/agents/openai.yaml +4 -0
- package/skills/audit-page/SKILL.md +50 -0
- package/skills/audit-page/agents/openai.yaml +4 -0
- package/skills/audit-urls/SKILL.md +39 -0
- package/skills/audit-urls/agents/openai.yaml +4 -0
- package/skills/cannibalisation/SKILL.md +31 -0
- package/skills/cannibalisation/agents/openai.yaml +4 -0
- package/skills/community-intent/SKILL.md +39 -0
- package/skills/community-intent/agents/openai.yaml +4 -0
- package/skills/compare-crawls/SKILL.md +40 -0
- package/skills/compare-crawls/agents/openai.yaml +4 -0
- package/skills/content-optimization/SKILL.md +31 -0
- package/skills/content-optimization/agents/openai.yaml +4 -0
- package/skills/crawl-diff/SKILL.md +51 -0
- package/skills/crawl-diff/agents/openai.yaml +4 -0
- package/skills/crawl-history/SKILL.md +37 -0
- package/skills/crawl-history/agents/openai.yaml +4 -0
- package/skills/crawl-report/SKILL.md +37 -0
- package/skills/crawl-report/agents/openai.yaml +4 -0
- package/skills/crawler-rules/SKILL.md +34 -0
- package/skills/crawler-rules/agents/openai.yaml +4 -0
- package/skills/ctr-underperformers/SKILL.md +31 -0
- package/skills/ctr-underperformers/agents/openai.yaml +4 -0
- package/skills/decaying-pages/SKILL.md +31 -0
- package/skills/decaying-pages/agents/openai.yaml +4 -0
- package/skills/entity-readiness/SKILL.md +34 -0
- package/skills/entity-readiness/agents/openai.yaml +4 -0
- package/skills/explain-crawl-issue/SKILL.md +32 -0
- package/skills/explain-crawl-issue/agents/openai.yaml +4 -0
- package/skills/generate-llms-txt/SKILL.md +37 -0
- package/skills/generate-llms-txt/agents/openai.yaml +4 -0
- package/skills/geo-gaps/SKILL.md +37 -0
- package/skills/geo-gaps/agents/openai.yaml +4 -0
- package/skills/index-coverage/SKILL.md +84 -0
- package/skills/index-coverage/agents/openai.yaml +4 -0
- package/skills/index-coverage-plan/SKILL.md +50 -0
- package/skills/index-coverage-plan/agents/openai.yaml +4 -0
- package/skills/index-monitor/SKILL.md +49 -0
- package/skills/index-monitor/agents/openai.yaml +4 -0
- package/skills/index-watch/SKILL.md +77 -0
- package/skills/index-watch/agents/openai.yaml +4 -0
- package/skills/internal-links/SKILL.md +31 -0
- package/skills/internal-links/agents/openai.yaml +4 -0
- package/skills/link-recovery/SKILL.md +51 -0
- package/skills/link-recovery/agents/openai.yaml +4 -0
- package/skills/llms-txt-audit/SKILL.md +34 -0
- package/skills/llms-txt-audit/agents/openai.yaml +4 -0
- package/skills/measure-change/SKILL.md +52 -0
- package/skills/measure-change/agents/openai.yaml +4 -0
- package/skills/monthly-action-plan/SKILL.md +50 -0
- package/skills/monthly-action-plan/agents/openai.yaml +4 -0
- package/skills/monthly-report/SKILL.md +50 -0
- package/skills/monthly-report/agents/openai.yaml +4 -0
- package/skills/narrative-report/SKILL.md +51 -0
- package/skills/narrative-report/agents/openai.yaml +4 -0
- package/skills/okf-build/SKILL.md +39 -0
- package/skills/okf-build/agents/openai.yaml +4 -0
- package/skills/okf-validate/SKILL.md +43 -0
- package/skills/okf-validate/agents/openai.yaml +4 -0
- package/skills/page-opportunities/SKILL.md +31 -0
- package/skills/page-opportunities/agents/openai.yaml +4 -0
- package/skills/performance/SKILL.md +50 -0
- package/skills/performance/agents/openai.yaml +4 -0
- package/skills/performance-audit/SKILL.md +31 -0
- package/skills/performance-audit/agents/openai.yaml +4 -0
- package/skills/pseo-audit/SKILL.md +103 -0
- package/skills/pseo-audit/agents/openai.yaml +4 -0
- package/skills/query-clusters/SKILL.md +31 -0
- package/skills/query-clusters/agents/openai.yaml +4 -0
- package/skills/quick-wins/SKILL.md +31 -0
- package/skills/quick-wins/agents/openai.yaml +4 -0
- package/skills/redirect-trace/SKILL.md +51 -0
- package/skills/redirect-trace/agents/openai.yaml +4 -0
- package/skills/refresh-priorities/SKILL.md +48 -0
- package/skills/refresh-priorities/agents/openai.yaml +4 -0
- package/skills/search-performance-overview/SKILL.md +48 -0
- package/skills/search-performance-overview/agents/openai.yaml +4 -0
- package/skills/second-page/SKILL.md +50 -0
- package/skills/second-page/agents/openai.yaml +4 -0
- package/skills/segment-impact/SKILL.md +50 -0
- package/skills/segment-impact/agents/openai.yaml +4 -0
- package/skills/seo/SKILL.md +74 -0
- package/skills/seo/agents/openai.yaml +4 -0
- package/skills/seo-fix-queue/SKILL.md +50 -0
- package/skills/seo-fix-queue/agents/openai.yaml +4 -0
- package/skills/seo-geo-readiness/SKILL.md +60 -0
- package/skills/seo-geo-readiness/agents/openai.yaml +4 -0
- package/skills/seo-site-audit/SKILL.md +59 -0
- package/skills/seo-site-audit/agents/openai.yaml +4 -0
- package/skills/seo-to-ai-query/SKILL.md +31 -0
- package/skills/seo-to-ai-query/agents/openai.yaml +4 -0
- package/skills/setup-check/SKILL.md +49 -0
- package/skills/setup-check/agents/openai.yaml +4 -0
- package/skills/site-crawl/SKILL.md +39 -0
- package/skills/site-crawl/agents/openai.yaml +4 -0
- package/skills/striking-distance/SKILL.md +52 -0
- package/skills/striking-distance/agents/openai.yaml +4 -0
- package/skills/technical-watch/SKILL.md +49 -0
- package/skills/technical-watch/agents/openai.yaml +4 -0
- package/skills/top-fixes/SKILL.md +38 -0
- package/skills/top-fixes/agents/openai.yaml +4 -0
- package/skills/traffic-anomaly/SKILL.md +52 -0
- package/skills/traffic-anomaly/agents/openai.yaml +4 -0
- package/skills/update-correlation/SKILL.md +51 -0
- package/skills/update-correlation/agents/openai.yaml +4 -0
- package/skills/update-postmortem/SKILL.md +49 -0
- package/skills/update-postmortem/agents/openai.yaml +4 -0
- package/.jshintrc +0 -18
- package/.npmignore +0 -3
- package/.travis.yml +0 -3
- package/Makefile +0 -10
- package/index.js +0 -2
- package/lib/middleware.js +0 -159
- package/lib/seo.js +0 -32
- package/test/init.js +0 -43
- package/test/middleware.test.js +0 -111
- package/test/seo-page-result.html +0 -9
- package/test/seo-page.html +0 -9
- package/test/seo-routes.js +0 -5
- package/test/vendor/jquery-1.11.1.min.js +0 -4
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crawl-diff
|
|
3
|
+
description: Compare a bounded same-origin crawl with its previous saved snapshot; use it to review technical changes after a release without claiming complete site coverage.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Compare crawl snapshots
|
|
7
|
+
|
|
8
|
+
Use `crawl-diff` after a deploy, migration, or planned technical change. It
|
|
9
|
+
crawls a bounded same-origin set, saves the result, and compares it with the
|
|
10
|
+
previous saved run for the same surface. This turns status, indexability,
|
|
11
|
+
canonical, metadata, content, and inventory movement into a review queue. It
|
|
12
|
+
does not prove that a changed page affected search performance.
|
|
13
|
+
|
|
14
|
+
## Run the report
|
|
15
|
+
|
|
16
|
+
With MCP, call `seo_list_reports` with `{"category":"monitoring"}`, then call
|
|
17
|
+
`seo_describe_report` with `{"id":"crawl-diff"}`. Run the exact schema with
|
|
18
|
+
`seo_run_report`, for example
|
|
19
|
+
`{"id":"crawl-diff","params":{"startUrl":"https://example.com/","site":"sc-domain:example.com","limit":250,"js":false,"refresh":true}}`.
|
|
20
|
+
|
|
21
|
+
CLI parity uses the same definition:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
seo reports describe crawl-diff --json
|
|
25
|
+
seo reports run crawl-diff --params '{"startUrl":"https://example.com/","site":"sc-domain:example.com","limit":250,"refresh":true}' --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The schema types `limit` as a broad number. Pass a positive whole-page bound and
|
|
29
|
+
keep it stable between comparison runs.
|
|
30
|
+
|
|
31
|
+
## Interpret the output
|
|
32
|
+
|
|
33
|
+
Compare `run` with `previousRun` before reading `summary`. A missing previous
|
|
34
|
+
run means the current crawl is a baseline, not a change result. Check the start
|
|
35
|
+
URL, limit, URL count, timestamps, rendering choice, and `warnings` for both
|
|
36
|
+
runs.
|
|
37
|
+
|
|
38
|
+
`summary` counts crawled, added, removed, changed, new errors, indexability
|
|
39
|
+
flips, and high-priority recommendations. Trace every important count into
|
|
40
|
+
`items`, where `before`, `after`, and `changes` preserve observed evidence.
|
|
41
|
+
`recommendations` rank review actions; they do not override the raw snapshots.
|
|
42
|
+
A removed URL may be outside the current discovered set or limit rather than
|
|
43
|
+
deleted. A fetch or extraction failure cannot support a resolved issue.
|
|
44
|
+
|
|
45
|
+
## Act safely
|
|
46
|
+
|
|
47
|
+
Verify high-priority status and indexability changes directly, then compare the
|
|
48
|
+
deployment intent. Restore accidental failures or controls, but leave intended
|
|
49
|
+
redirects, canonicals, and noindex directives alone. Repeat with comparable
|
|
50
|
+
scope after a fix. Never call a bounded diff an inventory-wide audit or infer
|
|
51
|
+
ranking impact from technical change alone.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crawl-history
|
|
3
|
+
description: Discover locally saved crawl snapshots and their compact metadata without loading full evidence. Use to select stable report ids for follow-ups, comparisons, or verification.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# List saved crawl reports
|
|
7
|
+
|
|
8
|
+
This report is the index for local crawl history. It returns metadata only, ordered newest first, so an agent can choose a snapshot without loading pages and issues or fetching the site again. It says what is stored locally, not what is currently true online.
|
|
9
|
+
|
|
10
|
+
## Run it
|
|
11
|
+
|
|
12
|
+
For MCP, call `seo_list_reports` with category `crawl` if discovery is needed. Call `seo_describe_report` with `{ "id": "crawl-history" }`, then `seo_run_report` with:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"id": "crawl-history",
|
|
17
|
+
"params": {
|
|
18
|
+
"site": "sc-domain:example.com",
|
|
19
|
+
"limit": 10
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Confirm MCP `isError` is false, then consume `structuredContent`. The equivalent CLI commands are:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
seo reports describe crawl-history --json
|
|
28
|
+
seo reports run crawl-history --params '{"site":"sc-domain:example.com","limit":10}' --json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The site filter prevents an unrelated recent crawl from becoming the implicit source. Increase `limit` only when older baselines are genuinely needed.
|
|
32
|
+
|
|
33
|
+
## Choose a source deliberately
|
|
34
|
+
|
|
35
|
+
Review each report's id, site, start URL, creation time, status, total pages, issue count, configuration hash, and storage version. Counts are orientation metadata, not enough to judge severity or data completeness. A smaller page count could reflect a scope change, cap, failure, or real site change.
|
|
36
|
+
|
|
37
|
+
Select an explicit id and load it with `crawl-report` before analysis. For a comparison, inspect both candidates' configuration and caveats instead of assuming adjacent timestamps are comparable. If the expected snapshot is absent, do not silently substitute another site or a fresh crawl; state that the local report was not found. Report lists can also expose old data, so include the creation time whenever presenting a saved finding as context.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crawl-report
|
|
3
|
+
description: Load a saved crawl snapshot without fetching the site again and opt into detailed evidence only when needed. Use for investigation, verification, or a stable source for follow-up reports.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Load a saved crawl report
|
|
7
|
+
|
|
8
|
+
Saved reports make technical analysis reproducible: several follow-ups can use the same crawl instead of observing the site at different times. Loading a report is a local storage operation, not a fresh check, so always retain its creation time and original crawl boundaries in the explanation.
|
|
9
|
+
|
|
10
|
+
## Run it
|
|
11
|
+
|
|
12
|
+
For MCP, call `seo_list_reports` with category `crawl` only for report discovery. Call `seo_describe_report` with `{ "id": "crawl-report" }`, then call `seo_run_report` with:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"id": "crawl-report",
|
|
17
|
+
"params": {
|
|
18
|
+
"id": "crawl_example_20260710",
|
|
19
|
+
"includeIssues": true
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Check `isError` and use MCP `structuredContent`. CLI parity is:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
seo reports describe crawl-report --json
|
|
28
|
+
seo reports run crawl-report --params '{"id":"crawl_example_20260710","includeIssues":true}' --json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Omitting `id` loads the latest saved report, optionally filtered by `site`. Use an explicit id whenever reproducibility matters. `includePages` adds request and page records; `includeIssues` adds the issue inventory.
|
|
32
|
+
|
|
33
|
+
## Read the snapshot
|
|
34
|
+
|
|
35
|
+
Confirm `id`, source URL and site, `generatedAt`, definition id, configuration hash, crawl status, and `requestEvidenceStatus`. Then inspect summary counts, `pageLimitReached`, data sources, warnings, and caveats. Provider states and crawl completeness determine which conclusions are supported.
|
|
36
|
+
|
|
37
|
+
Keep the default compact result for orientation. Request large page or issue arrays only to answer a concrete question, and filter downstream work by stable rule and URL fields rather than parsing rendered text. A report can be internally valid yet stale, capped, or partial. It cannot prove the current live state. For comparisons, load both reports and establish equivalent scope before interpreting deltas; for verification, run a new crawl with the same configuration and retain both report ids.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: crawler-rules
|
|
3
|
+
description: Discover stable crawler rule ids with their categories and guidance metadata before querying findings. Use when an agent needs a valid filter for explanations or affected-URL reports.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Discover crawler rules
|
|
7
|
+
|
|
8
|
+
Rules are the stable vocabulary connecting crawl issues, summaries, affected URLs, and remediation guidance. Listing them answers "which checks exist?" It does not say that a site triggered those checks or that every listed convention is a search-engine requirement.
|
|
9
|
+
|
|
10
|
+
## Run it
|
|
11
|
+
|
|
12
|
+
For MCP, use `seo_list_reports` with category `crawl` only if report discovery is needed. Call `seo_describe_report` with `{ "id": "crawler-rules" }`, then `seo_run_report` with:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"id": "crawler-rules",
|
|
17
|
+
"params": { "category": "metadata" }
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Read `structuredContent` after checking `isError`. CLI parity is:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
seo reports describe crawler-rules --json
|
|
25
|
+
seo reports run crawler-rules --params '{"category":"metadata"}' --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Omit `category` to discover the full inventory. Useful categories include response, indexability, canonical, metadata, headings, content, links, images, structured-data, international, performance, mobile, security, social, and geo.
|
|
29
|
+
|
|
30
|
+
## Use ids, not prose
|
|
31
|
+
|
|
32
|
+
Read the returned id, title, category, default severity, and guidance metadata. Pass the exact id to `explain-crawl-issue` for the rule contract or to `affected-urls` for crawl evidence. Do not infer that similarly named rules have identical source semantics, and do not create implementation work from the catalog alone.
|
|
33
|
+
|
|
34
|
+
The category input is constrained to the crawler's supported category enum. Describe the report before filtering and pass one of those exact values; unknown or misspelled categories are rejected as invalid input rather than becoming a misleading empty result. A valid category can still return no rules if the registry changes, so use the unfiltered inventory for discovery. Treat default severity as general triage metadata; actual priority comes from affected pages, observed evidence, scope, intent, and available demand data.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ctr-underperformers
|
|
3
|
+
description: Find high-impression page-one GSC rows below a site-aware CTR benchmark; use when an agent needs a bounded snippet review queue with heuristic shortfalls kept explicit.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CTR underperformers
|
|
7
|
+
|
|
8
|
+
Use this report to prioritise retained query/page rows whose observed CTR is materially below a position-based benchmark. It aggregates duplicate rows before analysis and prefers a robust site-aware peer benchmark when enough evidence exists, otherwise it uses a built-in fallback curve. The result can identify snippets worth reviewing, but it cannot observe the live SERP layout, explain user intent, isolate title or description effects, or promise that the calculated shortfall is recoverable.
|
|
9
|
+
|
|
10
|
+
## Run the report
|
|
11
|
+
|
|
12
|
+
Use the compact MCP flow:
|
|
13
|
+
|
|
14
|
+
1. Call `seo_list_reports` with `{"category":"opportunities"}`.
|
|
15
|
+
2. Call `seo_describe_report` with `{"id":"ctr-underperformers"}`.
|
|
16
|
+
3. Call `seo_run_report` with `{"id":"ctr-underperformers","params":{"site":"sc-domain:example.com","minImpressions":250,"includeBrand":false}}`.
|
|
17
|
+
|
|
18
|
+
The CLI calls the same handler:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
seo reports describe ctr-underperformers --json
|
|
22
|
+
seo reports run ctr-underperformers --params '{"site":"sc-domain:example.com","minImpressions":250,"includeBrand":false}' --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`site` is required. This catalog schema exposes only `minImpressions` and `includeBrand`; the report itself uses a final-data 28-day window and reports its output limit in `summary`.
|
|
26
|
+
|
|
27
|
+
## Interpret and act
|
|
28
|
+
|
|
29
|
+
Check `dataStatus`, `range`, `source.completeness`, `possiblyTruncated`, validation counts, and `selection` before looking at the queue. Invalid rows make the report partial; duplicate rows are aggregated, not silently counted twice. For every item, keep query, URL, impressions, position, observed CTR, target CTR, benchmark source/confidence, and estimated shortfall together. The shortfall is directional prioritisation math, not a traffic forecast. Page-one average position also hides day, device, geography, and result-feature variation.
|
|
30
|
+
|
|
31
|
+
Safe actions are to inspect the current SERP and displayed title link, confirm the page matches intent, then test clearer framing where evidence supports it. Annotate the change and compare a complete later period. Do not rewrite already appropriate copy merely to chase the benchmark, infer causation from CTR alone, or call a partial empty result an all-clear.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: decaying-pages
|
|
3
|
+
description: Compare retained GSC query-page rows across equal finalized windows to find observed click declines; use when an agent needs a bounded investigation queue without invented attribution.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Decaying queries and pages
|
|
7
|
+
|
|
8
|
+
Use this report to identify retained query/page combinations that lost clicks between adjacent equal-length periods or year-over-year windows. It requires evidence in both windows, excludes URL shifts, and groups returned rows by diagnosis signal and page template. This avoids turning a row missing from GSC's retained query data into zero traffic. The report shows observed movement, not why it happened.
|
|
9
|
+
|
|
10
|
+
## Run the report
|
|
11
|
+
|
|
12
|
+
Use the compact MCP flow:
|
|
13
|
+
|
|
14
|
+
1. Call `seo_list_reports` with `{"category":"opportunities"}`.
|
|
15
|
+
2. Call `seo_describe_report` with `{"id":"decaying-pages"}`.
|
|
16
|
+
3. Call `seo_run_report` with `{"id":"decaying-pages","params":{"site":"sc-domain:example.com","days":28,"comparison":"previous-period","limit":20,"minDropPct":20,"minPreviousClicks":10,"minClickLoss":5}}`.
|
|
17
|
+
|
|
18
|
+
The CLI uses the same report definition:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
seo reports describe decaying-pages --json
|
|
22
|
+
seo reports run decaying-pages --params '{"site":"sc-domain:example.com","days":28,"comparison":"previous-period","limit":20,"minDropPct":20,"minPreviousClicks":10,"minClickLoss":5}' --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`site` is required. Choose `year-over-year` only when the requested window fits GSC's available history. Brand terms and `includeBrand` control navigational-query filtering.
|
|
26
|
+
|
|
27
|
+
## Interpret and act
|
|
28
|
+
|
|
29
|
+
Read `dataStatus`, `ranges`, and `source.completeness` first. Check current and previous fetched rows, caps, truncation, invalid rows, excluded URL shifts, and output limits in `selection`. `summary.observedRetainedQueryClickLoss` covers eligible retained rows; `returnedObservedRetainedQueryClickLoss` covers only the bounded output. Each item preserves current and previous clicks, impressions, CTR, position, `clickLoss`, `dropPct`, signals, and an evidence scope of `retained-query-page-row`. A diagnosis such as `lost_position` or `lost_ctr` labels correlated movement, not a cause.
|
|
30
|
+
|
|
31
|
+
Safe actions include checking deployments and annotations, live indexability, SERP composition, demand seasonality, and page-template patterns before editing. Use groups to find repeated technical or content hypotheses, then verify individual URLs. Do not sum capped rows into a property-wide loss, treat missing retained rows as zero, or claim that a content change, ranking update, or technical issue caused the decline without separate evidence.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: entity-readiness
|
|
3
|
+
description: Inventory entity-related markup and identity signals without claiming recognition or authority. Use when reviewing schema types, names, authors, dates, sameAs links, and social references across crawlable pages.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Review entity readiness
|
|
7
|
+
|
|
8
|
+
Consistent names, authorship, structured data, and external identity references can make a site easier to interpret. This report measures those observable signals across evaluated pages. It does not score authority, validate ownership of linked profiles, or prove that any search or AI system recognizes an entity.
|
|
9
|
+
|
|
10
|
+
## Run it
|
|
11
|
+
|
|
12
|
+
For MCP, discover the report with `seo_list_reports` category `crawl` only when necessary. Call `seo_describe_report` with `{ "id": "entity-readiness" }`, then `seo_run_report` with:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"id": "entity-readiness",
|
|
17
|
+
"params": { "reportId": "crawl_example_20260710" }
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Use `structuredContent` after confirming `isError` is false. CLI parity is:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
seo reports describe entity-readiness --json
|
|
25
|
+
seo reports run entity-readiness --params '{"reportId":"crawl_example_20260710"}' --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Pass `url` only when a fresh crawl is intended. A saved report keeps this inventory aligned with other technical findings.
|
|
29
|
+
|
|
30
|
+
## Read the observations
|
|
31
|
+
|
|
32
|
+
Check `dataStatus`, `evaluatedPages`, `crawlPages`, and caveats before interpreting coverage. The analysis evaluates eligible, successfully fetched pages; skipped or non-indexable pages are not evidence of absence. Checks are informational observations with counts and coverage, not pass/fail requirements.
|
|
33
|
+
|
|
34
|
+
Use `entities.schemaTypes` to see which types were parsed, `sameAsByType` and `sameAs` to review identity references, `socialProfiles` to inspect linked profiles, and `authors` to find observed bylines or structured authors. Sample the source pages before recommending global markup changes: a product, article, person, and organization need different semantics. Fix malformed or inconsistent markup only when the page's real subject supports it. Confirm names, URLs, authorship, and dates with the publisher, then re-crawl the same scope. Never infer Knowledge Graph inclusion, ownership, expertise, rankings, visibility, or citations from these signals alone.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explain-crawl-issue
|
|
3
|
+
description: Translate one crawler rule id into technical meaning, remediation guidance, and a verification method. Use after a crawl identifies a rule and before turning it into implementation work.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Explain a crawler rule
|
|
7
|
+
|
|
8
|
+
Crawler findings use stable rule ids so agents can join summaries, affected URLs, and guidance without parsing prose. This report explains the rule definition; it does not inspect a site or prove that the rule triggered on any particular page.
|
|
9
|
+
|
|
10
|
+
## Run it
|
|
11
|
+
|
|
12
|
+
If the id is unknown, use `crawler-rules` first. For MCP report discovery, call `seo_list_reports` with category `crawl` only when needed. Then call `seo_describe_report` with `{ "id": "explain-crawl-issue" }` and `seo_run_report` with:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"id": "explain-crawl-issue",
|
|
17
|
+
"params": { "ruleId": "missing_title" }
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Check MCP `isError`, then read `structuredContent`. The exact CLI equivalent is:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
seo reports describe explain-crawl-issue --json
|
|
25
|
+
seo reports run explain-crawl-issue --params '{"ruleId":"missing_title"}' --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Apply the guidance carefully
|
|
29
|
+
|
|
30
|
+
Read the rule's category, default severity, why it matters, fix steps, ignored impact, verification method, and agent hints. Default severity is generic prioritization metadata; actual urgency depends on affected templates, page purpose, response state, demand evidence, and publisher intent. Guidance describes the condition checked by the crawler, not a search-engine penalty or guaranteed ranking effect.
|
|
31
|
+
|
|
32
|
+
Pair the definition with `affected-urls` from the same saved crawl. Inspect the per-URL evidence and sample enough page types to find the implementation boundary. For `missing_title`, for example, confirm that the final HTML truly lacks a useful title and that the crawler did not receive an error or intermediate response before changing a template. Create the smallest shared fix, preserve intentional controls, and use the stated verification method on the same bounded URLs. If no affected-URL evidence exists, present the output as reference documentation only.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: generate-llms-txt
|
|
3
|
+
description: Generate a bounded llms.txt draft from eligible crawl pages while exposing its URL and token budgets. Use when an agent needs a reviewable starting point rather than an automatically publishable file.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Generate an llms.txt draft
|
|
7
|
+
|
|
8
|
+
This report turns crawl evidence into concise agent-facing navigation. It selects successfully fetched, indexable pages, removes common utility paths, groups suitable URLs, and stops at explicit URL and token budgets. The output is a draft: the crawler cannot determine publisher intent or guarantee factual summaries.
|
|
9
|
+
|
|
10
|
+
## Run it
|
|
11
|
+
|
|
12
|
+
For MCP, call `seo_list_reports` with category `crawl` only if discovery is needed. Call `seo_describe_report` with `{ "id": "generate-llms-txt" }`, then call `seo_run_report` with:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"id": "generate-llms-txt",
|
|
17
|
+
"params": {
|
|
18
|
+
"reportId": "crawl_example_20260710",
|
|
19
|
+
"maxUrls": 50,
|
|
20
|
+
"tokenBudget": 4000,
|
|
21
|
+
"exclude": ["/account/*", "/search"]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Check `isError` and consume `structuredContent`. CLI parity is:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
seo reports describe generate-llms-txt --json
|
|
30
|
+
seo reports run generate-llms-txt --params '{"reportId":"crawl_example_20260710","maxUrls":50,"tokenBudget":4000,"exclude":["/account/*","/search"]}' --json
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Review before publishing
|
|
34
|
+
|
|
35
|
+
Inspect `content`, `includedUrls`, `estimatedTokens`, and `sections`. Confirm every URL is canonical, public, current, useful to an agent, and safe to promote. Review generated titles and descriptions against the pages themselves. Use exclusions for private, transactional, faceted, search, or low-value routes, and keep the file deliberately small.
|
|
36
|
+
|
|
37
|
+
Load the source with `crawl-report` to check its date, page cap, failures, and caveats. The generator currently does not return a separate candidate count, omitted count, source metadata block, or explicit truncation flag. Reaching `maxUrls` or the token budget should therefore be treated as possible truncation, not a complete inventory. A technically valid draft does not prove search or AI benefit, selection, indexing, visibility, or citations. Publish only after human review, then fetch the final file and validate its links.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: geo-gaps
|
|
3
|
+
description: Find URL-level technical barriers to AI-search eligibility while keeping access and selection separate. Use when reviewing response, crawl, indexability, canonical, or snippet restrictions from a crawl.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Find AI-search eligibility gaps
|
|
7
|
+
|
|
8
|
+
Content cannot be selected when a system cannot retrieve or use it, but technical access never guarantees selection. This report narrows crawl evidence to response failures, robots restrictions, non-indexing directives, canonicalized pages, and snippet controls. It is a diagnostic URL list, not a visibility score.
|
|
9
|
+
|
|
10
|
+
## Run it
|
|
11
|
+
|
|
12
|
+
For MCP, call `seo_list_reports` with category `crawl` only if discovery is required. Call `seo_describe_report` with `{ "id": "geo-gaps" }`, then call `seo_run_report` with:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"id": "geo-gaps",
|
|
17
|
+
"params": {
|
|
18
|
+
"reportId": "crawl_example_20260710",
|
|
19
|
+
"limit": 25
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Confirm `isError` is false and consume `structuredContent`. The CLI flow is:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
seo reports describe geo-gaps --json
|
|
28
|
+
seo reports run geo-gaps --params '{"reportId":"crawl_example_20260710","limit":25}' --json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Interpret each gap
|
|
32
|
+
|
|
33
|
+
For every URL, separate `issues` from `searchEligibility`. Review successful HTML response, crawl permission, indexable-candidate status, declared and effective indexability, canonical evidence, and snippet eligibility. A `null` access state means unknown, not allowed. Semantic HTML, structured data, authorship, dates, question headings, and answerable blocks are observations; they do not override a hard access restriction or create eligibility by themselves.
|
|
34
|
+
|
|
35
|
+
Read `dataStatus`, `source`, and `selection` before interpreting the URL list. `source.partialReasons` explains missing page or request evidence, an incomplete crawl, page-cap stops, skipped URLs, failed requests, and extraction failures. Keep `configuredMaxPages`, `pageLimitReached`, request evidence status, and the evaluated, matched, returned, and truncated page counts with any conclusion. Propagated `warnings` and `caveats` remain part of the result.
|
|
36
|
+
|
|
37
|
+
Confirm intent before treating `noindex`, robots rules, canonicals, or snippet limits as defects. Fix unintended response and access conflicts first, then verify the exact URL and directive after deployment. A `complete` result describes only the pages evaluated by that crawl, while `partial` or `unavailable` evidence cannot support an all-clear. An empty or short gap list does not prove indexing, visibility, selection, citation, or complete site coverage.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: index-coverage
|
|
3
|
+
description: Compare a saved crawl and sitemap with Google Search Console page results, then choose representative URLs for URL Inspection. Use when an agent needs to investigate index coverage or decide where limited URL Inspection checks will answer the most useful questions without treating a missing Search Analytics row as proof that a page is unindexed.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Investigate index coverage signals
|
|
7
|
+
|
|
8
|
+
Use `index-coverage` when the question is "which pages should I inspect?" A
|
|
9
|
+
site can expose a page through links, a crawl, or a sitemap while Search
|
|
10
|
+
Console returns no page row for the chosen period. That mismatch deserves
|
|
11
|
+
review. It does not prove that the page is unindexed.
|
|
12
|
+
|
|
13
|
+
The report compares three different kinds of evidence:
|
|
14
|
+
|
|
15
|
+
- A saved crawl shows which pages the local crawler fetched and which current
|
|
16
|
+
controls it observed.
|
|
17
|
+
- Sitemaps show URLs submitted as discovery hints. They do not prove crawling
|
|
18
|
+
or indexing.
|
|
19
|
+
- Search Analytics page rows show Google Search visibility returned during an
|
|
20
|
+
exact finalized date range. They are not a complete index inventory.
|
|
21
|
+
|
|
22
|
+
Use URL Inspection after this report when you need Google's current indexed
|
|
23
|
+
verdict for a representative URL.
|
|
24
|
+
|
|
25
|
+
## Run the report
|
|
26
|
+
|
|
27
|
+
With MCP, call `seo_list_reports` with `{"category":"monitoring"}`. Call
|
|
28
|
+
`seo_describe_report` with `{"id":"index-coverage"}`, then call
|
|
29
|
+
`seo_run_report`, for example:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{"id":"index-coverage","params":{"site":"sc-domain:example.com","sitemaps":["https://example.com/sitemap.xml"],"days":90,"rowLimit":100000}}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The report uses the latest saved crawl for `site` unless `crawlReportId` names
|
|
36
|
+
one explicitly. Run `site-crawl` first when no suitable local crawl exists.
|
|
37
|
+
Pass `sitemaps` when the crawl did not capture useful robots.txt sitemap
|
|
38
|
+
declarations or when you need a specific sitemap scope.
|
|
39
|
+
|
|
40
|
+
The CLI uses the same schema and report logic:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
seo reports describe index-coverage --json
|
|
44
|
+
seo reports run index-coverage --params '{"site":"sc-domain:example.com","sitemaps":["https://example.com/sitemap.xml"],"days":90,"rowLimit":100000}' --json
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Read the evidence before the URL lists
|
|
48
|
+
|
|
49
|
+
Start with `sources`. Check `completeness`, `rowLimit`, `rowLimitReached`,
|
|
50
|
+
invalid URLs, duplicate URLs, the Search Console date range, and invalid
|
|
51
|
+
metric rows. A partial or truncated source makes absence comparisons less
|
|
52
|
+
reliable.
|
|
53
|
+
|
|
54
|
+
Then inspect these groups:
|
|
55
|
+
|
|
56
|
+
- `retainedSearchVisibility` contains pages with Search Analytics
|
|
57
|
+
impressions in the selected period.
|
|
58
|
+
- `crawlableWithoutRetainedSearchVisibility` contains fetched crawlable pages
|
|
59
|
+
with no returned Search Console row. Treat these as review candidates.
|
|
60
|
+
- `blockedOrNonIndexable` keeps current crawl controls and historical search
|
|
61
|
+
visibility separate. A control can be intentional.
|
|
62
|
+
- `sitemapOnly` and `searchConsoleOnly` show mismatches in the available source
|
|
63
|
+
inventories. Scope, redirects, URL variants, and source limits may explain
|
|
64
|
+
them.
|
|
65
|
+
- `templateReview` groups repeated URL shapes for sampling. A cluster is not a
|
|
66
|
+
content-quality, duplication, or index-bloat verdict.
|
|
67
|
+
|
|
68
|
+
Every detail list is limited. Use `count`, `returned`, and `omitted` together
|
|
69
|
+
before describing the size of a group.
|
|
70
|
+
|
|
71
|
+
## Choose useful follow-up checks
|
|
72
|
+
|
|
73
|
+
Pick representative URLs from important templates, high-value site sections,
|
|
74
|
+
and unexpected sitemap-only groups. Prefer a small sample that tests different
|
|
75
|
+
failure theories over a long random list.
|
|
76
|
+
|
|
77
|
+
Run `index-watch` for those URLs to collect exact URL Inspection evidence. Use
|
|
78
|
+
`index-coverage-plan` when the inventory is too large for the available daily
|
|
79
|
+
quota. Fix crawl or sitemap scope problems before drawing conclusions from
|
|
80
|
+
cross-source mismatches.
|
|
81
|
+
|
|
82
|
+
Never call a URL indexed because it had Search Analytics visibility during the
|
|
83
|
+
period. Never call it unindexed because no row appeared. Do not turn a limited
|
|
84
|
+
or incomplete source into a whole-site index coverage percentage.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Index coverage signals"
|
|
3
|
+
short_description: "Choose pages for URL Inspection from crawl and search evidence"
|
|
4
|
+
default_prompt: "Use $index-coverage to compare crawl, sitemap, and Search Console evidence, then choose representative URLs for URL Inspection."
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: index-coverage-plan
|
|
3
|
+
description: Allocate sitemap URLs across available GSC properties under URL Inspection capacity; use it to design a monitoring cycle before spending inspection quota.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Plan inspection coverage
|
|
7
|
+
|
|
8
|
+
Use `index-coverage-plan` when sitemap inventory is larger than the URL
|
|
9
|
+
Inspection checks you can run each day. It fetches sitemap URLs, maps them to
|
|
10
|
+
the most specific available Search Console properties, estimates cycle time,
|
|
11
|
+
and can suggest URL-prefix properties for large folders. It does not call URL
|
|
12
|
+
Inspection and does not report whether any URL is indexed.
|
|
13
|
+
|
|
14
|
+
## Run the report
|
|
15
|
+
|
|
16
|
+
With MCP, call `seo_list_reports` with `{"category":"monitoring"}`. Call
|
|
17
|
+
`seo_describe_report` with `{"id":"index-coverage-plan"}`, then call
|
|
18
|
+
`seo_run_report`, for example
|
|
19
|
+
`{"id":"index-coverage-plan","params":{"site":"sc-domain:example.com","sitemaps":["https://example.com/sitemap.xml"],"dailyLimit":200,"targetCycleDays":7,"maxUrls":50000}}`.
|
|
20
|
+
|
|
21
|
+
The CLI uses the same report schema:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
seo reports describe index-coverage-plan --json
|
|
25
|
+
seo reports run index-coverage-plan --params '{"site":"sc-domain:example.com","sitemaps":["https://example.com/sitemap.xml"],"dailyLimit":200,"targetCycleDays":7,"maxUrls":50000}' --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Pass `properties` only when you intentionally want to override discovered GSC
|
|
29
|
+
properties. Every sitemap URL must belong to the root property.
|
|
30
|
+
|
|
31
|
+
## Interpret the output
|
|
32
|
+
|
|
33
|
+
Read `summary.sitemapUrls`, `urlCount`, property count, daily capacity,
|
|
34
|
+
estimated cycle days, target cycle days, and suggestion count together.
|
|
35
|
+
`properties` shows each allocation, daily limit, estimated cycle, and sample
|
|
36
|
+
URLs. `suggestions` identifies folders that might benefit from a separate
|
|
37
|
+
URL-prefix property and explains the calculated reason.
|
|
38
|
+
|
|
39
|
+
Inspect every `warning`. Sitemap fetch failures, invalid or out-of-property
|
|
40
|
+
URLs, nested-sitemap boundaries, deduplication, or `maxUrls` truncation make the
|
|
41
|
+
plan incomplete. Estimated cycle time is arithmetic based on discovered URLs
|
|
42
|
+
and configured capacity; it is not a promise that Google will process or index
|
|
43
|
+
those URLs.
|
|
44
|
+
|
|
45
|
+
## Act safely
|
|
46
|
+
|
|
47
|
+
Use the plan to set a realistic recurring `index-monitor` limit. Add a suggested
|
|
48
|
+
property only if you control it and the operational benefit is worth the setup.
|
|
49
|
+
Fix sitemap discovery problems before increasing quota. Do not report an index
|
|
50
|
+
coverage percentage, excluded count, or all-clear from this allocation plan.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: index-monitor
|
|
3
|
+
description: Select due sitemap URLs and store bounded Google URL Inspection snapshots; use it for recurring index-state monitoring under local quota controls.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Monitor sitemap URLs
|
|
7
|
+
|
|
8
|
+
Use `index-monitor` for a recurring, quota-aware sample of sitemap URLs. It
|
|
9
|
+
builds a bounded inventory, allocates URLs to the most specific GSC property,
|
|
10
|
+
selects due checks, calls URL Inspection, and stores snapshots for later change
|
|
11
|
+
classification. The result describes Google's indexed snapshot for selected
|
|
12
|
+
URLs. It is not a live crawl and cannot establish the status of every sitemap
|
|
13
|
+
URL in one run.
|
|
14
|
+
|
|
15
|
+
## Run the report
|
|
16
|
+
|
|
17
|
+
With MCP, call `seo_list_reports` with `{"category":"monitoring"}`, then
|
|
18
|
+
`seo_describe_report` with `{"id":"index-monitor"}`. Call `seo_run_report` with
|
|
19
|
+
schema-valid parameters, for example
|
|
20
|
+
`{"id":"index-monitor","params":{"site":"sc-domain:example.com","sitemaps":["https://example.com/sitemap.xml"],"dailyLimit":200,"inspectLimit":25,"maxUrls":50000,"languageCode":"en-GB"}}`.
|
|
21
|
+
|
|
22
|
+
CLI parity uses the same registry:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
seo reports describe index-monitor --json
|
|
26
|
+
seo reports run index-monitor --params '{"site":"sc-domain:example.com","sitemaps":["https://example.com/sitemap.xml"],"dailyLimit":200,"inspectLimit":25,"maxUrls":50000,"languageCode":"en-GB"}' --json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Interpret the output
|
|
30
|
+
|
|
31
|
+
Read `dataStatus` and `source` first. Check sitemap and inventory limits,
|
|
32
|
+
discovered and invalid URLs, truncation flags, omitted minimum count, daily
|
|
33
|
+
limit, inspection limit, freshness window, and retry interval.
|
|
34
|
+
|
|
35
|
+
In `summary`, keep inventory states distinct: never attempted, never succeeded,
|
|
36
|
+
retry waiting, fresh, stale, due, selected, unselected due, attempted,
|
|
37
|
+
inspected, failed, quota blocked, deferred, and skipped. A due URL that was not
|
|
38
|
+
selected has no new inspection result. `properties` explains allocation and
|
|
39
|
+
execution per property. In `items`, separate `inspectionStatus`, `indexStatus`,
|
|
40
|
+
current issue codes, regressions, recoveries, alerts, and operational errors.
|
|
41
|
+
Read `caveats` and `warnings` before an all-clear.
|
|
42
|
+
|
|
43
|
+
## Act safely
|
|
44
|
+
|
|
45
|
+
Investigate regressions and current issues with a live page audit, sitemap
|
|
46
|
+
review, and the exact inspection evidence. Retry failed, deferred, or
|
|
47
|
+
quota-blocked checks according to `retryAt`; do not convert them into SEO
|
|
48
|
+
defects. Increase cycle coverage gradually. A complete selected batch still
|
|
49
|
+
does not prove inventory-wide indexing, recrawl timing, or future inclusion.
|