seo 0.0.14 → 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.
Files changed (146) hide show
  1. package/LICENSE +201 -0
  2. package/PRIVACY.md +95 -0
  3. package/README.md +338 -35
  4. package/SECURITY.md +55 -0
  5. package/TERMS.md +94 -0
  6. package/TRADEMARKS.md +27 -0
  7. package/dist/cli.js +125 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/dist-CSY2_p-j.js +713 -0
  10. package/dist/dist-CSY2_p-j.js.map +1 -0
  11. package/dist/dist-FeAUNn9A.js +3 -0
  12. package/dist/index.d.ts +17921 -0
  13. package/dist/index.js +26769 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/mcp.d.ts +57 -0
  16. package/dist/mcp.js +26744 -0
  17. package/dist/mcp.js.map +1 -0
  18. package/dist/package-uzXzqDW6.js +23818 -0
  19. package/dist/package-uzXzqDW6.js.map +1 -0
  20. package/package.json +101 -23
  21. package/skills/README.md +81 -0
  22. package/skills/affected-urls/SKILL.md +39 -0
  23. package/skills/affected-urls/agents/openai.yaml +4 -0
  24. package/skills/ai-readiness/SKILL.md +34 -0
  25. package/skills/ai-readiness/agents/openai.yaml +4 -0
  26. package/skills/ai-referrals/SKILL.md +31 -0
  27. package/skills/ai-referrals/agents/openai.yaml +4 -0
  28. package/skills/audit-page/SKILL.md +50 -0
  29. package/skills/audit-page/agents/openai.yaml +4 -0
  30. package/skills/audit-urls/SKILL.md +39 -0
  31. package/skills/audit-urls/agents/openai.yaml +4 -0
  32. package/skills/cannibalisation/SKILL.md +31 -0
  33. package/skills/cannibalisation/agents/openai.yaml +4 -0
  34. package/skills/community-intent/SKILL.md +39 -0
  35. package/skills/community-intent/agents/openai.yaml +4 -0
  36. package/skills/compare-crawls/SKILL.md +40 -0
  37. package/skills/compare-crawls/agents/openai.yaml +4 -0
  38. package/skills/content-optimization/SKILL.md +31 -0
  39. package/skills/content-optimization/agents/openai.yaml +4 -0
  40. package/skills/crawl-diff/SKILL.md +51 -0
  41. package/skills/crawl-diff/agents/openai.yaml +4 -0
  42. package/skills/crawl-history/SKILL.md +37 -0
  43. package/skills/crawl-history/agents/openai.yaml +4 -0
  44. package/skills/crawl-report/SKILL.md +37 -0
  45. package/skills/crawl-report/agents/openai.yaml +4 -0
  46. package/skills/crawler-rules/SKILL.md +34 -0
  47. package/skills/crawler-rules/agents/openai.yaml +4 -0
  48. package/skills/ctr-underperformers/SKILL.md +31 -0
  49. package/skills/ctr-underperformers/agents/openai.yaml +4 -0
  50. package/skills/decaying-pages/SKILL.md +31 -0
  51. package/skills/decaying-pages/agents/openai.yaml +4 -0
  52. package/skills/entity-readiness/SKILL.md +34 -0
  53. package/skills/entity-readiness/agents/openai.yaml +4 -0
  54. package/skills/explain-crawl-issue/SKILL.md +32 -0
  55. package/skills/explain-crawl-issue/agents/openai.yaml +4 -0
  56. package/skills/generate-llms-txt/SKILL.md +37 -0
  57. package/skills/generate-llms-txt/agents/openai.yaml +4 -0
  58. package/skills/geo-gaps/SKILL.md +37 -0
  59. package/skills/geo-gaps/agents/openai.yaml +4 -0
  60. package/skills/index-coverage/SKILL.md +84 -0
  61. package/skills/index-coverage/agents/openai.yaml +4 -0
  62. package/skills/index-coverage-plan/SKILL.md +50 -0
  63. package/skills/index-coverage-plan/agents/openai.yaml +4 -0
  64. package/skills/index-monitor/SKILL.md +49 -0
  65. package/skills/index-monitor/agents/openai.yaml +4 -0
  66. package/skills/index-watch/SKILL.md +77 -0
  67. package/skills/index-watch/agents/openai.yaml +4 -0
  68. package/skills/internal-links/SKILL.md +31 -0
  69. package/skills/internal-links/agents/openai.yaml +4 -0
  70. package/skills/link-recovery/SKILL.md +51 -0
  71. package/skills/link-recovery/agents/openai.yaml +4 -0
  72. package/skills/llms-txt-audit/SKILL.md +34 -0
  73. package/skills/llms-txt-audit/agents/openai.yaml +4 -0
  74. package/skills/measure-change/SKILL.md +52 -0
  75. package/skills/measure-change/agents/openai.yaml +4 -0
  76. package/skills/monthly-action-plan/SKILL.md +50 -0
  77. package/skills/monthly-action-plan/agents/openai.yaml +4 -0
  78. package/skills/monthly-report/SKILL.md +50 -0
  79. package/skills/monthly-report/agents/openai.yaml +4 -0
  80. package/skills/narrative-report/SKILL.md +51 -0
  81. package/skills/narrative-report/agents/openai.yaml +4 -0
  82. package/skills/okf-build/SKILL.md +39 -0
  83. package/skills/okf-build/agents/openai.yaml +4 -0
  84. package/skills/okf-validate/SKILL.md +43 -0
  85. package/skills/okf-validate/agents/openai.yaml +4 -0
  86. package/skills/page-opportunities/SKILL.md +31 -0
  87. package/skills/page-opportunities/agents/openai.yaml +4 -0
  88. package/skills/performance/SKILL.md +50 -0
  89. package/skills/performance/agents/openai.yaml +4 -0
  90. package/skills/performance-audit/SKILL.md +31 -0
  91. package/skills/performance-audit/agents/openai.yaml +4 -0
  92. package/skills/pseo-audit/SKILL.md +103 -0
  93. package/skills/pseo-audit/agents/openai.yaml +4 -0
  94. package/skills/query-clusters/SKILL.md +31 -0
  95. package/skills/query-clusters/agents/openai.yaml +4 -0
  96. package/skills/quick-wins/SKILL.md +31 -0
  97. package/skills/quick-wins/agents/openai.yaml +4 -0
  98. package/skills/redirect-trace/SKILL.md +51 -0
  99. package/skills/redirect-trace/agents/openai.yaml +4 -0
  100. package/skills/refresh-priorities/SKILL.md +48 -0
  101. package/skills/refresh-priorities/agents/openai.yaml +4 -0
  102. package/skills/search-performance-overview/SKILL.md +48 -0
  103. package/skills/search-performance-overview/agents/openai.yaml +4 -0
  104. package/skills/second-page/SKILL.md +50 -0
  105. package/skills/second-page/agents/openai.yaml +4 -0
  106. package/skills/segment-impact/SKILL.md +50 -0
  107. package/skills/segment-impact/agents/openai.yaml +4 -0
  108. package/skills/seo/SKILL.md +74 -0
  109. package/skills/seo/agents/openai.yaml +4 -0
  110. package/skills/seo-fix-queue/SKILL.md +50 -0
  111. package/skills/seo-fix-queue/agents/openai.yaml +4 -0
  112. package/skills/seo-geo-readiness/SKILL.md +60 -0
  113. package/skills/seo-geo-readiness/agents/openai.yaml +4 -0
  114. package/skills/seo-site-audit/SKILL.md +59 -0
  115. package/skills/seo-site-audit/agents/openai.yaml +4 -0
  116. package/skills/seo-to-ai-query/SKILL.md +31 -0
  117. package/skills/seo-to-ai-query/agents/openai.yaml +4 -0
  118. package/skills/setup-check/SKILL.md +49 -0
  119. package/skills/setup-check/agents/openai.yaml +4 -0
  120. package/skills/site-crawl/SKILL.md +39 -0
  121. package/skills/site-crawl/agents/openai.yaml +4 -0
  122. package/skills/striking-distance/SKILL.md +52 -0
  123. package/skills/striking-distance/agents/openai.yaml +4 -0
  124. package/skills/technical-watch/SKILL.md +49 -0
  125. package/skills/technical-watch/agents/openai.yaml +4 -0
  126. package/skills/top-fixes/SKILL.md +38 -0
  127. package/skills/top-fixes/agents/openai.yaml +4 -0
  128. package/skills/traffic-anomaly/SKILL.md +52 -0
  129. package/skills/traffic-anomaly/agents/openai.yaml +4 -0
  130. package/skills/update-correlation/SKILL.md +51 -0
  131. package/skills/update-correlation/agents/openai.yaml +4 -0
  132. package/skills/update-postmortem/SKILL.md +49 -0
  133. package/skills/update-postmortem/agents/openai.yaml +4 -0
  134. package/.jshintrc +0 -18
  135. package/.npmignore +0 -3
  136. package/.travis.yml +0 -3
  137. package/Makefile +0 -10
  138. package/index.js +0 -2
  139. package/lib/middleware.js +0 -159
  140. package/lib/seo.js +0 -32
  141. package/test/init.js +0 -43
  142. package/test/middleware.test.js +0 -111
  143. package/test/seo-page-result.html +0 -9
  144. package/test/seo-page.html +0 -9
  145. package/test/seo-routes.js +0 -5
  146. 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,4 @@
