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,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: performance-audit
|
|
3
|
+
description: Audit one URL with local Lighthouse lab data and optional CrUX field Core Web Vitals; use when an agent must separate reproducible diagnostics, real-user evidence, and fallback transport checks.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Performance audit
|
|
7
|
+
|
|
8
|
+
Use this report to diagnose page performance with three deliberately separate evidence classes. Lighthouse provides one local lab run and actionable diagnostics. CrUX, when `SEO_CRUX_API_KEY` is configured and coverage exists, provides p75 field Core Web Vitals for a device and URL or origin scope. If Lighthouse cannot run, the report falls back to unscored HTTP transport evidence so the failure remains useful without pretending it measured page experience.
|
|
9
|
+
|
|
10
|
+
## Run the report
|
|
11
|
+
|
|
12
|
+
Use the compact MCP flow:
|
|
13
|
+
|
|
14
|
+
1. Call `seo_list_reports` with `{"category":"ai-search"}`.
|
|
15
|
+
2. Call `seo_describe_report` with `{"id":"performance-audit"}`.
|
|
16
|
+
3. Call `seo_run_report` with `{"id":"performance-audit","params":{"url":"https://example.com/","strategy":"mobile","refresh":true}}`.
|
|
17
|
+
|
|
18
|
+
The CLI invokes the same report:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
seo reports describe performance-audit --json
|
|
22
|
+
seo reports run performance-audit --params '{"url":"https://example.com/","strategy":"mobile","refresh":true}' --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`url` is required; `strategy` is `mobile` or `desktop`. Omit `refresh` to allow the 24-hour local cache.
|
|
26
|
+
|
|
27
|
+
## Interpret and act
|
|
28
|
+
|
|
29
|
+
Start with `dataStatus`, `source`, `labDataStatus`, and `fieldDataStatus`. A Lighthouse `score`, `grade`, lab metrics, and `labInsights` describe that test environment and run. CrUX `fieldData.metrics` describes aggregated real-user p75 values; preserve `scope`, `formFactor`, `collectionPeriod`, missing metrics, and assessment. Origin-level data is not page-level evidence. If `source` is `fetch-fallback`, `fallbackFetchDuration` is the complete local fetch workflow, not TTFB, Lighthouse, LCP, CLS, TBT, or INP, and it never earns a score.
|
|
30
|
+
|
|
31
|
+
Use `topActions` as hypotheses tied to its evidence, then reproduce the relevant lab issue and verify after a change. Prioritise field failures with adequate coverage, recurring lab bottlenecks, and explicit savings evidence. Do not combine lab and field values into a new score, compare mobile with desktop as equivalent populations, or claim a ranking outcome from a passing or failing audit.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pseo-audit
|
|
3
|
+
description: Audit programmatic SEO template families with retained Google Search Console data, sitemap discovery, bounded page crawls, and exact URL Inspection evidence. Use when an agent needs to find repeated URL templates, compare their search visibility, check sampled index or crawl problems, or review whether generated pages have distinct intent and utility.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# pSEO audit
|
|
7
|
+
|
|
8
|
+
Call `seo_list_reports` with category `reporting` when discovery is needed.
|
|
9
|
+
Call `seo_describe_report` with id `pseo-audit`, then call `seo_run_report` with
|
|
10
|
+
that id and only the described parameters. Read `structuredContent` as the
|
|
11
|
+
machine contract. Use the CLI for CI, saved JSON, or environments without MCP.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
seo reports describe pseo-audit --json
|
|
15
|
+
seo reports run pseo-audit --params '{"site":"sc-domain:example.com","detail":"summary"}' --json
|
|
16
|
+
|
|
17
|
+
seo pseo audit --project <project> --json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The catalog command is the portable agent path and rejects parameters outside
|
|
21
|
+
the MCP schema. The focused pSEO command adds human-readable flags and project
|
|
22
|
+
selection while calling the same implementation.
|
|
23
|
+
|
|
24
|
+
Pass `--site sc-domain:example.com` instead of `--project` when no project profile exists.
|
|
25
|
+
|
|
26
|
+
## Run the audit in two passes
|
|
27
|
+
|
|
28
|
+
Start with discovery and retained Search Console evidence. Keep MCP output compact.
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"site": "sc-domain:example.com",
|
|
33
|
+
"detail": "summary"
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Add sitemap URLs when Search Console may not expose the full template population.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
seo pseo audit \
|
|
41
|
+
--project example \
|
|
42
|
+
--sitemap https://example.com/sitemap.xml \
|
|
43
|
+
--json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Rerun important templates with bounded technical samples. Three crawl and three URL Inspection samples are a sensible starting point. The maximum is 10 per template.
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"site": "sc-domain:example.com",
|
|
51
|
+
"crawlSamples": 3,
|
|
52
|
+
"inspectSamples": 3,
|
|
53
|
+
"detail": "full"
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
URL Inspection uses property quota. Only request it when index evidence changes the decision.
|
|
58
|
+
|
|
59
|
+
## Read the evidence in this order
|
|
60
|
+
|
|
61
|
+
1. Check `dataStatus`, `source`, `selection`, `warnings`, and `caveats`.
|
|
62
|
+
2. Use `population` to separate discovered, GSC-visible, sampled, and untested URLs.
|
|
63
|
+
3. Read the template `verdict`, then confirm it against `crawl`, `inspection`, and `evidence`.
|
|
64
|
+
4. Use `metrics.topQueries`, `queryPatterns`, and sample-level fields for the proposed action.
|
|
65
|
+
|
|
66
|
+
The report applies the output limit after ranking eligible templates by retained page impressions, clicks, URL count, and a stable signature tie-break.
|
|
67
|
+
|
|
68
|
+
## Keep claims inside the contract
|
|
69
|
+
|
|
70
|
+
- `PASS` is the only indexed URL Inspection verdict. `NEUTRAL` means excluded, `FAIL` means invalid, and every other value is unknown.
|
|
71
|
+
- `coverageState` is diagnostic text. Never parse it to decide whether a URL is indexed.
|
|
72
|
+
- URL Inspection describes Google's indexed snapshot for one URL. It does not prove that every URL in the template is healthy or currently appearing in search.
|
|
73
|
+
- Clicks, impressions, CTR, and position come from retained page-dimension Search Analytics rows. They are not guaranteed property totals.
|
|
74
|
+
- Query patterns and examples come from retained query/page rows. Anonymized and lower-ranked rows may be absent.
|
|
75
|
+
- Word count is descriptive. Do not recommend a minimum word count or call a page thin because it is short.
|
|
76
|
+
- Literal query-term coverage and path entity fit are review heuristics. They are not Google ranking factors or spam-policy verdicts.
|
|
77
|
+
- A sitemap URL with no GSC row does not prove zero demand. Performance may be omitted or credited to a canonical URL.
|
|
78
|
+
|
|
79
|
+
## Explain verdicts precisely
|
|
80
|
+
|
|
81
|
+
- `index-risk` means one or more sampled URLs returned exact excluded or invalid verdicts. State the sample count.
|
|
82
|
+
- `crawl-risk` means sampled URLs showed HTTP, robots, noindex, canonical, or fetch failures.
|
|
83
|
+
- `content-review` means at least three usable samples showed repeated metadata or weak literal term coverage. Ask for human review of originality, accuracy, and page-specific utility.
|
|
84
|
+
- `opportunity` means retained page rows triggered position, CTR, or entity-fit heuristics. Verify the query intent before changing templates.
|
|
85
|
+
- `healthy` requires at least two conclusive indexed samples and two usable crawl samples. It remains a sample finding.
|
|
86
|
+
- `inconclusive` means search evidence exists but technical sampling is too weak for a health verdict.
|
|
87
|
+
- `no-data` means no retained page evidence was found for the detected template. Do not turn that into a quality judgment.
|
|
88
|
+
|
|
89
|
+
## Useful controls
|
|
90
|
+
|
|
91
|
+
- `templateLimit`: 1 to 100 templates.
|
|
92
|
+
- `minimumTemplateUrls`: 2 to 100 repeated URLs. The default is 3.
|
|
93
|
+
- `minimumTemplateShare`: 0 to 1. The default is 0, so count controls discovery.
|
|
94
|
+
- `minimumTemplateImpressions`: retained page-impression threshold. The default is 0.
|
|
95
|
+
- `crawlSamples` and `inspectSamples`: 0 to 10 per template.
|
|
96
|
+
- `brandTerms`: explicit terms to exclude. Domain-derived terms are used when none are supplied.
|
|
97
|
+
- `refresh`: bypass supported local provider and HTTP caches.
|
|
98
|
+
|
|
99
|
+
For CSV files run:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
seo export pseo --project <project> --out ./seo-exports/pseo
|
|
103
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: query-clusters
|
|
3
|
+
description: Group retained GSC queries by deterministic token overlap and page evidence; use when an agent needs reproducible demand themes without embeddings or assumed search intent.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Query clusters
|
|
7
|
+
|
|
8
|
+
Use this report to organise retained GSC query/page rows into stable lexical themes. It normalizes queries, removes low-actionability and optionally branded rows, aggregates page evidence, then groups related wording by shared tokens. This is useful for navigation, information architecture, and review queues because the same input produces the same grouping. Token overlap does not prove shared intent, justify a new page, or establish that current URLs compete with each other.
|
|
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":"query-clusters"}`.
|
|
16
|
+
3. Call `seo_run_report` with `{"id":"query-clusters","params":{"site":"sc-domain:example.com","scope":"/guides/","minImpressions":50,"limit":20,"includeBrand":false}}`.
|
|
17
|
+
|
|
18
|
+
The CLI uses the same registry and report handler:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
seo reports describe query-clusters --json
|
|
22
|
+
seo reports run query-clusters --params '{"site":"sc-domain:example.com","scope":"/guides/","minImpressions":50,"limit":20,"includeBrand":false}' --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`site` is required. `scope` filters to pages containing the supplied string. The catalog schema exposes a fixed final-data 28-day report window; inspect `range` rather than assuming another period.
|
|
26
|
+
|
|
27
|
+
## Interpret and act
|
|
28
|
+
|
|
29
|
+
Start with `summary`: retain cluster count, query count, clicks, impressions, threshold, limit, brand filtering, and high-opportunity count. Read each cluster's member queries, pages, demand, performance, and recommendation together. Expected CTR and opportunity labels are heuristic, using a leave-cluster-out site benchmark when enough peer evidence exists and otherwise a fallback curve. Page-two clusters do not claim a CTR-only click lift. Queries omitted below the threshold or outside the output cap remain outside the conclusion.
|
|
30
|
+
|
|
31
|
+
Safe actions include reviewing whether a cluster maps to one intent, improving section structure on an existing page, clarifying navigation, or investigating URL overlap with a dedicated report. Do not create one page per cluster, merge pages based on tokens alone, infer semantic equivalence, or describe a low-volume omitted theme as absent demand.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quick-wins
|
|
3
|
+
description: Rank retained position 4-10 GSC query-page rows below a site-aware CTR target; use when an agent needs a bounded opportunity queue with optional live-content verification.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Quick wins
|
|
7
|
+
|
|
8
|
+
Use this report to prioritise retained query/page rows with meaningful impressions, average positions from 4 through 10, and CTR below a leave-target-out site benchmark or documented fallback curve. Optional page verification checks whether the live page covers the query or presents technical evidence before recommending a content action. “Quick win” describes the review queue, not effort, certainty, or expected traffic.
|
|
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":"quick-wins"}`.
|
|
16
|
+
3. Call `seo_run_report` with `{"id":"quick-wins","params":{"site":"sc-domain:example.com","days":90,"limit":20,"minImpressions":100,"verifyContent":true,"verifyLimit":5}}`.
|
|
17
|
+
|
|
18
|
+
The CLI calls the same definition:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
seo reports describe quick-wins --json
|
|
22
|
+
seo reports run quick-wins --params '{"site":"sc-domain:example.com","days":90,"limit":20,"minImpressions":100,"verifyContent":true,"verifyLimit":5}' --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`site` is required. `limit` bounds returned rows and `verifyLimit` bounds live page checks. Use `js:true` and higher fetch rates only when needed and permitted.
|
|
26
|
+
|
|
27
|
+
## Interpret and act
|
|
28
|
+
|
|
29
|
+
Check `dataStatus`, date range, source row cap, `possiblyTruncated`, `selection.invalidRows`, filters, and limited rows. Read `methodology` and each item's benchmark confidence before using `targetCtr`. `estimatedCtrClickShortfall` and priority score are heuristics, explicitly not estimated lift. Inspect `verification.requested`, attempted, verified, failed, and technical counts. An unverified item still has GSC evidence but cannot support a content-coverage conclusion. Review groups and template patterns for repeated hypotheses without converting their sums into forecasts.
|
|
30
|
+
|
|
31
|
+
Safe actions are to inspect the live SERP, resolve technical conflicts, test clearer snippet framing, improve a genuinely missing answer, or add a relevant internal link. Record the change and compare a later complete window. Do not promise clicks, force query wording into copy, treat average position as a stable rank, or call filtered or capped evidence an all-clear.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: redirect-trace
|
|
3
|
+
description: Record every HTTP redirect hop and inspect the final page's indexability signals; use it to debug loops, broken chains, and destination mismatches for one URL.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Trace one redirect path
|
|
7
|
+
|
|
8
|
+
Use `redirect-trace` when a specific URL behaves unexpectedly after a move,
|
|
9
|
+
canonical change, or routing release. It follows HTTP redirects manually,
|
|
10
|
+
records each response, and audits the final destination for basic indexability
|
|
11
|
+
and canonical evidence. The trace is one observation from the machine and time
|
|
12
|
+
that ran it; CDNs, geography, cookies, user agents, and later deploys can differ.
|
|
13
|
+
|
|
14
|
+
## Run the report
|
|
15
|
+
|
|
16
|
+
With MCP, call `seo_list_reports` with `{"category":"monitoring"}`. Call
|
|
17
|
+
`seo_describe_report` with `{"id":"redirect-trace"}`, then call
|
|
18
|
+
`seo_run_report`, for example
|
|
19
|
+
`{"id":"redirect-trace","params":{"url":"https://example.com/old-page","maxHops":8,"js":false,"refresh":true}}`.
|
|
20
|
+
|
|
21
|
+
The CLI uses the same registry:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
seo reports describe redirect-trace --json
|
|
25
|
+
seo reports run redirect-trace --params '{"url":"https://example.com/old-page","maxHops":8,"refresh":true}' --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`maxHops` is currently a broad number in discovery. Pass a small positive whole
|
|
29
|
+
number; very large chains are not a useful success condition.
|
|
30
|
+
|
|
31
|
+
## Interpret the output
|
|
32
|
+
|
|
33
|
+
Read `chain` in order. Each step contains the requested URL, status, `Location`,
|
|
34
|
+
resolved next URL, and duration. Then compare `finalUrl` with `finalPage` and
|
|
35
|
+
`summary.finalStatus`. `summary.issues` can identify a loop, hop limit,
|
|
36
|
+
redirect without location, final 4xx or 5xx, non-indexable final page, or a
|
|
37
|
+
canonical mismatch.
|
|
38
|
+
|
|
39
|
+
Inspect `metaRobots`, `xRobotsTag`, canonical, and `warnings` as observations.
|
|
40
|
+
A missing `finalPage` or fetch warning limits indexability conclusions.
|
|
41
|
+
JavaScript rendering affects final-page extraction, not the HTTP redirect chain.
|
|
42
|
+
A canonical pointing elsewhere can be intentional; a 302 can also be
|
|
43
|
+
intentional. The report does not know the desired destination.
|
|
44
|
+
|
|
45
|
+
## Act safely
|
|
46
|
+
|
|
47
|
+
Confirm the intended URL map before editing redirects. Prefer one direct
|
|
48
|
+
permanent redirect for a genuine move, remove loops, restore missing locations,
|
|
49
|
+
and align the final canonical only when the destination is correct. Re-run the
|
|
50
|
+
trace after deployment. Do not declare an SEO defect or ranking impact from a
|
|
51
|
+
chain difference without intent and search evidence.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refresh-priorities
|
|
3
|
+
description: Combine several first-party opportunity reports into a bounded refresh queue. Use it to prioritize investigation while preserving each source's distinct meaning and limits.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Refresh priorities workflow
|
|
7
|
+
|
|
8
|
+
This workflow helps choose what to inspect next by combining decay, position,
|
|
9
|
+
CTR, exposure, diagnosis, content verification, and optional GA4 signals. It
|
|
10
|
+
does not make those signals interchangeable or predict the benefit of an edit.
|
|
11
|
+
The queue is a deterministic prioritization aid, not an autonomous content
|
|
12
|
+
brief.
|
|
13
|
+
|
|
14
|
+
## Run it
|
|
15
|
+
|
|
16
|
+
Use the exact MCP discovery flow:
|
|
17
|
+
|
|
18
|
+
1. Call `seo_list_reports` with `category: "workflows"` and select `refresh-priorities`.
|
|
19
|
+
2. Call `seo_describe_report` with `id: "refresh-priorities"`; inspect all bounds.
|
|
20
|
+
3. Call `seo_run_report` with that id and schema-valid parameters.
|
|
21
|
+
|
|
22
|
+
CLI parity:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
seo reports describe refresh-priorities --json
|
|
26
|
+
seo reports run refresh-priorities --params '{"site":"sc-domain:example.com","days":90,"recentDays":7,"limit":10,"includeBrand":false,"verifyContent":true,"verifyLimit":5}' --json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Add `ga4PropertyId` only when that property's sessions are needed and accessible.
|
|
30
|
+
`verifyLimit` caps fetched content checks; it does not verify every queued URL.
|
|
31
|
+
|
|
32
|
+
## Interpret and act
|
|
33
|
+
|
|
34
|
+
Read the workflow's steps and skipped states before its queue. For each queued
|
|
35
|
+
item preserve `source`, `impactKind`, score breakdown, date window, completeness,
|
|
36
|
+
verification status, and rationale. A click decline, low CTR, second-page
|
|
37
|
+
average position, and GA4 session signal have different semantics. Missing GA4
|
|
38
|
+
or failed content fetches must remain unavailable, not become zero-weight proof.
|
|
39
|
+
|
|
40
|
+
Inspect the top few URLs manually. Confirm query intent, current content,
|
|
41
|
+
technical accessibility, internal links, competing pages, and whether a recent
|
|
42
|
+
change already explains the observation. Choose a bounded edit only when the
|
|
43
|
+
evidence supports it, record the change date, and measure later. Never delete,
|
|
44
|
+
merge, or rewrite content solely from the combined score. Do not present the
|
|
45
|
+
score as expected clicks, revenue, ranking lift, or causal confidence.
|
|
46
|
+
|
|
47
|
+
MCP `structuredContent` is the machine contract. Use Markdown for a concise
|
|
48
|
+
human queue while retaining the underlying evidence fields for agents.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: search-performance-overview
|
|
3
|
+
description: Find where Google Search clicks and impressions changed, which pages or queries explain the movement, and which focused report to run next. Use when search performance moved or an agent needs a first-party baseline but does not yet know where to investigate.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Search performance overview
|
|
7
|
+
|
|
8
|
+
Use this when organic search performance changed and you do not yet know which
|
|
9
|
+
pages, queries, countries, or devices explain it. It is also the best first
|
|
10
|
+
report for a newly connected Search Console property. The report finds where
|
|
11
|
+
the movement sits, then points to the focused report that can verify the issue.
|
|
12
|
+
|
|
13
|
+
## Run it
|
|
14
|
+
|
|
15
|
+
Use the exact MCP discovery flow:
|
|
16
|
+
|
|
17
|
+
1. Call `seo_list_reports` with `category: "workflows"` and select `search-performance-overview`.
|
|
18
|
+
2. Call `seo_describe_report` with `id: "search-performance-overview"` and inspect its schema.
|
|
19
|
+
3. Call `seo_run_report` with that id and only schema-valid parameters.
|
|
20
|
+
|
|
21
|
+
CLI parity:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
seo reports describe search-performance-overview --json
|
|
25
|
+
seo reports run search-performance-overview --params '{"site":"sc-domain:example.com","days":90,"recentDays":7,"limit":10,"includeBrand":false}' --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`days` sets the main evidence window and `recentDays` sets the recent comparison
|
|
29
|
+
period. `limit` caps the items returned; it does not increase provider coverage.
|
|
30
|
+
|
|
31
|
+
## Interpret and act
|
|
32
|
+
|
|
33
|
+
Read the workflow envelope first: `workflow`, `site`, `generatedAt`, `summary`,
|
|
34
|
+
`steps`, `actions`, and `output`. Every step has its own status and evidence.
|
|
35
|
+
Then inspect the report's `dataStatus`, skipped sections, partial reasons,
|
|
36
|
+
priorities, and nested anomaly, update, segment, decay, cannibalisation,
|
|
37
|
+
striking-distance, and quick-win results. Do not let one complete section hide a
|
|
38
|
+
failed or capped neighbour.
|
|
39
|
+
|
|
40
|
+
Start with actions that cite reproducible evidence. Confirm affected URLs,
|
|
41
|
+
provider dates, selection limits, and intentional technical controls before
|
|
42
|
+
editing anything. Run a focused report to inspect detail rather than asking this
|
|
43
|
+
broad workflow for a larger payload. Sparse data may legitimately skip a
|
|
44
|
+
section. Update overlap, opportunity scores, average position, and timing are
|
|
45
|
+
investigation signals, not causation or forecasts.
|
|
46
|
+
|
|
47
|
+
Treat MCP `structuredContent` as the machine contract. Use Markdown for the
|
|
48
|
+
human summary while preserving structured evidence references in any handoff.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Search performance overview"
|
|
3
|
+
short_description: "Find where Google Search performance changed"
|
|
4
|
+
default_prompt: "Use $search-performance-overview to find where Google Search performance changed, explain the pages or queries behind it, and choose the next focused report."
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: second-page
|
|
3
|
+
description: Find retained GSC page-query rows with average positions from 10 through 20. Use them as bounded investigation prompts, not promised ranking wins.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Second-page opportunities
|
|
7
|
+
|
|
8
|
+
This report surfaces page-query combinations near the first-page boundary so an
|
|
9
|
+
agent can inspect whether the page satisfies the observed query. It is a triage
|
|
10
|
+
tool. Average position is aggregated across searches, locations, devices, and
|
|
11
|
+
time; it is not an exact rank, proof of intent mismatch, or evidence that an
|
|
12
|
+
edit will improve performance.
|
|
13
|
+
|
|
14
|
+
## Run it
|
|
15
|
+
|
|
16
|
+
Use the exact MCP discovery flow:
|
|
17
|
+
|
|
18
|
+
1. Call `seo_list_reports` with `category: "reporting"` and select `second-page`.
|
|
19
|
+
2. Call `seo_describe_report` with `id: "second-page"`; inspect bounds and defaults.
|
|
20
|
+
3. Call `seo_run_report` with `id: "second-page"` and matching parameters.
|
|
21
|
+
|
|
22
|
+
CLI parity:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
seo reports describe second-page --json
|
|
26
|
+
seo reports run second-page --params '{"site":"sc-domain:example.com","range":28,"minImpressions":50,"limit":10,"includeBrand":false,"verifyContent":true,"verifyLimit":5}' --json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`range` is the analysis window. `minImpressions` removes very sparse candidates.
|
|
30
|
+
`limit` is a retained-output cap. `verifyContent` fetches only up to
|
|
31
|
+
`verifyLimit` candidates, so unverified items remain unknown rather than failed.
|
|
32
|
+
|
|
33
|
+
## Interpret and act
|
|
34
|
+
|
|
35
|
+
Check source completeness, date range, `selection`, `methodology`, provenance,
|
|
36
|
+
brand filtering, and caveats before ranking the items. Duplicate provider rows
|
|
37
|
+
should already be aggregated deterministically, but retained limits still mean
|
|
38
|
+
the output is not a complete inventory. Read impressions, clicks, CTR, and
|
|
39
|
+
average position as observed metrics. Treat the priority value as a transparent
|
|
40
|
+
heuristic, not expected click lift.
|
|
41
|
+
|
|
42
|
+
For a promising item, inspect the live page and search intent, verify that the
|
|
43
|
+
query is appropriate for the URL, review internal linking and competing pages,
|
|
44
|
+
then make one defensible change. Preserve pages already satisfying intent.
|
|
45
|
+
Never add text solely to hit a length threshold, promise a first-page result,
|
|
46
|
+
or infer cannibalisation from one row. If the source is capped, partial, or
|
|
47
|
+
filtered, say so in the recommendation.
|
|
48
|
+
|
|
49
|
+
Use MCP `structuredContent` as the machine contract and Markdown only to explain
|
|
50
|
+
the evidence and next investigation to a human.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: segment-impact
|
|
3
|
+
description: Compare matched retained GSC rows across adjacent periods for one dimension; use it to locate where observed movement is concentrated without treating missing rows as zero.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Compare segment movement
|
|
7
|
+
|
|
8
|
+
Use `segment-impact` after a property-level change is visible and you need to
|
|
9
|
+
find which pages, queries, countries, or devices moved. It compares equal-length
|
|
10
|
+
adjacent finalized GSC windows. The report deliberately limits conclusions to
|
|
11
|
+
segments retained in both windows, so its deltas are comparable without
|
|
12
|
+
inventing zeros for rows that disappeared from one retained result set.
|
|
13
|
+
|
|
14
|
+
## Run the report
|
|
15
|
+
|
|
16
|
+
With MCP, call `seo_list_reports` with `{"category":"diagnosis"}`, then
|
|
17
|
+
`seo_describe_report` with `{"id":"segment-impact"}`. Then call
|
|
18
|
+
`seo_run_report` with the described report, for example
|
|
19
|
+
`{"id":"segment-impact","params":{"site":"sc-domain:example.com","dimension":"page","days":28,"compareDays":28,"limit":20,"maxRows":50000,"unmatchedLimit":10}}`.
|
|
20
|
+
|
|
21
|
+
The CLI uses the same schema:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
seo reports describe segment-impact --json
|
|
25
|
+
seo reports run segment-impact --params '{"site":"sc-domain:example.com","dimension":"page","days":28,"compareDays":28,"limit":20,"maxRows":50000,"unmatchedLimit":10}' --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Use either relative windows or an explicit `startDate` and `endDate` after
|
|
29
|
+
checking the current schema. Do not send undeclared fields.
|
|
30
|
+
|
|
31
|
+
## Interpret the output
|
|
32
|
+
|
|
33
|
+
Confirm `before`, `after`, and `rangeDays` before reading movement. Inspect
|
|
34
|
+
`dataStatus`, `source.before`, `source.after`, and `source.completeness` for
|
|
35
|
+
provider calls, row caps, and possible truncation. `selection` explains invalid,
|
|
36
|
+
duplicate, conflicting, matched, unmatched, returned, and limited rows.
|
|
37
|
+
|
|
38
|
+
In `items`, `clickDelta` and `impressionDelta` are after minus before. A positive
|
|
39
|
+
`positionDelta` is worse because a larger GSC average position is lower in the
|
|
40
|
+
results. `unmatchedSegments` are observations retained in one window only; they
|
|
41
|
+
are not gains from or losses to zero. Read `warnings`, `caveats`, and
|
|
42
|
+
`methodology` before describing a leading segment.
|
|
43
|
+
|
|
44
|
+
## Act safely
|
|
45
|
+
|
|
46
|
+
Use the top matched movers to define a smaller investigation: audit affected
|
|
47
|
+
pages, group repeated templates, or compare query intent. Check unmatched rows
|
|
48
|
+
separately with a wider export if they matter. Segment concentration does not
|
|
49
|
+
establish why movement happened, and a limited or possibly truncated result
|
|
50
|
+
cannot support an inventory-wide winner or loser claim.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: seo
|
|
3
|
+
description: Route SEO work across the local seo CLI and MCP server. Use when an agent needs to choose between technical SEO, Search Console, GA4, crawl, opportunity, monitoring, and reporting workflows or inspect evidence returned by several reports.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# seo
|
|
7
|
+
|
|
8
|
+
Use the `seo` MCP server exposed by the repository or installed package.
|
|
9
|
+
|
|
10
|
+
Reason from MCP `structuredContent`. Treat text or Markdown content as the
|
|
11
|
+
display layer. When MCP is unavailable use explicit CLI selectors and `--json`:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
seo report --project <project> --json
|
|
15
|
+
seo report --site sc-domain:example.com --json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Use the default Markdown output from `seo report-narrative` or
|
|
19
|
+
`seo monthly-report` only when the user wants a readable report rather than a
|
|
20
|
+
machine contract.
|
|
21
|
+
|
|
22
|
+
## MCP flow
|
|
23
|
+
|
|
24
|
+
The default MCP server exposes three tools:
|
|
25
|
+
|
|
26
|
+
1. Call `seo_list_reports` to discover compact report ids, optionally by
|
|
27
|
+
category.
|
|
28
|
+
2. Call `seo_describe_report` once for the selected id to load its exact JSON
|
|
29
|
+
Schema.
|
|
30
|
+
3. Call `seo_run_report` with that id and a bounded `params` object.
|
|
31
|
+
|
|
32
|
+
Do not guess parameters or ask for every report schema up front. Reuse a schema
|
|
33
|
+
for repeated runs in the same session.
|
|
34
|
+
|
|
35
|
+
## Which report id to use
|
|
36
|
+
|
|
37
|
+
- Diagnosis: `search-performance-overview`,
|
|
38
|
+
`segment-impact`, `striking-distance`, `traffic-anomaly`, and
|
|
39
|
+
`update-correlation`.
|
|
40
|
+
- Main follow-ups: `refresh-priorities`, `quick-wins`, `second-page`,
|
|
41
|
+
`decaying-pages`, `cannibalisation`, `ctr-underperformers`, and `query-clusters`.
|
|
42
|
+
- Page work: `audit-page`, `page-opportunities`, `content-optimization`,
|
|
43
|
+
`internal-links`, and `performance-audit`.
|
|
44
|
+
- Technical crawling: `site-crawl`, `top-fixes`, `affected-urls`,
|
|
45
|
+
`explain-crawl-issue`, `crawl-report`, and `compare-crawls`.
|
|
46
|
+
- Indexing and monitoring: `index-coverage`, `index-watch`, `index-monitor`,
|
|
47
|
+
`index-coverage-plan`, `crawl-diff`, `redirect-trace`, and `link-recovery`.
|
|
48
|
+
- AI-search evidence: `ai-readiness`, `geo-gaps`, `community-intent`,
|
|
49
|
+
`seo-to-ai-query`, and `ai-referrals`.
|
|
50
|
+
- Reporting and measurement: `narrative-report`, `monthly-report`,
|
|
51
|
+
`measure-change`, `pseo-audit`, `update-postmortem`, and
|
|
52
|
+
`technical-watch`.
|
|
53
|
+
- Local setup health: `setup-check`.
|
|
54
|
+
|
|
55
|
+
Use the CLI for project-profile administration and intentionally raw provider
|
|
56
|
+
queries. Useful commands include `seo projects list --json`, `seo gsc-query`,
|
|
57
|
+
`seo url-inspect`, `seo ga4-properties`, `seo ga4-report`, and `seo updates`.
|
|
58
|
+
|
|
59
|
+
## Rules
|
|
60
|
+
|
|
61
|
+
- Treat observations as evidence within the report's methodology and data limits. Do not invent metrics.
|
|
62
|
+
- Check `dataStatus`, source completeness, selection counts, warnings, and caveats before summarising a report.
|
|
63
|
+
- In diagnosis output, check `summary.updateAttributionStatus` first and treat `summary.updateAttribution` as update-correlation context, not the site's overall diagnosis.
|
|
64
|
+
- If `dataStatus` is `partial` or `unavailable`, name the skipped or incomplete evidence before describing findings. Treat capped sources the same way. Never turn unavailable or capped evidence into a zero-result claim.
|
|
65
|
+
- Treat quick-win CTR targets and calculated shortfalls as deterministic prioritisation heuristics, not traffic forecasts.
|
|
66
|
+
- Quote `principle` and `evidenceRef` when explaining recommendations.
|
|
67
|
+
- Do not generate titles, metas, or copy. Keep advice structural and diagnostic.
|
|
68
|
+
- If the tool returns no rows, say that clearly instead of padding the answer.
|
|
69
|
+
- Remember that grouped GSC query totals can undercount due to anonymised rows.
|
|
70
|
+
|
|
71
|
+
## Refresh behaviour
|
|
72
|
+
|
|
73
|
+
- Tool output is cached locally.
|
|
74
|
+
- Pass `refresh: true` when the user explicitly wants a fresh fetch.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: seo-fix-queue
|
|
3
|
+
description: Turn seo crawl and report evidence into a prioritized implementation queue. Use when the user wants exact SEO fixes, implementation tickets, affected URLs, verification steps, or a ranked technical SEO and GEO backlog.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SEO fix queue
|
|
7
|
+
|
|
8
|
+
Run the bounded queue directly:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
seo crawl-queue --project <project> --json
|
|
12
|
+
seo crawl-queue https://example.com --json
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Through MCP, use `seo_run_report` with report id `site-crawl` and
|
|
16
|
+
`saveReport: true`. Pass its `reportId` to report ids `top-fixes` and
|
|
17
|
+
`affected-urls`. Reuse that report instead of crawling again. Call
|
|
18
|
+
`seo_describe_report` before a report when its parameters are not already
|
|
19
|
+
known.
|
|
20
|
+
|
|
21
|
+
## Check the evidence before ranking work
|
|
22
|
+
|
|
23
|
+
1. Read `dataStatus`, source joins, selection counts, warnings, and caveats.
|
|
24
|
+
2. Check `summary.pageLimitReached`. A capped crawl cannot support an
|
|
25
|
+
inventory-wide zero or all-clear.
|
|
26
|
+
3. Preserve the returned priority order unless stronger evidence supports a
|
|
27
|
+
change.
|
|
28
|
+
4. Use GSC or GA4 evidence only when the source join is available. Do not call a
|
|
29
|
+
page search-visible or valuable from crawl evidence alone.
|
|
30
|
+
5. Keep failed fetches, missing provider data, and filtered rows separate from
|
|
31
|
+
observed zeros.
|
|
32
|
+
|
|
33
|
+
Each queue item should retain its rule id, priority, evidence, affected count,
|
|
34
|
+
bounded URL sample, fix, and verification step. Explain unfamiliar rules with
|
|
35
|
+
structured output:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
seo explain --rule <rule-id> --json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Use report id `explain-crawl-issue` through `seo_run_report`.
|
|
42
|
+
|
|
43
|
+
Write Markdown implementation tickets only when the user wants a handoff file:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
seo crawl --project <project> --format markdown --output seo-fixes.md
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Keep the final answer short. Show the top material fixes and end with the next
|
|
50
|
+
verification command. Do not dump every rule the crawler checked.
|