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.
Files changed (83) hide show
  1. package/.claude-plugin/plugin.json +10 -3
  2. package/CHANGELOG.md +103 -0
  3. package/agents/wp-content-strategist.md +104 -0
  4. package/agents/wp-monitoring-agent.md +44 -0
  5. package/agents/wp-site-manager.md +19 -0
  6. package/docs/GUIDE.md +183 -23
  7. package/docs/plans/2026-03-01-tier4-5-implementation.md +1783 -0
  8. package/docs/plans/2026-03-01-tier4-5-observability-automation-design.md +426 -0
  9. package/docs/plans/2026-03-01-wcop-reassessment-v2.6.0.md +403 -0
  10. package/hooks/hooks.json +9 -0
  11. package/package.json +19 -3
  12. package/servers/wp-rest-bridge/build/tools/comments.d.ts +6 -6
  13. package/servers/wp-rest-bridge/build/tools/cwv.d.ts +3 -0
  14. package/servers/wp-rest-bridge/build/tools/cwv.js +196 -0
  15. package/servers/wp-rest-bridge/build/tools/ga4.d.ts +3 -0
  16. package/servers/wp-rest-bridge/build/tools/ga4.js +323 -0
  17. package/servers/wp-rest-bridge/build/tools/gsc.d.ts +3 -0
  18. package/servers/wp-rest-bridge/build/tools/gsc.js +354 -0
  19. package/servers/wp-rest-bridge/build/tools/index.d.ts +38 -38
  20. package/servers/wp-rest-bridge/build/tools/index.js +18 -0
  21. package/servers/wp-rest-bridge/build/tools/media.d.ts +2 -2
  22. package/servers/wp-rest-bridge/build/tools/multisite-sites.d.ts +2 -2
  23. package/servers/wp-rest-bridge/build/tools/plausible.d.ts +3 -0
  24. package/servers/wp-rest-bridge/build/tools/plausible.js +207 -0
  25. package/servers/wp-rest-bridge/build/tools/plugin-repository.d.ts +1 -1
  26. package/servers/wp-rest-bridge/build/tools/search.d.ts +2 -2
  27. package/servers/wp-rest-bridge/build/tools/slack.d.ts +3 -0
  28. package/servers/wp-rest-bridge/build/tools/slack.js +129 -0
  29. package/servers/wp-rest-bridge/build/tools/unified-content.d.ts +8 -8
  30. package/servers/wp-rest-bridge/build/tools/unified-taxonomies.d.ts +4 -4
  31. package/servers/wp-rest-bridge/build/tools/users.d.ts +6 -6
  32. package/servers/wp-rest-bridge/build/tools/wc-coupons.d.ts +1 -1
  33. package/servers/wp-rest-bridge/build/tools/wc-customers.d.ts +3 -3
  34. package/servers/wp-rest-bridge/build/tools/wc-orders.d.ts +4 -4
  35. package/servers/wp-rest-bridge/build/tools/wc-products.d.ts +8 -8
  36. package/servers/wp-rest-bridge/build/tools/wc-webhooks.d.ts +4 -4
  37. package/servers/wp-rest-bridge/build/tools/wc-workflows.d.ts +3 -0
  38. package/servers/wp-rest-bridge/build/tools/wc-workflows.js +222 -0
  39. package/servers/wp-rest-bridge/build/wordpress.d.ts +23 -0
  40. package/servers/wp-rest-bridge/build/wordpress.js +178 -0
  41. package/servers/wp-rest-bridge/package.json +1 -0
  42. package/skills/wordpress-router/SKILL.md +1 -1
  43. package/skills/wordpress-router/references/decision-tree.md +12 -2
  44. package/skills/wp-alerting/SKILL.md +142 -0
  45. package/skills/wp-alerting/references/alert-thresholds.md +79 -0
  46. package/skills/wp-alerting/references/escalation-paths.md +92 -0
  47. package/skills/wp-alerting/references/report-scheduling.md +142 -0
  48. package/skills/wp-alerting/references/slack-integration.md +109 -0
  49. package/skills/wp-alerting/scripts/alerting_inspect.mjs +150 -0
  50. package/skills/wp-analytics/SKILL.md +158 -0
  51. package/skills/wp-analytics/references/analytics-dashboards.md +83 -0
  52. package/skills/wp-analytics/references/cwv-monitoring.md +101 -0
  53. package/skills/wp-analytics/references/ga4-integration.md +76 -0
  54. package/skills/wp-analytics/references/plausible-setup.md +92 -0
  55. package/skills/wp-analytics/references/traffic-attribution.md +92 -0
  56. package/skills/wp-analytics/scripts/analytics_inspect.mjs +153 -0
  57. package/skills/wp-content/SKILL.md +1 -0
  58. package/skills/wp-content-attribution/SKILL.md +3 -0
  59. package/skills/wp-content-optimization/SKILL.md +173 -0
  60. package/skills/wp-content-optimization/references/content-freshness.md +234 -0
  61. package/skills/wp-content-optimization/references/headline-optimization.md +171 -0
  62. package/skills/wp-content-optimization/references/meta-optimization.md +243 -0
  63. package/skills/wp-content-optimization/references/readability-analysis.md +201 -0
  64. package/skills/wp-content-optimization/references/seo-content-scoring.md +245 -0
  65. package/skills/wp-content-optimization/scripts/content_optimization_inspect.mjs +237 -0
  66. package/skills/wp-content-workflows/SKILL.md +142 -0
  67. package/skills/wp-content-workflows/references/content-lifecycle-hooks.md +131 -0
  68. package/skills/wp-content-workflows/references/multi-channel-actions.md +151 -0
  69. package/skills/wp-content-workflows/references/schedule-triggers.md +118 -0
  70. package/skills/wp-content-workflows/references/trigger-management.md +159 -0
  71. package/skills/wp-content-workflows/references/wp-action-hooks.md +114 -0
  72. package/skills/wp-content-workflows/scripts/workflow_inspect.mjs +202 -0
  73. package/skills/wp-monitoring/SKILL.md +3 -0
  74. package/skills/wp-programmatic-seo/SKILL.md +2 -0
  75. package/skills/wp-search-console/SKILL.md +122 -0
  76. package/skills/wp-search-console/references/competitor-gap-analysis.md +226 -0
  77. package/skills/wp-search-console/references/content-seo-feedback.md +181 -0
  78. package/skills/wp-search-console/references/gsc-setup.md +110 -0
  79. package/skills/wp-search-console/references/indexing-management.md +182 -0
  80. package/skills/wp-search-console/references/keyword-tracking.md +181 -0
  81. package/skills/wp-search-console/scripts/search_console_inspect.mjs +178 -0
  82. package/skills/wp-social-email/SKILL.md +1 -0
  83. package/skills/wp-webhooks/SKILL.md +1 -0