1
+ interface:
2
+ display_name: "Crawl diff"
3
+ short_description: "Compare a bounded live crawl with its previous snapshot"
4
+ default_prompt: "Use $crawl-diff to run the crawl-diff report and explain its evidence and limits."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "List crawl reports"
3
+ short_description: "List saved crawl metadata"
4
+ default_prompt: "Use $crawl-history to run the crawl-history report and explain its evidence and limits."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Get crawl report"
3
+ short_description: "Load one saved crawl report"
4
+ default_prompt: "Use $crawl-report to run the crawl-report report and explain its evidence and limits."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "List rules"
3
+ short_description: "List crawler rule ids and guidance metadata"
4
+ default_prompt: "Use $crawler-rules to run the crawler-rules report and explain its evidence and limits."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "CTR underperformers"
3
+ short_description: "Find retained GSC queries below a position-based CTR benchmark"
4
+ default_prompt: "Use $ctr-underperformers to run the ctr-underperformers report and explain its evidence and limits."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Decaying queries and pages"
3
+ short_description: "Find observed click declines across retained GSC windows"
4
+ default_prompt: "Use $decaying-pages to run the decaying-pages report and explain its evidence and limits."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Entity readiness"
3
+ short_description: "Review entity-related site observations"
4
+ default_prompt: "Use $entity-readiness to run the entity-readiness report and explain its evidence and limits."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Explain issue"
3
+ short_description: "Explain one crawler rule"
4
+ default_prompt: "Use $explain-crawl-issue to run the explain-crawl-issue report and explain its evidence and limits."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Generate llms.txt"
3
+ short_description: "Generate an llms.txt draft from crawl evidence"
4
+ default_prompt: "Use $generate-llms-txt to run the generate-llms-txt report and explain its evidence and limits."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "GEO gaps"
3
+ short_description: "Return technical AI-search eligibility gaps from crawl evidence"
4
+ default_prompt: "Use $geo-gaps to run the geo-gaps report and explain its evidence and limits."
@@ -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,4 @@
1
+ interface:
2
+ display_name: "Index coverage plan"
3
+ short_description: "Plan URL Inspection allocation across Search Console properties"
4
+ default_prompt: "Use $index-coverage-plan to run the index-coverage-plan report and explain its evidence and limits."
@@ -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.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Index monitor"
3
+ short_description: "Run bounded sitemap-driven URL Inspection monitoring"
4
+ default_prompt: "Use $index-monitor to run the index-monitor report and explain its evidence and limits."