claude-plugin-wordpress-manager 2.3.1 → 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.
Files changed (65) hide show
  1. package/.claude-plugin/plugin.json +15 -3
  2. package/CHANGELOG.md +62 -0
  3. package/agents/wp-content-strategist.md +104 -0
  4. package/agents/wp-distribution-manager.md +98 -0
  5. package/docs/GUIDE.md +183 -23
  6. package/docs/plans/2026-03-01-tier3-wcop-design.md +373 -0
  7. package/docs/plans/2026-03-01-tier3-wcop-implementation.md +915 -0
  8. package/hooks/hooks.json +18 -0
  9. package/package.json +18 -3
  10. package/servers/wp-rest-bridge/build/tools/buffer.d.ts +3 -0
  11. package/servers/wp-rest-bridge/build/tools/buffer.js +205 -0
  12. package/servers/wp-rest-bridge/build/tools/comments.d.ts +6 -6
  13. package/servers/wp-rest-bridge/build/tools/gsc.d.ts +3 -0
  14. package/servers/wp-rest-bridge/build/tools/gsc.js +354 -0
  15. package/servers/wp-rest-bridge/build/tools/index.d.ts +38 -38
  16. package/servers/wp-rest-bridge/build/tools/index.js +12 -0
  17. package/servers/wp-rest-bridge/build/tools/mailchimp.d.ts +3 -0
  18. package/servers/wp-rest-bridge/build/tools/mailchimp.js +265 -0
  19. package/servers/wp-rest-bridge/build/tools/media.d.ts +2 -2
  20. package/servers/wp-rest-bridge/build/tools/multisite-sites.d.ts +2 -2
  21. package/servers/wp-rest-bridge/build/tools/plugin-repository.d.ts +1 -1
  22. package/servers/wp-rest-bridge/build/tools/search.d.ts +2 -2
  23. package/servers/wp-rest-bridge/build/tools/sendgrid.d.ts +3 -0
  24. package/servers/wp-rest-bridge/build/tools/sendgrid.js +255 -0
  25. package/servers/wp-rest-bridge/build/tools/unified-content.d.ts +8 -8
  26. package/servers/wp-rest-bridge/build/tools/unified-taxonomies.d.ts +4 -4
  27. package/servers/wp-rest-bridge/build/tools/users.d.ts +6 -6
  28. package/servers/wp-rest-bridge/build/tools/wc-coupons.d.ts +1 -1
  29. package/servers/wp-rest-bridge/build/tools/wc-customers.d.ts +3 -3
  30. package/servers/wp-rest-bridge/build/tools/wc-orders.d.ts +4 -4
  31. package/servers/wp-rest-bridge/build/tools/wc-products.d.ts +8 -8
  32. package/servers/wp-rest-bridge/build/tools/wc-webhooks.d.ts +4 -4
  33. package/servers/wp-rest-bridge/build/types.d.ts +122 -0
  34. package/servers/wp-rest-bridge/build/wordpress.d.ts +14 -0
  35. package/servers/wp-rest-bridge/build/wordpress.js +151 -0
  36. package/servers/wp-rest-bridge/package.json +1 -0
  37. package/skills/wordpress-router/references/decision-tree.md +8 -2
  38. package/skills/wp-content/SKILL.md +2 -0
  39. package/skills/wp-content-attribution/SKILL.md +2 -0
  40. package/skills/wp-content-optimization/SKILL.md +172 -0
  41. package/skills/wp-content-optimization/references/content-freshness.md +234 -0
  42. package/skills/wp-content-optimization/references/headline-optimization.md +171 -0
  43. package/skills/wp-content-optimization/references/meta-optimization.md +243 -0
  44. package/skills/wp-content-optimization/references/readability-analysis.md +201 -0
  45. package/skills/wp-content-optimization/references/seo-content-scoring.md +245 -0
  46. package/skills/wp-content-optimization/scripts/content_optimization_inspect.mjs +237 -0
  47. package/skills/wp-content-repurposing/SKILL.md +1 -0
  48. package/skills/wp-monitoring/SKILL.md +1 -0
  49. package/skills/wp-programmatic-seo/SKILL.md +2 -0
  50. package/skills/wp-search-console/SKILL.md +121 -0
  51. package/skills/wp-search-console/references/competitor-gap-analysis.md +226 -0
  52. package/skills/wp-search-console/references/content-seo-feedback.md +181 -0
  53. package/skills/wp-search-console/references/gsc-setup.md +110 -0
  54. package/skills/wp-search-console/references/indexing-management.md +182 -0
  55. package/skills/wp-search-console/references/keyword-tracking.md +181 -0
  56. package/skills/wp-search-console/scripts/search_console_inspect.mjs +178 -0
  57. package/skills/wp-social-email/SKILL.md +152 -0
  58. package/skills/wp-social-email/references/audience-segmentation.md +173 -0
  59. package/skills/wp-social-email/references/buffer-social-publishing.md +124 -0
  60. package/skills/wp-social-email/references/content-to-distribution.md +156 -0
  61. package/skills/wp-social-email/references/distribution-analytics.md +208 -0
  62. package/skills/wp-social-email/references/mailchimp-integration.md +145 -0
  63. package/skills/wp-social-email/references/sendgrid-transactional.md +165 -0
  64. package/skills/wp-social-email/scripts/distribution_inspect.mjs +165 -0
  65. package/skills/wp-webhooks/SKILL.md +1 -0