@@ -18,6 +18,12 @@ import { wcWebhookTools, wcWebhookHandlers } from './wc-webhooks.js';
18
18
  import { mailchimpTools, mailchimpHandlers } from './mailchimp.js';
19
19
  import { bufferTools, bufferHandlers } from './buffer.js';
20
20
  import { sendgridTools, sendgridHandlers } from './sendgrid.js';
21
+ import { gscTools, gscHandlers } from './gsc.js';
22
+ import { ga4Tools, ga4Handlers } from './ga4.js';
23
+ import { plausibleTools, plausibleHandlers } from './plausible.js';
24
+ import { cwvTools, cwvHandlers } from './cwv.js';
25
+ import { slackTools, slackHandlers } from './slack.js';
26
+ import { wcWorkflowTools, wcWorkflowHandlers } from './wc-workflows.js';
21
27
  // Combine all tools
22
28
  export const allTools = [
23
29
  ...unifiedContentTools, // 8 tools
@@ -40,6 +46,12 @@ export const allTools = [
40
46
  ...mailchimpTools, // 7 tools
41
47
  ...bufferTools, // 5 tools
42
48
  ...sendgridTools, // 6 tools
49
+ ...gscTools, // 8 tools
50
+ ...ga4Tools, // 6 tools
51
+ ...plausibleTools, // 4 tools
52
+ ...cwvTools, // 4 tools
53
+ ...slackTools, // 3 tools
54
+ ...wcWorkflowTools, // 4 tools
43
55
  ];
44
56
  // Combine all handlers
45
57
  export const toolHandlers = {
@@ -63,4 +75,10 @@ export const toolHandlers = {
63
75
  ...mailchimpHandlers,
64
76
  ...bufferHandlers,
65
77
  ...sendgridHandlers,
78
+ ...gscHandlers,
79
+ ...ga4Handlers,
80
+ ...plausibleHandlers,
81
+ ...cwvHandlers,
82
+ ...slackHandlers,
83
+ ...wcWorkflowHandlers,
66
84
  };
@@ -8,16 +8,16 @@ declare const listMediaSchema: z.ZodObject<{
8
8
  _fields: z.ZodOptional<z.ZodString>;
9
9
  include_pagination: z.ZodOptional<z.ZodBoolean>;
10
10
  }, "strict", z.ZodTypeAny, {
11
+ search?: string | undefined;
11
12
  page?: number | undefined;
12
13
  per_page?: number | undefined;
13
- search?: string | undefined;
14
14
  _embed?: boolean | undefined;
15
15
  _fields?: string | undefined;
16
16
  include_pagination?: boolean | undefined;
17
17
  }, {
18
+ search?: string | undefined;
18
19
  page?: number | undefined;
19
20
  per_page?: number | undefined;
20
- search?: string | undefined;
21
21
  _embed?: boolean | undefined;
22
22
  _fields?: string | undefined;
23
23
  include_pagination?: boolean | undefined;
@@ -23,14 +23,14 @@ declare const msCreateSiteSchema: z.ZodObject<{
23
23
  email: z.ZodString;
24
24
  site_id: z.ZodOptional<z.ZodString>;
25
25
  }, "strict", z.ZodTypeAny, {
26
+ email: string;
26
27
  slug: string;
27
28
  title: string;
28
- email: string;
29
29
  site_id?: string | undefined;
30
30
  }, {
31
+ email: string;
31
32
  slug: string;
32
33
  title: string;
33
- email: string;
34
34
  site_id?: string | undefined;
35
35
  }>;
36
36
  declare const msActivateSiteSchema: z.ZodObject<{
@@ -0,0 +1,3 @@
1
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
+ export declare const plausibleTools: Tool[];
3
+ export declare const plausibleHandlers: Record<string, Function>;
@@ -0,0 +1,207 @@
1
+ import { hasPlausible, makePlausibleRequest } from '../wordpress.js';
2
+ import { z } from 'zod';
3
+ // ── Zod Schemas ─────────────────────────────────────────────────
4
+ const periodEnum = z.enum(['day', '7d', '30d', 'month', '6mo', '12mo', 'custom']);
5
+ const plGetStatsSchema = z.object({
6
+ site_id: z.string().describe('Plausible site domain (e.g. "mysite.com")'),
7
+ period: periodEnum.optional().default('30d')
8
+ .describe('Time period (default: 30d)'),
9
+ date: z.string().optional()
10
+ .describe('Date in YYYY-MM-DD format (or date range for custom period: "2024-01-01,2024-01-31")'),
11
+ metrics: z.string().optional().default('visitors,pageviews,bounce_rate,visit_duration')
12
+ .describe('Comma-separated metrics (default: visitors,pageviews,bounce_rate,visit_duration)'),
13
+ }).strict();
14
+ const plGetTimeseriesSchema = z.object({
15
+ site_id: z.string().describe('Plausible site domain (e.g. "mysite.com")'),
16
+ period: periodEnum.optional().default('30d')
17
+ .describe('Time period (default: 30d)'),
18
+ date: z.string().optional()
19
+ .describe('Date in YYYY-MM-DD format (or date range for custom period)'),
20
+ metrics: z.string().optional().default('visitors,pageviews')
21
+ .describe('Comma-separated metrics (default: visitors,pageviews)'),
22
+ interval: z.enum(['date', 'month']).optional().default('date')
23
+ .describe('Data point interval (default: date)'),
24
+ }).strict();
25
+ const plGetBreakdownSchema = z.object({
26
+ site_id: z.string().describe('Plausible site domain (e.g. "mysite.com")'),
27
+ property: z.enum([
28
+ 'event:page',
29
+ 'visit:source',
30
+ 'visit:country',
31
+ 'visit:device',
32
+ 'visit:browser',
33
+ 'visit:os',
34
+ 'visit:utm_medium',
35
+ 'visit:utm_source',
36
+ 'visit:utm_campaign',
37
+ ]).describe('Property to break down by'),
38
+ period: periodEnum.optional().default('30d')
39
+ .describe('Time period (default: 30d)'),
40
+ date: z.string().optional()
41
+ .describe('Date in YYYY-MM-DD format (or date range for custom period)'),
42
+ metrics: z.string().optional().default('visitors,pageviews')
43
+ .describe('Comma-separated metrics (default: visitors,pageviews)'),
44
+ limit: z.number().optional().default(100)
45
+ .describe('Maximum number of results (default: 100)'),
46
+ }).strict();
47
+ const plGetRealtimeSchema = z.object({
48
+ site_id: z.string().describe('Plausible site domain (e.g. "mysite.com")'),
49
+ }).strict();
50
+ // ── Tool Definitions ────────────────────────────────────────────
51
+ export const plausibleTools = [
52
+ {
53
+ name: "pl_get_stats",
54
+ description: "Gets aggregate statistics from Plausible Analytics (visitors, pageviews, bounce rate, visit duration)",
55
+ inputSchema: {
56
+ type: "object",
57
+ properties: {
58
+ site_id: { type: "string", description: 'Plausible site domain (e.g. "mysite.com")' },
59
+ period: {
60
+ type: "string",
61
+ enum: ["day", "7d", "30d", "month", "6mo", "12mo", "custom"],
62
+ description: "Time period (default: 30d)",
63
+ },
64
+ date: { type: "string", description: 'Date in YYYY-MM-DD format (or date range for custom period: "2024-01-01,2024-01-31")' },
65
+ metrics: { type: "string", description: "Comma-separated metrics (default: visitors,pageviews,bounce_rate,visit_duration)" },
66
+ },
67
+ required: ["site_id"],
68
+ },
69
+ },
70
+ {
71
+ name: "pl_get_timeseries",
72
+ description: "Gets time-series data points from Plausible Analytics for charting trends over time",
73
+ inputSchema: {
74
+ type: "object",
75
+ properties: {
76
+ site_id: { type: "string", description: 'Plausible site domain (e.g. "mysite.com")' },
77
+ period: {
78
+ type: "string",
79
+ enum: ["day", "7d", "30d", "month", "6mo", "12mo", "custom"],
80
+ description: "Time period (default: 30d)",
81
+ },
82
+ date: { type: "string", description: "Date in YYYY-MM-DD format (or date range for custom period)" },
83
+ metrics: { type: "string", description: "Comma-separated metrics (default: visitors,pageviews)" },
84
+ interval: {
85
+ type: "string",
86
+ enum: ["date", "month"],
87
+ description: "Data point interval (default: date)",
88
+ },
89
+ },
90
+ required: ["site_id"],
91
+ },
92
+ },
93
+ {
94
+ name: "pl_get_breakdown",
95
+ description: "Gets a breakdown of stats by property (page, source, country, device, browser, OS, UTM params) from Plausible Analytics",
96
+ inputSchema: {
97
+ type: "object",
98
+ properties: {
99
+ site_id: { type: "string", description: 'Plausible site domain (e.g. "mysite.com")' },
100
+ property: {
101
+ type: "string",
102
+ enum: [
103
+ "event:page",
104
+ "visit:source",
105
+ "visit:country",
106
+ "visit:device",
107
+ "visit:browser",
108
+ "visit:os",
109
+ "visit:utm_medium",
110
+ "visit:utm_source",
111
+ "visit:utm_campaign",
112
+ ],
113
+ description: "Property to break down by",
114
+ },
115
+ period: {
116
+ type: "string",
117
+ enum: ["day", "7d", "30d", "month", "6mo", "12mo", "custom"],
118
+ description: "Time period (default: 30d)",
119
+ },
120
+ date: { type: "string", description: "Date in YYYY-MM-DD format (or date range for custom period)" },
121
+ metrics: { type: "string", description: "Comma-separated metrics (default: visitors,pageviews)" },
122
+ limit: { type: "number", description: "Maximum number of results (default: 100)" },
123
+ },
124
+ required: ["site_id", "property"],
125
+ },
126
+ },
127
+ {
128
+ name: "pl_get_realtime",
129
+ description: "Gets the number of current visitors on the site from Plausible Analytics",
130
+ inputSchema: {
131
+ type: "object",
132
+ properties: {
133
+ site_id: { type: "string", description: 'Plausible site domain (e.g. "mysite.com")' },
134
+ },
135
+ required: ["site_id"],
136
+ },
137
+ },
138
+ ];
139
+ // ── Handlers ────────────────────────────────────────────────────
140
+ export const plausibleHandlers = {
141
+ pl_get_stats: async (params) => {
142
+ if (!hasPlausible()) {
143
+ return { toolResult: { isError: true, content: [{ type: "text", text: "Plausible Analytics not configured. Add plausible_api_key to WP_SITES_CONFIG." }] } };
144
+ }
145
+ try {
146
+ const { site_id, period, date, metrics } = plGetStatsSchema.parse(params);
147
+ const queryParams = { site_id, period, metrics };
148
+ if (date)
149
+ queryParams.date = date;
150
+ const response = await makePlausibleRequest('GET', 'stats/aggregate', queryParams);
151
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
152
+ }
153
+ catch (error) {
154
+ const errorMessage = error.response?.data?.error || error.message;
155
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting Plausible stats: ${errorMessage}` }] } };
156
+ }
157
+ },
158
+ pl_get_timeseries: async (params) => {
159
+ if (!hasPlausible()) {
160
+ return { toolResult: { isError: true, content: [{ type: "text", text: "Plausible Analytics not configured. Add plausible_api_key to WP_SITES_CONFIG." }] } };
161
+ }
162
+ try {
163
+ const { site_id, period, date, metrics, interval } = plGetTimeseriesSchema.parse(params);
164
+ const queryParams = { site_id, period, metrics, interval };
165
+ if (date)
166
+ queryParams.date = date;
167
+ const response = await makePlausibleRequest('GET', 'stats/timeseries', queryParams);
168
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
169
+ }
170
+ catch (error) {
171
+ const errorMessage = error.response?.data?.error || error.message;
172
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting Plausible timeseries: ${errorMessage}` }] } };
173
+ }
174
+ },
175
+ pl_get_breakdown: async (params) => {
176
+ if (!hasPlausible()) {
177
+ return { toolResult: { isError: true, content: [{ type: "text", text: "Plausible Analytics not configured. Add plausible_api_key to WP_SITES_CONFIG." }] } };
178
+ }
179
+ try {
180
+ const { site_id, property, period, date, metrics, limit } = plGetBreakdownSchema.parse(params);
181
+ const queryParams = { site_id, property, period, metrics, limit };
182
+ if (date)
183
+ queryParams.date = date;
184
+ const response = await makePlausibleRequest('GET', 'stats/breakdown', queryParams);
185
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
186
+ }
187
+ catch (error) {
188
+ const errorMessage = error.response?.data?.error || error.message;
189
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting Plausible breakdown: ${errorMessage}` }] } };
190
+ }
191
+ },
192
+ pl_get_realtime: async (params) => {
193
+ if (!hasPlausible()) {
194
+ return { toolResult: { isError: true, content: [{ type: "text", text: "Plausible Analytics not configured. Add plausible_api_key to WP_SITES_CONFIG." }] } };
195
+ }
196
+ try {
197
+ const { site_id } = plGetRealtimeSchema.parse(params);
198
+ const queryParams = { site_id };
199
+ const response = await makePlausibleRequest('GET', 'stats/realtime/visitors', queryParams);
200
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify({ visitors: response }, null, 2) }] } };
201
+ }
202
+ catch (error) {
203
+ const errorMessage = error.response?.data?.error || error.message;
204
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting Plausible realtime visitors: ${errorMessage}` }] } };
205
+ }
206
+ },
207
+ };
@@ -5,9 +5,9 @@ declare const searchPluginRepositorySchema: z.ZodObject<{
5
5
  page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
6
6
  per_page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
7
7
  }, "strict", z.ZodTypeAny, {
8
+ search: string;
8
9
  page: number;
9
10
  per_page: number;
10
- search: string;
11
11
  }, {
12
12
  search: string;
13
13
  page?: number | undefined;
@@ -11,18 +11,18 @@ declare const wpSearchSchema: z.ZodObject<{
11
11
  include_pagination: z.ZodOptional<z.ZodBoolean>;
12
12
  }, "strip", z.ZodTypeAny, {
13
13
  search: string;
14
+ type?: string | undefined;
14
15
  page?: number | undefined;
15
16
  per_page?: number | undefined;
16
- type?: string | undefined;
17
17
  _embed?: boolean | undefined;
18
18
  _fields?: string | undefined;
19
19
  include_pagination?: boolean | undefined;
20
20
  subtype?: string | undefined;
21
21
  }, {
22
22
  search: string;
23
+ type?: string | undefined;
23
24
  page?: number | undefined;
24
25
  per_page?: number | undefined;
25
- type?: string | undefined;
26
26
  _embed?: boolean | undefined;
27
27
  _fields?: string | undefined;
28
28
  include_pagination?: boolean | undefined;
@@ -0,0 +1,3 @@
1
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
+ export declare const slackTools: Tool[];
3
+ export declare const slackHandlers: Record<string, Function>;
@@ -0,0 +1,129 @@
1
+ import { hasSlackWebhook, getSlackWebhookUrl, hasSlackBot, makeSlackBotRequest } from '../wordpress.js';
2
+ import axios from 'axios';
3
+ import { z } from 'zod';
4
+ // ── Zod Schemas ─────────────────────────────────────────────────
5
+ const slackSendAlertSchema = z.object({
6
+ text: z.string().describe('Alert message text (supports Slack markdown)'),
7
+ channel: z.string().optional().describe('Override channel (webhook default if omitted)'),
8
+ username: z.string().optional().default('WP Monitor').describe('Bot display name'),
9
+ icon_emoji: z.string().optional().default(':warning:').describe('Bot icon emoji'),
10
+ blocks: z.array(z.any()).optional().describe('Slack Block Kit blocks (optional, overrides text for rich formatting)'),
11
+ }).strict();
12
+ const slackSendMessageSchema = z.object({
13
+ channel: z.string().describe('Channel ID or name (e.g., #general or C01234ABC)'),
14
+ text: z.string().describe('Message text (required as fallback even with blocks)'),
15
+ blocks: z.array(z.any()).optional().describe('Slack Block Kit blocks for rich formatting'),
16
+ thread_ts: z.string().optional().describe('Thread timestamp for threaded replies'),
17
+ }).strict();
18
+ const slackListChannelsSchema = z.object({
19
+ limit: z.number().optional().default(100).describe('Max channels to return (default 100)'),
20
+ types: z.string().optional().default('public_channel').describe('Channel types (default: public_channel)'),
21
+ }).strict();
22
+ // ── Tool Definitions ────────────────────────────────────────────
23
+ export const slackTools = [
24
+ {
25
+ name: "slack_send_alert",
26
+ description: "Sends an alert notification to Slack via Incoming Webhook (zero-config, no Bot Token needed)",
27
+ inputSchema: {
28
+ type: "object",
29
+ properties: {
30
+ text: { type: "string", description: "Alert message text (Slack markdown)" },
31
+ channel: { type: "string", description: "Override channel (optional)" },
32
+ username: { type: "string", description: "Bot display name (default: WP Monitor)" },
33
+ icon_emoji: { type: "string", description: "Bot icon emoji (default: :warning:)" },
34
+ blocks: { type: "array", items: { type: "object" }, description: "Block Kit blocks (optional)" },
35
+ },
36
+ required: ["text"],
37
+ },
38
+ },
39
+ {
40
+ name: "slack_send_message",
41
+ description: "Sends a message to a Slack channel via Bot Token (supports Block Kit, threads)",
42
+ inputSchema: {
43
+ type: "object",
44
+ properties: {
45
+ channel: { type: "string", description: "Channel ID or name" },
46
+ text: { type: "string", description: "Message text (fallback for blocks)" },
47
+ blocks: { type: "array", items: { type: "object" }, description: "Block Kit blocks" },
48
+ thread_ts: { type: "string", description: "Thread timestamp for replies" },
49
+ },
50
+ required: ["channel", "text"],
51
+ },
52
+ },
53
+ {
54
+ name: "slack_list_channels",
55
+ description: "Lists Slack workspace channels via Bot Token",
56
+ inputSchema: {
57
+ type: "object",
58
+ properties: {
59
+ limit: { type: "number", description: "Max channels (default 100)" },
60
+ types: { type: "string", description: "Channel types (default: public_channel)" },
61
+ },
62
+ },
63
+ },
64
+ ];
65
+ // ── Handlers ────────────────────────────────────────────────────
66
+ export const slackHandlers = {
67
+ slack_send_alert: async (params) => {
68
+ if (!hasSlackWebhook()) {
69
+ return { toolResult: { isError: true, content: [{ type: "text", text: "Slack webhook not configured. Add slack_webhook_url to WP_SITES_CONFIG." }] } };
70
+ }
71
+ try {
72
+ const { text, channel, username, icon_emoji, blocks } = params;
73
+ const webhookUrl = getSlackWebhookUrl();
74
+ const payload = { text, username: username || 'WP Monitor', icon_emoji: icon_emoji || ':warning:' };
75
+ if (channel)
76
+ payload.channel = channel;
77
+ if (blocks)
78
+ payload.blocks = blocks;
79
+ await axios.post(webhookUrl, payload, { timeout: 10000 });
80
+ return { toolResult: { content: [{ type: "text", text: "Alert sent successfully to Slack." }] } };
81
+ }
82
+ catch (error) {
83
+ const errorMessage = error.response?.data || error.message;
84
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error sending Slack alert: ${typeof errorMessage === 'string' ? errorMessage : JSON.stringify(errorMessage)}` }] } };
85
+ }
86
+ },
87
+ slack_send_message: async (params) => {
88
+ if (!hasSlackBot()) {
89
+ return { toolResult: { isError: true, content: [{ type: "text", text: "Slack Bot not configured. Add slack_bot_token to WP_SITES_CONFIG." }] } };
90
+ }
91
+ try {
92
+ const { channel, text, blocks, thread_ts } = params;
93
+ const payload = { channel, text };
94
+ if (blocks)
95
+ payload.blocks = blocks;
96
+ if (thread_ts)
97
+ payload.thread_ts = thread_ts;
98
+ const response = await makeSlackBotRequest('POST', 'chat.postMessage', payload);
99
+ if (!response.ok) {
100
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Slack API error: ${response.error}` }] } };
101
+ }
102
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify({ ok: true, channel: response.channel, ts: response.ts }, null, 2) }] } };
103
+ }
104
+ catch (error) {
105
+ const errorMessage = error.response?.data?.error || error.message;
106
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error sending Slack message: ${errorMessage}` }] } };
107
+ }
108
+ },
109
+ slack_list_channels: async (params) => {
110
+ if (!hasSlackBot()) {
111
+ return { toolResult: { isError: true, content: [{ type: "text", text: "Slack Bot not configured. Add slack_bot_token to WP_SITES_CONFIG." }] } };
112
+ }
113
+ try {
114
+ const { limit, types } = params;
115
+ const response = await makeSlackBotRequest('GET', `conversations.list?limit=${limit || 100}&types=${types || 'public_channel'}`);
116
+ if (!response.ok) {
117
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Slack API error: ${response.error}` }] } };
118
+ }
119
+ const channels = (response.channels || []).map((ch) => ({
120
+ id: ch.id, name: ch.name, topic: ch.topic?.value, num_members: ch.num_members,
121
+ }));
122
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(channels, null, 2) }] } };
123
+ }
124
+ catch (error) {
125
+ const errorMessage = error.response?.data?.error || error.message;
126
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing Slack channels: ${errorMessage}` }] } };
127
+ }
128
+ },
129
+ };
@@ -20,9 +20,9 @@ declare const listContentSchema: z.ZodObject<{
20
20
  include_pagination: z.ZodOptional<z.ZodBoolean>;
21
21
  }, "strip", z.ZodTypeAny, {
22
22
  content_type: string;
23
+ search?: string | undefined;
23
24
  page?: number | undefined;
24
25
  per_page?: number | undefined;
25
- search?: string | undefined;
26
26
  slug?: string | undefined;
27
27
  status?: string | undefined;
28
28
  author?: number | number[] | undefined;
@@ -38,9 +38,9 @@ declare const listContentSchema: z.ZodObject<{
38
38
  include_pagination?: boolean | undefined;
39
39
  }, {
40
40
  content_type: string;
41
+ search?: string | undefined;
41
42
  page?: number | undefined;
42
43
  per_page?: number | undefined;
43
- search?: string | undefined;
44
44
  slug?: string | undefined;
45
45
  status?: string | undefined;
46
46
  author?: number | number[] | undefined;
@@ -61,13 +61,13 @@ declare const getContentSchema: z.ZodObject<{
61
61
  _embed: z.ZodOptional<z.ZodBoolean>;
62
62
  _fields: z.ZodOptional<z.ZodString>;
63
63
  }, "strip", z.ZodTypeAny, {
64
- content_type: string;
65
64
  id: number;
65
+ content_type: string;
66
66
  _embed?: boolean | undefined;
67
67
  _fields?: string | undefined;
68
68
  }, {
69
- content_type: string;
70
69
  id: number;
70
+ content_type: string;
71
71
  _embed?: boolean | undefined;
72
72
  _fields?: string | undefined;
73
73
  }>;
@@ -138,8 +138,8 @@ declare const updateContentSchema: z.ZodObject<{
138
138
  meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
139
139
  custom_fields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
140
140
  }, "strip", z.ZodTypeAny, {
141
- content_type: string;
142
141
  id: number;
142
+ content_type: string;
143
143
  slug?: string | undefined;
144
144
  status?: string | undefined;
145
145
  author?: number | undefined;
@@ -155,8 +155,8 @@ declare const updateContentSchema: z.ZodObject<{
155
155
  meta?: Record<string, any> | undefined;
156
156
  custom_fields?: Record<string, any> | undefined;
157
157
  }, {
158
- content_type: string;
159
158
  id: number;
159
+ content_type: string;
160
160
  slug?: string | undefined;
161
161
  status?: string | undefined;
162
162
  author?: number | undefined;
@@ -177,12 +177,12 @@ declare const deleteContentSchema: z.ZodObject<{
177
177
  id: z.ZodNumber;
178
178
  force: z.ZodOptional<z.ZodBoolean>;
179
179
  }, "strip", z.ZodTypeAny, {
180
- content_type: string;
181
180
  id: number;
181
+ content_type: string;
182
182
  force?: boolean | undefined;
183
183
  }, {
184
- content_type: string;
185
184
  id: number;
185
+ content_type: string;
186
186
  force?: boolean | undefined;
187
187
  }>;
188
188
  declare const discoverContentTypesSchema: z.ZodObject<{
@@ -25,12 +25,12 @@ declare const listTermsSchema: z.ZodObject<{
25
25
  include_pagination: z.ZodOptional<z.ZodBoolean>;
26
26
  }, "strip", z.ZodTypeAny, {
27
27
  taxonomy: string;
28
+ search?: string | undefined;
28
29
  page?: number | undefined;
29
30
  per_page?: number | undefined;
30
- search?: string | undefined;
31
31
  slug?: string | undefined;
32
32
  parent?: number | undefined;
33
- orderby?: "slug" | "id" | "description" | "name" | "include" | "term_group" | "count" | undefined;
33
+ orderby?: "id" | "slug" | "description" | "name" | "include" | "term_group" | "count" | undefined;
34
34
  order?: "asc" | "desc" | undefined;
35
35
  _embed?: boolean | undefined;
36
36
  _fields?: string | undefined;
@@ -38,12 +38,12 @@ declare const listTermsSchema: z.ZodObject<{
38
38
  hide_empty?: boolean | undefined;
39
39
  }, {
40
40
  taxonomy: string;
41
+ search?: string | undefined;
41
42
  page?: number | undefined;
42
43
  per_page?: number | undefined;
43
- search?: string | undefined;
44
44
  slug?: string | undefined;
45
45
  parent?: number | undefined;
46
- orderby?: "slug" | "id" | "description" | "name" | "include" | "term_group" | "count" | undefined;
46
+ orderby?: "id" | "slug" | "description" | "name" | "include" | "term_group" | "count" | undefined;
47
47
  order?: "asc" | "desc" | undefined;
48
48
  _embed?: boolean | undefined;
49
49
  _fields?: string | undefined;
@@ -12,10 +12,10 @@ declare const listUsersSchema: z.ZodObject<{
12
12
  _fields: z.ZodOptional<z.ZodString>;
13
13
  include_pagination: z.ZodOptional<z.ZodBoolean>;
14
14
  }, "strip", z.ZodTypeAny, {
15
+ search?: string | undefined;
15
16
  page?: number | undefined;
16
17
  per_page?: number | undefined;
17
- search?: string | undefined;
18
- orderby?: "url" | "slug" | "id" | "name" | "include" | "registered_date" | "email" | undefined;
18
+ orderby?: "url" | "id" | "email" | "slug" | "name" | "include" | "registered_date" | undefined;
19
19
  order?: "asc" | "desc" | undefined;
20
20
  _embed?: boolean | undefined;
21
21
  _fields?: string | undefined;
@@ -23,10 +23,10 @@ declare const listUsersSchema: z.ZodObject<{
23
23
  context?: "view" | "embed" | "edit" | undefined;
24
24
  roles?: string[] | undefined;
25
25
  }, {
26
+ search?: string | undefined;
26
27
  page?: number | undefined;
27
28
  per_page?: number | undefined;
28
- search?: string | undefined;
29
- orderby?: "url" | "slug" | "id" | "name" | "include" | "registered_date" | "email" | undefined;
29
+ orderby?: "url" | "id" | "email" | "slug" | "name" | "include" | "registered_date" | undefined;
30
30
  order?: "asc" | "desc" | undefined;
31
31
  _embed?: boolean | undefined;
32
32
  _fields?: string | undefined;
@@ -117,10 +117,10 @@ declare const updateUserSchema: z.ZodObject<{
117
117
  }, "strict", z.ZodTypeAny, {
118
118
  id: number;
119
119
  url?: string | undefined;
120
+ email?: string | undefined;
120
121
  slug?: string | undefined;
121
122
  description?: string | undefined;
122
123
  name?: string | undefined;
123
- email?: string | undefined;
124
124
  roles?: string[] | undefined;
125
125
  username?: string | undefined;
126
126
  first_name?: string | undefined;
@@ -131,10 +131,10 @@ declare const updateUserSchema: z.ZodObject<{
131
131
  }, {
132
132
  id: number;
133
133
  url?: string | undefined;
134
+ email?: string | undefined;
134
135
  slug?: string | undefined;
135
136
  description?: string | undefined;
136
137
  name?: string | undefined;
137
- email?: string | undefined;
138
138
  roles?: string[] | undefined;
139
139
  username?: string | undefined;
140
140
  first_name?: string | undefined;
@@ -9,9 +9,9 @@ declare const wcListCouponsSchema: z.ZodObject<{
9
9
  per_page: number;
10
10
  search?: string | undefined;
11
11
  }, {
12
+ search?: string | undefined;
12
13
  page?: number | undefined;
13
14
  per_page?: number | undefined;
14
- search?: string | undefined;
15
15
  }>;
16
16
  declare const wcGetCouponSchema: z.ZodObject<{
17
17
  id: z.ZodNumber;
@@ -14,15 +14,15 @@ declare const wcListCustomersSchema: z.ZodObject<{
14
14
  order: "asc" | "desc";
15
15
  role: "author" | "customer" | "all" | "administrator" | "editor" | "contributor" | "subscriber";
16
16
  search?: string | undefined;
17
- orderby?: "id" | "name" | "registered_date" | undefined;
18
17
  email?: string | undefined;
18
+ orderby?: "id" | "name" | "registered_date" | undefined;
19
19
  }, {
20
+ search?: string | undefined;
21
+ email?: string | undefined;
20
22
  page?: number | undefined;
21
23
  per_page?: number | undefined;
22
- search?: string | undefined;
23
24
  orderby?: "id" | "name" | "registered_date" | undefined;
24
25
  order?: "asc" | "desc" | undefined;
25
- email?: string | undefined;
26
26
  role?: "author" | "customer" | "all" | "administrator" | "editor" | "contributor" | "subscriber" | undefined;
27
27
  }>;
28
28
  declare const wcGetCustomerSchema: z.ZodObject<{