@wplaunchify/ml-mcp-server 2.7.7 → 2.7.9

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.
@@ -6,12 +6,20 @@ import { makeWordPressRequest } from '../wordpress.js';
6
6
  * Proxies to FluentCRM's database via WordPress plugin
7
7
  */
8
8
  // ==================== ZOD SCHEMA DEFINITIONS ====================
9
+ const fluentCrmContactStatusSchema = z.enum([
10
+ 'subscribed',
11
+ 'pending',
12
+ 'unsubscribed',
13
+ 'bounced',
14
+ 'complained',
15
+ 'transactional',
16
+ ]);
9
17
  // Contact schemas
10
18
  const listContactsSchema = z.object({
11
19
  page: z.number().optional(),
12
20
  per_page: z.number().optional(),
13
21
  search: z.string().optional(),
14
- status: z.enum(['subscribed', 'unsubscribed', 'bounced', 'complained']).optional(),
22
+ status: fluentCrmContactStatusSchema.optional(),
15
23
  tags: z.array(z.number()).optional(),
16
24
  lists: z.array(z.number()).optional(),
17
25
  });
@@ -19,11 +27,18 @@ const createContactSchema = z.object({
19
27
  email: z.string().email(),
20
28
  first_name: z.string().optional(),
21
29
  last_name: z.string().optional(),
22
- status: z.enum(['subscribed', 'unsubscribed', 'pending']).optional(),
30
+ status: fluentCrmContactStatusSchema.optional(),
23
31
  tags: z.array(z.number()).optional(),
24
32
  lists: z.array(z.number()).optional(),
25
33
  custom_fields: z.record(z.any()).optional(),
26
34
  });
35
+ const updateContactSchema = z.object({
36
+ id: z.number(),
37
+ email: z.string().email().optional(),
38
+ first_name: z.string().optional(),
39
+ last_name: z.string().optional(),
40
+ status: fluentCrmContactStatusSchema.optional(),
41
+ });
27
42
  // List schemas
28
43
  const listListsSchema = z.object({
29
44
  page: z.number().optional(),
@@ -59,6 +74,15 @@ const createCampaignSchema = z.object({
59
74
  status: z.enum(['draft', 'scheduled']).optional(),
60
75
  scheduled_at: z.string().optional(),
61
76
  });
77
+ const campaignIdSchema = z.object({ id: z.number() });
78
+ const campaignLinksSchema = z.object({
79
+ id: z.number(),
80
+ limit: z.number().int().positive().optional(),
81
+ });
82
+ const campaignClickersSchema = z.object({
83
+ id: z.number(),
84
+ include_contact: z.boolean().optional(),
85
+ });
62
86
  // Template schemas
63
87
  const listTemplatesSchema = z.object({
64
88
  page: z.number().optional(),
@@ -92,13 +116,7 @@ export const fluentCRMTools = [
92
116
  {
93
117
  name: 'fcrm_update_contact',
94
118
  description: 'Update an existing FluentCRM contact',
95
- inputSchema: { type: 'object', properties: z.object({
96
- id: z.number(),
97
- email: z.string().email().optional(),
98
- first_name: z.string().optional(),
99
- last_name: z.string().optional(),
100
- status: z.enum(['subscribed', 'unsubscribed', 'pending']).optional(),
101
- }).shape }
119
+ inputSchema: { type: 'object', properties: updateContactSchema.shape }
102
120
  },
103
121
  {
104
122
  name: 'fcrm_delete_contact',
@@ -218,7 +236,22 @@ export const fluentCRMTools = [
218
236
  {
219
237
  name: 'fcrm_get_campaign',
220
238
  description: 'Get a specific FluentCRM campaign by ID',
221
- inputSchema: { type: 'object', properties: z.object({ id: z.number() }).shape }
239
+ inputSchema: { type: 'object', properties: campaignIdSchema.shape }
240
+ },
241
+ {
242
+ name: 'fcrm_get_campaign_stats',
243
+ description: 'Get FluentCRM campaign analytics: sends, opens, clicks, rates, unsubscribes (requires FluentMCP REST route fc-manager/v1/fcrm/campaigns/{id}/stats)',
244
+ inputSchema: { type: 'object', properties: campaignIdSchema.shape }
245
+ },
246
+ {
247
+ name: 'fcrm_get_campaign_links',
248
+ description: 'Get per-link unique click counts for a FluentCRM campaign (optional limit; default 50 on server; requires FluentMCP route .../campaigns/{id}/links)',
249
+ inputSchema: { type: 'object', properties: campaignLinksSchema.shape }
250
+ },
251
+ {
252
+ name: 'fcrm_get_campaign_clickers',
253
+ description: 'List subscribers who clicked links in a campaign; set include_contact true for email and names (requires FluentMCP route .../campaigns/{id}/clickers)',
254
+ inputSchema: { type: 'object', properties: campaignClickersSchema.shape }
222
255
  },
223
256
  {
224
257
  name: 'fcrm_create_campaign',
@@ -537,6 +570,43 @@ export const fluentCRMHandlers = {
537
570
  return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } };
538
571
  }
539
572
  },
573
+ fcrm_get_campaign_stats: async (args) => {
574
+ try {
575
+ const response = await makeWordPressRequest('GET', `fc-manager/v1/fcrm/campaigns/${args.id}/stats`);
576
+ return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } };
577
+ }
578
+ catch (error) {
579
+ return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } };
580
+ }
581
+ },
582
+ fcrm_get_campaign_links: async (args) => {
583
+ try {
584
+ const params = new URLSearchParams();
585
+ if (args.limit != null)
586
+ params.append('limit', String(args.limit));
587
+ const q = params.toString();
588
+ const path = `fc-manager/v1/fcrm/campaigns/${args.id}/links` + (q ? `?${q}` : '');
589
+ const response = await makeWordPressRequest('GET', path);
590
+ return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } };
591
+ }
592
+ catch (error) {
593
+ return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } };
594
+ }
595
+ },
596
+ fcrm_get_campaign_clickers: async (args) => {
597
+ try {
598
+ const params = new URLSearchParams();
599
+ if (args.include_contact === true)
600
+ params.append('include_contact', 'true');
601
+ const q = params.toString();
602
+ const path = `fc-manager/v1/fcrm/campaigns/${args.id}/clickers` + (q ? `?${q}` : '');
603
+ const response = await makeWordPressRequest('GET', path);
604
+ return { toolResult: { content: [{ type: 'text', text: JSON.stringify(response, null, 2) }] } };
605
+ }
606
+ catch (error) {
607
+ return { toolResult: { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] } };
608
+ }
609
+ },
540
610
  // Template handlers
541
611
  fcrm_list_templates: async (args) => {
542
612
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wplaunchify/ml-mcp-server",
3
- "version": "2.7.7",
3
+ "version": "2.7.9",
4
4
  "description": "Universal MCP Server for WordPress + Fluent Suite (Community, CRM, Cart) + FluentMCP Pro. Comprehensive tools for AI-powered WordPress management via Claude, Cursor, and other MCP clients.",
5
5
  "type": "module",
6
6
  "main": "./build/server.js",