claude-plugin-wordpress-manager 2.4.0 → 2.6.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/.claude-plugin/plugin.json +10 -3
- package/CHANGELOG.md +42 -0
- package/agents/wp-content-strategist.md +104 -0
- package/docs/GUIDE.md +183 -23
- package/package.json +12 -3
- package/servers/wp-rest-bridge/build/tools/comments.d.ts +6 -6
- package/servers/wp-rest-bridge/build/tools/gsc.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/gsc.js +354 -0
- package/servers/wp-rest-bridge/build/tools/index.d.ts +38 -38
- package/servers/wp-rest-bridge/build/tools/index.js +3 -0
- package/servers/wp-rest-bridge/build/tools/media.d.ts +2 -2
- package/servers/wp-rest-bridge/build/tools/multisite-sites.d.ts +2 -2
- package/servers/wp-rest-bridge/build/tools/plugin-repository.d.ts +1 -1
- package/servers/wp-rest-bridge/build/tools/search.d.ts +2 -2
- package/servers/wp-rest-bridge/build/tools/unified-content.d.ts +8 -8
- package/servers/wp-rest-bridge/build/tools/unified-taxonomies.d.ts +4 -4
- package/servers/wp-rest-bridge/build/tools/users.d.ts +6 -6
- package/servers/wp-rest-bridge/build/tools/wc-coupons.d.ts +1 -1
- package/servers/wp-rest-bridge/build/tools/wc-customers.d.ts +3 -3
- package/servers/wp-rest-bridge/build/tools/wc-orders.d.ts +4 -4
- package/servers/wp-rest-bridge/build/tools/wc-products.d.ts +8 -8
- package/servers/wp-rest-bridge/build/tools/wc-webhooks.d.ts +4 -4
- package/servers/wp-rest-bridge/build/wordpress.d.ts +5 -0
- package/servers/wp-rest-bridge/build/wordpress.js +39 -0
- package/servers/wp-rest-bridge/package.json +1 -0
- package/skills/wordpress-router/references/decision-tree.md +6 -2
- package/skills/wp-content/SKILL.md +1 -0
- package/skills/wp-content-attribution/SKILL.md +2 -0
- package/skills/wp-content-optimization/SKILL.md +172 -0
- package/skills/wp-content-optimization/references/content-freshness.md +234 -0
- package/skills/wp-content-optimization/references/headline-optimization.md +171 -0
- package/skills/wp-content-optimization/references/meta-optimization.md +243 -0
- package/skills/wp-content-optimization/references/readability-analysis.md +201 -0
- package/skills/wp-content-optimization/references/seo-content-scoring.md +245 -0
- package/skills/wp-content-optimization/scripts/content_optimization_inspect.mjs +237 -0
- package/skills/wp-monitoring/SKILL.md +1 -0
- package/skills/wp-programmatic-seo/SKILL.md +2 -0
- package/skills/wp-search-console/SKILL.md +121 -0
- package/skills/wp-search-console/references/competitor-gap-analysis.md +226 -0
- package/skills/wp-search-console/references/content-seo-feedback.md +181 -0
- package/skills/wp-search-console/references/gsc-setup.md +110 -0
- package/skills/wp-search-console/references/indexing-management.md +182 -0
- package/skills/wp-search-console/references/keyword-tracking.md +181 -0
- package/skills/wp-search-console/scripts/search_console_inspect.mjs +178 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Content SEO Feedback
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Content SEO feedback connects Google Search Console performance data to WordPress content strategy. By analyzing page-level metrics (clicks, impressions, CTR, position), you can identify underperforming content, discover optimization opportunities, and make data-driven decisions about content refreshes, title rewrites, and new content creation.
|
|
6
|
+
|
|
7
|
+
## Identifying Underperforming Pages
|
|
8
|
+
|
|
9
|
+
### Get page-level performance data
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Tool: gsc_page_performance
|
|
13
|
+
Params:
|
|
14
|
+
site_url: "https://example.com/"
|
|
15
|
+
start_date: "2026-02-01"
|
|
16
|
+
end_date: "2026-02-28"
|
|
17
|
+
row_limit: 200
|
|
18
|
+
Returns: Array of pages with clicks, impressions, ctr, position
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Detect declining pages
|
|
22
|
+
|
|
23
|
+
Compare two periods to find pages with declining performance:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
# Previous period
|
|
27
|
+
Tool: gsc_page_performance
|
|
28
|
+
Params:
|
|
29
|
+
site_url: "https://example.com/"
|
|
30
|
+
start_date: "2026-01-01"
|
|
31
|
+
end_date: "2026-01-31"
|
|
32
|
+
row_limit: 200
|
|
33
|
+
|
|
34
|
+
# Current period
|
|
35
|
+
Tool: gsc_page_performance
|
|
36
|
+
Params:
|
|
37
|
+
site_url: "https://example.com/"
|
|
38
|
+
start_date: "2026-02-01"
|
|
39
|
+
end_date: "2026-02-28"
|
|
40
|
+
row_limit: 200
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Compare results to identify:
|
|
44
|
+
- **Click decline > 20%** — high priority for content refresh
|
|
45
|
+
- **Impression decline > 30%** — content may be losing relevance or competitors have overtaken
|
|
46
|
+
- **Position increase > 3 positions** (lower is better) — content is dropping in rankings
|
|
47
|
+
|
|
48
|
+
### Categorize pages by performance
|
|
49
|
+
|
|
50
|
+
| Category | Criteria | Action |
|
|
51
|
+
|----------|----------|--------|
|
|
52
|
+
| High performers | Top 10% by clicks | Protect and expand — add internal links, update regularly |
|
|
53
|
+
| Declining stars | Previously top, now dropping | Content refresh — update data, add sections, improve media |
|
|
54
|
+
| Hidden gems | High impressions, low CTR | Title/meta optimization — rewrite to improve click-through |
|
|
55
|
+
| Dead weight | Low impressions, low clicks | Evaluate for removal, consolidation, or major rewrite |
|
|
56
|
+
| Rising pages | Increasing impressions and clicks | Accelerate — build more internal links, add supporting content |
|
|
57
|
+
|
|
58
|
+
## Content Refresh Strategies
|
|
59
|
+
|
|
60
|
+
### Strategy 1: Refresh based on declining clicks
|
|
61
|
+
|
|
62
|
+
1. **Identify declining pages** using period comparison (see above)
|
|
63
|
+
2. **Fetch the WordPress content** using `wp_get_post` with the page URL
|
|
64
|
+
3. **Analyze queries** driving traffic to the page using `gsc_search_analytics` with `dimensions: ["query"]` filtered by the page URL
|
|
65
|
+
4. **Update the content** to better address the top queries:
|
|
66
|
+
- Add missing subtopics that queries suggest users are looking for
|
|
67
|
+
- Update outdated statistics, dates, and references
|
|
68
|
+
- Expand thin sections with more depth
|
|
69
|
+
- Add FAQ sections based on question-type queries
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
# Find queries for a specific declining page
|
|
73
|
+
Tool: gsc_search_analytics
|
|
74
|
+
Params:
|
|
75
|
+
site_url: "https://example.com/"
|
|
76
|
+
start_date: "2026-02-01"
|
|
77
|
+
end_date: "2026-02-28"
|
|
78
|
+
dimensions: ["query"]
|
|
79
|
+
dimension_filter_groups:
|
|
80
|
+
- filters:
|
|
81
|
+
- dimension: "page"
|
|
82
|
+
operator: "equals"
|
|
83
|
+
expression: "https://example.com/blog/wordpress-performance/"
|
|
84
|
+
row_limit: 50
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Strategy 2: New content from high-impression queries
|
|
88
|
+
|
|
89
|
+
Queries with high impressions but low or zero clicks on your pages represent untapped opportunities:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
Tool: gsc_search_analytics
|
|
93
|
+
Params:
|
|
94
|
+
site_url: "https://example.com/"
|
|
95
|
+
start_date: "2026-02-01"
|
|
96
|
+
end_date: "2026-02-28"
|
|
97
|
+
dimensions: ["query", "page"]
|
|
98
|
+
row_limit: 500
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Filter for queries where:
|
|
102
|
+
- `impressions > 200` and `clicks < 5` — your page appears but users do not click
|
|
103
|
+
- `position > 10` — you rank on page 2+ and need a dedicated, optimized page
|
|
104
|
+
|
|
105
|
+
These queries can inform new blog post topics or dedicated landing pages.
|
|
106
|
+
|
|
107
|
+
### Strategy 3: Content consolidation
|
|
108
|
+
|
|
109
|
+
Multiple pages ranking for the same query cannibalize each other:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
Tool: gsc_search_analytics
|
|
113
|
+
Params:
|
|
114
|
+
site_url: "https://example.com/"
|
|
115
|
+
start_date: "2026-02-01"
|
|
116
|
+
end_date: "2026-02-28"
|
|
117
|
+
dimensions: ["query", "page"]
|
|
118
|
+
row_limit: 1000
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Look for queries that appear with 2+ different pages. When multiple pages compete:
|
|
122
|
+
1. Choose the strongest page (most clicks/best position)
|
|
123
|
+
2. Merge content from the weaker page into the stronger one
|
|
124
|
+
3. Redirect the weaker URL to the stronger page
|
|
125
|
+
4. Update internal links to point to the consolidated page
|
|
126
|
+
|
|
127
|
+
## Title and Meta Description Optimization
|
|
128
|
+
|
|
129
|
+
### Find CTR optimization opportunities
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
Tool: gsc_search_analytics
|
|
133
|
+
Params:
|
|
134
|
+
site_url: "https://example.com/"
|
|
135
|
+
start_date: "2026-02-01"
|
|
136
|
+
end_date: "2026-02-28"
|
|
137
|
+
dimensions: ["query", "page"]
|
|
138
|
+
row_limit: 200
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Target pages where:
|
|
142
|
+
- `position < 5` and `ctr < 0.05` — ranking well but not getting clicks (expected CTR for top 5 is 5-15%)
|
|
143
|
+
- `position < 3` and `ctr < 0.10` — top 3 positions should have 10%+ CTR
|
|
144
|
+
|
|
145
|
+
### Title tag optimization guidelines
|
|
146
|
+
|
|
147
|
+
Based on search data patterns:
|
|
148
|
+
- **Include the primary query** in the title — queries that appear verbatim in titles get higher CTR
|
|
149
|
+
- **Front-load keywords** — the first 60 characters are visible in SERPs
|
|
150
|
+
- **Add power words** — "Guide", "2026", "Complete", "Best" boost CTR by 5-15%
|
|
151
|
+
- **Use numbers** — "10 Tips", "5 Steps" increase CTR by 10-20% vs generic titles
|
|
152
|
+
- **Match intent** — if queries are questions, use question format in title
|
|
153
|
+
|
|
154
|
+
### Meta description optimization
|
|
155
|
+
|
|
156
|
+
- **Include target query** — Google bolds matching terms in descriptions
|
|
157
|
+
- **Add a CTA** — "Learn more", "Get started", "Read the full guide"
|
|
158
|
+
- **Stay under 155 characters** — longer descriptions get truncated
|
|
159
|
+
- **Differentiate from competitors** — include unique value propositions
|
|
160
|
+
|
|
161
|
+
## WordPress Integration Workflow
|
|
162
|
+
|
|
163
|
+
Complete content optimization loop using GSC data and WordPress tools:
|
|
164
|
+
|
|
165
|
+
1. **Pull page performance**: `gsc_page_performance` for all pages
|
|
166
|
+
2. **Identify targets**: Filter for declining or underperforming pages
|
|
167
|
+
3. **Get query context**: `gsc_search_analytics` filtered by target page URL
|
|
168
|
+
4. **Fetch WordPress content**: `wp_get_post` to get current content
|
|
169
|
+
5. **Update content**: `wp_update_post` with improved title, content, and meta
|
|
170
|
+
6. **Monitor results**: Re-check `gsc_page_performance` after 2-4 weeks
|
|
171
|
+
|
|
172
|
+
## Best Practices
|
|
173
|
+
|
|
174
|
+
- **Refresh cadence**: Review page performance monthly; refresh declining content quarterly
|
|
175
|
+
- **Data threshold**: Only act on pages with 100+ impressions — below that, data is statistically unreliable
|
|
176
|
+
- **Patience after changes**: Wait 2-4 weeks after content changes before measuring impact; Google needs time to re-crawl and re-evaluate
|
|
177
|
+
- **Track changes**: Note the date and nature of each content update so you can correlate with performance changes
|
|
178
|
+
- **Prioritize by impact**: Focus on pages with the highest impression volume first — small CTR improvements on high-impression pages yield more clicks than large improvements on low-impression pages
|
|
179
|
+
- **Seasonal awareness**: Some traffic drops are seasonal, not quality-related; compare year-over-year when possible
|
|
180
|
+
- **Avoid over-optimization**: Do not stuff keywords into titles or content; natural language performs better in modern search
|
|
181
|
+
- **Internal linking**: After refreshing content, add internal links from other relevant pages to boost crawl priority
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# GSC Setup
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Google Search Console integration requires a Google Cloud service account with Search Console API access. The service account's JSON key file is configured in `WP_SITES_CONFIG`, enabling all 8 GSC MCP tools to authenticate and query search data for your WordPress site.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
### Step 1: Create a Google Cloud Project
|
|
10
|
+
|
|
11
|
+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
12
|
+
2. Create a new project or select an existing one
|
|
13
|
+
3. Enable the **Google Search Console API** (also called "Search Console API" or "Webmasters API") under APIs & Services → Library
|
|
14
|
+
|
|
15
|
+
### Step 2: Create a Service Account
|
|
16
|
+
|
|
17
|
+
1. Navigate to IAM & Admin → Service Accounts
|
|
18
|
+
2. Click **Create Service Account**
|
|
19
|
+
3. Name it (e.g., `wp-search-console`) and add a description
|
|
20
|
+
4. No additional roles are needed at the project level
|
|
21
|
+
5. Click **Done**
|
|
22
|
+
|
|
23
|
+
### Step 3: Generate JSON Key File
|
|
24
|
+
|
|
25
|
+
1. Click on the newly created service account
|
|
26
|
+
2. Go to the **Keys** tab
|
|
27
|
+
3. Click **Add Key** → **Create new key** → **JSON**
|
|
28
|
+
4. Download the JSON key file and store it securely
|
|
29
|
+
|
|
30
|
+
The JSON key file contains:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"type": "service_account",
|
|
35
|
+
"project_id": "your-project-id",
|
|
36
|
+
"private_key_id": "key-id",
|
|
37
|
+
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
|
|
38
|
+
"client_email": "wp-search-console@your-project.iam.gserviceaccount.com",
|
|
39
|
+
"client_id": "123456789",
|
|
40
|
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
|
41
|
+
"token_uri": "https://oauth2.googleapis.com/token"
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Step 4: Grant Search Console Access
|
|
46
|
+
|
|
47
|
+
1. Go to [Google Search Console](https://search.google.com/search-console)
|
|
48
|
+
2. Select your property (site)
|
|
49
|
+
3. Navigate to **Settings** → **Users and permissions**
|
|
50
|
+
4. Click **Add user**
|
|
51
|
+
5. Enter the service account email (e.g., `wp-search-console@your-project.iam.gserviceaccount.com`)
|
|
52
|
+
6. Set permission to **Full** (for read access and sitemap management) or **Restricted** (read-only)
|
|
53
|
+
|
|
54
|
+
### Step 5: Configure WP_SITES_CONFIG
|
|
55
|
+
|
|
56
|
+
Add GSC credentials to your site configuration:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"sites": [{
|
|
61
|
+
"name": "my-site",
|
|
62
|
+
"url": "https://example.com",
|
|
63
|
+
"gsc": {
|
|
64
|
+
"gsc_service_account_key": "/path/to/service-account-key.json",
|
|
65
|
+
"gsc_site_url": "https://example.com/"
|
|
66
|
+
}
|
|
67
|
+
}]
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Important notes on `gsc_site_url`:**
|
|
72
|
+
- Use the exact property URL as it appears in Search Console
|
|
73
|
+
- For domain properties, use `sc-domain:example.com`
|
|
74
|
+
- For URL-prefix properties, use the full URL with trailing slash: `https://example.com/`
|
|
75
|
+
- The value must match exactly — a mismatch will result in 403 errors
|
|
76
|
+
|
|
77
|
+
## Verification
|
|
78
|
+
|
|
79
|
+
After configuration, verify the setup works:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
Tool: gsc_list_sites
|
|
83
|
+
Returns: Array of verified sites with siteUrl, permissionLevel
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
You should see your site listed with `permissionLevel` of `siteOwner` or `siteFullUser`.
|
|
87
|
+
|
|
88
|
+
## Permissions and Scopes
|
|
89
|
+
|
|
90
|
+
The service account requires the following OAuth scope:
|
|
91
|
+
|
|
92
|
+
- `https://www.googleapis.com/auth/webmasters.readonly` — for read-only access (search analytics, URL inspection, sitemap listing)
|
|
93
|
+
- `https://www.googleapis.com/auth/webmasters` — for full access (includes sitemap submission and deletion)
|
|
94
|
+
|
|
95
|
+
The MCP tools automatically request the appropriate scope based on the operation.
|
|
96
|
+
|
|
97
|
+
## Troubleshooting
|
|
98
|
+
|
|
99
|
+
- **403 Forbidden**: The service account email has not been added to Search Console, or `gsc_site_url` does not match the property URL
|
|
100
|
+
- **404 Not Found**: The site URL format is incorrect (missing trailing slash or wrong protocol)
|
|
101
|
+
- **Authentication errors**: The JSON key file path is invalid or the file is malformed
|
|
102
|
+
- **No data returned**: The site may be newly verified; Search Console data takes 24-48 hours to populate
|
|
103
|
+
|
|
104
|
+
## Best Practices
|
|
105
|
+
|
|
106
|
+
- **Key file security**: Store the JSON key file outside the project directory; never commit it to version control
|
|
107
|
+
- **Least privilege**: Use **Restricted** permission if you only need read access (search analytics, URL inspection)
|
|
108
|
+
- **Separate accounts**: Use a dedicated service account per project to isolate access
|
|
109
|
+
- **Key rotation**: Rotate service account keys periodically (every 90 days recommended)
|
|
110
|
+
- **Domain property**: Prefer domain-level properties (`sc-domain:example.com`) over URL-prefix properties for complete data coverage
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Indexing Management
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Indexing management ensures that Google discovers, crawls, and indexes your WordPress pages correctly. The GSC MCP tools provide URL inspection for individual pages and sitemap management for bulk discovery. Together, these tools help you monitor crawl coverage, diagnose indexing issues, and control which pages appear in search results.
|
|
6
|
+
|
|
7
|
+
## URL Inspection
|
|
8
|
+
|
|
9
|
+
### Inspect a single URL
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Tool: gsc_inspect_url
|
|
13
|
+
Params:
|
|
14
|
+
site_url: "https://example.com/"
|
|
15
|
+
inspection_url: "https://example.com/blog/wordpress-seo-guide/"
|
|
16
|
+
Returns:
|
|
17
|
+
indexStatusResult:
|
|
18
|
+
verdict: "PASS" # PASS | NEUTRAL | FAIL
|
|
19
|
+
coverageState: "Submitted and indexed"
|
|
20
|
+
robotsTxtState: "ALLOWED"
|
|
21
|
+
indexingState: "INDEXING_ALLOWED"
|
|
22
|
+
lastCrawlTime: "2026-02-25T10:30:00Z"
|
|
23
|
+
pageFetchState: "SUCCESSFUL"
|
|
24
|
+
crawledAs: "MOBILE"
|
|
25
|
+
mobileUsabilityResult:
|
|
26
|
+
verdict: "PASS"
|
|
27
|
+
richResultsResult:
|
|
28
|
+
detectedItems: [...]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Understanding inspection results
|
|
32
|
+
|
|
33
|
+
Key fields in the response:
|
|
34
|
+
|
|
35
|
+
| Field | Values | Meaning |
|
|
36
|
+
|-------|--------|---------|
|
|
37
|
+
| `verdict` | PASS / NEUTRAL / FAIL | Overall indexing status |
|
|
38
|
+
| `coverageState` | Various | Detailed coverage status |
|
|
39
|
+
| `robotsTxtState` | ALLOWED / DISALLOWED | Whether robots.txt blocks the URL |
|
|
40
|
+
| `indexingState` | INDEXING_ALLOWED / INDEXING_NOT_ALLOWED | Whether meta robots/noindex blocks indexing |
|
|
41
|
+
| `pageFetchState` | SUCCESSFUL / SOFT_404 / NOT_FOUND / REDIRECT | Crawl outcome |
|
|
42
|
+
| `crawledAs` | MOBILE / DESKTOP | Which crawler accessed the page |
|
|
43
|
+
|
|
44
|
+
### Common coverage states
|
|
45
|
+
|
|
46
|
+
- **Submitted and indexed** — page is in the index and appearing in search results
|
|
47
|
+
- **Crawled - currently not indexed** — Google crawled it but chose not to index (quality or duplicate concern)
|
|
48
|
+
- **Discovered - currently not indexed** — Google knows about it but has not crawled it yet
|
|
49
|
+
- **Excluded by 'noindex' tag** — the page has a noindex directive
|
|
50
|
+
- **Blocked by robots.txt** — robots.txt prevents crawling
|
|
51
|
+
- **Page with redirect** — the URL redirects to another page
|
|
52
|
+
- **Soft 404** — the page returns 200 but Google treats it as a 404
|
|
53
|
+
|
|
54
|
+
## Sitemap Management
|
|
55
|
+
|
|
56
|
+
### List sitemaps
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Tool: gsc_list_sitemaps
|
|
60
|
+
Params:
|
|
61
|
+
site_url: "https://example.com/"
|
|
62
|
+
Returns: Array of sitemaps with:
|
|
63
|
+
path: "https://example.com/sitemap_index.xml"
|
|
64
|
+
lastSubmitted: "2026-02-20T08:00:00Z"
|
|
65
|
+
isPending: false
|
|
66
|
+
isSitemapsIndex: true
|
|
67
|
+
lastDownloaded: "2026-02-25T06:00:00Z"
|
|
68
|
+
warnings: 0
|
|
69
|
+
errors: 0
|
|
70
|
+
contents:
|
|
71
|
+
- type: "web"
|
|
72
|
+
submitted: 150
|
|
73
|
+
indexed: 142
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Submit a sitemap
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Tool: gsc_submit_sitemap
|
|
80
|
+
Params:
|
|
81
|
+
site_url: "https://example.com/"
|
|
82
|
+
sitemap_url: "https://example.com/sitemap_index.xml"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Submit after:
|
|
86
|
+
- Initial site setup
|
|
87
|
+
- Adding a new sitemap (e.g., a video sitemap or news sitemap)
|
|
88
|
+
- Changing sitemap URL structure
|
|
89
|
+
- Major content additions (100+ new pages)
|
|
90
|
+
|
|
91
|
+
### Delete a sitemap
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
Tool: gsc_delete_sitemap
|
|
95
|
+
Params:
|
|
96
|
+
site_url: "https://example.com/"
|
|
97
|
+
sitemap_url: "https://example.com/old-sitemap.xml"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Delete when:
|
|
101
|
+
- A sitemap URL has changed (submit the new one, delete the old)
|
|
102
|
+
- A sitemap contains only 404/removed pages
|
|
103
|
+
- Consolidating multiple sitemaps into one
|
|
104
|
+
|
|
105
|
+
## Monitoring Crawl Coverage
|
|
106
|
+
|
|
107
|
+
### Bulk URL inspection workflow
|
|
108
|
+
|
|
109
|
+
For auditing multiple pages, iterate through URLs from your WordPress site:
|
|
110
|
+
|
|
111
|
+
1. **Get WordPress pages** using `wp_list_posts` with `status: "publish"`
|
|
112
|
+
2. **Inspect each URL** using `gsc_inspect_url` for each published page
|
|
113
|
+
3. **Categorize results** by `coverageState`:
|
|
114
|
+
- Indexed: `verdict === "PASS"`
|
|
115
|
+
- Not indexed: `verdict === "FAIL"` or `verdict === "NEUTRAL"`
|
|
116
|
+
4. **Report findings** with counts per coverage state
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
# Example workflow
|
|
120
|
+
Step 1: wp_list_posts status="publish" per_page=100 → Array of posts with links
|
|
121
|
+
Step 2: For each post.link → gsc_inspect_url inspection_url=post.link
|
|
122
|
+
Step 3: Group by coverageState → { indexed: 85, not_indexed: 12, errors: 3 }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Sitemap vs index comparison
|
|
126
|
+
|
|
127
|
+
Compare sitemap-submitted URLs against indexed URLs to find coverage gaps:
|
|
128
|
+
|
|
129
|
+
1. **List sitemaps** with `gsc_list_sitemaps` to get submitted/indexed counts
|
|
130
|
+
2. **Calculate coverage rate**: `indexed / submitted * 100`
|
|
131
|
+
3. **Investigate gaps**: If coverage is below 90%, inspect non-indexed URLs individually
|
|
132
|
+
|
|
133
|
+
## Handling Indexing Issues
|
|
134
|
+
|
|
135
|
+
### Crawled but not indexed
|
|
136
|
+
|
|
137
|
+
This means Google fetched the page but deemed it unworthy of indexing. Common causes:
|
|
138
|
+
- **Thin content**: Page has very little unique content
|
|
139
|
+
- **Duplicate content**: Substantially similar to another indexed page
|
|
140
|
+
- **Low quality**: Content does not meet quality thresholds
|
|
141
|
+
|
|
142
|
+
**Actions:**
|
|
143
|
+
1. Inspect the URL with `gsc_inspect_url` to confirm the status
|
|
144
|
+
2. Review the page content — add depth, unique value, or original research
|
|
145
|
+
3. Check for duplicate content — use canonical tags to consolidate
|
|
146
|
+
4. After improving, request re-indexing (not available via API; use Search Console UI)
|
|
147
|
+
|
|
148
|
+
### Discovered but not indexed
|
|
149
|
+
|
|
150
|
+
Google knows the URL exists but has not crawled it. This often indicates:
|
|
151
|
+
- **Crawl budget**: The site has too many pages relative to its authority
|
|
152
|
+
- **Internal linking**: The page is poorly linked from other pages
|
|
153
|
+
- **Priority**: Google does not consider the page important enough to crawl
|
|
154
|
+
|
|
155
|
+
**Actions:**
|
|
156
|
+
1. Improve internal linking to the page from high-authority pages
|
|
157
|
+
2. Add the URL to the sitemap if it is not already included
|
|
158
|
+
3. Reduce crawl waste by blocking thin/utility pages with `noindex`
|
|
159
|
+
|
|
160
|
+
### Blocked by robots.txt
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
# Check if the URL is blocked
|
|
164
|
+
Tool: gsc_inspect_url
|
|
165
|
+
Params:
|
|
166
|
+
inspection_url: "https://example.com/admin-page/"
|
|
167
|
+
|
|
168
|
+
# If robotsTxtState is "DISALLOWED", review the robots.txt file
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Ensure your `robots.txt` is not accidentally blocking important content pages.
|
|
172
|
+
|
|
173
|
+
## Best Practices
|
|
174
|
+
|
|
175
|
+
- **Sitemap freshness**: WordPress SEO plugins (Yoast, Rank Math) auto-generate sitemaps; submit the index sitemap once and let the plugin manage updates
|
|
176
|
+
- **Inspection frequency**: Do not over-inspect; GSC has API quotas. Batch inspections for weekly or monthly audits
|
|
177
|
+
- **New content**: After publishing a significant post, inspect it after 48-72 hours to verify crawling
|
|
178
|
+
- **Redirect chains**: Avoid chains of 3+ redirects; they slow crawling and may cause indexing issues
|
|
179
|
+
- **Status codes**: Regularly check for soft 404s — pages that return 200 but appear empty or error-like to Googlebot
|
|
180
|
+
- **Canonical tags**: Ensure every page has a self-referencing canonical or points to the preferred version
|
|
181
|
+
- **Crawl budget**: For large sites (10,000+ pages), prioritize indexing of high-value pages by improving internal linking and reducing index bloat
|
|
182
|
+
- **Mobile-first**: Google uses mobile crawling by default; ensure `crawledAs: "MOBILE"` succeeds for all important pages
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Keyword Tracking
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Keyword tracking uses GSC search analytics data to monitor how your WordPress site ranks for specific queries in Google Search. The `gsc_search_analytics` and `gsc_top_queries` tools provide clicks, impressions, CTR, and average position data that can be filtered by date range, query, page, country, and device.
|
|
6
|
+
|
|
7
|
+
## Core Tools
|
|
8
|
+
|
|
9
|
+
### Get top queries
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Tool: gsc_top_queries
|
|
13
|
+
Params:
|
|
14
|
+
site_url: "https://example.com/"
|
|
15
|
+
start_date: "2026-02-01"
|
|
16
|
+
end_date: "2026-02-28"
|
|
17
|
+
row_limit: 50
|
|
18
|
+
Returns: Array of queries with clicks, impressions, ctr, position
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This returns the top-performing queries ranked by clicks. Use `row_limit` to control how many queries are returned (default: 25, max: 25000).
|
|
22
|
+
|
|
23
|
+
### Query search analytics with dimensions
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Tool: gsc_search_analytics
|
|
27
|
+
Params:
|
|
28
|
+
site_url: "https://example.com/"
|
|
29
|
+
start_date: "2026-02-01"
|
|
30
|
+
end_date: "2026-02-28"
|
|
31
|
+
dimensions: ["query", "page"]
|
|
32
|
+
row_limit: 100
|
|
33
|
+
Returns: Array of rows with keys (query, page), clicks, impressions, ctr, position
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Available dimensions:
|
|
37
|
+
- `query` — the search query text
|
|
38
|
+
- `page` — the URL that appeared in search results
|
|
39
|
+
- `country` — ISO 3166-1 alpha-3 country code
|
|
40
|
+
- `device` — DESKTOP, MOBILE, or TABLET
|
|
41
|
+
- `date` — individual date breakdown
|
|
42
|
+
|
|
43
|
+
### Filter by specific query
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
Tool: gsc_search_analytics
|
|
47
|
+
Params:
|
|
48
|
+
site_url: "https://example.com/"
|
|
49
|
+
start_date: "2026-02-01"
|
|
50
|
+
end_date: "2026-02-28"
|
|
51
|
+
dimensions: ["query", "date"]
|
|
52
|
+
dimension_filter_groups:
|
|
53
|
+
- filters:
|
|
54
|
+
- dimension: "query"
|
|
55
|
+
operator: "contains"
|
|
56
|
+
expression: "wordpress seo"
|
|
57
|
+
row_limit: 100
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Filter operators:
|
|
61
|
+
- `contains` — query contains the expression
|
|
62
|
+
- `equals` — exact match
|
|
63
|
+
- `notContains` — excludes queries containing the expression
|
|
64
|
+
- `notEquals` — excludes exact matches
|
|
65
|
+
|
|
66
|
+
## Tracking Position Changes Over Time
|
|
67
|
+
|
|
68
|
+
### Daily position tracking
|
|
69
|
+
|
|
70
|
+
To track how a keyword's position changes day by day:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
Tool: gsc_search_analytics
|
|
74
|
+
Params:
|
|
75
|
+
site_url: "https://example.com/"
|
|
76
|
+
start_date: "2026-02-01"
|
|
77
|
+
end_date: "2026-02-28"
|
|
78
|
+
dimensions: ["query", "date"]
|
|
79
|
+
dimension_filter_groups:
|
|
80
|
+
- filters:
|
|
81
|
+
- dimension: "query"
|
|
82
|
+
operator: "equals"
|
|
83
|
+
expression: "best wordpress plugins"
|
|
84
|
+
row_limit: 28
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
This returns one row per day for the specific query, showing position movement across the date range.
|
|
88
|
+
|
|
89
|
+
### Compare periods
|
|
90
|
+
|
|
91
|
+
To compare performance between two periods, make two `gsc_search_analytics` calls with different date ranges and compare the results:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
# Period 1: Previous month
|
|
95
|
+
Tool: gsc_search_analytics
|
|
96
|
+
Params:
|
|
97
|
+
site_url: "https://example.com/"
|
|
98
|
+
start_date: "2026-01-01"
|
|
99
|
+
end_date: "2026-01-31"
|
|
100
|
+
dimensions: ["query"]
|
|
101
|
+
row_limit: 100
|
|
102
|
+
|
|
103
|
+
# Period 2: Current month
|
|
104
|
+
Tool: gsc_search_analytics
|
|
105
|
+
Params:
|
|
106
|
+
site_url: "https://example.com/"
|
|
107
|
+
start_date: "2026-02-01"
|
|
108
|
+
end_date: "2026-02-28"
|
|
109
|
+
dimensions: ["query"]
|
|
110
|
+
row_limit: 100
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Compare `position`, `clicks`, and `impressions` between periods to identify improving and declining keywords.
|
|
114
|
+
|
|
115
|
+
## Query-Level Analysis
|
|
116
|
+
|
|
117
|
+
### High-impression, low-CTR queries
|
|
118
|
+
|
|
119
|
+
These are queries where your page appears frequently but users rarely click — indicating a title or meta description optimization opportunity:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
Tool: gsc_search_analytics
|
|
123
|
+
Params:
|
|
124
|
+
site_url: "https://example.com/"
|
|
125
|
+
start_date: "2026-02-01"
|
|
126
|
+
end_date: "2026-02-28"
|
|
127
|
+
dimensions: ["query", "page"]
|
|
128
|
+
row_limit: 200
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Filter results where `impressions > 100` and `ctr < 0.02` (2%). These queries should be prioritized for title tag and meta description improvements.
|
|
132
|
+
|
|
133
|
+
### Position 4-20 keywords (striking distance)
|
|
134
|
+
|
|
135
|
+
Keywords ranking on positions 4-20 are in "striking distance" — small improvements can move them to page 1 or top 3:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
Tool: gsc_search_analytics
|
|
139
|
+
Params:
|
|
140
|
+
site_url: "https://example.com/"
|
|
141
|
+
start_date: "2026-02-01"
|
|
142
|
+
end_date: "2026-02-28"
|
|
143
|
+
dimensions: ["query", "page"]
|
|
144
|
+
row_limit: 500
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Filter results where `position >= 4` and `position <= 20` and `impressions > 50`. These are the highest-ROI optimization targets.
|
|
148
|
+
|
|
149
|
+
### Device-specific rankings
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
Tool: gsc_search_analytics
|
|
153
|
+
Params:
|
|
154
|
+
site_url: "https://example.com/"
|
|
155
|
+
start_date: "2026-02-01"
|
|
156
|
+
end_date: "2026-02-28"
|
|
157
|
+
dimensions: ["query", "device"]
|
|
158
|
+
row_limit: 100
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Compare mobile vs desktop rankings. Significant position differences may indicate mobile usability issues.
|
|
162
|
+
|
|
163
|
+
## Creating Keyword Dashboards
|
|
164
|
+
|
|
165
|
+
Build a comprehensive keyword report by combining multiple queries:
|
|
166
|
+
|
|
167
|
+
1. **Top 50 queries by clicks** — `gsc_top_queries` with `row_limit: 50`
|
|
168
|
+
2. **Position trends for target keywords** — `gsc_search_analytics` with `dimensions: ["query", "date"]` filtered by target queries
|
|
169
|
+
3. **Page-level performance** — `gsc_page_performance` to see which pages drive the most search traffic
|
|
170
|
+
4. **Country breakdown** — `gsc_search_analytics` with `dimensions: ["query", "country"]` for geo-specific insights
|
|
171
|
+
|
|
172
|
+
## Best Practices
|
|
173
|
+
|
|
174
|
+
- **Date range selection**: Use at least 28 days of data for reliable averages; short ranges (< 7 days) produce noisy data
|
|
175
|
+
- **Regular monitoring**: Track core keywords weekly to catch position drops early; monthly for trend analysis
|
|
176
|
+
- **Segment by intent**: Group queries by intent (informational, transactional, navigational) to align with content strategy
|
|
177
|
+
- **Position averages**: GSC reports average position weighted by impressions; a page ranking #1 for one query and #50 for another may show position 25
|
|
178
|
+
- **Data freshness**: GSC data has a 2-3 day delay; do not expect same-day data
|
|
179
|
+
- **Row limits**: Default row limit is 1000; for comprehensive audits, increase to 25000
|
|
180
|
+
- **Branded vs non-branded**: Separate branded queries (containing your brand name) from non-branded to get a clearer picture of organic discovery
|
|
181
|
+
- **Click vs impression trends**: Rising impressions with flat clicks indicates a CTR problem; rising clicks with flat impressions indicates improved CTR or rankings
|