claude-plugin-wordpress-manager 2.4.0 → 2.9.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 +103 -0
- package/agents/wp-content-strategist.md +104 -0
- package/agents/wp-monitoring-agent.md +44 -0
- package/agents/wp-site-manager.md +19 -0
- package/docs/GUIDE.md +183 -23
- package/docs/plans/2026-03-01-tier4-5-implementation.md +1783 -0
- package/docs/plans/2026-03-01-tier4-5-observability-automation-design.md +426 -0
- package/docs/plans/2026-03-01-wcop-reassessment-v2.6.0.md +403 -0
- package/hooks/hooks.json +9 -0
- package/package.json +19 -3
- package/servers/wp-rest-bridge/build/tools/comments.d.ts +6 -6
- package/servers/wp-rest-bridge/build/tools/cwv.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/cwv.js +196 -0
- package/servers/wp-rest-bridge/build/tools/ga4.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/ga4.js +323 -0
- 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 +18 -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/plausible.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/plausible.js +207 -0
- 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/slack.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/slack.js +129 -0
- 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/tools/wc-workflows.d.ts +3 -0
- package/servers/wp-rest-bridge/build/tools/wc-workflows.js +222 -0
- package/servers/wp-rest-bridge/build/wordpress.d.ts +23 -0
- package/servers/wp-rest-bridge/build/wordpress.js +178 -0
- package/servers/wp-rest-bridge/package.json +1 -0
- package/skills/wordpress-router/SKILL.md +1 -1
- package/skills/wordpress-router/references/decision-tree.md +12 -2
- package/skills/wp-alerting/SKILL.md +142 -0
- package/skills/wp-alerting/references/alert-thresholds.md +79 -0
- package/skills/wp-alerting/references/escalation-paths.md +92 -0
- package/skills/wp-alerting/references/report-scheduling.md +142 -0
- package/skills/wp-alerting/references/slack-integration.md +109 -0
- package/skills/wp-alerting/scripts/alerting_inspect.mjs +150 -0
- package/skills/wp-analytics/SKILL.md +158 -0
- package/skills/wp-analytics/references/analytics-dashboards.md +83 -0
- package/skills/wp-analytics/references/cwv-monitoring.md +101 -0
- package/skills/wp-analytics/references/ga4-integration.md +76 -0
- package/skills/wp-analytics/references/plausible-setup.md +92 -0
- package/skills/wp-analytics/references/traffic-attribution.md +92 -0
- package/skills/wp-analytics/scripts/analytics_inspect.mjs +153 -0
- package/skills/wp-content/SKILL.md +1 -0
- package/skills/wp-content-attribution/SKILL.md +3 -0
- package/skills/wp-content-optimization/SKILL.md +173 -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-content-workflows/SKILL.md +142 -0
- package/skills/wp-content-workflows/references/content-lifecycle-hooks.md +131 -0
- package/skills/wp-content-workflows/references/multi-channel-actions.md +151 -0
- package/skills/wp-content-workflows/references/schedule-triggers.md +118 -0
- package/skills/wp-content-workflows/references/trigger-management.md +159 -0
- package/skills/wp-content-workflows/references/wp-action-hooks.md +114 -0
- package/skills/wp-content-workflows/scripts/workflow_inspect.mjs +202 -0
- package/skills/wp-monitoring/SKILL.md +3 -0
- package/skills/wp-programmatic-seo/SKILL.md +2 -0
- package/skills/wp-search-console/SKILL.md +122 -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
- package/skills/wp-social-email/SKILL.md +1 -0
- package/skills/wp-webhooks/SKILL.md +1 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow_inspect.mjs — Detect workflow automation configuration readiness.
|
|
3
|
+
*
|
|
4
|
+
* Checks WP_SITES_CONFIG for Slack/SendGrid/Mailchimp credentials.
|
|
5
|
+
* Scans for automation plugins, custom REST endpoints, WP-Cron config,
|
|
6
|
+
* and webhook setup.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node workflow_inspect.mjs [--cwd=/path/to/project]
|
|
10
|
+
*
|
|
11
|
+
* Exit codes:
|
|
12
|
+
* 0 — workflow configuration found
|
|
13
|
+
* 1 — no workflow configuration found
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { readFileSync, existsSync, readdirSync } from 'node:fs';
|
|
17
|
+
import { join, resolve } from 'node:path';
|
|
18
|
+
import { argv, stdout, exit } from 'node:process';
|
|
19
|
+
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Helpers
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
function readFileSafe(filePath) {
|
|
25
|
+
try { return readFileSync(filePath, 'utf-8'); } catch { return null; }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function existsSafe(filePath) {
|
|
29
|
+
try { return existsSync(filePath); } catch { return false; }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function globDir(dirPath) {
|
|
33
|
+
try { return readdirSync(dirPath); } catch { return []; }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Detectors
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
function detectActionChannelConfig() {
|
|
41
|
+
const channels = { configured: false, indicators: [], missing: [] };
|
|
42
|
+
const raw = process.env.WP_SITES_CONFIG;
|
|
43
|
+
if (!raw) { channels.missing.push('WP_SITES_CONFIG env var not set'); return channels; }
|
|
44
|
+
|
|
45
|
+
let sites;
|
|
46
|
+
try { sites = JSON.parse(raw); } catch { channels.missing.push('WP_SITES_CONFIG is not valid JSON'); return channels; }
|
|
47
|
+
if (!Array.isArray(sites)) { channels.missing.push('WP_SITES_CONFIG is not an array'); return channels; }
|
|
48
|
+
|
|
49
|
+
const keys = ['slack_webhook_url', 'slack_bot_token', 'sendgrid_api_key', 'mailchimp_api_key'];
|
|
50
|
+
|
|
51
|
+
for (const site of sites) {
|
|
52
|
+
const label = site.id || site.url || 'unknown';
|
|
53
|
+
for (const key of keys) {
|
|
54
|
+
if (site[key]) {
|
|
55
|
+
channels.configured = true;
|
|
56
|
+
channels.indicators.push(`${key} configured for ${label}`);
|
|
57
|
+
} else {
|
|
58
|
+
channels.missing.push(`${key} not set for ${label}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return channels;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function detectAutomationPlugins(cwd) {
|
|
66
|
+
const result = { found: false, indicators: [], recommendations: [] };
|
|
67
|
+
const pluginsDir = join(cwd, 'wp-content', 'plugins');
|
|
68
|
+
const plugins = globDir(pluginsDir);
|
|
69
|
+
|
|
70
|
+
const automationPlugins = [
|
|
71
|
+
'automatewoo',
|
|
72
|
+
'wp-fusion',
|
|
73
|
+
'fluent-crm',
|
|
74
|
+
'suretriggers',
|
|
75
|
+
'wp-crontrol',
|
|
76
|
+
'advanced-cron-manager',
|
|
77
|
+
'advanced-cron-manager-pro',
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
for (const plugin of automationPlugins) {
|
|
81
|
+
if (plugins.includes(plugin)) {
|
|
82
|
+
result.found = true;
|
|
83
|
+
result.indicators.push(`plugin: ${plugin}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!result.found) {
|
|
88
|
+
result.recommendations.push('Install wp-crontrol for cron event management');
|
|
89
|
+
result.recommendations.push('Consider FluentCRM or AutomateWoo for advanced workflows');
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function detectCustomRestEndpoints(cwd) {
|
|
95
|
+
const rest = { found: false, indicators: [] };
|
|
96
|
+
|
|
97
|
+
// Look for wp-manager workflow namespace in plugin/theme files
|
|
98
|
+
const muPluginsDir = join(cwd, 'wp-content', 'mu-plugins');
|
|
99
|
+
const pluginsDir = join(cwd, 'wp-content', 'plugins');
|
|
100
|
+
const themeDir = join(cwd, 'wp-content', 'themes');
|
|
101
|
+
|
|
102
|
+
const searchDirs = [muPluginsDir, pluginsDir, themeDir];
|
|
103
|
+
const pattern = /register_rest_route\s*\(\s*['"]wp-manager\/v1\/workflows['"]/;
|
|
104
|
+
|
|
105
|
+
for (const dir of searchDirs) {
|
|
106
|
+
const files = globDir(dir);
|
|
107
|
+
for (const file of files) {
|
|
108
|
+
const filePath = join(dir, file);
|
|
109
|
+
if (file.endsWith('.php')) {
|
|
110
|
+
const content = readFileSafe(filePath);
|
|
111
|
+
if (content && pattern.test(content)) {
|
|
112
|
+
rest.found = true;
|
|
113
|
+
rest.indicators.push(`REST endpoint in ${filePath}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return rest;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function detectWpCronConfig(cwd) {
|
|
122
|
+
const cron = { disabled: false, alternate: false, indicators: [], recommendations: [] };
|
|
123
|
+
|
|
124
|
+
const wpConfig = readFileSafe(join(cwd, 'wp-config.php'));
|
|
125
|
+
if (!wpConfig) {
|
|
126
|
+
cron.recommendations.push('wp-config.php not found — cannot check cron config');
|
|
127
|
+
return cron;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (/define\s*\(\s*['"]DISABLE_WP_CRON['"]\s*,\s*true\s*\)/i.test(wpConfig)) {
|
|
131
|
+
cron.disabled = true;
|
|
132
|
+
cron.indicators.push('DISABLE_WP_CRON is true — server-side cron expected');
|
|
133
|
+
}
|
|
134
|
+
if (/define\s*\(\s*['"]ALTERNATE_WP_CRON['"]\s*,\s*true\s*\)/i.test(wpConfig)) {
|
|
135
|
+
cron.alternate = true;
|
|
136
|
+
cron.indicators.push('ALTERNATE_WP_CRON is true — redirect-based cron active');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const cronPath = join(cwd, 'wp-cron.php');
|
|
140
|
+
if (existsSafe(cronPath)) {
|
|
141
|
+
cron.indicators.push('wp-cron.php found');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (cron.disabled) {
|
|
145
|
+
cron.recommendations.push('Ensure server cron job calls wp-cron.php for scheduled triggers');
|
|
146
|
+
}
|
|
147
|
+
return cron;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function detectWebhookConfig() {
|
|
151
|
+
const webhooks = { configured: false, indicators: [] };
|
|
152
|
+
const raw = process.env.WP_SITES_CONFIG;
|
|
153
|
+
if (!raw) return webhooks;
|
|
154
|
+
|
|
155
|
+
let sites;
|
|
156
|
+
try { sites = JSON.parse(raw); } catch { return webhooks; }
|
|
157
|
+
if (!Array.isArray(sites)) return webhooks;
|
|
158
|
+
|
|
159
|
+
for (const site of sites) {
|
|
160
|
+
const label = site.id || site.url || 'unknown';
|
|
161
|
+
if (site.wc_webhook_secret || site.webhook_secret) {
|
|
162
|
+
webhooks.configured = true;
|
|
163
|
+
webhooks.indicators.push(`webhook secret configured for ${label}`);
|
|
164
|
+
}
|
|
165
|
+
if (site.url) {
|
|
166
|
+
webhooks.indicators.push(`site URL available for ${label} — wc-webhooks tools can be used`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return webhooks;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
// Main
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
|
|
176
|
+
function main() {
|
|
177
|
+
const cwdArg = argv.find(a => a.startsWith('--cwd='));
|
|
178
|
+
const cwd = cwdArg ? resolve(cwdArg.split('=')[1]) : process.cwd();
|
|
179
|
+
|
|
180
|
+
const channels = detectActionChannelConfig();
|
|
181
|
+
const plugins = detectAutomationPlugins(cwd);
|
|
182
|
+
const rest = detectCustomRestEndpoints(cwd);
|
|
183
|
+
const cron = detectWpCronConfig(cwd);
|
|
184
|
+
const webhooks = detectWebhookConfig();
|
|
185
|
+
|
|
186
|
+
const anyConfigured = channels.configured || plugins.found || rest.found || webhooks.configured || cron.indicators.length > 0;
|
|
187
|
+
|
|
188
|
+
const report = {
|
|
189
|
+
workflow_configured: anyConfigured,
|
|
190
|
+
action_channels: channels,
|
|
191
|
+
automation_plugins: plugins,
|
|
192
|
+
custom_rest_endpoints: rest,
|
|
193
|
+
wp_cron: cron,
|
|
194
|
+
webhooks,
|
|
195
|
+
cwd,
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
199
|
+
exit(anyConfigured ? 0 : 1);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
main();
|
|
@@ -129,3 +129,6 @@ See `references/fleet-monitoring.md`
|
|
|
129
129
|
- **`wp-security`** — hardening procedures triggered by monitoring alerts
|
|
130
130
|
- **`wp-performance`** — optimization actions based on performance trends
|
|
131
131
|
- **`wp-cicd`** — CI/CD quality gates that complement monitoring (pre-deploy checks)
|
|
132
|
+
- **`wp-search-console`** — add GSC search performance checks to periodic SEO monitoring
|
|
133
|
+
- **`wp-alerting`** — severity-based alert routing (Slack + email) for monitoring findings
|
|
134
|
+
- **`wp-analytics`** — analytics data used in performance dashboards and threshold evaluation
|
|
@@ -95,3 +95,5 @@ The script checks headless frontend presence, SEO plugins, content volume, custo
|
|
|
95
95
|
- `wp-rest-api` — REST API endpoints for content CRUD
|
|
96
96
|
- `wp-content` — content management fundamentals
|
|
97
97
|
- `wp-content-repurposing` — transform existing content into new formats
|
|
98
|
+
- `wp-search-console` — monitor performance of generated pages via GSC keyword tracking and indexing status
|
|
99
|
+
- `wp-content-optimization` — optimize programmatic page templates for headlines, readability, and SEO scoring
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wp-search-console
|
|
3
|
+
description: This skill should be used when the user asks about "Google Search Console",
|
|
4
|
+
"GSC", "keyword tracking", "keyword rankings", "search analytics",
|
|
5
|
+
"indexing status", "URL inspection", "sitemap management",
|
|
6
|
+
"search performance", "SEO feedback", "content SEO",
|
|
7
|
+
"competitor gap analysis", "keyword gap", or mentions monitoring
|
|
8
|
+
WordPress site search performance.
|
|
9
|
+
version: 1.0.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# WordPress Search Console Skill
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
Google Search Console connects WordPress content to Google Search data via 8 MCP tools. These tools enable keyword tracking, indexing management, sitemap operations, and search performance analysis directly from the WordPress authoring environment. By bridging GSC data with WordPress content, you can identify optimization opportunities, monitor indexing health, and build data-driven content strategies.
|
|
17
|
+
|
|
18
|
+
## When to Use
|
|
19
|
+
|
|
20
|
+
- User wants to check how their WordPress pages perform in Google Search
|
|
21
|
+
- User needs to track keyword rankings and position changes over time
|
|
22
|
+
- User asks about indexing status or why a page is not appearing in Google
|
|
23
|
+
- User wants to submit or manage XML sitemaps
|
|
24
|
+
- User needs search analytics data (clicks, impressions, CTR, average position)
|
|
25
|
+
- User asks about content SEO improvements based on search data
|
|
26
|
+
- User wants to identify keyword gaps or content opportunities
|
|
27
|
+
- User needs to inspect a specific URL for crawl and indexing details
|
|
28
|
+
|
|
29
|
+
## Decision Tree
|
|
30
|
+
|
|
31
|
+
1. **What aspect of Search Console?**
|
|
32
|
+
- "setup" / "connect GSC" / "service account" / "verify site" → GSC setup (Section 1)
|
|
33
|
+
- "keyword tracking" / "rankings" / "position" / "top queries" → Keyword tracking (Section 2)
|
|
34
|
+
- "indexing" / "URL inspection" / "sitemap" / "crawl" / "not indexed" → Indexing management (Section 3)
|
|
35
|
+
- "content SEO" / "underperforming pages" / "content refresh" / "optimize title" → Content SEO feedback (Section 4)
|
|
36
|
+
- "competitor gap" / "keyword gap" / "content opportunities" / "missing keywords" → Competitor gap analysis (Section 5)
|
|
37
|
+
|
|
38
|
+
2. **Run detection first:**
|
|
39
|
+
```bash
|
|
40
|
+
node skills/wp-search-console/scripts/search_console_inspect.mjs [--cwd=/path/to/project]
|
|
41
|
+
```
|
|
42
|
+
This identifies configured GSC credentials and verified sites.
|
|
43
|
+
|
|
44
|
+
## Service Overview
|
|
45
|
+
|
|
46
|
+
| Service | Tools | Auth Type | Use Case |
|
|
47
|
+
|---------|-------|-----------|----------|
|
|
48
|
+
| Google Search Console | 8 tools (`gsc_*`) | Service Account JSON | Search analytics, indexing, sitemaps |
|
|
49
|
+
|
|
50
|
+
## Sections
|
|
51
|
+
|
|
52
|
+
### Section 1: GSC Setup
|
|
53
|
+
See `references/gsc-setup.md`
|
|
54
|
+
- Service account creation in Google Cloud Console
|
|
55
|
+
- JSON key file configuration
|
|
56
|
+
- WP_SITES_CONFIG setup with gsc_service_account_key and gsc_site_url
|
|
57
|
+
- Site verification and permissions
|
|
58
|
+
|
|
59
|
+
### Section 2: Keyword Tracking
|
|
60
|
+
See `references/keyword-tracking.md`
|
|
61
|
+
- Using gsc_search_analytics and gsc_top_queries for keyword monitoring
|
|
62
|
+
- Date range and dimension filters
|
|
63
|
+
- Tracking position changes over time
|
|
64
|
+
- Query-level analysis (clicks, impressions, CTR, average position)
|
|
65
|
+
|
|
66
|
+
### Section 3: Indexing Management
|
|
67
|
+
See `references/indexing-management.md`
|
|
68
|
+
- Using gsc_inspect_url for indexing status checks
|
|
69
|
+
- Sitemap operations (list, submit, delete)
|
|
70
|
+
- Monitoring crawl coverage
|
|
71
|
+
- Handling indexing issues and bulk URL inspection
|
|
72
|
+
|
|
73
|
+
### Section 4: Content SEO Feedback
|
|
74
|
+
See `references/content-seo-feedback.md`
|
|
75
|
+
- Connecting search data to WordPress content strategy
|
|
76
|
+
- Identifying underperforming pages with gsc_page_performance
|
|
77
|
+
- Content refresh strategies based on declining metrics
|
|
78
|
+
- Title and meta description optimization from search data
|
|
79
|
+
|
|
80
|
+
### Section 5: Competitor Gap Analysis
|
|
81
|
+
See `references/competitor-gap-analysis.md`
|
|
82
|
+
- Identifying keyword gaps using search analytics data
|
|
83
|
+
- Analyzing query coverage vs potential queries
|
|
84
|
+
- Finding content opportunities from query data
|
|
85
|
+
- Cross-referencing with WordPress content inventory
|
|
86
|
+
|
|
87
|
+
## Reference Files
|
|
88
|
+
|
|
89
|
+
| File | Content |
|
|
90
|
+
|------|---------|
|
|
91
|
+
| `references/gsc-setup.md` | Service account creation, JSON key config, site verification |
|
|
92
|
+
| `references/keyword-tracking.md` | Search analytics queries, position monitoring, dashboards |
|
|
93
|
+
| `references/indexing-management.md` | URL inspection, sitemap management, crawl coverage |
|
|
94
|
+
| `references/content-seo-feedback.md` | Page performance, content refresh, title optimization |
|
|
95
|
+
| `references/competitor-gap-analysis.md` | Keyword gaps, content opportunities, position strategies |
|
|
96
|
+
|
|
97
|
+
## MCP Tools
|
|
98
|
+
|
|
99
|
+
| Tool | Description |
|
|
100
|
+
|------|-------------|
|
|
101
|
+
| `gsc_list_sites` | List all verified sites in Google Search Console |
|
|
102
|
+
| `gsc_search_analytics` | Query search analytics data with dimensions and filters |
|
|
103
|
+
| `gsc_inspect_url` | Inspect a URL for indexing status and crawl details |
|
|
104
|
+
| `gsc_list_sitemaps` | List submitted sitemaps and their status |
|
|
105
|
+
| `gsc_submit_sitemap` | Submit a new sitemap URL to GSC |
|
|
106
|
+
| `gsc_delete_sitemap` | Remove a sitemap from GSC |
|
|
107
|
+
| `gsc_top_queries` | Get top search queries with clicks, impressions, CTR, position |
|
|
108
|
+
| `gsc_page_performance` | Get page-level performance data with search metrics |
|
|
109
|
+
|
|
110
|
+
## Recommended Agent
|
|
111
|
+
|
|
112
|
+
Use the **`wp-content-strategist`** agent for SEO feedback loops and content optimization workflows that combine Search Console data with WordPress content management.
|
|
113
|
+
|
|
114
|
+
## Related Skills
|
|
115
|
+
|
|
116
|
+
- **`wp-programmatic-seo`** — generate SEO-optimized content at scale using search data
|
|
117
|
+
- **`wp-content-attribution`** — track content sources and attribute search traffic
|
|
118
|
+
- **`wp-monitoring`** — monitor site health metrics alongside search performance
|
|
119
|
+
- **`wp-social-email`** — distribute optimized content across social and email channels
|
|
120
|
+
- **`wp-content`** — create and manage WordPress content informed by search analytics
|
|
121
|
+
- **`wp-content-optimization`** — use GSC data as input for AI-driven content optimization and triage
|
|
122
|
+
- Per correlare keyword GSC con traffico GA4, vedi `wp-analytics`
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# Competitor Gap Analysis
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Competitor gap analysis uses Google Search Console data to identify keyword opportunities your WordPress site is missing. By analyzing your query coverage, position distribution, and content inventory, you can find topics where you have search visibility but no dedicated content, or where competitors likely rank for queries you do not yet target.
|
|
6
|
+
|
|
7
|
+
## Identifying Keyword Gaps
|
|
8
|
+
|
|
9
|
+
### Step 1: Export your full query coverage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Tool: gsc_search_analytics
|
|
13
|
+
Params:
|
|
14
|
+
site_url: "https://example.com/"
|
|
15
|
+
start_date: "2026-02-01"
|
|
16
|
+
end_date: "2026-02-28"
|
|
17
|
+
dimensions: ["query"]
|
|
18
|
+
row_limit: 5000
|
|
19
|
+
Returns: Array of all queries with clicks, impressions, ctr, position
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This gives you every query Google associates with your site. Sort by impressions to see which topics generate the most search visibility.
|
|
23
|
+
|
|
24
|
+
### Step 2: Map queries to content
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
Tool: gsc_search_analytics
|
|
28
|
+
Params:
|
|
29
|
+
site_url: "https://example.com/"
|
|
30
|
+
start_date: "2026-02-01"
|
|
31
|
+
end_date: "2026-02-28"
|
|
32
|
+
dimensions: ["query", "page"]
|
|
33
|
+
row_limit: 5000
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This maps each query to the page that ranks for it. Look for:
|
|
37
|
+
- **Queries without a dedicated page** — a query matches a generic page rather than a focused article
|
|
38
|
+
- **Multiple queries pointing to one page** — the page may be covering too many topics and could be split
|
|
39
|
+
- **Queries with position > 20** — you appear in results but have no strong content to compete
|
|
40
|
+
|
|
41
|
+
### Step 3: Identify content gaps
|
|
42
|
+
|
|
43
|
+
Cross-reference your queries with your WordPress content inventory:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
# Get all published content
|
|
47
|
+
Step 1: wp_list_posts status="publish" per_page=100 → Array of posts with titles and URLs
|
|
48
|
+
|
|
49
|
+
# Get all queries with page mapping
|
|
50
|
+
Step 2: gsc_search_analytics dimensions=["query", "page"] row_limit=5000
|
|
51
|
+
|
|
52
|
+
# Compare: queries that map to pages not optimized for them = content gaps
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Analyzing Query Coverage
|
|
56
|
+
|
|
57
|
+
### Position distribution analysis
|
|
58
|
+
|
|
59
|
+
Categorize your queries by position to understand coverage quality:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
Tool: gsc_search_analytics
|
|
63
|
+
Params:
|
|
64
|
+
site_url: "https://example.com/"
|
|
65
|
+
start_date: "2026-02-01"
|
|
66
|
+
end_date: "2026-02-28"
|
|
67
|
+
dimensions: ["query"]
|
|
68
|
+
row_limit: 5000
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Group results by position ranges:
|
|
72
|
+
|
|
73
|
+
| Position Range | Category | Strategy |
|
|
74
|
+
|----------------|----------|----------|
|
|
75
|
+
| 1-3 | Dominant | Protect — monitor and update regularly |
|
|
76
|
+
| 4-10 | Competitive | Optimize — content refresh, internal links, backlinks |
|
|
77
|
+
| 11-20 | Striking distance | Target — create supporting content, build topic clusters |
|
|
78
|
+
| 21-50 | Weak presence | Evaluate — is the content worth investing in? |
|
|
79
|
+
| 50+ | Minimal visibility | Decide — create new dedicated content or abandon |
|
|
80
|
+
|
|
81
|
+
### Topic cluster gaps
|
|
82
|
+
|
|
83
|
+
Group related queries into topic clusters to find areas where your coverage is incomplete:
|
|
84
|
+
|
|
85
|
+
1. Export all queries with `gsc_search_analytics`
|
|
86
|
+
2. Group queries by root topic (e.g., "wordpress seo", "wordpress performance", "wordpress security")
|
|
87
|
+
3. Count unique queries per topic and average position per topic
|
|
88
|
+
4. Topics with few queries or high average position are underserved
|
|
89
|
+
|
|
90
|
+
## Finding Content Opportunities
|
|
91
|
+
|
|
92
|
+
### High-impression, no-click queries
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
Tool: gsc_search_analytics
|
|
96
|
+
Params:
|
|
97
|
+
site_url: "https://example.com/"
|
|
98
|
+
start_date: "2026-02-01"
|
|
99
|
+
end_date: "2026-02-28"
|
|
100
|
+
dimensions: ["query", "page"]
|
|
101
|
+
row_limit: 1000
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Filter for queries where `impressions > 100` and `clicks == 0`. These are searches where Google shows your site but users never click — likely because:
|
|
105
|
+
- Your page does not match the query intent
|
|
106
|
+
- Your title and description are not compelling for that query
|
|
107
|
+
- You rank too low (position > 20) for the query to generate clicks
|
|
108
|
+
|
|
109
|
+
For each opportunity, decide whether to:
|
|
110
|
+
- **Optimize the existing page** for that query (if the topic is related)
|
|
111
|
+
- **Create a new dedicated page** targeting that query (if the topic is distinct)
|
|
112
|
+
|
|
113
|
+
### Question-based queries
|
|
114
|
+
|
|
115
|
+
Filter queries that start with question words (what, how, why, when, where, which, can, does, is):
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
Tool: gsc_search_analytics
|
|
119
|
+
Params:
|
|
120
|
+
site_url: "https://example.com/"
|
|
121
|
+
start_date: "2026-02-01"
|
|
122
|
+
end_date: "2026-02-28"
|
|
123
|
+
dimensions: ["query"]
|
|
124
|
+
dimension_filter_groups:
|
|
125
|
+
- filters:
|
|
126
|
+
- dimension: "query"
|
|
127
|
+
operator: "contains"
|
|
128
|
+
expression: "how to"
|
|
129
|
+
row_limit: 200
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Question queries map directly to FAQ content, how-to guides, and tutorial posts. If you appear for these queries but don't have dedicated content, create:
|
|
133
|
+
- FAQ sections on existing pages
|
|
134
|
+
- Standalone how-to articles
|
|
135
|
+
- Comprehensive guides that answer multiple related questions
|
|
136
|
+
|
|
137
|
+
### Long-tail opportunities
|
|
138
|
+
|
|
139
|
+
Queries with 4+ words are typically long-tail keywords with lower competition:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
Tool: gsc_search_analytics
|
|
143
|
+
Params:
|
|
144
|
+
site_url: "https://example.com/"
|
|
145
|
+
start_date: "2026-02-01"
|
|
146
|
+
end_date: "2026-02-28"
|
|
147
|
+
dimensions: ["query"]
|
|
148
|
+
row_limit: 2000
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Filter for queries containing 4+ words with `impressions > 20`. Long-tail keywords often have:
|
|
152
|
+
- Higher conversion intent
|
|
153
|
+
- Lower competition
|
|
154
|
+
- More specific content requirements
|
|
155
|
+
|
|
156
|
+
Create focused content addressing the exact long-tail query.
|
|
157
|
+
|
|
158
|
+
## Position Improvement Strategies
|
|
159
|
+
|
|
160
|
+
### Strategy 1: Topic clusters
|
|
161
|
+
|
|
162
|
+
For queries where you rank 11-20, build topic clusters:
|
|
163
|
+
|
|
164
|
+
1. Identify the core topic from your query data
|
|
165
|
+
2. Create a **pillar page** — comprehensive guide covering the broad topic
|
|
166
|
+
3. Create **cluster pages** — focused articles on subtopics
|
|
167
|
+
4. **Interlink** all cluster pages to the pillar and vice versa
|
|
168
|
+
5. Monitor position changes with `gsc_search_analytics` over 4-8 weeks
|
|
169
|
+
|
|
170
|
+
### Strategy 2: Content depth expansion
|
|
171
|
+
|
|
172
|
+
For queries where you rank 4-10 but cannot break into top 3:
|
|
173
|
+
|
|
174
|
+
1. Analyze the query with `gsc_search_analytics` filtered by the specific query
|
|
175
|
+
2. Fetch the ranking page with `wp_get_post`
|
|
176
|
+
3. Expand the content:
|
|
177
|
+
- Add 500-1000 words of additional depth
|
|
178
|
+
- Include data, statistics, or original research
|
|
179
|
+
- Add images, tables, or diagrams
|
|
180
|
+
- Add expert quotes or citations
|
|
181
|
+
4. Update via `wp_update_post`
|
|
182
|
+
|
|
183
|
+
### Strategy 3: Internal link building
|
|
184
|
+
|
|
185
|
+
Boost underperforming pages with strategic internal links:
|
|
186
|
+
|
|
187
|
+
1. Identify pages ranking 11-30 for valuable queries
|
|
188
|
+
2. Find high-authority pages on your site (top performers from `gsc_page_performance`)
|
|
189
|
+
3. Add contextual internal links from high-authority pages to underperforming pages
|
|
190
|
+
4. Use the target query as anchor text (naturally, not forced)
|
|
191
|
+
|
|
192
|
+
## Cross-Referencing with WordPress Content
|
|
193
|
+
|
|
194
|
+
### Audit workflow
|
|
195
|
+
|
|
196
|
+
Complete gap analysis workflow combining GSC and WordPress data:
|
|
197
|
+
|
|
198
|
+
1. **Export all queries**: `gsc_search_analytics` with `dimensions: ["query"]`, `row_limit: 5000`
|
|
199
|
+
2. **Export all pages**: `gsc_page_performance` with `row_limit: 500`
|
|
200
|
+
3. **List WordPress content**: `wp_list_posts` with `status: "publish"`
|
|
201
|
+
4. **Map coverage**: For each WordPress post, check if it has GSC data
|
|
202
|
+
5. **Find orphans**: WordPress posts with no GSC impressions may have indexing or quality issues
|
|
203
|
+
6. **Find gaps**: Queries without a dedicated WordPress post are content opportunities
|
|
204
|
+
|
|
205
|
+
### Priority scoring
|
|
206
|
+
|
|
207
|
+
Score content opportunities by potential impact:
|
|
208
|
+
|
|
209
|
+
| Factor | Weight | Measurement |
|
|
210
|
+
|--------|--------|-------------|
|
|
211
|
+
| Impressions | High | More impressions = more potential traffic |
|
|
212
|
+
| Current position | Medium | Closer to page 1 = easier to improve |
|
|
213
|
+
| CTR gap | Medium | Low CTR vs expected = quick win with title optimization |
|
|
214
|
+
| Competition | Low | Long-tail queries typically have less competition |
|
|
215
|
+
| Business relevance | High | Queries related to products/services have higher value |
|
|
216
|
+
|
|
217
|
+
## Best Practices
|
|
218
|
+
|
|
219
|
+
- **Regular cadence**: Run gap analysis monthly to catch new opportunities as query landscape evolves
|
|
220
|
+
- **Focus on intent**: Not all queries are worth targeting; prioritize queries that align with your content goals and business objectives
|
|
221
|
+
- **Quality over quantity**: One comprehensive article targeting a cluster of related queries outperforms five thin articles each targeting a single query
|
|
222
|
+
- **Track outcomes**: After creating content for identified gaps, monitor its performance in GSC after 4-8 weeks
|
|
223
|
+
- **Avoid keyword cannibalization**: Before creating new content, check if an existing page already targets the same query cluster
|
|
224
|
+
- **Use search data directionally**: GSC data shows what Google associates with your site, not what your competitors rank for; use it as a map of your current footprint and expand from there
|
|
225
|
+
- **Combine with external tools**: For true competitive analysis (what competitors rank for that you do not), supplement GSC data with third-party tools like Ahrefs, SEMrush, or Moz
|
|
226
|
+
- **Content calendar integration**: Feed identified opportunities into your WordPress editorial calendar for systematic execution
|