@@ -0,0 +1,145 @@
1
+ # Mailchimp Integration
2
+
3
+ ## Overview
4
+
5
+ Mailchimp is the email marketing platform for audience management and campaign delivery. The WP REST Bridge provides 7 MCP tools (`mc_*`) that cover the full campaign lifecycle: audience management, campaign creation, content setting, sending, and reporting.
6
+
7
+ ## Setup
8
+
9
+ ### API Key Configuration
10
+
11
+ Add Mailchimp credentials to `WP_SITES_CONFIG`:
12
+
13
+ ```json
14
+ {
15
+ "sites": [{
16
+ "name": "my-site",
17
+ "url": "https://example.com",
18
+ "distribution": {
19
+ "mailchimp": {
20
+ "api_key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us14",
21
+ "server_prefix": "us14"
22
+ }
23
+ }
24
+ }]
25
+ }
26
+ ```
27
+
28
+ The server prefix is the suffix of your API key (e.g., `us14`). All Mailchimp API requests route through `https://{server_prefix}.api.mailchimp.com/3.0/`.
29
+
30
+ ## Audience Management
31
+
32
+ ### List all audiences
33
+
34
+ ```
35
+ Tool: mc_list_audiences
36
+ Returns: Array of audiences with id, name, member count, stats
37
+ ```
38
+
39
+ ### Get audience members
40
+
41
+ ```
42
+ Tool: mc_get_audience_members
43
+ Params:
44
+ audience_id: "abc123def4"
45
+ count: 50
46
+ offset: 0
47
+ status: "subscribed" # subscribed | unsubscribed | cleaned | pending
48
+ ```
49
+
50
+ ### Add a subscriber
51
+
52
+ ```
53
+ Tool: mc_add_subscriber
54
+ Params:
55
+ audience_id: "abc123def4"
56
+ email: "user@example.com"
57
+ status: "subscribed"
58
+ merge_fields:
59
+ FNAME: "Jane"
60
+ LNAME: "Doe"
61
+ tags: ["wordpress-user", "blog-subscriber"]
62
+ ```
63
+
64
+ If the email already exists, the subscriber record is updated (upsert behavior).
65
+
66
+ ## Campaign Workflow
67
+
68
+ The campaign lifecycle follows four steps: create → set content → send → report.
69
+
70
+ ### Step 1: Create campaign
71
+
72
+ ```
73
+ Tool: mc_create_campaign
74
+ Params:
75
+ type: "regular" # regular | plaintext | absplit
76
+ audience_id: "abc123def4"
77
+ subject: "March Newsletter: New Blog Posts"
78
+ from_name: "My Site"
79
+ reply_to: "newsletter@example.com"
80
+ Returns: campaign_id
81
+ ```
82
+
83
+ ### Step 2: Set campaign content
84
+
85
+ ```
86
+ Tool: mc_set_campaign_content
87
+ Params:
88
+ campaign_id: "campaign_xyz"
89
+ html: "<html><body><h1>Newsletter</h1>...</body></html>"
90
+ ```
91
+
92
+ For WordPress content, fetch the post with `wp_get_post` and format the content as HTML for the campaign body.
93
+
94
+ ### Step 3: Send campaign
95
+
96
+ ```
97
+ Tool: mc_send_campaign
98
+ Params:
99
+ campaign_id: "campaign_xyz"
100
+ # Or schedule for later:
101
+ # schedule_time: "2026-03-15T10:00:00Z"
102
+ ```
103
+
104
+ ### Step 4: Get report
105
+
106
+ ```
107
+ Tool: mc_get_campaign_report
108
+ Params:
109
+ campaign_id: "campaign_xyz"
110
+ Returns:
111
+ emails_sent: 1250
112
+ opens: { total: 487, unique: 412, rate: 0.33 }
113
+ clicks: { total: 98, unique: 76, rate: 0.061 }
114
+ bounces: { hard: 3, soft: 12 }
115
+ unsubscribes: 2
116
+ ```
117
+
118
+ ## A/B Testing
119
+
120
+ Create an A/B split campaign to test subject lines, content, or send times:
121
+
122
+ ```
123
+ Tool: mc_create_campaign
124
+ Params:
125
+ type: "absplit"
126
+ audience_id: "abc123def4"
127
+ subject: "Version A Subject"
128
+ variate_settings:
129
+ test_size: 30 # 30% of audience gets test
130
+ wait_time: 4 # hours before picking winner
131
+ winner_criteria: "opens"
132
+ subject_lines:
133
+ - "Version A Subject"
134
+ - "Version B Subject"
135
+ ```
136
+
137
+ ## Best Practices
138
+
139
+ - **Send time optimization**: Analyze `mc_get_campaign_report` data to identify peak open hours; schedule campaigns accordingly
140
+ - **List hygiene**: Regularly check for `cleaned` status members; high bounce rates damage sender reputation
141
+ - **Merge fields**: Use `FNAME` personalization in subject lines — personalized subjects see 20-30% higher open rates
142
+ - **Tags over groups**: Use tags for flexible segmentation; they are easier to manage via API than interest groups
143
+ - **Double opt-in**: Enable for GDPR compliance; set subscriber status to `pending` and let Mailchimp handle the confirmation email
144
+ - **Unsubscribe handling**: Never re-add unsubscribed users; check status before calling `mc_add_subscriber`
145
+ - **Frequency**: Monitor unsubscribe rate per campaign; rates above 0.5% indicate over-sending
@@ -0,0 +1,165 @@
1
+ # SendGrid Transactional Email
2
+
3
+ ## Overview
4
+
5
+ SendGrid handles transactional email delivery — messages triggered by user actions such as account creation, password resets, order confirmations, and notifications. The WP REST Bridge provides 6 MCP tools (`sg_*`) for sending email, managing templates, and tracking contacts.
6
+
7
+ ## Setup
8
+
9
+ ### API Key Configuration
10
+
11
+ Add SendGrid credentials to `WP_SITES_CONFIG`:
12
+
13
+ ```json
14
+ {
15
+ "sites": [{
16
+ "name": "my-site",
17
+ "url": "https://example.com",
18
+ "distribution": {
19
+ "sendgrid": {
20
+ "api_key": "SG.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
21
+ "from_email": "noreply@example.com",
22
+ "from_name": "My Site"
23
+ }
24
+ }
25
+ }]
26
+ }
27
+ ```
28
+
29
+ Use a Restricted Access API key with only the permissions needed (Mail Send, Template Engine, Marketing Contacts).
30
+
31
+ ## Transactional Email
32
+
33
+ ### Send a plain email
34
+
35
+ ```
36
+ Tool: sg_send_email
37
+ Params:
38
+ to: "user@example.com"
39
+ subject: "Welcome to My Site"
40
+ html: "<h1>Welcome!</h1><p>Thanks for creating your account.</p>"
41
+ ```
42
+
43
+ ### Send with a dynamic template
44
+
45
+ ```
46
+ Tool: sg_send_email
47
+ Params:
48
+ to: "user@example.com"
49
+ template_id: "d-abc123def456"
50
+ dynamic_template_data:
51
+ first_name: "Jane"
52
+ order_number: "WC-1042"
53
+ order_total: "$49.99"
54
+ order_url: "https://example.com/my-account/orders/1042"
55
+ ```
56
+
57
+ ### Common transactional email types
58
+
59
+ | Type | Trigger | Template Variables |
60
+ |------|---------|-------------------|
61
+ | Welcome email | User registration | `first_name`, `login_url` |
62
+ | Password reset | Password reset request | `reset_link`, `expiry_time` |
63
+ | Order confirmation | WooCommerce order placed | `order_number`, `items`, `total` |
64
+ | Shipping notification | Order status → shipped | `tracking_number`, `carrier`, `eta` |
65
+ | Review request | 7 days after delivery | `product_name`, `review_url` |
66
+
67
+ ## Template Management
68
+
69
+ ### List templates
70
+
71
+ ```
72
+ Tool: sg_list_templates
73
+ Params:
74
+ generations: "dynamic" # legacy | dynamic
75
+ Returns: Array of templates with id, name, generation, versions
76
+ ```
77
+
78
+ ### Get template details
79
+
80
+ ```
81
+ Tool: sg_get_template
82
+ Params:
83
+ template_id: "d-abc123def456"
84
+ Returns:
85
+ id, name, generation
86
+ versions: [{ id, name, subject, html_content, active }]
87
+ ```
88
+
89
+ Dynamic templates use Handlebars syntax for variable substitution:
90
+
91
+ ```html
92
+ <h1>Hi {{first_name}},</h1>
93
+ <p>Your order #{{order_number}} has been confirmed.</p>
94
+ {{#if tracking_number}}
95
+ <p>Tracking: {{tracking_number}}</p>
96
+ {{/if}}
97
+ ```
98
+
99
+ ## Contact Management
100
+
101
+ ### List contacts
102
+
103
+ ```
104
+ Tool: sg_list_contacts
105
+ Params:
106
+ # Optional search query using SGQL
107
+ query: "email LIKE '%@example.com'"
108
+ Returns: Array of contacts with id, email, first_name, last_name, custom_fields
109
+ ```
110
+
111
+ ### Add or update contacts
112
+
113
+ ```
114
+ Tool: sg_add_contacts
115
+ Params:
116
+ list_ids: ["list_abc123"]
117
+ contacts:
118
+ - email: "user@example.com"
119
+ first_name: "Jane"
120
+ last_name: "Doe"
121
+ custom_fields:
122
+ wp_user_id: "42"
123
+ signup_source: "blog"
124
+ ```
125
+
126
+ Contacts are upserted by email address. If the email already exists, fields are merged.
127
+
128
+ ## WordPress Integration Patterns
129
+
130
+ ### New user → Welcome email
131
+
132
+ ```
133
+ 1. WordPress user_register event triggers webhook
134
+ 2. Webhook handler calls sg_send_email with welcome template
135
+ 3. sg_add_contacts adds user to "New Users" contact list
136
+ ```
137
+
138
+ ### WooCommerce order → Confirmation email
139
+
140
+ ```
141
+ 1. order.created webhook fires
142
+ 2. Extract order details (number, items, total)
143
+ 3. sg_send_email with order confirmation template + dynamic data
144
+ ```
145
+
146
+ ### Blog subscriber → Drip sequence
147
+
148
+ ```
149
+ 1. Newsletter form submission adds subscriber via mc_add_subscriber
150
+ 2. sg_send_email sends immediate welcome/confirmation
151
+ 3. Scheduled follow-ups via campaign automation
152
+ ```
153
+
154
+ ## Best Practices
155
+
156
+ - **SPF/DKIM/DMARC**: Configure DNS records for your sending domain; without these, emails land in spam
157
+ - SPF: Add SendGrid's include to your TXT record
158
+ - DKIM: Create CNAME records provided by SendGrid domain authentication
159
+ - DMARC: Start with `p=none` policy, move to `p=quarantine` after monitoring
160
+ - **Dedicated IP**: For volumes above 50k emails/month, use a dedicated IP and warm it gradually (start with 100/day, increase over 4 weeks)
161
+ - **Bounce handling**: Monitor `sg_get_stats` for bounce rates; rates above 5% trigger SendGrid compliance review
162
+ - **Unsubscribe**: Include an unsubscribe link in every email (required by CAN-SPAM); use SendGrid's built-in unsubscribe groups
163
+ - **Template versioning**: Keep templates in version control; use SendGrid's active version feature to deploy changes safely
164
+ - **Rate limiting**: SendGrid enforces rate limits per API key; batch contact additions in groups of 1000
165
+ - **From address consistency**: Use the same `from_email` across all transactional messages to build domain reputation
@@ -0,0 +1,165 @@
1
+ /**
2
+ * distribution_inspect.mjs — Detect social/email distribution configuration.
3
+ *
4
+ * Checks WP_SITES_CONFIG for connector API keys, WordPress plugins,
5
+ * and content readiness for distribution.
6
+ *
7
+ * Usage:
8
+ * node distribution_inspect.mjs [--cwd=/path/to/project]
9
+ *
10
+ * Exit codes:
11
+ * 0 — distribution configuration found
12
+ * 1 — no distribution configuration found
13
+ */
14
+
15
+ import { readFileSync, existsSync, readdirSync } from 'node:fs';
16
+ import { join, resolve } from 'node:path';
17
+ import { argv, stdout, exit } from 'node:process';
18
+
19
+ // ---------------------------------------------------------------------------
20
+ // Helpers
21
+ // ---------------------------------------------------------------------------
22
+
23
+ function readFileSafe(filePath) {
24
+ try { return readFileSync(filePath, 'utf-8'); } catch { return null; }
25
+ }
26
+
27
+ function existsSafe(filePath) {
28
+ try { return existsSync(filePath); } catch { return false; }
29
+ }
30
+
31
+ function globDir(dirPath) {
32
+ try { return readdirSync(dirPath); } catch { return []; }
33
+ }
34
+
35
+ // ---------------------------------------------------------------------------
36
+ // Detectors
37
+ // ---------------------------------------------------------------------------
38
+
39
+ function detectServices() {
40
+ const services = {
41
+ mailchimp: { configured: false, indicators: [] },
42
+ buffer: { configured: false, indicators: [] },
43
+ sendgrid: { configured: false, indicators: [] },
44
+ };
45
+
46
+ const raw = process.env.WP_SITES_CONFIG;
47
+ if (!raw) return services;
48
+
49
+ let sites;
50
+ try { sites = JSON.parse(raw); } catch { return services; }
51
+ if (!Array.isArray(sites)) return services;
52
+
53
+ for (const site of sites) {
54
+ const label = site.name || site.url || 'unknown';
55
+
56
+ if (site.mailchimp_api_key) {
57
+ services.mailchimp.configured = true;
58
+ services.mailchimp.indicators.push(`mailchimp_api_key configured for ${label}`);
59
+ }
60
+ if (site.buffer_access_token) {
61
+ services.buffer.configured = true;
62
+ services.buffer.indicators.push(`buffer_access_token configured for ${label}`);
63
+ }
64
+ if (site.sendgrid_api_key) {
65
+ services.sendgrid.configured = true;
66
+ services.sendgrid.indicators.push(`sendgrid_api_key configured for ${label}`);
67
+ }
68
+ }
69
+
70
+ return services;
71
+ }
72
+
73
+ function detectDistributionPlugins(cwd) {
74
+ const indicators = [];
75
+ const plugins = globDir(join(cwd, 'wp-content', 'plugins'));
76
+
77
+ const distributionPlugins = [
78
+ 'mailchimp-for-wp', 'mc4wp',
79
+ 'jetpack',
80
+ 'social-warfare', 'monarch', 'shared-counts',
81
+ 'newsletter', 'email-subscribers',
82
+ ];
83
+
84
+ for (const plugin of plugins) {
85
+ if (distributionPlugins.some(dp => plugin.toLowerCase().includes(dp))) {
86
+ indicators.push(`distribution_plugin: ${plugin}`);
87
+ }
88
+ }
89
+
90
+ return { found: indicators.length > 0, indicators };
91
+ }
92
+
93
+ function detectContentReadiness(cwd) {
94
+ // Check wp-content directory exists
95
+ if (!existsSafe(join(cwd, 'wp-content'))) return false;
96
+
97
+ // Check for posts/content indicators
98
+ const uploads = globDir(join(cwd, 'wp-content', 'uploads'));
99
+ if (uploads.length > 0) return true;
100
+
101
+ // Check for themes (site is set up)
102
+ const themes = globDir(join(cwd, 'wp-content', 'themes'));
103
+ if (themes.length > 0) return true;
104
+
105
+ return false;
106
+ }
107
+
108
+ // ---------------------------------------------------------------------------
109
+ // Main
110
+ // ---------------------------------------------------------------------------
111
+
112
+ function main() {
113
+ const cwdArg = argv.find(a => a.startsWith('--cwd='));
114
+ const cwd = cwdArg ? resolve(cwdArg.split('=')[1]) : process.cwd();
115
+
116
+ const services = detectServices();
117
+ const plugins = detectDistributionPlugins(cwd);
118
+ const contentReady = detectContentReadiness(cwd);
119
+
120
+ const hasServices = services.mailchimp.configured ||
121
+ services.buffer.configured ||
122
+ services.sendgrid.configured;
123
+ const found = hasServices || plugins.found;
124
+
125
+ const recommendations = [];
126
+
127
+ if (services.mailchimp.configured) {
128
+ recommendations.push('Mailchimp configured — use distribution_send skill to create and send email campaigns');
129
+ }
130
+ if (services.buffer.configured) {
131
+ recommendations.push('Buffer configured — use distribution_send skill to schedule social media posts');
132
+ }
133
+ if (services.sendgrid.configured) {
134
+ recommendations.push('SendGrid configured — use distribution_send skill for transactional and marketing emails');
135
+ }
136
+ if (plugins.found) {
137
+ recommendations.push('Distribution plugins detected — check plugin settings for additional integration opportunities');
138
+ }
139
+ if (!found) {
140
+ recommendations.push('No distribution configuration detected — use wp-social-email skill to set up Mailchimp, Buffer, or SendGrid');
141
+ }
142
+ if (!contentReady) {
143
+ recommendations.push('No content detected — create posts before setting up distribution workflows');
144
+ }
145
+ if (found && contentReady) {
146
+ recommendations.push('Distribution services and content are ready — consider scheduling an automated campaign');
147
+ }
148
+
149
+ const report = {
150
+ tool: 'distribution_inspect',
151
+ version: '1.0.0',
152
+ timestamp: new Date().toISOString(),
153
+ cwd,
154
+ found,
155
+ services,
156
+ plugins,
157
+ content_ready: contentReady,
158
+ recommendations,
159
+ };
160
+
161
+ stdout.write(JSON.stringify(report, null, 2) + '\n');
162
+ exit(found ? 0 : 1);
163
+ }
164
+
165
+ main();
@@ -105,3 +105,4 @@ See `references/payload-formats.md`
105
105
  - **`wp-headless`** — headless revalidation webhooks and ISR triggers
106
106
  - **`wp-woocommerce`** — WooCommerce store operations (webhook source events)
107
107
  - **`wp-cicd`** — CI/CD webhooks for deployment triggers
108
+ - **wp-social-email** — direct publishing to social/email (alternative to webhook-based distribution)